123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436843784388439844084418442844384448445844684478448844984508451845284538454845584568457845884598460846184628463846484658466846784688469847084718472847384748475847684778478847984808481848284838484848584868487848884898490849184928493849484958496849784988499850085018502850385048505850685078508850985108511851285138514851585168517851885198520852185228523852485258526852785288529853085318532853385348535853685378538853985408541854285438544854585468547854885498550855185528553855485558556855785588559856085618562856385648565856685678568856985708571857285738574857585768577857885798580858185828583858485858586858785888589859085918592859385948595859685978598859986008601860286038604860586068607860886098610861186128613861486158616861786188619862086218622862386248625862686278628862986308631863286338634863586368637863886398640864186428643864486458646864786488649865086518652865386548655865686578658865986608661866286638664866586668667866886698670867186728673867486758676867786788679868086818682868386848685868686878688868986908691869286938694869586968697869886998700870187028703870487058706870787088709871087118712871387148715871687178718871987208721872287238724872587268727872887298730873187328733873487358736873787388739874087418742874387448745874687478748874987508751875287538754875587568757875887598760876187628763876487658766876787688769877087718772877387748775877687778778877987808781878287838784878587868787878887898790879187928793879487958796879787988799880088018802880388048805880688078808880988108811881288138814881588168817881888198820882188228823882488258826882788288829883088318832883388348835883688378838883988408841884288438844884588468847884888498850885188528853885488558856885788588859886088618862886388648865886688678868886988708871887288738874887588768877887888798880888188828883888488858886888788888889889088918892889388948895889688978898889989008901890289038904890589068907890889098910891189128913891489158916891789188919892089218922892389248925892689278928892989308931893289338934893589368937893889398940894189428943894489458946894789488949895089518952895389548955895689578958895989608961896289638964896589668967896889698970897189728973897489758976897789788979898089818982898389848985898689878988898989908991899289938994899589968997899889999000900190029003900490059006900790089009901090119012901390149015901690179018901990209021902290239024902590269027902890299030903190329033903490359036903790389039904090419042904390449045904690479048904990509051905290539054905590569057905890599060906190629063906490659066906790689069907090719072907390749075907690779078907990809081908290839084908590869087908890899090909190929093909490959096909790989099910091019102910391049105910691079108910991109111911291139114911591169117911891199120912191229123912491259126912791289129913091319132913391349135913691379138913991409141914291439144914591469147914891499150915191529153915491559156915791589159916091619162916391649165916691679168916991709171917291739174917591769177917891799180918191829183918491859186918791889189919091919192919391949195919691979198919992009201920292039204920592069207920892099210921192129213921492159216921792189219922092219222922392249225922692279228922992309231923292339234923592369237923892399240924192429243924492459246924792489249925092519252925392549255925692579258925992609261926292639264926592669267926892699270927192729273927492759276927792789279928092819282928392849285928692879288928992909291929292939294929592969297929892999300930193029303930493059306930793089309931093119312931393149315931693179318931993209321932293239324932593269327932893299330933193329333933493359336933793389339934093419342934393449345934693479348934993509351935293539354935593569357935893599360936193629363936493659366936793689369937093719372937393749375937693779378937993809381938293839384938593869387938893899390939193929393939493959396939793989399940094019402940394049405940694079408940994109411941294139414941594169417941894199420942194229423942494259426942794289429943094319432943394349435943694379438943994409441944294439444944594469447944894499450945194529453945494559456945794589459946094619462946394649465946694679468946994709471947294739474947594769477947894799480948194829483948494859486948794889489949094919492949394949495949694979498949995009501950295039504950595069507950895099510951195129513951495159516951795189519952095219522952395249525952695279528952995309531953295339534953595369537953895399540954195429543954495459546954795489549955095519552955395549555955695579558955995609561956295639564956595669567956895699570957195729573957495759576957795789579958095819582958395849585958695879588958995909591959295939594959595969597959895999600960196029603960496059606960796089609961096119612961396149615961696179618961996209621962296239624962596269627962896299630963196329633963496359636963796389639964096419642964396449645964696479648964996509651965296539654965596569657965896599660966196629663966496659666966796689669967096719672967396749675967696779678967996809681968296839684968596869687968896899690969196929693969496959696969796989699970097019702970397049705970697079708970997109711971297139714971597169717971897199720972197229723972497259726972797289729973097319732973397349735973697379738973997409741974297439744974597469747974897499750975197529753975497559756975797589759976097619762976397649765976697679768976997709771977297739774977597769777977897799780978197829783978497859786978797889789979097919792979397949795979697979798979998009801980298039804980598069807980898099810981198129813981498159816981798189819982098219822982398249825982698279828982998309831983298339834983598369837983898399840984198429843984498459846984798489849985098519852985398549855985698579858985998609861986298639864986598669867986898699870987198729873987498759876987798789879988098819882988398849885988698879888988998909891989298939894989598969897989898999900990199029903990499059906990799089909991099119912991399149915991699179918991999209921992299239924992599269927992899299930993199329933993499359936993799389939994099419942994399449945994699479948994999509951995299539954995599569957995899599960996199629963996499659966996799689969997099719972997399749975997699779978997999809981998299839984998599869987998899899990999199929993999499959996999799989999100001000110002100031000410005100061000710008100091001010011100121001310014100151001610017100181001910020100211002210023100241002510026100271002810029100301003110032100331003410035100361003710038100391004010041100421004310044100451004610047100481004910050100511005210053100541005510056100571005810059100601006110062100631006410065100661006710068100691007010071100721007310074100751007610077100781007910080100811008210083100841008510086100871008810089100901009110092100931009410095100961009710098100991010010101101021010310104101051010610107101081010910110101111011210113101141011510116101171011810119101201012110122101231012410125101261012710128101291013010131101321013310134101351013610137101381013910140101411014210143101441014510146101471014810149101501015110152101531015410155101561015710158101591016010161101621016310164101651016610167101681016910170101711017210173101741017510176101771017810179101801018110182101831018410185101861018710188101891019010191101921019310194101951019610197101981019910200102011020210203102041020510206102071020810209102101021110212102131021410215102161021710218102191022010221102221022310224102251022610227102281022910230102311023210233102341023510236102371023810239102401024110242102431024410245102461024710248102491025010251102521025310254102551025610257102581025910260102611026210263102641026510266102671026810269102701027110272102731027410275102761027710278102791028010281102821028310284102851028610287102881028910290102911029210293102941029510296102971029810299103001030110302103031030410305103061030710308103091031010311103121031310314103151031610317103181031910320103211032210323103241032510326103271032810329103301033110332103331033410335103361033710338103391034010341103421034310344103451034610347103481034910350103511035210353103541035510356103571035810359103601036110362103631036410365103661036710368103691037010371103721037310374103751037610377103781037910380103811038210383103841038510386103871038810389103901039110392103931039410395103961039710398103991040010401104021040310404104051040610407104081040910410104111041210413104141041510416104171041810419104201042110422104231042410425104261042710428104291043010431104321043310434104351043610437104381043910440104411044210443104441044510446104471044810449104501045110452104531045410455104561045710458104591046010461104621046310464104651046610467104681046910470104711047210473104741047510476104771047810479104801048110482104831048410485104861048710488104891049010491104921049310494104951049610497104981049910500105011050210503105041050510506105071050810509105101051110512105131051410515105161051710518105191052010521105221052310524105251052610527105281052910530105311053210533105341053510536105371053810539105401054110542105431054410545105461054710548105491055010551105521055310554105551055610557105581055910560105611056210563105641056510566105671056810569105701057110572105731057410575105761057710578105791058010581105821058310584105851058610587105881058910590105911059210593105941059510596105971059810599106001060110602106031060410605106061060710608106091061010611106121061310614106151061610617106181061910620106211062210623106241062510626106271062810629106301063110632106331063410635106361063710638106391064010641106421064310644106451064610647106481064910650106511065210653106541065510656106571065810659106601066110662106631066410665106661066710668106691067010671106721067310674106751067610677106781067910680106811068210683106841068510686106871068810689106901069110692106931069410695106961069710698106991070010701107021070310704107051070610707107081070910710107111071210713107141071510716107171071810719107201072110722107231072410725107261072710728107291073010731107321073310734107351073610737107381073910740107411074210743107441074510746107471074810749107501075110752107531075410755107561075710758107591076010761107621076310764107651076610767107681076910770107711077210773107741077510776107771077810779107801078110782107831078410785107861078710788107891079010791107921079310794107951079610797107981079910800108011080210803108041080510806108071080810809108101081110812108131081410815108161081710818108191082010821108221082310824108251082610827108281082910830108311083210833108341083510836108371083810839108401084110842108431084410845108461084710848108491085010851108521085310854108551085610857108581085910860108611086210863108641086510866108671086810869108701087110872108731087410875108761087710878108791088010881108821088310884108851088610887108881088910890108911089210893108941089510896108971089810899109001090110902109031090410905109061090710908109091091010911109121091310914109151091610917109181091910920109211092210923109241092510926109271092810929109301093110932109331093410935109361093710938109391094010941109421094310944109451094610947109481094910950109511095210953109541095510956109571095810959109601096110962109631096410965109661096710968109691097010971109721097310974109751097610977109781097910980109811098210983109841098510986109871098810989109901099110992109931099410995109961099710998109991100011001110021100311004110051100611007110081100911010110111101211013110141101511016110171101811019110201102111022110231102411025110261102711028110291103011031110321103311034110351103611037110381103911040110411104211043110441104511046110471104811049110501105111052110531105411055110561105711058110591106011061110621106311064110651106611067110681106911070110711107211073110741107511076110771107811079110801108111082110831108411085110861108711088110891109011091110921109311094110951109611097110981109911100111011110211103111041110511106111071110811109111101111111112111131111411115111161111711118111191112011121111221112311124111251112611127111281112911130111311113211133111341113511136111371113811139111401114111142111431114411145111461114711148111491115011151111521115311154111551115611157111581115911160111611116211163111641116511166111671116811169111701117111172111731117411175111761117711178111791118011181111821118311184111851118611187111881118911190111911119211193111941119511196111971119811199112001120111202112031120411205112061120711208112091121011211112121121311214112151121611217112181121911220112211122211223112241122511226112271122811229112301123111232112331123411235112361123711238112391124011241112421124311244112451124611247112481124911250112511125211253112541125511256112571125811259112601126111262112631126411265112661126711268112691127011271112721127311274112751127611277112781127911280112811128211283112841128511286112871128811289112901129111292112931129411295112961129711298112991130011301113021130311304113051130611307113081130911310113111131211313113141131511316113171131811319113201132111322113231132411325113261132711328113291133011331113321133311334113351133611337113381133911340113411134211343113441134511346113471134811349113501135111352113531135411355113561135711358113591136011361113621136311364113651136611367113681136911370113711137211373113741137511376113771137811379113801138111382113831138411385113861138711388113891139011391113921139311394113951139611397113981139911400114011140211403114041140511406114071140811409114101141111412114131141411415114161141711418114191142011421114221142311424114251142611427114281142911430114311143211433114341143511436114371143811439114401144111442114431144411445114461144711448114491145011451114521145311454114551145611457114581145911460114611146211463114641146511466114671146811469114701147111472114731147411475114761147711478114791148011481114821148311484114851148611487114881148911490114911149211493114941149511496114971149811499115001150111502115031150411505115061150711508115091151011511115121151311514115151151611517115181151911520115211152211523115241152511526115271152811529115301153111532115331153411535115361153711538115391154011541115421154311544115451154611547115481154911550115511155211553115541155511556115571155811559115601156111562115631156411565115661156711568115691157011571115721157311574115751157611577115781157911580115811158211583115841158511586115871158811589115901159111592115931159411595115961159711598115991160011601116021160311604116051160611607116081160911610116111161211613116141161511616116171161811619116201162111622116231162411625116261162711628116291163011631116321163311634116351163611637116381163911640116411164211643116441164511646116471164811649116501165111652116531165411655116561165711658116591166011661116621166311664116651166611667116681166911670116711167211673116741167511676116771167811679116801168111682116831168411685116861168711688116891169011691116921169311694116951169611697116981169911700117011170211703117041170511706117071170811709117101171111712117131171411715117161171711718117191172011721117221172311724117251172611727117281172911730117311173211733117341173511736117371173811739117401174111742117431174411745117461174711748117491175011751117521175311754117551175611757117581175911760117611176211763117641176511766117671176811769117701177111772117731177411775117761177711778117791178011781117821178311784117851178611787117881178911790117911179211793117941179511796117971179811799118001180111802118031180411805118061180711808118091181011811118121181311814118151181611817118181181911820118211182211823118241182511826118271182811829118301183111832118331183411835118361183711838118391184011841118421184311844118451184611847118481184911850118511185211853118541185511856118571185811859118601186111862118631186411865118661186711868118691187011871118721187311874118751187611877118781187911880118811188211883118841188511886118871188811889118901189111892118931189411895118961189711898118991190011901119021190311904119051190611907119081190911910119111191211913119141191511916119171191811919119201192111922119231192411925119261192711928119291193011931119321193311934119351193611937119381193911940119411194211943119441194511946119471194811949119501195111952119531195411955119561195711958119591196011961119621196311964119651196611967119681196911970119711197211973119741197511976119771197811979119801198111982119831198411985119861198711988119891199011991119921199311994119951199611997119981199912000120011200212003120041200512006120071200812009120101201112012120131201412015120161201712018120191202012021120221202312024120251202612027120281202912030120311203212033120341203512036120371203812039120401204112042120431204412045120461204712048120491205012051120521205312054120551205612057120581205912060120611206212063120641206512066120671206812069120701207112072120731207412075120761207712078120791208012081120821208312084120851208612087120881208912090120911209212093120941209512096120971209812099121001210112102121031210412105121061210712108121091211012111121121211312114121151211612117121181211912120121211212212123121241212512126121271212812129121301213112132121331213412135121361213712138121391214012141121421214312144121451214612147121481214912150121511215212153121541215512156121571215812159121601216112162121631216412165121661216712168121691217012171121721217312174121751217612177121781217912180121811218212183121841218512186121871218812189121901219112192121931219412195121961219712198121991220012201122021220312204122051220612207122081220912210122111221212213122141221512216122171221812219122201222112222122231222412225122261222712228122291223012231122321223312234122351223612237122381223912240122411224212243122441224512246122471224812249122501225112252122531225412255122561225712258122591226012261122621226312264122651226612267122681226912270122711227212273122741227512276122771227812279122801228112282122831228412285122861228712288122891229012291122921229312294122951229612297122981229912300123011230212303123041230512306123071230812309123101231112312123131231412315123161231712318123191232012321123221232312324123251232612327123281232912330123311233212333123341233512336123371233812339123401234112342123431234412345123461234712348123491235012351123521235312354123551235612357123581235912360123611236212363123641236512366123671236812369123701237112372123731237412375123761237712378123791238012381123821238312384123851238612387123881238912390123911239212393123941239512396123971239812399124001240112402124031240412405124061240712408124091241012411124121241312414124151241612417124181241912420124211242212423124241242512426124271242812429124301243112432124331243412435124361243712438124391244012441124421244312444124451244612447124481244912450124511245212453124541245512456124571245812459124601246112462124631246412465124661246712468124691247012471124721247312474124751247612477124781247912480124811248212483124841248512486124871248812489124901249112492124931249412495124961249712498124991250012501125021250312504125051250612507125081250912510125111251212513125141251512516125171251812519125201252112522125231252412525125261252712528125291253012531125321253312534125351253612537125381253912540125411254212543125441254512546125471254812549125501255112552125531255412555125561255712558125591256012561125621256312564125651256612567125681256912570125711257212573125741257512576125771257812579125801258112582125831258412585125861258712588125891259012591125921259312594125951259612597125981259912600126011260212603126041260512606126071260812609126101261112612126131261412615126161261712618126191262012621126221262312624126251262612627126281262912630126311263212633126341263512636126371263812639126401264112642126431264412645126461264712648126491265012651126521265312654126551265612657126581265912660126611266212663126641266512666126671266812669126701267112672126731267412675126761267712678126791268012681126821268312684126851268612687126881268912690126911269212693126941269512696126971269812699127001270112702127031270412705127061270712708127091271012711127121271312714127151271612717127181271912720127211272212723127241272512726127271272812729127301273112732127331273412735127361273712738127391274012741127421274312744127451274612747127481274912750127511275212753127541275512756127571275812759127601276112762127631276412765127661276712768127691277012771127721277312774127751277612777127781277912780127811278212783127841278512786127871278812789127901279112792127931279412795127961279712798127991280012801128021280312804128051280612807128081280912810128111281212813128141281512816128171281812819128201282112822128231282412825128261282712828128291283012831128321283312834128351283612837128381283912840128411284212843128441284512846128471284812849128501285112852128531285412855128561285712858128591286012861128621286312864128651286612867128681286912870128711287212873128741287512876128771287812879128801288112882128831288412885128861288712888128891289012891128921289312894128951289612897128981289912900129011290212903129041290512906129071290812909129101291112912129131291412915129161291712918129191292012921129221292312924129251292612927129281292912930129311293212933129341293512936129371293812939129401294112942129431294412945129461294712948129491295012951129521295312954129551295612957129581295912960129611296212963129641296512966129671296812969129701297112972129731297412975129761297712978129791298012981129821298312984129851298612987129881298912990129911299212993129941299512996129971299812999130001300113002130031300413005130061300713008130091301013011130121301313014130151301613017130181301913020130211302213023130241302513026130271302813029130301303113032130331303413035130361303713038130391304013041130421304313044130451304613047130481304913050130511305213053130541305513056130571305813059130601306113062130631306413065130661306713068130691307013071130721307313074130751307613077130781307913080130811308213083130841308513086130871308813089130901309113092130931309413095130961309713098130991310013101131021310313104131051310613107131081310913110131111311213113131141311513116131171311813119131201312113122131231312413125131261312713128131291313013131131321313313134131351313613137131381313913140131411314213143131441314513146131471314813149131501315113152131531315413155131561315713158131591316013161131621316313164131651316613167131681316913170131711317213173131741317513176131771317813179131801318113182131831318413185131861318713188131891319013191131921319313194131951319613197131981319913200132011320213203132041320513206132071320813209132101321113212132131321413215132161321713218132191322013221132221322313224132251322613227132281322913230132311323213233132341323513236132371323813239132401324113242132431324413245132461324713248132491325013251132521325313254132551325613257132581325913260132611326213263132641326513266132671326813269132701327113272132731327413275132761327713278132791328013281132821328313284132851328613287132881328913290132911329213293132941329513296132971329813299133001330113302133031330413305133061330713308133091331013311133121331313314133151331613317133181331913320133211332213323133241332513326133271332813329133301333113332133331333413335133361333713338133391334013341133421334313344133451334613347133481334913350133511335213353133541335513356133571335813359133601336113362133631336413365133661336713368133691337013371133721337313374133751337613377133781337913380133811338213383133841338513386133871338813389133901339113392133931339413395133961339713398133991340013401134021340313404134051340613407134081340913410134111341213413134141341513416134171341813419134201342113422134231342413425134261342713428134291343013431134321343313434134351343613437134381343913440134411344213443134441344513446134471344813449134501345113452134531345413455134561345713458134591346013461134621346313464134651346613467134681346913470134711347213473134741347513476134771347813479134801348113482134831348413485134861348713488134891349013491134921349313494134951349613497134981349913500135011350213503135041350513506135071350813509135101351113512135131351413515135161351713518135191352013521135221352313524135251352613527135281352913530135311353213533135341353513536135371353813539135401354113542135431354413545135461354713548135491355013551135521355313554135551355613557135581355913560135611356213563135641356513566135671356813569135701357113572135731357413575135761357713578135791358013581135821358313584135851358613587135881358913590135911359213593135941359513596135971359813599136001360113602136031360413605136061360713608136091361013611136121361313614136151361613617136181361913620136211362213623136241362513626136271362813629136301363113632136331363413635136361363713638136391364013641136421364313644136451364613647136481364913650136511365213653136541365513656136571365813659136601366113662136631366413665136661366713668136691367013671136721367313674136751367613677136781367913680136811368213683136841368513686136871368813689136901369113692136931369413695136961369713698136991370013701137021370313704137051370613707137081370913710137111371213713137141371513716137171371813719137201372113722137231372413725137261372713728137291373013731137321373313734137351373613737137381373913740137411374213743137441374513746137471374813749137501375113752137531375413755137561375713758137591376013761137621376313764137651376613767137681376913770137711377213773137741377513776137771377813779137801378113782137831378413785137861378713788137891379013791137921379313794137951379613797137981379913800138011380213803138041380513806138071380813809138101381113812138131381413815138161381713818138191382013821138221382313824138251382613827138281382913830138311383213833138341383513836138371383813839138401384113842138431384413845138461384713848138491385013851138521385313854138551385613857138581385913860138611386213863138641386513866138671386813869138701387113872138731387413875138761387713878138791388013881138821388313884138851388613887138881388913890138911389213893138941389513896138971389813899139001390113902139031390413905139061390713908139091391013911139121391313914139151391613917139181391913920139211392213923139241392513926139271392813929139301393113932139331393413935139361393713938139391394013941139421394313944139451394613947139481394913950139511395213953139541395513956139571395813959139601396113962139631396413965139661396713968139691397013971139721397313974139751397613977139781397913980139811398213983139841398513986139871398813989139901399113992139931399413995139961399713998139991400014001140021400314004140051400614007140081400914010140111401214013140141401514016140171401814019140201402114022140231402414025140261402714028140291403014031140321403314034140351403614037140381403914040140411404214043140441404514046140471404814049140501405114052140531405414055140561405714058140591406014061140621406314064140651406614067140681406914070140711407214073140741407514076140771407814079140801408114082140831408414085140861408714088140891409014091140921409314094140951409614097140981409914100141011410214103141041410514106141071410814109141101411114112141131411414115141161411714118141191412014121141221412314124141251412614127141281412914130141311413214133141341413514136141371413814139141401414114142141431414414145141461414714148141491415014151141521415314154141551415614157141581415914160141611416214163141641416514166141671416814169141701417114172141731417414175141761417714178141791418014181141821418314184141851418614187141881418914190141911419214193141941419514196141971419814199142001420114202142031420414205142061420714208142091421014211142121421314214142151421614217142181421914220142211422214223142241422514226142271422814229142301423114232142331423414235142361423714238142391424014241142421424314244142451424614247142481424914250142511425214253142541425514256142571425814259142601426114262142631426414265142661426714268142691427014271142721427314274142751427614277142781427914280142811428214283142841428514286142871428814289142901429114292142931429414295142961429714298142991430014301143021430314304143051430614307143081430914310143111431214313143141431514316143171431814319143201432114322143231432414325143261432714328143291433014331143321433314334143351433614337143381433914340143411434214343143441434514346143471434814349143501435114352143531435414355143561435714358143591436014361143621436314364143651436614367143681436914370143711437214373143741437514376143771437814379143801438114382143831438414385143861438714388143891439014391143921439314394143951439614397143981439914400144011440214403144041440514406144071440814409144101441114412144131441414415144161441714418144191442014421144221442314424144251442614427144281442914430144311443214433144341443514436144371443814439144401444114442144431444414445144461444714448144491445014451144521445314454144551445614457144581445914460144611446214463144641446514466144671446814469144701447114472144731447414475144761447714478144791448014481144821448314484144851448614487144881448914490144911449214493144941449514496144971449814499145001450114502145031450414505145061450714508145091451014511145121451314514145151451614517145181451914520145211452214523145241452514526145271452814529145301453114532145331453414535145361453714538145391454014541145421454314544145451454614547145481454914550145511455214553145541455514556145571455814559145601456114562145631456414565145661456714568145691457014571145721457314574145751457614577145781457914580145811458214583145841458514586145871458814589145901459114592145931459414595145961459714598145991460014601146021460314604146051460614607146081460914610146111461214613146141461514616146171461814619146201462114622146231462414625146261462714628146291463014631146321463314634146351463614637146381463914640146411464214643146441464514646146471464814649146501465114652146531465414655146561465714658146591466014661146621466314664146651466614667146681466914670146711467214673146741467514676146771467814679146801468114682146831468414685146861468714688146891469014691146921469314694146951469614697146981469914700147011470214703147041470514706147071470814709147101471114712147131471414715147161471714718147191472014721147221472314724147251472614727147281472914730147311473214733147341473514736147371473814739147401474114742147431474414745147461474714748147491475014751147521475314754147551475614757147581475914760147611476214763147641476514766147671476814769147701477114772147731477414775147761477714778147791478014781147821478314784147851478614787147881478914790147911479214793147941479514796147971479814799148001480114802148031480414805148061480714808148091481014811148121481314814148151481614817148181481914820148211482214823148241482514826148271482814829148301483114832148331483414835148361483714838148391484014841148421484314844148451484614847148481484914850148511485214853148541485514856148571485814859148601486114862148631486414865148661486714868148691487014871148721487314874148751487614877148781487914880148811488214883148841488514886148871488814889148901489114892148931489414895148961489714898148991490014901149021490314904149051490614907149081490914910149111491214913149141491514916149171491814919149201492114922149231492414925149261492714928149291493014931149321493314934149351493614937149381493914940149411494214943149441494514946149471494814949149501495114952149531495414955149561495714958149591496014961149621496314964149651496614967149681496914970149711497214973149741497514976149771497814979149801498114982149831498414985149861498714988149891499014991149921499314994149951499614997149981499915000150011500215003150041500515006150071500815009150101501115012150131501415015150161501715018150191502015021150221502315024150251502615027150281502915030150311503215033150341503515036150371503815039150401504115042150431504415045150461504715048150491505015051150521505315054150551505615057150581505915060150611506215063150641506515066150671506815069150701507115072150731507415075150761507715078150791508015081150821508315084150851508615087150881508915090150911509215093150941509515096150971509815099151001510115102151031510415105151061510715108151091511015111151121511315114151151511615117151181511915120151211512215123151241512515126151271512815129151301513115132151331513415135151361513715138151391514015141151421514315144151451514615147151481514915150151511515215153151541515515156151571515815159151601516115162151631516415165151661516715168151691517015171151721517315174151751517615177151781517915180151811518215183151841518515186151871518815189151901519115192151931519415195151961519715198151991520015201152021520315204152051520615207152081520915210152111521215213152141521515216152171521815219152201522115222152231522415225152261522715228152291523015231152321523315234152351523615237152381523915240152411524215243152441524515246152471524815249152501525115252152531525415255152561525715258152591526015261152621526315264152651526615267152681526915270152711527215273152741527515276152771527815279152801528115282152831528415285152861528715288152891529015291152921529315294152951529615297152981529915300153011530215303153041530515306153071530815309153101531115312153131531415315153161531715318153191532015321153221532315324153251532615327153281532915330153311533215333153341533515336153371533815339153401534115342153431534415345153461534715348153491535015351153521535315354153551535615357153581535915360153611536215363153641536515366153671536815369153701537115372153731537415375153761537715378153791538015381153821538315384153851538615387153881538915390153911539215393153941539515396153971539815399154001540115402154031540415405154061540715408154091541015411154121541315414154151541615417154181541915420154211542215423154241542515426154271542815429154301543115432154331543415435154361543715438154391544015441154421544315444154451544615447154481544915450154511545215453154541545515456154571545815459154601546115462154631546415465154661546715468154691547015471154721547315474154751547615477154781547915480154811548215483154841548515486154871548815489154901549115492154931549415495154961549715498154991550015501155021550315504155051550615507155081550915510155111551215513155141551515516155171551815519155201552115522155231552415525155261552715528155291553015531155321553315534155351553615537155381553915540155411554215543155441554515546155471554815549155501555115552155531555415555155561555715558155591556015561155621556315564155651556615567155681556915570155711557215573155741557515576155771557815579155801558115582155831558415585155861558715588155891559015591155921559315594155951559615597155981559915600156011560215603156041560515606156071560815609156101561115612156131561415615156161561715618156191562015621156221562315624156251562615627156281562915630156311563215633156341563515636156371563815639156401564115642156431564415645156461564715648156491565015651156521565315654156551565615657156581565915660156611566215663156641566515666156671566815669156701567115672156731567415675156761567715678156791568015681156821568315684156851568615687156881568915690156911569215693156941569515696156971569815699157001570115702157031570415705157061570715708157091571015711157121571315714157151571615717157181571915720157211572215723157241572515726157271572815729157301573115732157331573415735157361573715738157391574015741157421574315744157451574615747157481574915750157511575215753157541575515756157571575815759157601576115762157631576415765157661576715768157691577015771157721577315774157751577615777157781577915780157811578215783157841578515786157871578815789157901579115792157931579415795157961579715798157991580015801158021580315804158051580615807158081580915810158111581215813158141581515816158171581815819158201582115822158231582415825158261582715828158291583015831158321583315834158351583615837158381583915840158411584215843158441584515846158471584815849158501585115852158531585415855158561585715858158591586015861158621586315864158651586615867158681586915870158711587215873158741587515876158771587815879158801588115882158831588415885158861588715888158891589015891158921589315894158951589615897158981589915900159011590215903159041590515906159071590815909159101591115912159131591415915159161591715918159191592015921159221592315924159251592615927159281592915930159311593215933159341593515936159371593815939159401594115942159431594415945159461594715948159491595015951159521595315954159551595615957159581595915960159611596215963159641596515966159671596815969159701597115972159731597415975159761597715978159791598015981159821598315984159851598615987159881598915990159911599215993159941599515996159971599815999160001600116002160031600416005160061600716008160091601016011160121601316014160151601616017160181601916020160211602216023160241602516026160271602816029160301603116032160331603416035160361603716038160391604016041160421604316044160451604616047160481604916050160511605216053160541605516056160571605816059160601606116062160631606416065160661606716068160691607016071160721607316074160751607616077160781607916080160811608216083160841608516086160871608816089160901609116092160931609416095160961609716098160991610016101161021610316104161051610616107161081610916110161111611216113161141611516116161171611816119161201612116122161231612416125161261612716128161291613016131161321613316134161351613616137161381613916140161411614216143161441614516146161471614816149161501615116152161531615416155161561615716158161591616016161161621616316164161651616616167161681616916170161711617216173161741617516176161771617816179161801618116182161831618416185161861618716188161891619016191161921619316194161951619616197161981619916200162011620216203162041620516206162071620816209162101621116212162131621416215162161621716218162191622016221162221622316224162251622616227162281622916230162311623216233162341623516236162371623816239162401624116242162431624416245162461624716248162491625016251162521625316254162551625616257162581625916260162611626216263162641626516266162671626816269162701627116272162731627416275162761627716278162791628016281162821628316284162851628616287162881628916290162911629216293162941629516296162971629816299163001630116302163031630416305163061630716308163091631016311163121631316314163151631616317163181631916320163211632216323163241632516326163271632816329163301633116332163331633416335163361633716338163391634016341163421634316344163451634616347163481634916350163511635216353163541635516356163571635816359163601636116362163631636416365163661636716368163691637016371163721637316374163751637616377163781637916380163811638216383163841638516386163871638816389163901639116392163931639416395163961639716398163991640016401164021640316404164051640616407164081640916410164111641216413164141641516416164171641816419164201642116422164231642416425164261642716428164291643016431164321643316434164351643616437164381643916440164411644216443164441644516446164471644816449164501645116452164531645416455164561645716458164591646016461164621646316464164651646616467164681646916470164711647216473164741647516476164771647816479164801648116482164831648416485164861648716488164891649016491164921649316494164951649616497164981649916500165011650216503165041650516506165071650816509165101651116512165131651416515165161651716518165191652016521165221652316524165251652616527165281652916530165311653216533165341653516536165371653816539165401654116542165431654416545165461654716548165491655016551165521655316554165551655616557165581655916560165611656216563165641656516566165671656816569165701657116572165731657416575165761657716578165791658016581165821658316584165851658616587165881658916590165911659216593165941659516596165971659816599166001660116602166031660416605166061660716608166091661016611166121661316614166151661616617166181661916620166211662216623166241662516626166271662816629166301663116632166331663416635166361663716638166391664016641166421664316644166451664616647166481664916650166511665216653166541665516656166571665816659166601666116662166631666416665166661666716668166691667016671166721667316674166751667616677166781667916680166811668216683166841668516686166871668816689166901669116692166931669416695166961669716698166991670016701167021670316704167051670616707167081670916710167111671216713167141671516716167171671816719167201672116722167231672416725167261672716728167291673016731167321673316734167351673616737167381673916740167411674216743167441674516746167471674816749167501675116752167531675416755167561675716758167591676016761167621676316764167651676616767167681676916770167711677216773167741677516776167771677816779167801678116782167831678416785167861678716788167891679016791167921679316794167951679616797167981679916800168011680216803168041680516806168071680816809168101681116812168131681416815168161681716818168191682016821168221682316824168251682616827168281682916830168311683216833168341683516836168371683816839168401684116842168431684416845168461684716848168491685016851168521685316854168551685616857168581685916860168611686216863168641686516866168671686816869168701687116872168731687416875168761687716878168791688016881168821688316884168851688616887168881688916890168911689216893168941689516896168971689816899169001690116902169031690416905169061690716908169091691016911169121691316914169151691616917169181691916920169211692216923169241692516926169271692816929169301693116932169331693416935169361693716938169391694016941169421694316944169451694616947169481694916950169511695216953169541695516956169571695816959169601696116962169631696416965169661696716968169691697016971169721697316974169751697616977169781697916980169811698216983169841698516986169871698816989169901699116992169931699416995169961699716998169991700017001170021700317004170051700617007170081700917010170111701217013170141701517016170171701817019170201702117022170231702417025170261702717028170291703017031170321703317034170351703617037170381703917040170411704217043170441704517046170471704817049170501705117052170531705417055170561705717058170591706017061170621706317064170651706617067170681706917070170711707217073170741707517076170771707817079170801708117082170831708417085170861708717088170891709017091170921709317094170951709617097170981709917100171011710217103171041710517106171071710817109171101711117112171131711417115171161711717118171191712017121171221712317124171251712617127171281712917130171311713217133171341713517136171371713817139171401714117142171431714417145171461714717148171491715017151171521715317154171551715617157171581715917160171611716217163171641716517166171671716817169171701717117172171731717417175171761717717178171791718017181171821718317184171851718617187171881718917190171911719217193171941719517196171971719817199172001720117202172031720417205172061720717208172091721017211172121721317214172151721617217172181721917220172211722217223172241722517226172271722817229172301723117232172331723417235172361723717238172391724017241172421724317244172451724617247172481724917250172511725217253172541725517256172571725817259172601726117262172631726417265172661726717268172691727017271172721727317274172751727617277172781727917280172811728217283172841728517286172871728817289172901729117292172931729417295172961729717298172991730017301173021730317304173051730617307173081730917310173111731217313173141731517316173171731817319173201732117322173231732417325173261732717328173291733017331173321733317334173351733617337173381733917340173411734217343173441734517346173471734817349173501735117352173531735417355173561735717358173591736017361173621736317364173651736617367173681736917370173711737217373173741737517376173771737817379173801738117382173831738417385173861738717388173891739017391173921739317394173951739617397173981739917400174011740217403174041740517406174071740817409174101741117412174131741417415174161741717418174191742017421174221742317424174251742617427174281742917430174311743217433174341743517436174371743817439174401744117442174431744417445174461744717448174491745017451174521745317454174551745617457174581745917460174611746217463174641746517466174671746817469174701747117472174731747417475174761747717478174791748017481174821748317484174851748617487174881748917490174911749217493174941749517496174971749817499175001750117502175031750417505175061750717508175091751017511175121751317514175151751617517175181751917520175211752217523175241752517526175271752817529175301753117532175331753417535175361753717538175391754017541175421754317544175451754617547175481754917550175511755217553175541755517556175571755817559175601756117562175631756417565175661756717568175691757017571175721757317574175751757617577175781757917580175811758217583175841758517586175871758817589175901759117592175931759417595175961759717598175991760017601176021760317604176051760617607176081760917610176111761217613176141761517616176171761817619176201762117622176231762417625176261762717628176291763017631176321763317634176351763617637176381763917640176411764217643176441764517646176471764817649176501765117652176531765417655176561765717658176591766017661176621766317664176651766617667176681766917670176711767217673176741767517676176771767817679176801768117682176831768417685176861768717688176891769017691176921769317694176951769617697176981769917700177011770217703177041770517706177071770817709177101771117712177131771417715177161771717718177191772017721177221772317724177251772617727177281772917730177311773217733177341773517736177371773817739177401774117742177431774417745177461774717748177491775017751177521775317754177551775617757177581775917760177611776217763177641776517766177671776817769177701777117772177731777417775177761777717778177791778017781177821778317784177851778617787177881778917790177911779217793177941779517796177971779817799178001780117802178031780417805178061780717808178091781017811178121781317814178151781617817178181781917820178211782217823178241782517826178271782817829178301783117832178331783417835178361783717838178391784017841178421784317844178451784617847178481784917850178511785217853178541785517856178571785817859178601786117862178631786417865178661786717868178691787017871178721787317874178751787617877178781787917880178811788217883178841788517886178871788817889178901789117892178931789417895178961789717898178991790017901179021790317904179051790617907179081790917910179111791217913179141791517916179171791817919179201792117922179231792417925179261792717928179291793017931179321793317934179351793617937179381793917940179411794217943179441794517946179471794817949179501795117952179531795417955179561795717958179591796017961179621796317964179651796617967179681796917970179711797217973179741797517976179771797817979179801798117982179831798417985179861798717988179891799017991179921799317994179951799617997179981799918000180011800218003180041800518006180071800818009180101801118012180131801418015180161801718018180191802018021180221802318024180251802618027180281802918030180311803218033180341803518036180371803818039180401804118042180431804418045180461804718048180491805018051180521805318054180551805618057180581805918060180611806218063180641806518066180671806818069180701807118072180731807418075180761807718078180791808018081180821808318084180851808618087180881808918090180911809218093180941809518096180971809818099181001810118102181031810418105181061810718108181091811018111181121811318114181151811618117181181811918120181211812218123181241812518126181271812818129181301813118132181331813418135181361813718138181391814018141181421814318144181451814618147181481814918150181511815218153181541815518156181571815818159181601816118162181631816418165181661816718168181691817018171181721817318174181751817618177181781817918180181811818218183181841818518186181871818818189181901819118192181931819418195181961819718198181991820018201182021820318204182051820618207182081820918210182111821218213182141821518216182171821818219182201822118222182231822418225182261822718228182291823018231182321823318234182351823618237182381823918240182411824218243182441824518246182471824818249182501825118252182531825418255182561825718258182591826018261182621826318264182651826618267182681826918270182711827218273182741827518276182771827818279182801828118282182831828418285182861828718288182891829018291182921829318294182951829618297182981829918300183011830218303183041830518306183071830818309183101831118312183131831418315183161831718318183191832018321183221832318324183251832618327183281832918330183311833218333183341833518336183371833818339183401834118342183431834418345183461834718348183491835018351183521835318354183551835618357183581835918360183611836218363183641836518366183671836818369183701837118372183731837418375183761837718378183791838018381183821838318384183851838618387183881838918390183911839218393183941839518396183971839818399184001840118402184031840418405184061840718408184091841018411184121841318414184151841618417184181841918420184211842218423184241842518426184271842818429184301843118432184331843418435184361843718438184391844018441184421844318444184451844618447184481844918450184511845218453184541845518456184571845818459184601846118462184631846418465184661846718468184691847018471184721847318474184751847618477184781847918480184811848218483184841848518486184871848818489184901849118492184931849418495184961849718498184991850018501185021850318504185051850618507185081850918510185111851218513185141851518516185171851818519185201852118522185231852418525185261852718528185291853018531185321853318534185351853618537185381853918540185411854218543185441854518546185471854818549185501855118552185531855418555185561855718558185591856018561185621856318564185651856618567185681856918570185711857218573185741857518576185771857818579185801858118582185831858418585185861858718588185891859018591185921859318594185951859618597185981859918600186011860218603186041860518606186071860818609186101861118612186131861418615186161861718618186191862018621186221862318624186251862618627186281862918630186311863218633186341863518636186371863818639186401864118642186431864418645186461864718648186491865018651186521865318654186551865618657186581865918660186611866218663186641866518666186671866818669186701867118672186731867418675186761867718678186791868018681186821868318684186851868618687186881868918690186911869218693186941869518696186971869818699187001870118702187031870418705187061870718708187091871018711187121871318714187151871618717187181871918720187211872218723187241872518726187271872818729187301873118732187331873418735187361873718738187391874018741187421874318744187451874618747187481874918750187511875218753187541875518756187571875818759187601876118762187631876418765187661876718768187691877018771187721877318774187751877618777187781877918780187811878218783187841878518786187871878818789187901879118792187931879418795187961879718798187991880018801188021880318804188051880618807188081880918810188111881218813188141881518816188171881818819188201882118822188231882418825188261882718828188291883018831188321883318834188351883618837188381883918840188411884218843188441884518846188471884818849188501885118852188531885418855188561885718858188591886018861188621886318864188651886618867188681886918870188711887218873188741887518876188771887818879188801888118882188831888418885188861888718888188891889018891188921889318894188951889618897188981889918900189011890218903189041890518906189071890818909189101891118912189131891418915189161891718918189191892018921189221892318924189251892618927189281892918930189311893218933189341893518936189371893818939189401894118942189431894418945189461894718948189491895018951189521895318954189551895618957189581895918960189611896218963189641896518966189671896818969189701897118972189731897418975189761897718978189791898018981189821898318984189851898618987189881898918990189911899218993189941899518996189971899818999190001900119002190031900419005190061900719008190091901019011190121901319014190151901619017190181901919020190211902219023190241902519026190271902819029190301903119032190331903419035190361903719038190391904019041190421904319044190451904619047190481904919050190511905219053190541905519056190571905819059190601906119062190631906419065190661906719068190691907019071190721907319074190751907619077190781907919080190811908219083190841908519086190871908819089190901909119092190931909419095190961909719098190991910019101191021910319104191051910619107191081910919110191111911219113191141911519116191171911819119191201912119122191231912419125191261912719128191291913019131191321913319134191351913619137191381913919140191411914219143191441914519146191471914819149191501915119152191531915419155191561915719158191591916019161191621916319164191651916619167191681916919170191711917219173191741917519176191771917819179191801918119182191831918419185191861918719188191891919019191191921919319194191951919619197191981919919200192011920219203192041920519206192071920819209192101921119212192131921419215192161921719218192191922019221192221922319224192251922619227192281922919230192311923219233192341923519236192371923819239192401924119242192431924419245192461924719248192491925019251192521925319254192551925619257192581925919260192611926219263192641926519266192671926819269192701927119272192731927419275192761927719278192791928019281192821928319284192851928619287192881928919290192911929219293192941929519296192971929819299193001930119302193031930419305193061930719308193091931019311193121931319314193151931619317193181931919320193211932219323193241932519326193271932819329193301933119332193331933419335193361933719338193391934019341193421934319344193451934619347193481934919350193511935219353193541935519356193571935819359193601936119362193631936419365193661936719368193691937019371193721937319374193751937619377193781937919380193811938219383193841938519386193871938819389193901939119392193931939419395193961939719398193991940019401194021940319404194051940619407194081940919410194111941219413194141941519416194171941819419194201942119422194231942419425194261942719428194291943019431194321943319434194351943619437194381943919440194411944219443194441944519446194471944819449194501945119452194531945419455194561945719458194591946019461194621946319464194651946619467194681946919470194711947219473194741947519476194771947819479194801948119482194831948419485194861948719488194891949019491194921949319494194951949619497194981949919500195011950219503195041950519506195071950819509195101951119512195131951419515195161951719518195191952019521195221952319524195251952619527195281952919530195311953219533195341953519536195371953819539195401954119542195431954419545195461954719548195491955019551195521955319554195551955619557195581955919560195611956219563195641956519566195671956819569195701957119572195731957419575195761957719578195791958019581195821958319584195851958619587195881958919590195911959219593195941959519596195971959819599196001960119602196031960419605196061960719608196091961019611196121961319614196151961619617196181961919620196211962219623196241962519626196271962819629196301963119632196331963419635196361963719638196391964019641196421964319644196451964619647196481964919650196511965219653196541965519656196571965819659196601966119662196631966419665196661966719668196691967019671196721967319674196751967619677196781967919680196811968219683196841968519686196871968819689196901969119692196931969419695196961969719698196991970019701197021970319704197051970619707197081970919710197111971219713197141971519716197171971819719197201972119722197231972419725197261972719728197291973019731197321973319734197351973619737197381973919740197411974219743197441974519746197471974819749197501975119752197531975419755197561975719758197591976019761197621976319764197651976619767197681976919770197711977219773197741977519776197771977819779197801978119782197831978419785197861978719788197891979019791197921979319794197951979619797197981979919800198011980219803198041980519806198071980819809198101981119812198131981419815198161981719818198191982019821198221982319824198251982619827198281982919830198311983219833198341983519836198371983819839198401984119842198431984419845198461984719848198491985019851198521985319854198551985619857198581985919860198611986219863198641986519866198671986819869198701987119872198731987419875198761987719878198791988019881198821988319884198851988619887198881988919890198911989219893198941989519896198971989819899199001990119902199031990419905199061990719908199091991019911199121991319914199151991619917199181991919920199211992219923199241992519926199271992819929199301993119932199331993419935199361993719938199391994019941199421994319944199451994619947199481994919950199511995219953199541995519956199571995819959199601996119962199631996419965199661996719968199691997019971199721997319974199751997619977199781997919980199811998219983199841998519986199871998819989199901999119992199931999419995199961999719998199992000020001200022000320004200052000620007200082000920010200112001220013200142001520016200172001820019200202002120022200232002420025200262002720028200292003020031200322003320034200352003620037200382003920040200412004220043200442004520046200472004820049200502005120052200532005420055200562005720058200592006020061200622006320064200652006620067200682006920070200712007220073200742007520076200772007820079200802008120082200832008420085200862008720088200892009020091200922009320094200952009620097200982009920100201012010220103201042010520106201072010820109201102011120112201132011420115201162011720118201192012020121201222012320124201252012620127201282012920130201312013220133201342013520136201372013820139201402014120142201432014420145201462014720148201492015020151201522015320154201552015620157201582015920160201612016220163201642016520166201672016820169201702017120172201732017420175201762017720178201792018020181201822018320184201852018620187201882018920190201912019220193201942019520196201972019820199202002020120202202032020420205202062020720208202092021020211202122021320214202152021620217202182021920220202212022220223202242022520226202272022820229202302023120232202332023420235202362023720238202392024020241202422024320244202452024620247202482024920250202512025220253202542025520256202572025820259202602026120262202632026420265202662026720268202692027020271202722027320274202752027620277202782027920280202812028220283202842028520286202872028820289202902029120292202932029420295202962029720298202992030020301203022030320304203052030620307203082030920310203112031220313203142031520316203172031820319203202032120322203232032420325203262032720328203292033020331203322033320334203352033620337203382033920340203412034220343203442034520346203472034820349203502035120352203532035420355203562035720358203592036020361203622036320364203652036620367203682036920370203712037220373203742037520376203772037820379203802038120382203832038420385203862038720388203892039020391203922039320394203952039620397203982039920400204012040220403204042040520406204072040820409204102041120412204132041420415204162041720418204192042020421204222042320424204252042620427204282042920430204312043220433204342043520436204372043820439204402044120442204432044420445204462044720448204492045020451204522045320454204552045620457204582045920460204612046220463204642046520466204672046820469204702047120472204732047420475204762047720478204792048020481204822048320484204852048620487204882048920490204912049220493204942049520496204972049820499205002050120502205032050420505205062050720508205092051020511205122051320514205152051620517205182051920520205212052220523205242052520526205272052820529205302053120532205332053420535205362053720538205392054020541205422054320544205452054620547205482054920550205512055220553205542055520556205572055820559205602056120562205632056420565205662056720568205692057020571205722057320574205752057620577205782057920580205812058220583205842058520586205872058820589205902059120592205932059420595205962059720598205992060020601206022060320604206052060620607206082060920610206112061220613206142061520616206172061820619206202062120622206232062420625206262062720628206292063020631206322063320634206352063620637206382063920640206412064220643206442064520646206472064820649206502065120652206532065420655206562065720658206592066020661206622066320664206652066620667206682066920670206712067220673206742067520676206772067820679206802068120682206832068420685206862068720688206892069020691206922069320694206952069620697206982069920700207012070220703207042070520706207072070820709207102071120712207132071420715207162071720718207192072020721207222072320724207252072620727207282072920730207312073220733207342073520736207372073820739207402074120742207432074420745207462074720748207492075020751207522075320754207552075620757207582075920760207612076220763207642076520766207672076820769207702077120772207732077420775207762077720778207792078020781207822078320784207852078620787207882078920790207912079220793207942079520796207972079820799208002080120802208032080420805208062080720808208092081020811208122081320814208152081620817208182081920820208212082220823208242082520826208272082820829208302083120832208332083420835208362083720838208392084020841208422084320844208452084620847208482084920850208512085220853208542085520856208572085820859208602086120862208632086420865208662086720868208692087020871208722087320874208752087620877208782087920880208812088220883208842088520886208872088820889208902089120892208932089420895208962089720898208992090020901209022090320904209052090620907209082090920910209112091220913209142091520916209172091820919209202092120922209232092420925209262092720928209292093020931209322093320934209352093620937209382093920940209412094220943209442094520946209472094820949209502095120952209532095420955209562095720958209592096020961209622096320964209652096620967209682096920970209712097220973209742097520976209772097820979209802098120982209832098420985209862098720988209892099020991209922099320994209952099620997209982099921000210012100221003210042100521006210072100821009210102101121012210132101421015210162101721018210192102021021210222102321024210252102621027210282102921030210312103221033210342103521036210372103821039210402104121042210432104421045210462104721048210492105021051210522105321054210552105621057210582105921060210612106221063210642106521066210672106821069210702107121072210732107421075210762107721078210792108021081210822108321084210852108621087210882108921090210912109221093210942109521096210972109821099211002110121102211032110421105211062110721108211092111021111211122111321114211152111621117211182111921120211212112221123211242112521126211272112821129211302113121132211332113421135211362113721138211392114021141211422114321144211452114621147211482114921150211512115221153211542115521156211572115821159211602116121162211632116421165211662116721168211692117021171211722117321174211752117621177211782117921180211812118221183211842118521186211872118821189211902119121192211932119421195211962119721198211992120021201212022120321204212052120621207212082120921210212112121221213212142121521216212172121821219212202122121222212232122421225212262122721228212292123021231212322123321234212352123621237212382123921240212412124221243212442124521246212472124821249212502125121252212532125421255212562125721258212592126021261212622126321264212652126621267212682126921270212712127221273212742127521276212772127821279212802128121282212832128421285212862128721288212892129021291212922129321294212952129621297212982129921300213012130221303213042130521306213072130821309213102131121312213132131421315213162131721318213192132021321213222132321324213252132621327213282132921330213312133221333213342133521336213372133821339213402134121342213432134421345213462134721348213492135021351213522135321354213552135621357213582135921360213612136221363213642136521366213672136821369213702137121372213732137421375213762137721378213792138021381213822138321384213852138621387213882138921390213912139221393213942139521396213972139821399214002140121402214032140421405214062140721408214092141021411214122141321414214152141621417214182141921420214212142221423214242142521426214272142821429214302143121432214332143421435214362143721438214392144021441214422144321444214452144621447214482144921450214512145221453214542145521456214572145821459214602146121462214632146421465214662146721468214692147021471214722147321474214752147621477214782147921480214812148221483214842148521486214872148821489214902149121492214932149421495214962149721498214992150021501215022150321504215052150621507215082150921510215112151221513215142151521516215172151821519215202152121522215232152421525215262152721528215292153021531215322153321534215352153621537215382153921540215412154221543215442154521546215472154821549215502155121552215532155421555215562155721558215592156021561215622156321564215652156621567215682156921570215712157221573215742157521576215772157821579215802158121582215832158421585215862158721588215892159021591215922159321594215952159621597215982159921600216012160221603216042160521606216072160821609216102161121612216132161421615216162161721618216192162021621216222162321624216252162621627216282162921630216312163221633216342163521636216372163821639216402164121642216432164421645216462164721648216492165021651216522165321654216552165621657216582165921660216612166221663216642166521666216672166821669216702167121672216732167421675216762167721678216792168021681216822168321684216852168621687216882168921690216912169221693216942169521696216972169821699217002170121702217032170421705217062170721708217092171021711217122171321714217152171621717217182171921720217212172221723217242172521726217272172821729217302173121732217332173421735217362173721738217392174021741217422174321744217452174621747217482174921750217512175221753217542175521756217572175821759217602176121762217632176421765217662176721768217692177021771217722177321774217752177621777217782177921780217812178221783217842178521786217872178821789217902179121792217932179421795217962179721798217992180021801218022180321804218052180621807218082180921810218112181221813218142181521816218172181821819218202182121822218232182421825218262182721828218292183021831218322183321834218352183621837218382183921840218412184221843218442184521846218472184821849218502185121852218532185421855218562185721858218592186021861218622186321864218652186621867218682186921870218712187221873218742187521876218772187821879218802188121882218832188421885218862188721888218892189021891218922189321894218952189621897218982189921900219012190221903219042190521906219072190821909219102191121912219132191421915219162191721918219192192021921219222192321924219252192621927219282192921930219312193221933219342193521936219372193821939219402194121942219432194421945219462194721948219492195021951219522195321954219552195621957219582195921960219612196221963219642196521966219672196821969219702197121972219732197421975219762197721978219792198021981219822198321984219852198621987219882198921990219912199221993219942199521996219972199821999220002200122002220032200422005220062200722008220092201022011220122201322014220152201622017220182201922020220212202222023220242202522026220272202822029220302203122032220332203422035220362203722038220392204022041220422204322044220452204622047220482204922050220512205222053220542205522056220572205822059220602206122062220632206422065220662206722068220692207022071220722207322074220752207622077220782207922080220812208222083220842208522086220872208822089220902209122092220932209422095220962209722098220992210022101221022210322104221052210622107221082210922110221112211222113221142211522116221172211822119221202212122122221232212422125221262212722128221292213022131221322213322134221352213622137221382213922140221412214222143221442214522146221472214822149221502215122152221532215422155221562215722158221592216022161221622216322164221652216622167221682216922170221712217222173221742217522176221772217822179221802218122182221832218422185221862218722188221892219022191221922219322194221952219622197221982219922200222012220222203222042220522206222072220822209222102221122212222132221422215222162221722218222192222022221222222222322224222252222622227222282222922230222312223222233222342223522236222372223822239222402224122242222432224422245222462224722248222492225022251222522225322254222552225622257222582225922260222612226222263222642226522266222672226822269222702227122272222732227422275222762227722278222792228022281222822228322284222852228622287222882228922290222912229222293222942229522296222972229822299223002230122302223032230422305223062230722308223092231022311223122231322314223152231622317223182231922320223212232222323223242232522326223272232822329223302233122332223332233422335223362233722338223392234022341223422234322344223452234622347223482234922350223512235222353223542235522356223572235822359223602236122362223632236422365223662236722368223692237022371223722237322374223752237622377223782237922380223812238222383223842238522386223872238822389223902239122392223932239422395223962239722398223992240022401224022240322404224052240622407224082240922410224112241222413224142241522416224172241822419224202242122422224232242422425224262242722428224292243022431224322243322434224352243622437224382243922440224412244222443224442244522446224472244822449224502245122452224532245422455224562245722458224592246022461224622246322464224652246622467224682246922470224712247222473224742247522476224772247822479224802248122482224832248422485224862248722488224892249022491224922249322494224952249622497224982249922500225012250222503225042250522506225072250822509225102251122512225132251422515225162251722518225192252022521225222252322524225252252622527225282252922530225312253222533225342253522536225372253822539225402254122542225432254422545225462254722548225492255022551225522255322554225552255622557225582255922560225612256222563225642256522566225672256822569225702257122572225732257422575225762257722578225792258022581225822258322584225852258622587225882258922590225912259222593225942259522596225972259822599226002260122602226032260422605226062260722608226092261022611226122261322614226152261622617226182261922620226212262222623226242262522626226272262822629226302263122632226332263422635226362263722638226392264022641226422264322644226452264622647226482264922650226512265222653226542265522656226572265822659226602266122662226632266422665226662266722668226692267022671226722267322674226752267622677226782267922680226812268222683226842268522686226872268822689226902269122692226932269422695226962269722698226992270022701227022270322704227052270622707227082270922710227112271222713227142271522716227172271822719227202272122722227232272422725227262272722728227292273022731227322273322734227352273622737227382273922740227412274222743227442274522746227472274822749227502275122752227532275422755227562275722758227592276022761227622276322764227652276622767227682276922770227712277222773227742277522776227772277822779227802278122782227832278422785227862278722788227892279022791227922279322794227952279622797227982279922800228012280222803228042280522806228072280822809228102281122812228132281422815228162281722818228192282022821228222282322824228252282622827228282282922830228312283222833228342283522836228372283822839228402284122842228432284422845228462284722848228492285022851228522285322854228552285622857228582285922860228612286222863228642286522866228672286822869228702287122872228732287422875228762287722878228792288022881228822288322884228852288622887228882288922890228912289222893228942289522896228972289822899229002290122902229032290422905229062290722908229092291022911229122291322914229152291622917229182291922920229212292222923229242292522926229272292822929229302293122932229332293422935229362293722938229392294022941229422294322944229452294622947229482294922950229512295222953229542295522956229572295822959229602296122962229632296422965229662296722968229692297022971229722297322974229752297622977229782297922980229812298222983229842298522986229872298822989229902299122992229932299422995229962299722998229992300023001230022300323004230052300623007230082300923010230112301223013230142301523016230172301823019230202302123022230232302423025230262302723028230292303023031230322303323034230352303623037230382303923040230412304223043230442304523046230472304823049230502305123052230532305423055230562305723058230592306023061230622306323064230652306623067230682306923070230712307223073230742307523076230772307823079230802308123082230832308423085230862308723088230892309023091230922309323094230952309623097230982309923100231012310223103231042310523106231072310823109231102311123112231132311423115231162311723118231192312023121231222312323124231252312623127231282312923130231312313223133231342313523136231372313823139231402314123142231432314423145231462314723148231492315023151231522315323154231552315623157231582315923160231612316223163231642316523166231672316823169231702317123172231732317423175231762317723178231792318023181231822318323184231852318623187231882318923190231912319223193231942319523196231972319823199232002320123202232032320423205232062320723208232092321023211232122321323214232152321623217232182321923220232212322223223232242322523226232272322823229232302323123232232332323423235232362323723238232392324023241232422324323244232452324623247232482324923250232512325223253232542325523256232572325823259232602326123262232632326423265232662326723268232692327023271232722327323274232752327623277232782327923280232812328223283232842328523286232872328823289232902329123292232932329423295232962329723298232992330023301233022330323304233052330623307233082330923310233112331223313233142331523316233172331823319233202332123322233232332423325233262332723328233292333023331233322333323334233352333623337233382333923340233412334223343233442334523346233472334823349233502335123352233532335423355233562335723358233592336023361233622336323364233652336623367233682336923370233712337223373233742337523376233772337823379233802338123382233832338423385233862338723388233892339023391233922339323394233952339623397233982339923400234012340223403234042340523406234072340823409234102341123412234132341423415234162341723418234192342023421234222342323424234252342623427234282342923430234312343223433234342343523436234372343823439234402344123442234432344423445234462344723448234492345023451234522345323454234552345623457234582345923460234612346223463234642346523466234672346823469234702347123472234732347423475234762347723478234792348023481234822348323484234852348623487234882348923490234912349223493234942349523496234972349823499235002350123502235032350423505235062350723508235092351023511235122351323514235152351623517235182351923520235212352223523235242352523526235272352823529235302353123532235332353423535235362353723538235392354023541235422354323544235452354623547235482354923550235512355223553235542355523556235572355823559235602356123562235632356423565235662356723568235692357023571235722357323574235752357623577235782357923580235812358223583235842358523586235872358823589235902359123592235932359423595235962359723598235992360023601236022360323604236052360623607236082360923610236112361223613236142361523616236172361823619236202362123622236232362423625236262362723628236292363023631236322363323634236352363623637236382363923640236412364223643236442364523646236472364823649236502365123652236532365423655236562365723658236592366023661236622366323664236652366623667236682366923670236712367223673236742367523676236772367823679236802368123682236832368423685236862368723688236892369023691236922369323694236952369623697236982369923700237012370223703237042370523706237072370823709237102371123712237132371423715237162371723718237192372023721237222372323724237252372623727237282372923730237312373223733237342373523736237372373823739237402374123742237432374423745237462374723748237492375023751237522375323754237552375623757237582375923760237612376223763237642376523766237672376823769237702377123772237732377423775237762377723778237792378023781237822378323784237852378623787237882378923790237912379223793237942379523796237972379823799238002380123802238032380423805238062380723808238092381023811238122381323814238152381623817238182381923820238212382223823238242382523826238272382823829238302383123832238332383423835238362383723838238392384023841238422384323844238452384623847238482384923850238512385223853238542385523856238572385823859238602386123862238632386423865238662386723868238692387023871238722387323874238752387623877238782387923880238812388223883238842388523886238872388823889238902389123892238932389423895238962389723898238992390023901239022390323904239052390623907239082390923910239112391223913239142391523916239172391823919239202392123922239232392423925239262392723928239292393023931239322393323934239352393623937239382393923940239412394223943239442394523946239472394823949239502395123952239532395423955239562395723958239592396023961239622396323964239652396623967239682396923970239712397223973239742397523976239772397823979239802398123982239832398423985239862398723988239892399023991239922399323994239952399623997239982399924000240012400224003240042400524006240072400824009240102401124012240132401424015240162401724018240192402024021240222402324024240252402624027240282402924030240312403224033240342403524036240372403824039240402404124042240432404424045240462404724048240492405024051240522405324054240552405624057240582405924060240612406224063240642406524066240672406824069240702407124072240732407424075240762407724078240792408024081240822408324084240852408624087240882408924090240912409224093240942409524096240972409824099241002410124102241032410424105241062410724108241092411024111241122411324114241152411624117241182411924120241212412224123241242412524126241272412824129241302413124132241332413424135241362413724138241392414024141241422414324144241452414624147241482414924150241512415224153241542415524156241572415824159241602416124162241632416424165241662416724168241692417024171241722417324174241752417624177241782417924180241812418224183241842418524186241872418824189241902419124192241932419424195241962419724198241992420024201242022420324204242052420624207242082420924210242112421224213242142421524216242172421824219242202422124222242232422424225242262422724228242292423024231242322423324234242352423624237242382423924240242412424224243242442424524246242472424824249242502425124252242532425424255242562425724258242592426024261242622426324264242652426624267242682426924270242712427224273242742427524276242772427824279242802428124282242832428424285242862428724288242892429024291242922429324294242952429624297242982429924300243012430224303243042430524306243072430824309243102431124312243132431424315243162431724318243192432024321243222432324324243252432624327243282432924330243312433224333243342433524336243372433824339243402434124342243432434424345243462434724348243492435024351243522435324354243552435624357243582435924360243612436224363243642436524366243672436824369243702437124372243732437424375243762437724378243792438024381243822438324384243852438624387243882438924390243912439224393243942439524396243972439824399244002440124402244032440424405244062440724408244092441024411244122441324414244152441624417244182441924420244212442224423244242442524426244272442824429244302443124432244332443424435244362443724438244392444024441244422444324444244452444624447244482444924450244512445224453244542445524456244572445824459244602446124462244632446424465244662446724468244692447024471244722447324474244752447624477244782447924480244812448224483244842448524486244872448824489244902449124492244932449424495244962449724498244992450024501245022450324504245052450624507245082450924510245112451224513245142451524516245172451824519245202452124522245232452424525245262452724528245292453024531245322453324534245352453624537245382453924540245412454224543245442454524546245472454824549245502455124552245532455424555245562455724558245592456024561245622456324564245652456624567245682456924570245712457224573245742457524576245772457824579245802458124582245832458424585245862458724588245892459024591245922459324594245952459624597245982459924600246012460224603246042460524606246072460824609246102461124612246132461424615246162461724618246192462024621246222462324624246252462624627246282462924630246312463224633246342463524636246372463824639246402464124642246432464424645246462464724648246492465024651246522465324654246552465624657246582465924660246612466224663246642466524666246672466824669246702467124672246732467424675246762467724678246792468024681246822468324684246852468624687246882468924690246912469224693246942469524696246972469824699247002470124702247032470424705247062470724708247092471024711247122471324714247152471624717247182471924720247212472224723247242472524726247272472824729247302473124732247332473424735247362473724738247392474024741247422474324744247452474624747247482474924750247512475224753247542475524756247572475824759247602476124762247632476424765247662476724768247692477024771247722477324774247752477624777247782477924780247812478224783247842478524786247872478824789247902479124792247932479424795247962479724798247992480024801248022480324804248052480624807248082480924810248112481224813248142481524816248172481824819248202482124822248232482424825248262482724828248292483024831248322483324834248352483624837248382483924840248412484224843248442484524846248472484824849248502485124852248532485424855248562485724858248592486024861248622486324864248652486624867248682486924870248712487224873248742487524876248772487824879248802488124882248832488424885248862488724888248892489024891248922489324894248952489624897248982489924900249012490224903249042490524906249072490824909249102491124912249132491424915249162491724918249192492024921249222492324924249252492624927249282492924930249312493224933249342493524936249372493824939249402494124942249432494424945249462494724948249492495024951249522495324954249552495624957249582495924960249612496224963249642496524966249672496824969249702497124972249732497424975249762497724978249792498024981249822498324984249852498624987249882498924990249912499224993249942499524996249972499824999250002500125002250032500425005250062500725008250092501025011250122501325014250152501625017250182501925020250212502225023250242502525026250272502825029250302503125032250332503425035250362503725038250392504025041250422504325044250452504625047250482504925050250512505225053250542505525056250572505825059250602506125062250632506425065250662506725068250692507025071250722507325074250752507625077250782507925080250812508225083250842508525086250872508825089250902509125092250932509425095250962509725098250992510025101251022510325104251052510625107251082510925110251112511225113251142511525116251172511825119251202512125122251232512425125251262512725128251292513025131251322513325134251352513625137251382513925140251412514225143251442514525146251472514825149251502515125152251532515425155251562515725158251592516025161251622516325164251652516625167251682516925170251712517225173251742517525176251772517825179251802518125182251832518425185251862518725188251892519025191251922519325194251952519625197251982519925200252012520225203252042520525206252072520825209252102521125212252132521425215252162521725218252192522025221252222522325224252252522625227252282522925230252312523225233252342523525236252372523825239252402524125242252432524425245252462524725248252492525025251252522525325254252552525625257252582525925260252612526225263252642526525266252672526825269252702527125272252732527425275252762527725278252792528025281252822528325284252852528625287252882528925290252912529225293252942529525296252972529825299253002530125302253032530425305253062530725308253092531025311253122531325314253152531625317253182531925320253212532225323253242532525326253272532825329253302533125332253332533425335253362533725338253392534025341253422534325344253452534625347253482534925350253512535225353253542535525356253572535825359253602536125362253632536425365253662536725368253692537025371253722537325374253752537625377253782537925380253812538225383253842538525386253872538825389253902539125392253932539425395253962539725398253992540025401254022540325404254052540625407254082540925410254112541225413254142541525416254172541825419254202542125422254232542425425254262542725428254292543025431254322543325434254352543625437254382543925440254412544225443254442544525446254472544825449254502545125452254532545425455254562545725458254592546025461254622546325464254652546625467254682546925470254712547225473254742547525476254772547825479254802548125482254832548425485254862548725488254892549025491254922549325494254952549625497254982549925500255012550225503255042550525506255072550825509255102551125512255132551425515255162551725518255192552025521255222552325524255252552625527255282552925530255312553225533255342553525536255372553825539255402554125542255432554425545255462554725548255492555025551255522555325554255552555625557255582555925560255612556225563255642556525566255672556825569255702557125572255732557425575255762557725578255792558025581255822558325584255852558625587255882558925590255912559225593255942559525596255972559825599256002560125602256032560425605256062560725608256092561025611256122561325614256152561625617256182561925620256212562225623256242562525626256272562825629256302563125632256332563425635256362563725638256392564025641256422564325644256452564625647256482564925650256512565225653256542565525656256572565825659256602566125662256632566425665256662566725668256692567025671256722567325674256752567625677256782567925680256812568225683256842568525686256872568825689256902569125692256932569425695256962569725698256992570025701257022570325704257052570625707257082570925710257112571225713257142571525716257172571825719257202572125722257232572425725257262572725728257292573025731257322573325734257352573625737257382573925740257412574225743257442574525746257472574825749257502575125752257532575425755257562575725758257592576025761257622576325764257652576625767257682576925770257712577225773257742577525776257772577825779257802578125782257832578425785257862578725788257892579025791257922579325794257952579625797257982579925800258012580225803258042580525806258072580825809258102581125812258132581425815258162581725818258192582025821258222582325824258252582625827258282582925830258312583225833258342583525836258372583825839258402584125842258432584425845258462584725848258492585025851258522585325854258552585625857258582585925860258612586225863258642586525866258672586825869258702587125872258732587425875258762587725878258792588025881258822588325884258852588625887258882588925890258912589225893258942589525896258972589825899259002590125902259032590425905259062590725908259092591025911259122591325914259152591625917259182591925920259212592225923259242592525926259272592825929259302593125932259332593425935259362593725938259392594025941259422594325944259452594625947259482594925950259512595225953259542595525956259572595825959259602596125962259632596425965259662596725968259692597025971259722597325974259752597625977259782597925980259812598225983259842598525986259872598825989259902599125992259932599425995259962599725998259992600026001260022600326004260052600626007260082600926010260112601226013260142601526016260172601826019260202602126022260232602426025260262602726028260292603026031260322603326034260352603626037260382603926040260412604226043260442604526046260472604826049260502605126052260532605426055260562605726058260592606026061260622606326064260652606626067260682606926070260712607226073260742607526076260772607826079260802608126082260832608426085260862608726088260892609026091260922609326094260952609626097260982609926100261012610226103261042610526106261072610826109261102611126112261132611426115261162611726118261192612026121261222612326124261252612626127261282612926130261312613226133261342613526136261372613826139261402614126142261432614426145261462614726148261492615026151261522615326154261552615626157261582615926160261612616226163261642616526166261672616826169261702617126172261732617426175261762617726178261792618026181261822618326184261852618626187261882618926190261912619226193261942619526196261972619826199262002620126202262032620426205262062620726208262092621026211262122621326214262152621626217262182621926220262212622226223262242622526226262272622826229262302623126232262332623426235262362623726238262392624026241262422624326244262452624626247262482624926250262512625226253262542625526256262572625826259262602626126262262632626426265262662626726268262692627026271262722627326274262752627626277262782627926280262812628226283262842628526286262872628826289262902629126292262932629426295262962629726298262992630026301263022630326304263052630626307263082630926310263112631226313263142631526316263172631826319263202632126322263232632426325263262632726328263292633026331263322633326334263352633626337263382633926340263412634226343263442634526346263472634826349263502635126352263532635426355263562635726358263592636026361263622636326364263652636626367263682636926370263712637226373263742637526376263772637826379263802638126382263832638426385263862638726388263892639026391263922639326394263952639626397263982639926400264012640226403264042640526406264072640826409264102641126412264132641426415264162641726418264192642026421264222642326424264252642626427264282642926430264312643226433264342643526436264372643826439264402644126442264432644426445264462644726448264492645026451264522645326454264552645626457264582645926460264612646226463264642646526466264672646826469264702647126472264732647426475264762647726478264792648026481264822648326484264852648626487264882648926490264912649226493264942649526496264972649826499265002650126502265032650426505265062650726508265092651026511265122651326514265152651626517265182651926520265212652226523265242652526526265272652826529265302653126532265332653426535265362653726538265392654026541265422654326544265452654626547265482654926550265512655226553265542655526556265572655826559265602656126562265632656426565265662656726568265692657026571265722657326574265752657626577265782657926580265812658226583265842658526586265872658826589265902659126592265932659426595265962659726598265992660026601266022660326604266052660626607266082660926610266112661226613266142661526616266172661826619266202662126622266232662426625266262662726628266292663026631266322663326634266352663626637266382663926640266412664226643266442664526646266472664826649266502665126652266532665426655266562665726658266592666026661266622666326664266652666626667266682666926670266712667226673266742667526676266772667826679266802668126682266832668426685266862668726688266892669026691266922669326694266952669626697266982669926700267012670226703267042670526706267072670826709267102671126712267132671426715267162671726718267192672026721267222672326724267252672626727267282672926730267312673226733267342673526736267372673826739267402674126742267432674426745267462674726748267492675026751267522675326754267552675626757267582675926760267612676226763267642676526766267672676826769267702677126772267732677426775267762677726778267792678026781267822678326784267852678626787267882678926790267912679226793267942679526796267972679826799268002680126802268032680426805268062680726808268092681026811268122681326814268152681626817268182681926820268212682226823268242682526826268272682826829268302683126832268332683426835268362683726838268392684026841268422684326844268452684626847268482684926850268512685226853268542685526856268572685826859268602686126862268632686426865268662686726868268692687026871268722687326874268752687626877268782687926880268812688226883268842688526886268872688826889268902689126892268932689426895268962689726898268992690026901269022690326904269052690626907269082690926910269112691226913269142691526916269172691826919269202692126922269232692426925269262692726928269292693026931269322693326934269352693626937269382693926940269412694226943269442694526946269472694826949269502695126952269532695426955269562695726958269592696026961269622696326964269652696626967269682696926970269712697226973269742697526976269772697826979269802698126982269832698426985269862698726988269892699026991269922699326994269952699626997269982699927000270012700227003270042700527006270072700827009270102701127012270132701427015270162701727018270192702027021270222702327024270252702627027270282702927030270312703227033270342703527036270372703827039270402704127042270432704427045270462704727048270492705027051270522705327054270552705627057270582705927060270612706227063270642706527066270672706827069270702707127072270732707427075270762707727078270792708027081270822708327084270852708627087270882708927090270912709227093270942709527096270972709827099271002710127102271032710427105271062710727108271092711027111271122711327114271152711627117271182711927120271212712227123271242712527126271272712827129271302713127132271332713427135271362713727138271392714027141271422714327144271452714627147271482714927150271512715227153271542715527156271572715827159271602716127162271632716427165271662716727168271692717027171271722717327174271752717627177271782717927180271812718227183271842718527186271872718827189271902719127192271932719427195271962719727198271992720027201272022720327204272052720627207272082720927210272112721227213272142721527216272172721827219272202722127222272232722427225272262722727228272292723027231272322723327234272352723627237272382723927240272412724227243272442724527246272472724827249272502725127252272532725427255272562725727258272592726027261272622726327264272652726627267272682726927270272712727227273272742727527276272772727827279272802728127282272832728427285272862728727288272892729027291272922729327294272952729627297272982729927300273012730227303273042730527306273072730827309273102731127312273132731427315273162731727318273192732027321273222732327324273252732627327273282732927330273312733227333273342733527336273372733827339273402734127342273432734427345273462734727348273492735027351273522735327354273552735627357273582735927360273612736227363273642736527366273672736827369273702737127372273732737427375273762737727378273792738027381273822738327384273852738627387273882738927390273912739227393273942739527396273972739827399274002740127402274032740427405274062740727408274092741027411274122741327414274152741627417274182741927420274212742227423274242742527426274272742827429274302743127432274332743427435274362743727438274392744027441274422744327444274452744627447274482744927450274512745227453274542745527456274572745827459274602746127462274632746427465274662746727468274692747027471274722747327474274752747627477274782747927480274812748227483274842748527486274872748827489274902749127492274932749427495274962749727498274992750027501275022750327504275052750627507275082750927510275112751227513275142751527516275172751827519275202752127522275232752427525275262752727528275292753027531275322753327534275352753627537275382753927540275412754227543275442754527546275472754827549275502755127552275532755427555275562755727558275592756027561275622756327564275652756627567275682756927570275712757227573275742757527576275772757827579275802758127582275832758427585275862758727588275892759027591275922759327594275952759627597275982759927600276012760227603276042760527606276072760827609276102761127612276132761427615276162761727618276192762027621276222762327624276252762627627276282762927630276312763227633276342763527636276372763827639276402764127642276432764427645276462764727648276492765027651276522765327654276552765627657276582765927660276612766227663276642766527666276672766827669276702767127672276732767427675276762767727678276792768027681276822768327684276852768627687276882768927690276912769227693276942769527696276972769827699277002770127702277032770427705277062770727708277092771027711277122771327714277152771627717277182771927720277212772227723277242772527726277272772827729277302773127732277332773427735277362773727738277392774027741277422774327744277452774627747277482774927750277512775227753277542775527756277572775827759277602776127762277632776427765277662776727768277692777027771277722777327774277752777627777277782777927780277812778227783277842778527786277872778827789277902779127792277932779427795277962779727798277992780027801278022780327804278052780627807278082780927810278112781227813278142781527816278172781827819278202782127822278232782427825278262782727828278292783027831278322783327834278352783627837278382783927840278412784227843278442784527846278472784827849278502785127852278532785427855278562785727858278592786027861278622786327864278652786627867278682786927870278712787227873278742787527876278772787827879278802788127882278832788427885278862788727888278892789027891278922789327894278952789627897278982789927900279012790227903279042790527906279072790827909279102791127912279132791427915279162791727918279192792027921279222792327924279252792627927279282792927930279312793227933279342793527936279372793827939279402794127942279432794427945279462794727948279492795027951279522795327954279552795627957279582795927960279612796227963279642796527966279672796827969279702797127972279732797427975279762797727978279792798027981279822798327984279852798627987279882798927990279912799227993279942799527996279972799827999280002800128002280032800428005280062800728008280092801028011280122801328014280152801628017280182801928020280212802228023280242802528026280272802828029280302803128032280332803428035280362803728038280392804028041280422804328044280452804628047280482804928050280512805228053280542805528056280572805828059280602806128062280632806428065280662806728068280692807028071280722807328074280752807628077280782807928080280812808228083280842808528086280872808828089280902809128092280932809428095280962809728098280992810028101281022810328104281052810628107281082810928110281112811228113281142811528116281172811828119281202812128122281232812428125281262812728128281292813028131281322813328134281352813628137281382813928140281412814228143281442814528146281472814828149281502815128152281532815428155281562815728158281592816028161281622816328164281652816628167281682816928170281712817228173281742817528176281772817828179281802818128182281832818428185281862818728188281892819028191281922819328194281952819628197281982819928200282012820228203282042820528206282072820828209282102821128212282132821428215282162821728218282192822028221282222822328224282252822628227282282822928230282312823228233282342823528236282372823828239282402824128242282432824428245282462824728248282492825028251282522825328254282552825628257282582825928260282612826228263282642826528266282672826828269282702827128272282732827428275282762827728278282792828028281282822828328284282852828628287282882828928290282912829228293282942829528296282972829828299283002830128302283032830428305283062830728308283092831028311283122831328314283152831628317283182831928320283212832228323283242832528326283272832828329283302833128332283332833428335283362833728338283392834028341283422834328344283452834628347283482834928350283512835228353283542835528356283572835828359283602836128362283632836428365283662836728368283692837028371283722837328374283752837628377283782837928380283812838228383283842838528386283872838828389283902839128392283932839428395283962839728398283992840028401284022840328404284052840628407284082840928410284112841228413284142841528416284172841828419284202842128422284232842428425284262842728428284292843028431284322843328434284352843628437284382843928440284412844228443284442844528446284472844828449284502845128452284532845428455284562845728458284592846028461284622846328464284652846628467284682846928470284712847228473284742847528476284772847828479284802848128482284832848428485284862848728488284892849028491284922849328494284952849628497284982849928500285012850228503285042850528506285072850828509285102851128512285132851428515285162851728518285192852028521285222852328524285252852628527285282852928530285312853228533285342853528536285372853828539285402854128542285432854428545285462854728548285492855028551285522855328554285552855628557285582855928560285612856228563285642856528566285672856828569285702857128572285732857428575285762857728578285792858028581285822858328584285852858628587285882858928590285912859228593285942859528596285972859828599286002860128602286032860428605286062860728608286092861028611286122861328614286152861628617286182861928620286212862228623286242862528626286272862828629286302863128632286332863428635286362863728638286392864028641286422864328644286452864628647286482864928650286512865228653286542865528656286572865828659286602866128662286632866428665286662866728668286692867028671286722867328674286752867628677286782867928680286812868228683286842868528686286872868828689286902869128692286932869428695286962869728698286992870028701287022870328704287052870628707287082870928710287112871228713287142871528716287172871828719287202872128722287232872428725287262872728728287292873028731287322873328734287352873628737287382873928740287412874228743287442874528746287472874828749287502875128752287532875428755287562875728758287592876028761287622876328764287652876628767287682876928770287712877228773287742877528776287772877828779287802878128782287832878428785287862878728788287892879028791287922879328794287952879628797287982879928800288012880228803288042880528806288072880828809288102881128812288132881428815288162881728818288192882028821288222882328824288252882628827288282882928830288312883228833288342883528836288372883828839288402884128842288432884428845288462884728848288492885028851288522885328854288552885628857288582885928860288612886228863288642886528866288672886828869288702887128872288732887428875288762887728878288792888028881288822888328884288852888628887288882888928890288912889228893288942889528896288972889828899289002890128902289032890428905289062890728908289092891028911289122891328914289152891628917289182891928920289212892228923289242892528926289272892828929289302893128932289332893428935289362893728938289392894028941289422894328944289452894628947289482894928950289512895228953289542895528956289572895828959289602896128962289632896428965289662896728968289692897028971289722897328974289752897628977289782897928980289812898228983289842898528986289872898828989289902899128992289932899428995289962899728998289992900029001290022900329004290052900629007290082900929010290112901229013290142901529016290172901829019290202902129022290232902429025290262902729028290292903029031290322903329034290352903629037290382903929040290412904229043290442904529046290472904829049290502905129052290532905429055290562905729058290592906029061290622906329064290652906629067290682906929070290712907229073290742907529076290772907829079290802908129082290832908429085290862908729088290892909029091290922909329094290952909629097290982909929100291012910229103291042910529106291072910829109291102911129112291132911429115291162911729118291192912029121291222912329124291252912629127291282912929130291312913229133291342913529136291372913829139291402914129142291432914429145291462914729148291492915029151291522915329154291552915629157291582915929160291612916229163291642916529166291672916829169291702917129172291732917429175291762917729178291792918029181291822918329184291852918629187291882918929190291912919229193291942919529196291972919829199292002920129202292032920429205292062920729208292092921029211292122921329214292152921629217292182921929220292212922229223292242922529226292272922829229292302923129232292332923429235292362923729238292392924029241292422924329244292452924629247292482924929250292512925229253292542925529256292572925829259292602926129262292632926429265292662926729268292692927029271292722927329274292752927629277292782927929280292812928229283292842928529286292872928829289292902929129292292932929429295292962929729298292992930029301293022930329304293052930629307293082930929310293112931229313293142931529316293172931829319293202932129322293232932429325293262932729328293292933029331293322933329334293352933629337293382933929340293412934229343293442934529346293472934829349293502935129352293532935429355293562935729358293592936029361293622936329364293652936629367293682936929370293712937229373293742937529376293772937829379293802938129382293832938429385293862938729388293892939029391293922939329394293952939629397293982939929400294012940229403294042940529406294072940829409294102941129412294132941429415294162941729418294192942029421294222942329424294252942629427294282942929430294312943229433294342943529436294372943829439294402944129442294432944429445294462944729448294492945029451294522945329454294552945629457294582945929460294612946229463294642946529466294672946829469294702947129472294732947429475294762947729478294792948029481294822948329484294852948629487294882948929490294912949229493294942949529496294972949829499295002950129502295032950429505295062950729508295092951029511295122951329514295152951629517295182951929520295212952229523295242952529526295272952829529295302953129532295332953429535295362953729538295392954029541295422954329544295452954629547295482954929550295512955229553295542955529556295572955829559295602956129562295632956429565295662956729568295692957029571295722957329574295752957629577295782957929580295812958229583295842958529586295872958829589295902959129592295932959429595295962959729598295992960029601296022960329604296052960629607296082960929610296112961229613296142961529616296172961829619296202962129622296232962429625296262962729628296292963029631296322963329634296352963629637296382963929640296412964229643296442964529646296472964829649296502965129652296532965429655296562965729658296592966029661296622966329664296652966629667296682966929670296712967229673296742967529676296772967829679296802968129682296832968429685296862968729688296892969029691296922969329694296952969629697296982969929700297012970229703297042970529706297072970829709297102971129712297132971429715297162971729718297192972029721297222972329724297252972629727297282972929730297312973229733297342973529736297372973829739297402974129742297432974429745297462974729748297492975029751297522975329754297552975629757297582975929760297612976229763297642976529766297672976829769297702977129772297732977429775297762977729778297792978029781297822978329784297852978629787297882978929790297912979229793297942979529796297972979829799298002980129802298032980429805298062980729808298092981029811298122981329814298152981629817298182981929820298212982229823298242982529826298272982829829298302983129832298332983429835298362983729838298392984029841298422984329844298452984629847298482984929850298512985229853298542985529856298572985829859298602986129862298632986429865298662986729868298692987029871298722987329874298752987629877298782987929880298812988229883298842988529886298872988829889298902989129892298932989429895298962989729898298992990029901299022990329904299052990629907299082990929910299112991229913299142991529916299172991829919299202992129922299232992429925299262992729928299292993029931299322993329934299352993629937299382993929940299412994229943299442994529946299472994829949299502995129952299532995429955299562995729958299592996029961299622996329964299652996629967299682996929970299712997229973299742997529976299772997829979299802998129982299832998429985299862998729988299892999029991299922999329994299952999629997299982999930000300013000230003300043000530006300073000830009300103001130012300133001430015300163001730018300193002030021300223002330024300253002630027300283002930030300313003230033300343003530036300373003830039300403004130042300433004430045300463004730048300493005030051300523005330054300553005630057300583005930060300613006230063300643006530066300673006830069300703007130072300733007430075300763007730078300793008030081300823008330084300853008630087300883008930090300913009230093300943009530096300973009830099301003010130102301033010430105301063010730108301093011030111301123011330114301153011630117301183011930120301213012230123301243012530126301273012830129301303013130132301333013430135301363013730138301393014030141301423014330144301453014630147301483014930150301513015230153301543015530156301573015830159301603016130162301633016430165301663016730168301693017030171301723017330174301753017630177301783017930180301813018230183301843018530186301873018830189301903019130192301933019430195301963019730198301993020030201302023020330204302053020630207302083020930210302113021230213302143021530216302173021830219302203022130222302233022430225302263022730228302293023030231302323023330234302353023630237302383023930240302413024230243302443024530246302473024830249302503025130252302533025430255302563025730258302593026030261302623026330264302653026630267302683026930270302713027230273302743027530276302773027830279302803028130282302833028430285302863028730288302893029030291302923029330294302953029630297302983029930300303013030230303303043030530306303073030830309303103031130312303133031430315303163031730318303193032030321303223032330324303253032630327303283032930330303313033230333303343033530336303373033830339303403034130342303433034430345303463034730348303493035030351303523035330354303553035630357303583035930360303613036230363303643036530366303673036830369303703037130372303733037430375303763037730378303793038030381303823038330384303853038630387303883038930390303913039230393303943039530396303973039830399304003040130402304033040430405304063040730408304093041030411304123041330414304153041630417304183041930420304213042230423304243042530426304273042830429304303043130432304333043430435304363043730438304393044030441304423044330444304453044630447304483044930450304513045230453304543045530456304573045830459304603046130462304633046430465304663046730468304693047030471304723047330474304753047630477304783047930480304813048230483304843048530486304873048830489304903049130492304933049430495304963049730498304993050030501305023050330504305053050630507305083050930510305113051230513305143051530516305173051830519305203052130522305233052430525305263052730528305293053030531305323053330534305353053630537305383053930540305413054230543305443054530546305473054830549305503055130552305533055430555305563055730558305593056030561305623056330564305653056630567305683056930570305713057230573305743057530576305773057830579305803058130582305833058430585305863058730588305893059030591305923059330594305953059630597305983059930600306013060230603306043060530606306073060830609306103061130612306133061430615306163061730618306193062030621306223062330624306253062630627306283062930630306313063230633306343063530636306373063830639306403064130642306433064430645306463064730648306493065030651306523065330654306553065630657306583065930660306613066230663306643066530666306673066830669306703067130672306733067430675306763067730678306793068030681306823068330684306853068630687306883068930690306913069230693306943069530696306973069830699307003070130702307033070430705307063070730708307093071030711307123071330714307153071630717307183071930720307213072230723307243072530726307273072830729307303073130732307333073430735307363073730738307393074030741307423074330744307453074630747307483074930750307513075230753307543075530756307573075830759307603076130762307633076430765307663076730768307693077030771307723077330774307753077630777307783077930780307813078230783307843078530786307873078830789307903079130792307933079430795307963079730798307993080030801308023080330804308053080630807308083080930810308113081230813308143081530816308173081830819308203082130822308233082430825308263082730828308293083030831308323083330834308353083630837308383083930840308413084230843308443084530846308473084830849308503085130852308533085430855308563085730858308593086030861308623086330864308653086630867308683086930870308713087230873308743087530876308773087830879308803088130882308833088430885308863088730888308893089030891308923089330894308953089630897308983089930900309013090230903309043090530906309073090830909309103091130912309133091430915309163091730918309193092030921309223092330924309253092630927309283092930930309313093230933309343093530936309373093830939309403094130942309433094430945309463094730948309493095030951309523095330954309553095630957309583095930960309613096230963309643096530966309673096830969309703097130972309733097430975309763097730978309793098030981309823098330984309853098630987309883098930990309913099230993309943099530996309973099830999310003100131002310033100431005310063100731008310093101031011310123101331014310153101631017310183101931020310213102231023310243102531026310273102831029310303103131032310333103431035310363103731038310393104031041310423104331044310453104631047310483104931050310513105231053310543105531056310573105831059310603106131062310633106431065310663106731068310693107031071310723107331074310753107631077310783107931080310813108231083310843108531086310873108831089310903109131092310933109431095310963109731098310993110031101311023110331104311053110631107311083110931110311113111231113311143111531116311173111831119311203112131122311233112431125311263112731128311293113031131311323113331134311353113631137311383113931140311413114231143311443114531146311473114831149311503115131152311533115431155311563115731158311593116031161311623116331164311653116631167311683116931170311713117231173311743117531176311773117831179311803118131182311833118431185311863118731188311893119031191311923119331194311953119631197311983119931200312013120231203312043120531206312073120831209312103121131212312133121431215312163121731218312193122031221312223122331224312253122631227312283122931230312313123231233312343123531236312373123831239312403124131242312433124431245312463124731248312493125031251312523125331254312553125631257312583125931260312613126231263312643126531266312673126831269312703127131272312733127431275312763127731278312793128031281312823128331284312853128631287312883128931290312913129231293312943129531296312973129831299313003130131302313033130431305313063130731308313093131031311313123131331314313153131631317313183131931320313213132231323313243132531326313273132831329313303133131332313333133431335313363133731338313393134031341313423134331344313453134631347313483134931350313513135231353313543135531356313573135831359313603136131362313633136431365313663136731368313693137031371313723137331374313753137631377313783137931380313813138231383313843138531386313873138831389313903139131392313933139431395313963139731398313993140031401314023140331404314053140631407314083140931410314113141231413314143141531416314173141831419314203142131422314233142431425314263142731428314293143031431314323143331434314353143631437314383143931440314413144231443314443144531446314473144831449314503145131452314533145431455314563145731458314593146031461314623146331464314653146631467314683146931470314713147231473314743147531476314773147831479314803148131482314833148431485314863148731488314893149031491314923149331494314953149631497314983149931500315013150231503315043150531506315073150831509315103151131512315133151431515315163151731518315193152031521315223152331524315253152631527315283152931530315313153231533315343153531536315373153831539315403154131542315433154431545315463154731548315493155031551315523155331554315553155631557315583155931560315613156231563315643156531566315673156831569315703157131572315733157431575315763157731578315793158031581315823158331584315853158631587315883158931590315913159231593315943159531596315973159831599316003160131602316033160431605316063160731608316093161031611316123161331614316153161631617316183161931620316213162231623316243162531626316273162831629316303163131632316333163431635316363163731638316393164031641316423164331644316453164631647316483164931650316513165231653316543165531656316573165831659316603166131662316633166431665316663166731668316693167031671316723167331674316753167631677316783167931680316813168231683316843168531686316873168831689316903169131692316933169431695316963169731698316993170031701317023170331704317053170631707317083170931710317113171231713317143171531716317173171831719317203172131722317233172431725317263172731728317293173031731317323173331734317353173631737317383173931740317413174231743317443174531746317473174831749317503175131752317533175431755317563175731758317593176031761317623176331764317653176631767317683176931770317713177231773317743177531776317773177831779317803178131782317833178431785317863178731788317893179031791317923179331794317953179631797317983179931800318013180231803318043180531806318073180831809318103181131812318133181431815318163181731818318193182031821318223182331824318253182631827318283182931830318313183231833318343183531836318373183831839318403184131842318433184431845318463184731848318493185031851318523185331854318553185631857318583185931860318613186231863318643186531866318673186831869318703187131872318733187431875318763187731878318793188031881318823188331884318853188631887318883188931890318913189231893318943189531896318973189831899319003190131902319033190431905319063190731908319093191031911319123191331914319153191631917319183191931920319213192231923319243192531926319273192831929319303193131932319333193431935319363193731938319393194031941319423194331944319453194631947319483194931950319513195231953319543195531956319573195831959319603196131962319633196431965319663196731968319693197031971319723197331974319753197631977319783197931980319813198231983319843198531986319873198831989319903199131992319933199431995319963199731998319993200032001320023200332004320053200632007320083200932010320113201232013320143201532016320173201832019320203202132022320233202432025320263202732028320293203032031320323203332034320353203632037320383203932040320413204232043320443204532046320473204832049320503205132052320533205432055320563205732058320593206032061320623206332064320653206632067320683206932070320713207232073320743207532076320773207832079320803208132082320833208432085320863208732088320893209032091320923209332094320953209632097320983209932100321013210232103321043210532106321073210832109321103211132112321133211432115321163211732118321193212032121321223212332124321253212632127321283212932130321313213232133321343213532136321373213832139321403214132142321433214432145321463214732148321493215032151321523215332154321553215632157321583215932160321613216232163321643216532166321673216832169321703217132172321733217432175321763217732178321793218032181321823218332184321853218632187321883218932190321913219232193321943219532196321973219832199322003220132202322033220432205322063220732208322093221032211322123221332214322153221632217322183221932220322213222232223322243222532226322273222832229322303223132232322333223432235322363223732238322393224032241322423224332244322453224632247322483224932250322513225232253322543225532256322573225832259322603226132262322633226432265322663226732268322693227032271322723227332274322753227632277322783227932280322813228232283322843228532286322873228832289322903229132292322933229432295322963229732298322993230032301323023230332304323053230632307323083230932310323113231232313323143231532316323173231832319323203232132322323233232432325323263232732328323293233032331323323233332334323353233632337323383233932340323413234232343323443234532346323473234832349323503235132352323533235432355323563235732358323593236032361323623236332364323653236632367323683236932370323713237232373323743237532376323773237832379323803238132382323833238432385323863238732388323893239032391323923239332394323953239632397323983239932400324013240232403324043240532406324073240832409324103241132412324133241432415324163241732418324193242032421324223242332424324253242632427324283242932430324313243232433324343243532436324373243832439324403244132442324433244432445324463244732448324493245032451324523245332454324553245632457324583245932460324613246232463324643246532466324673246832469324703247132472324733247432475324763247732478324793248032481324823248332484324853248632487324883248932490324913249232493324943249532496324973249832499325003250132502325033250432505325063250732508325093251032511325123251332514325153251632517325183251932520325213252232523325243252532526325273252832529325303253132532325333253432535325363253732538325393254032541325423254332544325453254632547325483254932550325513255232553325543255532556325573255832559325603256132562325633256432565325663256732568325693257032571325723257332574325753257632577325783257932580325813258232583325843258532586325873258832589325903259132592325933259432595325963259732598325993260032601326023260332604326053260632607326083260932610326113261232613326143261532616326173261832619326203262132622326233262432625326263262732628326293263032631326323263332634326353263632637326383263932640326413264232643326443264532646326473264832649326503265132652326533265432655326563265732658326593266032661326623266332664326653266632667326683266932670326713267232673326743267532676326773267832679326803268132682326833268432685326863268732688326893269032691326923269332694326953269632697326983269932700327013270232703327043270532706327073270832709327103271132712327133271432715327163271732718327193272032721327223272332724327253272632727327283272932730327313273232733327343273532736327373273832739327403274132742327433274432745327463274732748327493275032751327523275332754327553275632757327583275932760327613276232763327643276532766327673276832769327703277132772327733277432775327763277732778327793278032781327823278332784327853278632787327883278932790327913279232793327943279532796327973279832799328003280132802328033280432805328063280732808328093281032811328123281332814328153281632817328183281932820328213282232823328243282532826328273282832829328303283132832328333283432835328363283732838328393284032841328423284332844328453284632847328483284932850328513285232853328543285532856328573285832859328603286132862328633286432865328663286732868328693287032871328723287332874328753287632877328783287932880328813288232883328843288532886328873288832889328903289132892328933289432895328963289732898328993290032901329023290332904329053290632907329083290932910329113291232913329143291532916329173291832919329203292132922329233292432925329263292732928329293293032931329323293332934329353293632937329383293932940329413294232943329443294532946329473294832949329503295132952329533295432955329563295732958329593296032961329623296332964329653296632967329683296932970329713297232973329743297532976329773297832979329803298132982329833298432985329863298732988329893299032991329923299332994329953299632997329983299933000330013300233003330043300533006330073300833009330103301133012330133301433015330163301733018330193302033021330223302333024330253302633027330283302933030330313303233033330343303533036330373303833039330403304133042330433304433045330463304733048330493305033051330523305333054330553305633057330583305933060330613306233063330643306533066330673306833069330703307133072330733307433075330763307733078330793308033081330823308333084330853308633087330883308933090330913309233093330943309533096330973309833099331003310133102331033310433105331063310733108331093311033111331123311333114331153311633117331183311933120331213312233123331243312533126331273312833129331303313133132331333313433135331363313733138331393314033141331423314333144331453314633147331483314933150331513315233153331543315533156331573315833159331603316133162331633316433165331663316733168331693317033171331723317333174331753317633177331783317933180331813318233183331843318533186331873318833189331903319133192331933319433195331963319733198331993320033201332023320333204332053320633207332083320933210332113321233213332143321533216332173321833219332203322133222332233322433225332263322733228332293323033231332323323333234332353323633237332383323933240332413324233243332443324533246332473324833249332503325133252332533325433255332563325733258332593326033261332623326333264332653326633267332683326933270332713327233273332743327533276332773327833279332803328133282332833328433285332863328733288332893329033291332923329333294332953329633297332983329933300333013330233303333043330533306333073330833309333103331133312333133331433315333163331733318333193332033321333223332333324333253332633327333283332933330333313333233333333343333533336333373333833339333403334133342333433334433345333463334733348333493335033351333523335333354333553335633357333583335933360333613336233363333643336533366333673336833369333703337133372333733337433375333763337733378333793338033381333823338333384333853338633387333883338933390333913339233393333943339533396333973339833399334003340133402334033340433405334063340733408334093341033411334123341333414334153341633417334183341933420334213342233423334243342533426334273342833429334303343133432334333343433435334363343733438334393344033441334423344333444334453344633447334483344933450334513345233453334543345533456334573345833459334603346133462334633346433465334663346733468334693347033471334723347333474334753347633477334783347933480334813348233483334843348533486334873348833489334903349133492334933349433495334963349733498334993350033501335023350333504335053350633507335083350933510335113351233513335143351533516335173351833519335203352133522335233352433525335263352733528335293353033531335323353333534335353353633537335383353933540335413354233543335443354533546335473354833549335503355133552335533355433555335563355733558335593356033561335623356333564335653356633567335683356933570335713357233573335743357533576335773357833579335803358133582335833358433585335863358733588335893359033591335923359333594335953359633597335983359933600336013360233603336043360533606336073360833609336103361133612336133361433615336163361733618336193362033621336223362333624336253362633627336283362933630336313363233633336343363533636336373363833639336403364133642336433364433645336463364733648336493365033651336523365333654336553365633657336583365933660336613366233663336643366533666336673366833669336703367133672336733367433675336763367733678336793368033681336823368333684336853368633687336883368933690336913369233693336943369533696336973369833699337003370133702337033370433705337063370733708337093371033711337123371333714337153371633717337183371933720337213372233723337243372533726337273372833729337303373133732337333373433735337363373733738337393374033741337423374333744337453374633747337483374933750337513375233753337543375533756337573375833759337603376133762337633376433765337663376733768337693377033771337723377333774337753377633777337783377933780337813378233783337843378533786337873378833789337903379133792337933379433795337963379733798337993380033801338023380333804338053380633807338083380933810338113381233813338143381533816338173381833819338203382133822338233382433825338263382733828338293383033831338323383333834338353383633837338383383933840338413384233843338443384533846338473384833849338503385133852338533385433855338563385733858338593386033861338623386333864338653386633867338683386933870338713387233873338743387533876338773387833879338803388133882338833388433885338863388733888338893389033891338923389333894338953389633897338983389933900339013390233903339043390533906339073390833909339103391133912339133391433915339163391733918339193392033921339223392333924339253392633927339283392933930339313393233933339343393533936339373393833939339403394133942339433394433945339463394733948339493395033951339523395333954339553395633957339583395933960339613396233963339643396533966339673396833969339703397133972339733397433975339763397733978339793398033981339823398333984339853398633987339883398933990339913399233993339943399533996339973399833999340003400134002340033400434005340063400734008340093401034011340123401334014340153401634017340183401934020340213402234023340243402534026340273402834029340303403134032340333403434035340363403734038340393404034041340423404334044340453404634047340483404934050340513405234053340543405534056340573405834059340603406134062340633406434065340663406734068340693407034071340723407334074340753407634077340783407934080340813408234083340843408534086340873408834089340903409134092340933409434095340963409734098340993410034101341023410334104341053410634107341083410934110341113411234113341143411534116341173411834119341203412134122341233412434125341263412734128341293413034131341323413334134341353413634137341383413934140341413414234143341443414534146341473414834149341503415134152341533415434155341563415734158341593416034161341623416334164341653416634167341683416934170341713417234173341743417534176341773417834179341803418134182341833418434185341863418734188341893419034191341923419334194341953419634197341983419934200342013420234203342043420534206342073420834209342103421134212342133421434215342163421734218342193422034221342223422334224342253422634227342283422934230342313423234233342343423534236342373423834239342403424134242342433424434245342463424734248342493425034251342523425334254342553425634257342583425934260342613426234263342643426534266342673426834269342703427134272342733427434275342763427734278342793428034281342823428334284342853428634287342883428934290342913429234293342943429534296342973429834299343003430134302343033430434305343063430734308343093431034311343123431334314343153431634317343183431934320343213432234323343243432534326343273432834329343303433134332343333433434335343363433734338343393434034341343423434334344343453434634347343483434934350343513435234353343543435534356343573435834359343603436134362343633436434365343663436734368343693437034371343723437334374343753437634377343783437934380343813438234383343843438534386343873438834389343903439134392343933439434395343963439734398343993440034401344023440334404344053440634407344083440934410344113441234413344143441534416344173441834419344203442134422344233442434425344263442734428344293443034431344323443334434344353443634437344383443934440344413444234443344443444534446344473444834449344503445134452344533445434455344563445734458344593446034461344623446334464344653446634467344683446934470344713447234473344743447534476344773447834479344803448134482344833448434485344863448734488344893449034491344923449334494344953449634497344983449934500345013450234503345043450534506345073450834509345103451134512345133451434515345163451734518345193452034521345223452334524345253452634527345283452934530345313453234533345343453534536345373453834539345403454134542345433454434545345463454734548345493455034551345523455334554345553455634557345583455934560345613456234563345643456534566345673456834569345703457134572345733457434575345763457734578345793458034581345823458334584345853458634587345883458934590345913459234593345943459534596345973459834599346003460134602346033460434605346063460734608346093461034611346123461334614346153461634617346183461934620346213462234623346243462534626346273462834629346303463134632346333463434635346363463734638346393464034641346423464334644346453464634647346483464934650346513465234653346543465534656346573465834659346603466134662346633466434665346663466734668346693467034671346723467334674346753467634677346783467934680346813468234683346843468534686346873468834689346903469134692346933469434695346963469734698346993470034701347023470334704347053470634707347083470934710347113471234713347143471534716347173471834719347203472134722347233472434725347263472734728347293473034731347323473334734347353473634737347383473934740347413474234743347443474534746347473474834749347503475134752347533475434755347563475734758347593476034761347623476334764347653476634767347683476934770347713477234773347743477534776347773477834779347803478134782347833478434785347863478734788347893479034791347923479334794347953479634797347983479934800348013480234803348043480534806348073480834809348103481134812348133481434815348163481734818348193482034821348223482334824348253482634827348283482934830348313483234833348343483534836348373483834839348403484134842348433484434845348463484734848348493485034851348523485334854348553485634857348583485934860348613486234863348643486534866348673486834869348703487134872348733487434875348763487734878348793488034881348823488334884348853488634887348883488934890348913489234893348943489534896348973489834899349003490134902349033490434905349063490734908349093491034911349123491334914349153491634917349183491934920349213492234923349243492534926349273492834929349303493134932349333493434935349363493734938349393494034941349423494334944349453494634947349483494934950349513495234953349543495534956349573495834959349603496134962349633496434965349663496734968349693497034971349723497334974349753497634977349783497934980349813498234983349843498534986349873498834989349903499134992349933499434995349963499734998349993500035001350023500335004350053500635007350083500935010350113501235013350143501535016350173501835019350203502135022350233502435025350263502735028350293503035031350323503335034350353503635037350383503935040350413504235043350443504535046350473504835049350503505135052350533505435055350563505735058350593506035061350623506335064350653506635067350683506935070350713507235073350743507535076350773507835079350803508135082350833508435085350863508735088350893509035091350923509335094350953509635097350983509935100351013510235103351043510535106351073510835109351103511135112351133511435115351163511735118351193512035121351223512335124351253512635127351283512935130351313513235133351343513535136351373513835139351403514135142351433514435145351463514735148351493515035151351523515335154351553515635157351583515935160351613516235163351643516535166351673516835169351703517135172351733517435175351763517735178351793518035181351823518335184351853518635187351883518935190351913519235193351943519535196351973519835199352003520135202352033520435205352063520735208352093521035211352123521335214352153521635217352183521935220352213522235223352243522535226352273522835229352303523135232352333523435235352363523735238352393524035241352423524335244352453524635247352483524935250352513525235253352543525535256352573525835259352603526135262352633526435265352663526735268352693527035271352723527335274352753527635277352783527935280352813528235283352843528535286352873528835289352903529135292352933529435295352963529735298352993530035301353023530335304353053530635307353083530935310353113531235313353143531535316353173531835319353203532135322353233532435325353263532735328353293533035331353323533335334353353533635337353383533935340353413534235343353443534535346353473534835349353503535135352353533535435355353563535735358353593536035361353623536335364353653536635367353683536935370353713537235373353743537535376353773537835379353803538135382353833538435385353863538735388353893539035391353923539335394353953539635397353983539935400354013540235403354043540535406354073540835409354103541135412354133541435415354163541735418354193542035421354223542335424354253542635427354283542935430354313543235433354343543535436354373543835439354403544135442354433544435445354463544735448354493545035451354523545335454354553545635457354583545935460354613546235463354643546535466354673546835469354703547135472354733547435475354763547735478354793548035481354823548335484354853548635487354883548935490354913549235493354943549535496354973549835499355003550135502355033550435505355063550735508355093551035511355123551335514355153551635517355183551935520355213552235523355243552535526355273552835529355303553135532355333553435535355363553735538355393554035541355423554335544355453554635547355483554935550355513555235553355543555535556355573555835559355603556135562355633556435565355663556735568355693557035571355723557335574355753557635577355783557935580355813558235583355843558535586355873558835589355903559135592355933559435595355963559735598355993560035601356023560335604356053560635607356083560935610356113561235613356143561535616356173561835619356203562135622356233562435625356263562735628356293563035631356323563335634356353563635637356383563935640356413564235643356443564535646356473564835649356503565135652356533565435655356563565735658356593566035661356623566335664356653566635667356683566935670356713567235673356743567535676356773567835679356803568135682356833568435685356863568735688356893569035691356923569335694356953569635697356983569935700357013570235703357043570535706357073570835709357103571135712357133571435715357163571735718357193572035721357223572335724357253572635727357283572935730357313573235733357343573535736357373573835739357403574135742357433574435745357463574735748357493575035751357523575335754357553575635757357583575935760357613576235763357643576535766357673576835769357703577135772357733577435775357763577735778357793578035781357823578335784357853578635787357883578935790357913579235793357943579535796357973579835799358003580135802358033580435805358063580735808358093581035811358123581335814358153581635817358183581935820358213582235823358243582535826358273582835829358303583135832358333583435835358363583735838358393584035841358423584335844358453584635847358483584935850358513585235853358543585535856358573585835859358603586135862358633586435865358663586735868358693587035871358723587335874358753587635877358783587935880358813588235883358843588535886358873588835889358903589135892358933589435895358963589735898358993590035901359023590335904359053590635907359083590935910359113591235913359143591535916359173591835919359203592135922359233592435925359263592735928359293593035931359323593335934359353593635937359383593935940359413594235943359443594535946359473594835949359503595135952359533595435955359563595735958359593596035961359623596335964359653596635967359683596935970359713597235973359743597535976359773597835979359803598135982359833598435985359863598735988359893599035991359923599335994359953599635997359983599936000360013600236003360043600536006360073600836009360103601136012360133601436015360163601736018360193602036021360223602336024360253602636027360283602936030360313603236033360343603536036360373603836039360403604136042360433604436045360463604736048360493605036051360523605336054360553605636057360583605936060360613606236063360643606536066360673606836069360703607136072360733607436075360763607736078360793608036081360823608336084360853608636087360883608936090360913609236093360943609536096360973609836099361003610136102361033610436105361063610736108361093611036111361123611336114361153611636117361183611936120361213612236123361243612536126361273612836129361303613136132361333613436135361363613736138361393614036141361423614336144361453614636147361483614936150361513615236153361543615536156361573615836159361603616136162361633616436165361663616736168361693617036171361723617336174361753617636177361783617936180361813618236183361843618536186361873618836189361903619136192361933619436195361963619736198361993620036201362023620336204362053620636207362083620936210362113621236213362143621536216362173621836219362203622136222362233622436225362263622736228362293623036231362323623336234362353623636237362383623936240362413624236243362443624536246362473624836249362503625136252362533625436255362563625736258362593626036261362623626336264362653626636267362683626936270362713627236273362743627536276362773627836279362803628136282362833628436285362863628736288362893629036291362923629336294362953629636297362983629936300363013630236303363043630536306363073630836309363103631136312363133631436315363163631736318363193632036321363223632336324363253632636327363283632936330363313633236333363343633536336363373633836339363403634136342363433634436345363463634736348363493635036351363523635336354363553635636357363583635936360363613636236363363643636536366363673636836369363703637136372363733637436375363763637736378363793638036381363823638336384363853638636387363883638936390363913639236393363943639536396363973639836399364003640136402364033640436405364063640736408364093641036411364123641336414364153641636417364183641936420364213642236423364243642536426364273642836429364303643136432364333643436435364363643736438364393644036441364423644336444364453644636447364483644936450364513645236453364543645536456364573645836459364603646136462364633646436465364663646736468364693647036471364723647336474364753647636477364783647936480364813648236483364843648536486364873648836489364903649136492364933649436495364963649736498364993650036501365023650336504365053650636507365083650936510365113651236513365143651536516365173651836519365203652136522365233652436525365263652736528365293653036531365323653336534365353653636537365383653936540365413654236543365443654536546365473654836549365503655136552365533655436555365563655736558365593656036561365623656336564365653656636567365683656936570365713657236573365743657536576365773657836579365803658136582365833658436585365863658736588365893659036591365923659336594365953659636597365983659936600366013660236603366043660536606366073660836609366103661136612366133661436615366163661736618366193662036621366223662336624366253662636627366283662936630366313663236633366343663536636366373663836639366403664136642366433664436645366463664736648366493665036651366523665336654366553665636657366583665936660366613666236663366643666536666366673666836669366703667136672366733667436675366763667736678366793668036681366823668336684366853668636687366883668936690366913669236693366943669536696366973669836699367003670136702367033670436705367063670736708367093671036711367123671336714367153671636717367183671936720367213672236723367243672536726367273672836729367303673136732367333673436735367363673736738367393674036741367423674336744367453674636747367483674936750367513675236753367543675536756367573675836759367603676136762367633676436765367663676736768367693677036771367723677336774367753677636777367783677936780367813678236783367843678536786367873678836789367903679136792367933679436795367963679736798367993680036801368023680336804368053680636807368083680936810368113681236813368143681536816368173681836819368203682136822368233682436825368263682736828368293683036831368323683336834368353683636837368383683936840368413684236843368443684536846368473684836849368503685136852368533685436855368563685736858368593686036861368623686336864368653686636867368683686936870368713687236873368743687536876368773687836879368803688136882368833688436885368863688736888368893689036891368923689336894368953689636897368983689936900369013690236903369043690536906369073690836909369103691136912369133691436915369163691736918369193692036921369223692336924369253692636927369283692936930369313693236933369343693536936369373693836939369403694136942369433694436945369463694736948369493695036951369523695336954369553695636957369583695936960369613696236963369643696536966369673696836969369703697136972369733697436975369763697736978369793698036981369823698336984369853698636987369883698936990369913699236993369943699536996369973699836999370003700137002370033700437005370063700737008370093701037011370123701337014370153701637017370183701937020370213702237023370243702537026370273702837029370303703137032370333703437035370363703737038370393704037041370423704337044370453704637047370483704937050370513705237053370543705537056370573705837059370603706137062370633706437065370663706737068370693707037071370723707337074370753707637077370783707937080370813708237083370843708537086370873708837089370903709137092370933709437095370963709737098370993710037101371023710337104371053710637107371083710937110371113711237113371143711537116371173711837119371203712137122371233712437125371263712737128371293713037131371323713337134371353713637137371383713937140371413714237143371443714537146371473714837149371503715137152371533715437155371563715737158371593716037161371623716337164371653716637167371683716937170371713717237173371743717537176371773717837179371803718137182371833718437185371863718737188371893719037191371923719337194371953719637197371983719937200372013720237203372043720537206372073720837209372103721137212372133721437215372163721737218372193722037221372223722337224372253722637227372283722937230372313723237233372343723537236372373723837239372403724137242372433724437245372463724737248372493725037251372523725337254372553725637257372583725937260372613726237263372643726537266372673726837269372703727137272372733727437275372763727737278372793728037281372823728337284372853728637287372883728937290372913729237293372943729537296372973729837299373003730137302373033730437305373063730737308373093731037311373123731337314373153731637317373183731937320373213732237323373243732537326373273732837329373303733137332373333733437335373363733737338373393734037341373423734337344373453734637347373483734937350373513735237353373543735537356373573735837359373603736137362373633736437365373663736737368373693737037371373723737337374373753737637377373783737937380373813738237383373843738537386373873738837389373903739137392373933739437395373963739737398373993740037401374023740337404374053740637407374083740937410374113741237413374143741537416374173741837419374203742137422374233742437425374263742737428374293743037431374323743337434374353743637437374383743937440374413744237443374443744537446374473744837449374503745137452374533745437455374563745737458374593746037461374623746337464374653746637467374683746937470374713747237473374743747537476374773747837479374803748137482374833748437485374863748737488374893749037491374923749337494374953749637497374983749937500375013750237503375043750537506375073750837509375103751137512375133751437515375163751737518375193752037521375223752337524375253752637527375283752937530375313753237533375343753537536375373753837539375403754137542375433754437545375463754737548375493755037551375523755337554375553755637557375583755937560375613756237563375643756537566375673756837569375703757137572375733757437575375763757737578375793758037581375823758337584375853758637587375883758937590375913759237593375943759537596375973759837599376003760137602376033760437605376063760737608376093761037611376123761337614376153761637617376183761937620376213762237623376243762537626376273762837629376303763137632376333763437635376363763737638376393764037641376423764337644376453764637647376483764937650376513765237653376543765537656376573765837659376603766137662376633766437665376663766737668376693767037671376723767337674376753767637677376783767937680376813768237683376843768537686376873768837689376903769137692376933769437695376963769737698376993770037701377023770337704377053770637707377083770937710377113771237713377143771537716377173771837719377203772137722377233772437725377263772737728377293773037731377323773337734377353773637737377383773937740377413774237743377443774537746377473774837749377503775137752377533775437755377563775737758377593776037761377623776337764377653776637767377683776937770377713777237773377743777537776377773777837779377803778137782377833778437785377863778737788377893779037791377923779337794377953779637797377983779937800378013780237803378043780537806378073780837809378103781137812378133781437815378163781737818378193782037821378223782337824378253782637827378283782937830378313783237833378343783537836378373783837839378403784137842378433784437845378463784737848378493785037851378523785337854378553785637857378583785937860378613786237863378643786537866378673786837869378703787137872378733787437875378763787737878378793788037881378823788337884378853788637887378883788937890378913789237893378943789537896378973789837899379003790137902379033790437905379063790737908379093791037911379123791337914379153791637917379183791937920379213792237923379243792537926379273792837929379303793137932379333793437935379363793737938379393794037941379423794337944379453794637947379483794937950379513795237953379543795537956379573795837959379603796137962379633796437965379663796737968379693797037971379723797337974379753797637977379783797937980379813798237983379843798537986379873798837989379903799137992379933799437995379963799737998379993800038001380023800338004380053800638007380083800938010380113801238013380143801538016380173801838019380203802138022380233802438025380263802738028380293803038031380323803338034380353803638037380383803938040380413804238043380443804538046380473804838049380503805138052380533805438055380563805738058380593806038061380623806338064380653806638067380683806938070380713807238073380743807538076380773807838079380803808138082380833808438085380863808738088380893809038091380923809338094380953809638097380983809938100381013810238103381043810538106381073810838109381103811138112381133811438115381163811738118381193812038121381223812338124381253812638127381283812938130381313813238133381343813538136381373813838139381403814138142381433814438145381463814738148381493815038151381523815338154381553815638157381583815938160381613816238163381643816538166381673816838169381703817138172381733817438175381763817738178381793818038181381823818338184381853818638187381883818938190381913819238193381943819538196381973819838199382003820138202382033820438205382063820738208382093821038211382123821338214382153821638217382183821938220382213822238223382243822538226382273822838229382303823138232382333823438235382363823738238382393824038241382423824338244382453824638247382483824938250382513825238253382543825538256382573825838259382603826138262382633826438265382663826738268382693827038271382723827338274382753827638277382783827938280382813828238283382843828538286382873828838289382903829138292382933829438295382963829738298382993830038301383023830338304383053830638307383083830938310383113831238313383143831538316383173831838319383203832138322383233832438325383263832738328383293833038331383323833338334383353833638337383383833938340383413834238343383443834538346383473834838349383503835138352383533835438355383563835738358383593836038361383623836338364383653836638367383683836938370383713837238373383743837538376383773837838379383803838138382383833838438385383863838738388383893839038391383923839338394383953839638397383983839938400384013840238403384043840538406384073840838409384103841138412384133841438415384163841738418384193842038421384223842338424384253842638427384283842938430384313843238433384343843538436384373843838439384403844138442384433844438445384463844738448384493845038451384523845338454384553845638457384583845938460384613846238463384643846538466384673846838469384703847138472384733847438475384763847738478384793848038481384823848338484384853848638487384883848938490384913849238493384943849538496384973849838499385003850138502385033850438505385063850738508385093851038511385123851338514385153851638517385183851938520385213852238523385243852538526385273852838529385303853138532385333853438535385363853738538385393854038541385423854338544385453854638547385483854938550385513855238553385543855538556385573855838559385603856138562385633856438565385663856738568385693857038571385723857338574385753857638577385783857938580385813858238583385843858538586385873858838589385903859138592385933859438595385963859738598385993860038601386023860338604386053860638607386083860938610386113861238613386143861538616386173861838619386203862138622386233862438625386263862738628386293863038631386323863338634386353863638637386383863938640386413864238643386443864538646386473864838649386503865138652386533865438655386563865738658386593866038661386623866338664386653866638667386683866938670386713867238673386743867538676386773867838679386803868138682386833868438685386863868738688386893869038691386923869338694386953869638697386983869938700387013870238703387043870538706387073870838709387103871138712387133871438715387163871738718387193872038721387223872338724387253872638727387283872938730387313873238733387343873538736387373873838739387403874138742387433874438745387463874738748387493875038751387523875338754387553875638757387583875938760387613876238763387643876538766387673876838769387703877138772387733877438775387763877738778387793878038781387823878338784387853878638787387883878938790387913879238793387943879538796387973879838799388003880138802388033880438805388063880738808388093881038811388123881338814388153881638817388183881938820388213882238823388243882538826388273882838829388303883138832388333883438835388363883738838388393884038841388423884338844388453884638847388483884938850388513885238853388543885538856388573885838859388603886138862388633886438865388663886738868388693887038871388723887338874388753887638877388783887938880388813888238883388843888538886388873888838889388903889138892388933889438895388963889738898388993890038901389023890338904389053890638907389083890938910389113891238913389143891538916389173891838919389203892138922389233892438925389263892738928389293893038931389323893338934389353893638937389383893938940389413894238943389443894538946389473894838949389503895138952389533895438955389563895738958389593896038961389623896338964389653896638967389683896938970389713897238973389743897538976389773897838979389803898138982389833898438985389863898738988389893899038991389923899338994389953899638997389983899939000390013900239003390043900539006390073900839009390103901139012390133901439015390163901739018390193902039021390223902339024390253902639027390283902939030390313903239033390343903539036390373903839039390403904139042390433904439045390463904739048390493905039051390523905339054390553905639057390583905939060390613906239063390643906539066390673906839069390703907139072390733907439075390763907739078390793908039081390823908339084390853908639087390883908939090390913909239093390943909539096390973909839099391003910139102391033910439105391063910739108391093911039111391123911339114391153911639117391183911939120391213912239123391243912539126391273912839129391303913139132391333913439135391363913739138391393914039141 |
- /*
- This file is part of Ext JS 7.4.0.42
- Copyright (c) 2011-2021 Sencha Inc
- license: http://www.sencha.com/legal/sencha-software-license-agreement
- Contact: http://www.sencha.com/contact
- Commercial Usage
- Licensees holding valid commercial licenses may use this file in accordance with the Commercial
- Software License Agreement referenced above or, alternatively, in accordance with the
- terms contained in a written agreement between you and Sencha.
- If you are unsure which license is appropriate for your use, please contact the sales department
- at http://www.sencha.com/contact.
- Version: 7.4.0.42 Build date: 2021-05-04 14:42:24 (669f575eb1592a96aa3fb58a602faf3b96d819ea)
- */
- var Ext = Ext || {};
- (function(manifest){
- if(!Ext.manifest) {
- Ext.manifest = manifest;
- } else {
- for(var name in manifest) {
- Ext.manifest[name] = manifest[name];
- }
- }
- })({
- "paths": {
- "Ext": "../classic/classic/src",
- "Ext.AbstractManager": "../packages/core/src/AbstractManager.js",
- "Ext.Ajax": "../packages/core/src/Ajax.js",
- "Ext.AnimationQueue": "../packages/core/src/AnimationQueue.js",
- "Ext.ComponentManager": "../packages/core/src/ComponentManager.js",
- "Ext.ComponentQuery": "../packages/core/src/ComponentQuery.js",
- "Ext.Deferred": "../packages/core/src/Deferred.js",
- "Ext.Evented": "../packages/core/src/Evented.js",
- "Ext.Factory": "../packages/core/src/mixin/Factoryable.js",
- "Ext.GlobalEvents": "../packages/core/src/GlobalEvents.js",
- "Ext.Glyph": "../packages/core/src/Glyph.js",
- "Ext.JSON": "../packages/core/src/JSON.js",
- "Ext.Mixin": "../packages/core/src/class/Mixin.js",
- "Ext.Msg": "../classic/classic/src/window/MessageBox.js",
- "Ext.Progress": "../packages/core/src/Progress.js",
- "Ext.ProgressBase": "../packages/core/src/ProgressBase.js",
- "Ext.Promise": "../packages/core/src/Promise.js",
- "Ext.String.format": "../packages/core/src/Template.js",
- "Ext.TaskQueue": "../packages/core/src/TaskQueue.js",
- "Ext.Template": "../packages/core/src/Template.js",
- "Ext.Widget": "../packages/core/src/Widget.js",
- "Ext.XTemplate": "../packages/core/src/XTemplate.js",
- "Ext.app": "../packages/core/src/app",
- "Ext.data": "../packages/core/src/data",
- "Ext.direct": "../packages/core/src/direct",
- "Ext.dom": "../packages/core/src/dom",
- "Ext.dom.ButtonElement": "../classic/classic/src/dom/ButtonElement.js",
- "Ext.dom.Layer": "../classic/classic/src/dom/Layer.js",
- "Ext.drag": "../packages/core/src/drag",
- "Ext.event": "../packages/core/src/event",
- "Ext.event.publisher.MouseEnterLeave": "../classic/classic/src/event/publisher/MouseEnterLeave.js",
- "Ext.field": "../packages/core/src/field",
- "Ext.fx.Animation": "../packages/core/src/fx/Animation.js",
- "Ext.fx.Runner": "../packages/core/src/fx/Runner.js",
- "Ext.fx.State": "../packages/core/src/fx/State.js",
- "Ext.fx.animation": "../packages/core/src/fx/animation",
- "Ext.fx.easing": "../packages/core/src/fx/easing",
- "Ext.fx.runner": "../packages/core/src/fx/runner",
- "Ext.grid.AdvancedGroupStore": "../packages/core/src/grid/AdvancedGroupStore.js",
- "Ext.grid.plugin.BaseFilterBar": "../packages/core/src/grid/plugin/BaseFilterBar.js",
- "Ext.grid.plugin.BaseGroupingPanel": "../packages/core/src/grid/plugin/BaseGroupingPanel.js",
- "Ext.grid.plugin.BaseSummaries": "../packages/core/src/grid/plugin/BaseSummaries.js",
- "Ext.list": "../packages/core/src/list",
- "Ext.mixin": "../packages/core/src/mixin",
- "Ext.parse": "../packages/core/src/parse",
- "Ext.perf": "../packages/core/src/perf",
- "Ext.plugin.Abstract": "../packages/core/src/plugin/Abstract.js",
- "Ext.plugin.AbstractClipboard": "../packages/core/src/plugin/AbstractClipboard.js",
- "Ext.plugin.MouseEnter": "../packages/core/src/plugin/MouseEnter.js",
- "Ext.promise": "../packages/core/src/promise",
- "Ext.route": "../packages/core/src/route",
- "Ext.sparkline": "../packages/core/src/sparkline",
- "Ext.util": "../packages/core/src/util",
- "Ext.util.Animate": "../classic/classic/src/util/Animate.js",
- "Ext.util.ComponentDragger": "../classic/classic/src/util/ComponentDragger.js",
- "Ext.util.ElementContainer": "../classic/classic/src/util/ElementContainer.js",
- "Ext.util.Floating": "../classic/classic/src/util/Floating.js",
- "Ext.util.Format.format": "../packages/core/src/Template.js",
- "Ext.util.Memento": "../classic/classic/src/util/Memento.js",
- "Ext.util.ProtoElement": "../classic/classic/src/util/ProtoElement.js",
- "Ext.util.Queue": "../classic/classic/src/util/Queue.js",
- "Ext.util.Renderable": "../classic/classic/src/util/Renderable.js",
- "Ext.util.StoreHolder": "../classic/classic/src/util/StoreHolder.js",
- "Ext.util.TsvDecoder": "../packages/core/src/util/TSV.js"
- },
- "loadOrder": [
- {
- "path": "../packages/core/src/class/Mixin.js",
- "requires": [],
- "uses": [],
- "idx": 0
- },
- {
- "path": "../packages/core/src/util/DelayedTask.js",
- "requires": [],
- "uses": [
- 77
- ],
- "idx": 1
- },
- {
- "path": "../packages/core/src/util/Event.js",
- "requires": [
- 1
- ],
- "uses": [
- 24
- ],
- "idx": 2
- },
- {
- "path": "../packages/core/src/mixin/Identifiable.js",
- "requires": [],
- "uses": [],
- "idx": 3
- },
- {
- "path": "../packages/core/src/mixin/Observable.js",
- "requires": [
- 0,
- 2,
- 3
- ],
- "uses": [
- 52
- ],
- "idx": 4
- },
- {
- "path": "../packages/core/src/util/HashMap.js",
- "requires": [
- 4
- ],
- "uses": [],
- "idx": 5
- },
- {
- "path": "../packages/core/src/AbstractManager.js",
- "requires": [
- 5
- ],
- "uses": [],
- "idx": 6
- },
- {
- "path": "../packages/core/src/promise/Consequence.js",
- "requires": [],
- "uses": [
- 8
- ],
- "idx": 7
- },
- {
- "path": "../packages/core/src/promise/Deferred.js",
- "requires": [
- 7
- ],
- "uses": [
- 9
- ],
- "idx": 8
- },
- {
- "path": "../packages/core/src/promise/Promise.js",
- "requires": [
- 8
- ],
- "uses": [],
- "idx": 9
- },
- {
- "path": "../packages/core/src/Promise.js",
- "requires": [
- 9
- ],
- "uses": [
- 8
- ],
- "idx": 10
- },
- {
- "path": "../packages/core/src/Deferred.js",
- "requires": [
- 8,
- 10
- ],
- "uses": [
- 9
- ],
- "idx": 11
- },
- {
- "path": "../packages/core/src/mixin/Factoryable.js",
- "requires": [],
- "uses": [],
- "idx": 12
- },
- {
- "path": "../packages/core/src/data/request/Base.js",
- "requires": [
- 11,
- 12
- ],
- "uses": [
- 17
- ],
- "idx": 13
- },
- {
- "path": "../packages/core/src/data/flash/BinaryXhr.js",
- "requires": [],
- "uses": [
- 77
- ],
- "idx": 14
- },
- {
- "path": "../packages/core/src/data/request/Ajax.js",
- "requires": [
- 13,
- 14
- ],
- "uses": [],
- "idx": 15
- },
- {
- "path": "../packages/core/src/data/request/Form.js",
- "requires": [
- 13
- ],
- "uses": [],
- "idx": 16
- },
- {
- "path": "../packages/core/src/data/Connection.js",
- "requires": [
- 4,
- 11,
- 14,
- 15,
- 16
- ],
- "uses": [
- 12,
- 49
- ],
- "idx": 17
- },
- {
- "path": "../packages/core/src/Ajax.js",
- "requires": [
- 17
- ],
- "uses": [],
- "idx": 18
- },
- {
- "path": "../packages/core/src/AnimationQueue.js",
- "requires": [],
- "uses": [],
- "idx": 19
- },
- {
- "path": "../packages/core/src/mixin/Bufferable.js",
- "requires": [
- 0
- ],
- "uses": [],
- "idx": 20
- },
- {
- "path": "../packages/core/src/ComponentManager.js",
- "requires": [
- 20
- ],
- "uses": [
- 24,
- 36,
- 49,
- 89
- ],
- "idx": 21
- },
- {
- "path": "../packages/core/src/util/Operators.js",
- "requires": [],
- "uses": [],
- "idx": 22
- },
- {
- "path": "../packages/core/src/util/LruCache.js",
- "requires": [
- 5
- ],
- "uses": [],
- "idx": 23
- },
- {
- "path": "../packages/core/src/ComponentQuery.js",
- "requires": [
- 21,
- 22,
- 23
- ],
- "uses": [
- 95
- ],
- "idx": 24
- },
- {
- "path": "../packages/core/src/Evented.js",
- "requires": [
- 4
- ],
- "uses": [],
- "idx": 25
- },
- {
- "path": "../packages/core/src/util/Positionable.js",
- "requires": [],
- "uses": [
- 34,
- 49
- ],
- "idx": 26
- },
- {
- "path": "../packages/core/src/dom/UnderlayPool.js",
- "requires": [],
- "uses": [
- 49
- ],
- "idx": 27
- },
- {
- "path": "../packages/core/src/dom/Underlay.js",
- "requires": [
- 27
- ],
- "uses": [],
- "idx": 28
- },
- {
- "path": "../packages/core/src/dom/Shadow.js",
- "requires": [
- 28
- ],
- "uses": [],
- "idx": 29
- },
- {
- "path": "../packages/core/src/dom/Shim.js",
- "requires": [
- 28
- ],
- "uses": [],
- "idx": 30
- },
- {
- "path": "../packages/core/src/dom/ElementEvent.js",
- "requires": [
- 2
- ],
- "uses": [
- 37
- ],
- "idx": 31
- },
- {
- "path": "../packages/core/src/event/publisher/Publisher.js",
- "requires": [],
- "uses": [],
- "idx": 32
- },
- {
- "path": "../packages/core/src/util/Offset.js",
- "requires": [],
- "uses": [],
- "idx": 33
- },
- {
- "path": "../packages/core/src/util/Region.js",
- "requires": [
- 33
- ],
- "uses": [
- 49
- ],
- "idx": 34
- },
- {
- "path": "../packages/core/src/util/Point.js",
- "requires": [
- 34
- ],
- "uses": [],
- "idx": 35
- },
- {
- "path": "../packages/core/src/event/Event.js",
- "requires": [
- 35
- ],
- "uses": [
- 37,
- 77
- ],
- "idx": 36
- },
- {
- "path": "../packages/core/src/event/publisher/Dom.js",
- "requires": [
- 32,
- 36
- ],
- "uses": [
- 77
- ],
- "idx": 37
- },
- {
- "path": "../packages/core/src/event/publisher/Gesture.js",
- "requires": [
- 19,
- 35,
- 37
- ],
- "uses": [
- 36,
- 49,
- 313,
- 324,
- 325,
- 326,
- 327,
- 328,
- 329,
- 330,
- 331,
- 332,
- 333,
- 334
- ],
- "idx": 38
- },
- {
- "path": "../packages/core/src/mixin/Templatable.js",
- "requires": [
- 0
- ],
- "uses": [
- 49
- ],
- "idx": 39
- },
- {
- "path": "../packages/core/src/TaskQueue.js",
- "requires": [
- 19
- ],
- "uses": [],
- "idx": 40
- },
- {
- "path": "../packages/core/src/util/sizemonitor/Abstract.js",
- "requires": [
- 39,
- 40
- ],
- "uses": [],
- "idx": 41
- },
- {
- "path": "../packages/core/src/util/sizemonitor/Scroll.js",
- "requires": [
- 41
- ],
- "uses": [
- 40
- ],
- "idx": 42
- },
- {
- "path": "../packages/core/src/util/SizeMonitor.js",
- "requires": [
- 42
- ],
- "uses": [],
- "idx": 43
- },
- {
- "path": "../packages/core/src/event/publisher/ElementSize.js",
- "requires": [
- 32,
- 43
- ],
- "uses": [
- 40
- ],
- "idx": 44
- },
- {
- "path": "../packages/core/src/util/paintmonitor/Abstract.js",
- "requires": [],
- "uses": [
- 49
- ],
- "idx": 45
- },
- {
- "path": "../packages/core/src/util/paintmonitor/CssAnimation.js",
- "requires": [
- 45
- ],
- "uses": [],
- "idx": 46
- },
- {
- "path": "../packages/core/src/util/PaintMonitor.js",
- "requires": [
- 46
- ],
- "uses": [],
- "idx": 47
- },
- {
- "path": "../packages/core/src/event/publisher/ElementPaint.js",
- "requires": [
- 32,
- 40,
- 47
- ],
- "uses": [],
- "idx": 48
- },
- {
- "path": "../packages/core/src/dom/Element.js",
- "requires": [
- 4,
- 26,
- 29,
- 30,
- 31,
- 37,
- 38,
- 44,
- 48
- ],
- "uses": [
- 32,
- 34,
- 36,
- 75,
- 76,
- 95,
- 102,
- 253,
- 314,
- 335,
- 346,
- 348
- ],
- "idx": 49
- },
- {
- "path": "../packages/core/src/util/BasicFilter.js",
- "requires": [],
- "uses": [],
- "idx": 50
- },
- {
- "path": "../packages/core/src/util/Filter.js",
- "requires": [
- 50
- ],
- "uses": [],
- "idx": 51
- },
- {
- "path": "../packages/core/src/util/Observable.js",
- "requires": [
- 4
- ],
- "uses": [],
- "idx": 52
- },
- {
- "path": "../packages/core/src/util/AbstractMixedCollection.js",
- "requires": [
- 51,
- 52
- ],
- "uses": [],
- "idx": 53
- },
- {
- "path": "../packages/core/src/util/Sorter.js",
- "requires": [],
- "uses": [],
- "idx": 54
- },
- {
- "path": "../packages/core/src/util/Sortable.js",
- "requires": [
- 54
- ],
- "uses": [
- 56
- ],
- "idx": 55
- },
- {
- "path": "../packages/core/src/util/MixedCollection.js",
- "requires": [
- 53,
- 55
- ],
- "uses": [],
- "idx": 56
- },
- {
- "path": "../packages/core/src/util/TaskRunner.js",
- "requires": [],
- "uses": [],
- "idx": 57
- },
- {
- "path": "../classic/classic/src/fx/target/Target.js",
- "requires": [],
- "uses": [],
- "idx": 58
- },
- {
- "path": "../classic/classic/src/fx/target/Element.js",
- "requires": [
- 58
- ],
- "uses": [],
- "idx": 59
- },
- {
- "path": "../classic/classic/src/fx/target/ElementCSS.js",
- "requires": [
- 59
- ],
- "uses": [],
- "idx": 60
- },
- {
- "path": "../classic/classic/src/fx/target/CompositeElement.js",
- "requires": [
- 59
- ],
- "uses": [],
- "idx": 61
- },
- {
- "path": "../classic/classic/src/fx/target/CompositeElementCSS.js",
- "requires": [
- 60,
- 61
- ],
- "uses": [],
- "idx": 62
- },
- {
- "path": "../classic/classic/src/fx/target/Sprite.js",
- "requires": [
- 58
- ],
- "uses": [],
- "idx": 63
- },
- {
- "path": "../classic/classic/src/fx/target/CompositeSprite.js",
- "requires": [
- 63
- ],
- "uses": [],
- "idx": 64
- },
- {
- "path": "../classic/classic/src/fx/target/Component.js",
- "requires": [
- 58
- ],
- "uses": [
- 77
- ],
- "idx": 65
- },
- {
- "path": "../classic/classic/src/fx/Queue.js",
- "requires": [
- 5
- ],
- "uses": [],
- "idx": 66
- },
- {
- "path": "../classic/classic/src/fx/Manager.js",
- "requires": [
- 56,
- 57,
- 59,
- 60,
- 61,
- 62,
- 63,
- 64,
- 65,
- 66
- ],
- "uses": [],
- "idx": 67
- },
- {
- "path": "../classic/classic/src/fx/Animator.js",
- "requires": [
- 52,
- 67
- ],
- "uses": [
- 73
- ],
- "idx": 68
- },
- {
- "path": "../classic/classic/src/fx/CubicBezier.js",
- "requires": [],
- "uses": [],
- "idx": 69
- },
- {
- "path": "../classic/classic/src/fx/Easing.js",
- "requires": [
- 69
- ],
- "uses": [],
- "idx": 70
- },
- {
- "path": "../classic/classic/src/fx/DrawPath.js",
- "requires": [],
- "uses": [],
- "idx": 71
- },
- {
- "path": "../classic/classic/src/fx/PropertyHandler.js",
- "requires": [
- 71
- ],
- "uses": [],
- "idx": 72
- },
- {
- "path": "../classic/classic/src/fx/Anim.js",
- "requires": [
- 52,
- 67,
- 68,
- 69,
- 70,
- 72
- ],
- "uses": [],
- "idx": 73
- },
- {
- "path": "../classic/classic/src/util/Animate.js",
- "requires": [
- 67,
- 73
- ],
- "uses": [],
- "idx": 74
- },
- {
- "path": "../packages/core/src/dom/Fly.js",
- "requires": [
- 49
- ],
- "uses": [],
- "idx": 75
- },
- {
- "path": "../packages/core/src/dom/CompositeElementLite.js",
- "requires": [
- 75
- ],
- "uses": [
- 49
- ],
- "idx": 76
- },
- {
- "path": "../packages/core/src/GlobalEvents.js",
- "requires": [
- 4,
- 49
- ],
- "uses": [
- 21
- ],
- "idx": 77
- },
- {
- "path": "../packages/core/src/Glyph.js",
- "requires": [],
- "uses": [],
- "idx": 78
- },
- {
- "path": "../packages/core/src/JSON.js",
- "requires": [],
- "uses": [],
- "idx": 79
- },
- {
- "path": "../packages/core/src/Manifest.js",
- "requires": [],
- "uses": [],
- "idx": 80
- },
- {
- "path": "../packages/core/src/mixin/Inheritable.js",
- "requires": [
- 0
- ],
- "uses": [
- 21
- ],
- "idx": 81
- },
- {
- "path": "../packages/core/src/mixin/Bindable.js",
- "requires": [],
- "uses": [
- 12
- ],
- "idx": 82
- },
- {
- "path": "../packages/core/src/mixin/ComponentDelegation.js",
- "requires": [
- 0,
- 4
- ],
- "uses": [
- 2
- ],
- "idx": 83
- },
- {
- "path": "../packages/core/src/plugin/Abstract.js",
- "requires": [
- 3
- ],
- "uses": [],
- "idx": 84
- },
- {
- "path": "../packages/core/src/mixin/Pluggable.js",
- "requires": [
- 84
- ],
- "uses": [],
- "idx": 85
- },
- {
- "path": "../packages/core/src/mixin/Keyboard.js",
- "requires": [
- 0
- ],
- "uses": [
- 36
- ],
- "idx": 86
- },
- {
- "path": "../packages/core/src/mixin/Focusable.js",
- "requires": [],
- "uses": [
- 21,
- 24,
- 36,
- 49
- ],
- "idx": 87
- },
- {
- "path": "../packages/core/src/mixin/Accessible.js",
- "requires": [
- 0
- ],
- "uses": [],
- "idx": 88
- },
- {
- "path": "../packages/core/src/Widget.js",
- "requires": [
- 12,
- 25,
- 49,
- 81,
- 82,
- 83,
- 85,
- 86,
- 87,
- 88
- ],
- "uses": [
- 21,
- 24,
- 98
- ],
- "idx": 89
- },
- {
- "path": "../packages/core/src/mixin/Responsive.js",
- "requires": [
- 0
- ],
- "uses": [
- 49
- ],
- "idx": 90
- },
- {
- "path": "../classic/classic/src/ResponsiveWidget.js",
- "requires": [
- 90
- ],
- "uses": [],
- "idx": 91
- },
- {
- "path": "../packages/core/src/ProgressBase.js",
- "requires": [],
- "uses": [
- 98
- ],
- "idx": 92
- },
- {
- "path": "../packages/core/src/Progress.js",
- "requires": [
- 89,
- 92
- ],
- "uses": [],
- "idx": 93
- },
- {
- "path": "../packages/core/src/util/Format.js",
- "requires": [],
- "uses": [
- 95,
- 253
- ],
- "idx": 94
- },
- {
- "path": "../packages/core/src/Template.js",
- "requires": [
- 94
- ],
- "uses": [
- 253
- ],
- "idx": 95
- },
- {
- "path": "../packages/core/src/util/XTemplateParser.js",
- "requires": [],
- "uses": [],
- "idx": 96
- },
- {
- "path": "../packages/core/src/util/XTemplateCompiler.js",
- "requires": [
- 96
- ],
- "uses": [],
- "idx": 97
- },
- {
- "path": "../packages/core/src/XTemplate.js",
- "requires": [
- 95,
- 97
- ],
- "uses": [],
- "idx": 98
- },
- {
- "path": "../packages/core/src/app/EventDomain.js",
- "requires": [
- 2
- ],
- "uses": [],
- "idx": 99
- },
- {
- "path": "../packages/core/src/app/domain/Component.js",
- "requires": [
- 89,
- 99
- ],
- "uses": [],
- "idx": 100
- },
- {
- "path": "../classic/classic/src/util/ProtoElement.js",
- "requires": [],
- "uses": [
- 49,
- 253
- ],
- "idx": 101
- },
- {
- "path": "../packages/core/src/dom/CompositeElement.js",
- "requires": [
- 76
- ],
- "uses": [],
- "idx": 102
- },
- {
- "path": "../classic/classic/src/plugin/Manager.js",
- "requires": [],
- "uses": [],
- "idx": 103
- },
- {
- "path": "../packages/core/src/util/CSS.js",
- "requires": [],
- "uses": [
- 49
- ],
- "idx": 104
- },
- {
- "path": "../packages/core/src/fx/easing/Abstract.js",
- "requires": [],
- "uses": [],
- "idx": 105
- },
- {
- "path": "../packages/core/src/fx/easing/Linear.js",
- "requires": [
- 105
- ],
- "uses": [],
- "idx": 106
- },
- {
- "path": "../packages/core/src/util/translatable/Abstract.js",
- "requires": [
- 12,
- 25,
- 106
- ],
- "uses": [
- 19
- ],
- "idx": 107
- },
- {
- "path": "../packages/core/src/util/translatable/Dom.js",
- "requires": [
- 107
- ],
- "uses": [],
- "idx": 108
- },
- {
- "path": "../packages/core/src/util/translatable/ScrollPosition.js",
- "requires": [
- 108
- ],
- "uses": [],
- "idx": 109
- },
- {
- "path": "../classic/classic/src/scroll/Scroller.js",
- "requires": [
- 11,
- 12,
- 20,
- 25,
- 104,
- 109
- ],
- "uses": [
- 77,
- 471
- ],
- "idx": 110
- },
- {
- "path": "../classic/classic/src/util/Floating.js",
- "requires": [],
- "uses": [
- 21,
- 49,
- 75,
- 423
- ],
- "idx": 111
- },
- {
- "path": "../classic/classic/src/util/ElementContainer.js",
- "requires": [],
- "uses": [],
- "idx": 112
- },
- {
- "path": "../classic/classic/src/util/Renderable.js",
- "requires": [
- 49
- ],
- "uses": [
- 98,
- 117,
- 253
- ],
- "idx": 113
- },
- {
- "path": "../classic/classic/src/state/Provider.js",
- "requires": [
- 52
- ],
- "uses": [],
- "idx": 114
- },
- {
- "path": "../classic/classic/src/state/Manager.js",
- "requires": [
- 114
- ],
- "uses": [],
- "idx": 115
- },
- {
- "path": "../classic/classic/src/state/Stateful.js",
- "requires": [
- 57,
- 115
- ],
- "uses": [],
- "idx": 116
- },
- {
- "path": "../classic/classic/src/Component.js",
- "requires": [
- 21,
- 24,
- 26,
- 52,
- 74,
- 77,
- 81,
- 82,
- 83,
- 84,
- 86,
- 87,
- 88,
- 101,
- 102,
- 103,
- 110,
- 111,
- 112,
- 113,
- 116
- ],
- "uses": [
- 1,
- 49,
- 67,
- 98,
- 253,
- 418,
- 419,
- 420,
- 423,
- 431,
- 433,
- 498,
- 666,
- 686
- ],
- "idx": 117
- },
- {
- "path": "../classic/classic/src/Responsive.js",
- "requires": [
- 90,
- 91
- ],
- "uses": [],
- "idx": 118
- },
- {
- "path": "../classic/classic/src/layout/container/border/Region.js",
- "requires": [],
- "uses": [],
- "idx": 119
- },
- {
- "path": "../packages/core/src/app/EventBus.js",
- "requires": [
- 100
- ],
- "uses": [
- 99
- ],
- "idx": 120
- },
- {
- "path": "../packages/core/src/app/domain/Global.js",
- "requires": [
- 77,
- 99
- ],
- "uses": [],
- "idx": 121
- },
- {
- "path": "../packages/core/src/route/Handler.js",
- "requires": [],
- "uses": [],
- "idx": 122
- },
- {
- "path": "../packages/core/src/route/Action.js",
- "requires": [],
- "uses": [
- 11
- ],
- "idx": 123
- },
- {
- "path": "../packages/core/src/route/Route.js",
- "requires": [
- 122,
- 123
- ],
- "uses": [
- 10,
- 126
- ],
- "idx": 124
- },
- {
- "path": "../packages/core/src/util/History.js",
- "requires": [
- 52
- ],
- "uses": [],
- "idx": 125
- },
- {
- "path": "../packages/core/src/route/Router.js",
- "requires": [
- 123,
- 124,
- 125
- ],
- "uses": [
- 122
- ],
- "idx": 126
- },
- {
- "path": "../packages/core/src/route/Mixin.js",
- "requires": [
- 0,
- 122,
- 126
- ],
- "uses": [
- 125
- ],
- "idx": 127
- },
- {
- "path": "../packages/core/src/app/BaseController.js",
- "requires": [
- 4,
- 120,
- 121,
- 127
- ],
- "uses": [
- 226
- ],
- "idx": 128
- },
- {
- "path": "../packages/core/src/app/Util.js",
- "requires": [],
- "uses": [],
- "idx": 129
- },
- {
- "path": "../packages/core/src/util/CollectionKey.js",
- "requires": [
- 3
- ],
- "uses": [],
- "idx": 130
- },
- {
- "path": "../packages/core/src/util/Grouper.js",
- "requires": [
- 54
- ],
- "uses": [
- 221
- ],
- "idx": 131
- },
- {
- "path": "../packages/core/src/util/Collection.js",
- "requires": [
- 4,
- 51,
- 54,
- 130,
- 131
- ],
- "uses": [
- 178,
- 179,
- 180,
- 181
- ],
- "idx": 132
- },
- {
- "path": "../packages/core/src/data/Range.js",
- "requires": [
- 1,
- 11
- ],
- "uses": [],
- "idx": 133
- },
- {
- "path": "../packages/core/src/util/ObjectTemplate.js",
- "requires": [
- 98
- ],
- "uses": [],
- "idx": 134
- },
- {
- "path": "../packages/core/src/data/schema/Role.js",
- "requires": [],
- "uses": [
- 12
- ],
- "idx": 135
- },
- {
- "path": "../packages/core/src/data/schema/Association.js",
- "requires": [
- 135
- ],
- "uses": [],
- "idx": 136
- },
- {
- "path": "../packages/core/src/data/schema/OneToOne.js",
- "requires": [
- 136
- ],
- "uses": [],
- "idx": 137
- },
- {
- "path": "../packages/core/src/data/schema/ManyToOne.js",
- "requires": [
- 136
- ],
- "uses": [],
- "idx": 138
- },
- {
- "path": "../packages/core/src/data/schema/ManyToMany.js",
- "requires": [
- 136
- ],
- "uses": [],
- "idx": 139
- },
- {
- "path": "../packages/core/src/util/Inflector.js",
- "requires": [],
- "uses": [],
- "idx": 140
- },
- {
- "path": "../packages/core/src/data/schema/Namer.js",
- "requires": [
- 12,
- 140
- ],
- "uses": [],
- "idx": 141
- },
- {
- "path": "../packages/core/src/data/schema/Schema.js",
- "requires": [
- 12,
- 134,
- 137,
- 138,
- 139,
- 141
- ],
- "uses": [],
- "idx": 142
- },
- {
- "path": "../packages/core/src/data/AbstractStore.js",
- "requires": [
- 4,
- 12,
- 51,
- 132,
- 133,
- 142
- ],
- "uses": [
- 185
- ],
- "idx": 143
- },
- {
- "path": "../packages/core/src/data/Error.js",
- "requires": [],
- "uses": [],
- "idx": 144
- },
- {
- "path": "../packages/core/src/data/ErrorCollection.js",
- "requires": [
- 56,
- 144
- ],
- "uses": [
- 154
- ],
- "idx": 145
- },
- {
- "path": "../packages/core/src/data/operation/Operation.js",
- "requires": [],
- "uses": [],
- "idx": 146
- },
- {
- "path": "../packages/core/src/data/operation/Create.js",
- "requires": [
- 146
- ],
- "uses": [],
- "idx": 147
- },
- {
- "path": "../packages/core/src/data/operation/Destroy.js",
- "requires": [
- 146
- ],
- "uses": [],
- "idx": 148
- },
- {
- "path": "../packages/core/src/data/operation/Read.js",
- "requires": [
- 146
- ],
- "uses": [],
- "idx": 149
- },
- {
- "path": "../packages/core/src/data/operation/Update.js",
- "requires": [
- 146
- ],
- "uses": [],
- "idx": 150
- },
- {
- "path": "../packages/core/src/data/SortTypes.js",
- "requires": [],
- "uses": [],
- "idx": 151
- },
- {
- "path": "../packages/core/src/data/validator/Validator.js",
- "requires": [
- 12
- ],
- "uses": [],
- "idx": 152
- },
- {
- "path": "../packages/core/src/data/summary/Base.js",
- "requires": [
- 12
- ],
- "uses": [],
- "idx": 153
- },
- {
- "path": "../packages/core/src/data/field/Field.js",
- "requires": [
- 12,
- 151,
- 152,
- 153
- ],
- "uses": [],
- "idx": 154
- },
- {
- "path": "../packages/core/src/data/field/Array.js",
- "requires": [
- 154
- ],
- "uses": [],
- "idx": 155
- },
- {
- "path": "../packages/core/src/data/field/Boolean.js",
- "requires": [
- 154
- ],
- "uses": [],
- "idx": 156
- },
- {
- "path": "../packages/core/src/data/field/Date.js",
- "requires": [
- 154
- ],
- "uses": [],
- "idx": 157
- },
- {
- "path": "../packages/core/src/data/field/Integer.js",
- "requires": [
- 154
- ],
- "uses": [],
- "idx": 158
- },
- {
- "path": "../packages/core/src/data/field/Number.js",
- "requires": [
- 158
- ],
- "uses": [],
- "idx": 159
- },
- {
- "path": "../packages/core/src/data/field/String.js",
- "requires": [
- 154
- ],
- "uses": [],
- "idx": 160
- },
- {
- "path": "../packages/core/src/data/identifier/Generator.js",
- "requires": [
- 12
- ],
- "uses": [],
- "idx": 161
- },
- {
- "path": "../packages/core/src/data/identifier/Sequential.js",
- "requires": [
- 161
- ],
- "uses": [],
- "idx": 162
- },
- {
- "path": "../packages/core/src/data/Model.js",
- "requires": [
- 142,
- 145,
- 146,
- 147,
- 148,
- 149,
- 150,
- 152,
- 154,
- 155,
- 156,
- 157,
- 158,
- 159,
- 160,
- 161,
- 162
- ],
- "uses": [
- 12,
- 165,
- 252
- ],
- "idx": 163
- },
- {
- "path": "../packages/core/src/data/ResultSet.js",
- "requires": [],
- "uses": [],
- "idx": 164
- },
- {
- "path": "../packages/core/src/data/reader/Reader.js",
- "requires": [
- 4,
- 12,
- 23,
- 98,
- 164
- ],
- "uses": [
- 142
- ],
- "idx": 165
- },
- {
- "path": "../packages/core/src/data/writer/Writer.js",
- "requires": [
- 12
- ],
- "uses": [],
- "idx": 166
- },
- {
- "path": "../packages/core/src/data/proxy/Proxy.js",
- "requires": [
- 4,
- 12,
- 142,
- 165,
- 166
- ],
- "uses": [
- 146,
- 147,
- 148,
- 149,
- 150,
- 163,
- 194
- ],
- "idx": 167
- },
- {
- "path": "../packages/core/src/data/proxy/Client.js",
- "requires": [
- 167
- ],
- "uses": [],
- "idx": 168
- },
- {
- "path": "../packages/core/src/data/proxy/Memory.js",
- "requires": [
- 168
- ],
- "uses": [
- 51,
- 55
- ],
- "idx": 169
- },
- {
- "path": "../packages/core/src/data/ProxyStore.js",
- "requires": [
- 143,
- 146,
- 147,
- 148,
- 149,
- 150,
- 163,
- 167,
- 169
- ],
- "uses": [
- 142
- ],
- "idx": 170
- },
- {
- "path": "../packages/core/src/util/Group.js",
- "requires": [
- 132
- ],
- "uses": [],
- "idx": 171
- },
- {
- "path": "../packages/core/src/data/Group.js",
- "requires": [
- 171
- ],
- "uses": [],
- "idx": 172
- },
- {
- "path": "../packages/core/src/data/LocalStore.js",
- "requires": [
- 0,
- 172
- ],
- "uses": [
- 132
- ],
- "idx": 173
- },
- {
- "path": "../packages/core/src/data/proxy/Server.js",
- "requires": [
- 167
- ],
- "uses": [
- 95,
- 249
- ],
- "idx": 174
- },
- {
- "path": "../packages/core/src/data/proxy/Ajax.js",
- "requires": [
- 18,
- 174
- ],
- "uses": [],
- "idx": 175
- },
- {
- "path": "../packages/core/src/data/reader/Json.js",
- "requires": [
- 79,
- 165
- ],
- "uses": [],
- "idx": 176
- },
- {
- "path": "../packages/core/src/data/writer/Json.js",
- "requires": [
- 166
- ],
- "uses": [],
- "idx": 177
- },
- {
- "path": "../packages/core/src/util/SorterCollection.js",
- "requires": [
- 54,
- 132
- ],
- "uses": [],
- "idx": 178
- },
- {
- "path": "../packages/core/src/util/FilterCollection.js",
- "requires": [
- 51,
- 132
- ],
- "uses": [],
- "idx": 179
- },
- {
- "path": "../packages/core/src/util/GrouperCollection.js",
- "requires": [
- 131,
- 178
- ],
- "uses": [],
- "idx": 180
- },
- {
- "path": "../packages/core/src/util/GroupCollection.js",
- "requires": [
- 132,
- 171,
- 178,
- 179,
- 180
- ],
- "uses": [],
- "idx": 181
- },
- {
- "path": "../packages/core/src/data/Store.js",
- "requires": [
- 1,
- 163,
- 170,
- 173,
- 175,
- 176,
- 177,
- 181
- ],
- "uses": [
- 131,
- 185
- ],
- "idx": 182
- },
- {
- "path": "../packages/core/src/data/reader/Array.js",
- "requires": [
- 176
- ],
- "uses": [],
- "idx": 183
- },
- {
- "path": "../packages/core/src/data/ArrayStore.js",
- "requires": [
- 169,
- 182,
- 183
- ],
- "uses": [],
- "idx": 184
- },
- {
- "path": "../packages/core/src/data/StoreManager.js",
- "requires": [
- 56,
- 184
- ],
- "uses": [
- 12,
- 169,
- 177,
- 182,
- 183
- ],
- "idx": 185
- },
- {
- "path": "../packages/core/src/app/domain/Store.js",
- "requires": [
- 99,
- 143
- ],
- "uses": [],
- "idx": 186
- },
- {
- "path": "../packages/core/src/app/Controller.js",
- "requires": [
- 21,
- 100,
- 128,
- 129,
- 185,
- 186
- ],
- "uses": [
- 24,
- 142
- ],
- "idx": 187
- },
- {
- "path": "../packages/core/src/app/Application.js",
- "requires": [
- 56,
- 125,
- 187
- ],
- "uses": [
- 126
- ],
- "idx": 188
- },
- {
- "path": "../packages/core/src/app/Profile.js",
- "requires": [
- 4,
- 187
- ],
- "uses": [],
- "idx": 189
- },
- {
- "path": "../packages/core/src/app/domain/View.js",
- "requires": [
- 89,
- 99
- ],
- "uses": [],
- "idx": 190
- },
- {
- "path": "../packages/core/src/app/ViewController.js",
- "requires": [
- 12,
- 128,
- 190
- ],
- "uses": [],
- "idx": 191
- },
- {
- "path": "../packages/core/src/util/Bag.js",
- "requires": [],
- "uses": [],
- "idx": 192
- },
- {
- "path": "../packages/core/src/util/Scheduler.js",
- "requires": [
- 4,
- 192
- ],
- "uses": [
- 77
- ],
- "idx": 193
- },
- {
- "path": "../packages/core/src/data/Batch.js",
- "requires": [
- 4
- ],
- "uses": [],
- "idx": 194
- },
- {
- "path": "../packages/core/src/data/matrix/Slice.js",
- "requires": [],
- "uses": [],
- "idx": 195
- },
- {
- "path": "../packages/core/src/data/matrix/Side.js",
- "requires": [
- 195
- ],
- "uses": [],
- "idx": 196
- },
- {
- "path": "../packages/core/src/data/matrix/Matrix.js",
- "requires": [
- 196
- ],
- "uses": [],
- "idx": 197
- },
- {
- "path": "../packages/core/src/data/session/ChangesVisitor.js",
- "requires": [],
- "uses": [],
- "idx": 198
- },
- {
- "path": "../packages/core/src/data/session/ChildChangesVisitor.js",
- "requires": [
- 198
- ],
- "uses": [],
- "idx": 199
- },
- {
- "path": "../packages/core/src/data/session/BatchVisitor.js",
- "requires": [],
- "uses": [
- 194
- ],
- "idx": 200
- },
- {
- "path": "../packages/core/src/mixin/Dirty.js",
- "requires": [],
- "uses": [],
- "idx": 201
- },
- {
- "path": "../packages/core/src/data/Session.js",
- "requires": [
- 4,
- 142,
- 194,
- 197,
- 198,
- 199,
- 200,
- 201
- ],
- "uses": [],
- "idx": 202
- },
- {
- "path": "../packages/core/src/util/Schedulable.js",
- "requires": [],
- "uses": [],
- "idx": 203
- },
- {
- "path": "../packages/core/src/app/bind/BaseBinding.js",
- "requires": [
- 203
- ],
- "uses": [],
- "idx": 204
- },
- {
- "path": "../packages/core/src/app/bind/Binding.js",
- "requires": [
- 204
- ],
- "uses": [],
- "idx": 205
- },
- {
- "path": "../packages/core/src/app/bind/AbstractStub.js",
- "requires": [
- 203,
- 205
- ],
- "uses": [],
- "idx": 206
- },
- {
- "path": "../packages/core/src/app/bind/Stub.js",
- "requires": [
- 205,
- 206
- ],
- "uses": [
- 211
- ],
- "idx": 207
- },
- {
- "path": "../packages/core/src/app/bind/LinkStub.js",
- "requires": [
- 207
- ],
- "uses": [],
- "idx": 208
- },
- {
- "path": "../packages/core/src/app/bind/RootStub.js",
- "requires": [
- 206,
- 207,
- 208
- ],
- "uses": [],
- "idx": 209
- },
- {
- "path": "../packages/core/src/app/bind/Multi.js",
- "requires": [
- 204
- ],
- "uses": [],
- "idx": 210
- },
- {
- "path": "../packages/core/src/app/bind/Formula.js",
- "requires": [
- 23,
- 203
- ],
- "uses": [],
- "idx": 211
- },
- {
- "path": "../packages/core/src/util/Fly.js",
- "requires": [],
- "uses": [],
- "idx": 212
- },
- {
- "path": "../packages/core/src/parse/Tokenizer.js",
- "requires": [
- 212
- ],
- "uses": [],
- "idx": 213
- },
- {
- "path": "../packages/core/src/parse/Symbol.js",
- "requires": [],
- "uses": [],
- "idx": 214
- },
- {
- "path": "../packages/core/src/parse/symbol/Constant.js",
- "requires": [
- 214
- ],
- "uses": [],
- "idx": 215
- },
- {
- "path": "../packages/core/src/parse/symbol/Infix.js",
- "requires": [
- 214
- ],
- "uses": [],
- "idx": 216
- },
- {
- "path": "../packages/core/src/parse/symbol/InfixRight.js",
- "requires": [
- 216
- ],
- "uses": [],
- "idx": 217
- },
- {
- "path": "../packages/core/src/parse/symbol/Paren.js",
- "requires": [
- 214
- ],
- "uses": [],
- "idx": 218
- },
- {
- "path": "../packages/core/src/parse/symbol/Prefix.js",
- "requires": [
- 214
- ],
- "uses": [],
- "idx": 219
- },
- {
- "path": "../packages/core/src/parse/Parser.js",
- "requires": [
- 212,
- 213,
- 215,
- 217,
- 218,
- 219
- ],
- "uses": [
- 214,
- 216
- ],
- "idx": 220
- },
- {
- "path": "../packages/core/src/app/bind/Parser.js",
- "requires": [
- 94,
- 220
- ],
- "uses": [],
- "idx": 221
- },
- {
- "path": "../packages/core/src/app/bind/Template.js",
- "requires": [
- 94,
- 221
- ],
- "uses": [],
- "idx": 222
- },
- {
- "path": "../packages/core/src/app/bind/TemplateBinding.js",
- "requires": [
- 204,
- 210,
- 222
- ],
- "uses": [],
- "idx": 223
- },
- {
- "path": "../packages/core/src/data/ChainedStore.js",
- "requires": [
- 143,
- 173
- ],
- "uses": [
- 95,
- 185
- ],
- "idx": 224
- },
- {
- "path": "../packages/core/src/app/ViewModel.js",
- "requires": [
- 3,
- 12,
- 193,
- 202,
- 208,
- 209,
- 210,
- 211,
- 223,
- 224
- ],
- "uses": [
- 1,
- 142
- ],
- "idx": 225
- },
- {
- "path": "../packages/core/src/app/domain/Controller.js",
- "requires": [
- 99,
- 187
- ],
- "uses": [
- 128
- ],
- "idx": 226
- },
- {
- "path": "../packages/core/src/direct/Manager.js",
- "requires": [
- 4,
- 56
- ],
- "uses": [
- 95
- ],
- "idx": 227
- },
- {
- "path": "../packages/core/src/direct/Provider.js",
- "requires": [
- 4,
- 227
- ],
- "uses": [
- 18
- ],
- "idx": 228
- },
- {
- "path": "../packages/core/src/app/domain/Direct.js",
- "requires": [
- 99,
- 228
- ],
- "uses": [],
- "idx": 229
- },
- {
- "path": "../packages/core/src/data/PageMap.js",
- "requires": [
- 23
- ],
- "uses": [],
- "idx": 230
- },
- {
- "path": "../packages/core/src/data/BufferedStore.js",
- "requires": [
- 51,
- 54,
- 131,
- 170,
- 230
- ],
- "uses": [
- 178,
- 179,
- 181
- ],
- "idx": 231
- },
- {
- "path": "../packages/core/src/data/ClientStore.js",
- "requires": [
- 169,
- 182
- ],
- "uses": [],
- "idx": 232
- },
- {
- "path": "../packages/core/src/data/proxy/Direct.js",
- "requires": [
- 174,
- 227
- ],
- "uses": [],
- "idx": 233
- },
- {
- "path": "../packages/core/src/data/DirectStore.js",
- "requires": [
- 182,
- 233
- ],
- "uses": [],
- "idx": 234
- },
- {
- "path": "../packages/core/src/data/JsonP.js",
- "requires": [],
- "uses": [],
- "idx": 235
- },
- {
- "path": "../packages/core/src/data/proxy/JsonP.js",
- "requires": [
- 174,
- 235
- ],
- "uses": [],
- "idx": 236
- },
- {
- "path": "../packages/core/src/data/JsonPStore.js",
- "requires": [
- 176,
- 182,
- 236
- ],
- "uses": [],
- "idx": 237
- },
- {
- "path": "../packages/core/src/data/JsonStore.js",
- "requires": [
- 175,
- 176,
- 177,
- 182
- ],
- "uses": [],
- "idx": 238
- },
- {
- "path": "../packages/core/src/data/ModelManager.js",
- "requires": [
- 142
- ],
- "uses": [
- 163
- ],
- "idx": 239
- },
- {
- "path": "../packages/core/src/data/NodeInterface.js",
- "requires": [
- 4,
- 156,
- 158,
- 160,
- 177
- ],
- "uses": [
- 142
- ],
- "idx": 240
- },
- {
- "path": "../packages/core/src/mixin/Queryable.js",
- "requires": [],
- "uses": [
- 24
- ],
- "idx": 241
- },
- {
- "path": "../packages/core/src/data/TreeModel.js",
- "requires": [
- 163,
- 240,
- 241
- ],
- "uses": [],
- "idx": 242
- },
- {
- "path": "../packages/core/src/data/NodeStore.js",
- "requires": [
- 182,
- 240,
- 242
- ],
- "uses": [
- 163
- ],
- "idx": 243
- },
- {
- "path": "../packages/core/src/data/query/Compiler.js",
- "requires": [],
- "uses": [
- 79
- ],
- "idx": 244
- },
- {
- "path": "../packages/core/src/data/query/Converter.js",
- "requires": [],
- "uses": [],
- "idx": 245
- },
- {
- "path": "../packages/core/src/data/query/Stringifier.js",
- "requires": [],
- "uses": [
- 79
- ],
- "idx": 246
- },
- {
- "path": "../packages/core/src/data/query/Parser.js",
- "requires": [
- 220
- ],
- "uses": [],
- "idx": 247
- },
- {
- "path": "../packages/core/src/data/Query.js",
- "requires": [
- 3,
- 12,
- 50,
- 244,
- 245,
- 246,
- 247
- ],
- "uses": [],
- "idx": 248
- },
- {
- "path": "../packages/core/src/data/Request.js",
- "requires": [],
- "uses": [],
- "idx": 249
- },
- {
- "path": "../packages/core/src/data/TreeStore.js",
- "requires": [
- 54,
- 182,
- 240,
- 242
- ],
- "uses": [
- 163
- ],
- "idx": 250
- },
- {
- "path": "../packages/core/src/data/Types.js",
- "requires": [
- 151
- ],
- "uses": [],
- "idx": 251
- },
- {
- "path": "../packages/core/src/data/Validation.js",
- "requires": [
- 163
- ],
- "uses": [],
- "idx": 252
- },
- {
- "path": "../packages/core/src/dom/Helper.js",
- "requires": [],
- "uses": [
- 95
- ],
- "idx": 253
- },
- {
- "path": "../packages/core/src/dom/Query.js",
- "requires": [
- 22,
- 253
- ],
- "uses": [
- 23
- ],
- "idx": 254
- },
- {
- "path": "../packages/core/src/data/reader/Xml.js",
- "requires": [
- 165,
- 254
- ],
- "uses": [],
- "idx": 255
- },
- {
- "path": "../packages/core/src/data/writer/Xml.js",
- "requires": [
- 166
- ],
- "uses": [],
- "idx": 256
- },
- {
- "path": "../packages/core/src/data/XmlStore.js",
- "requires": [
- 175,
- 182,
- 255,
- 256
- ],
- "uses": [],
- "idx": 257
- },
- {
- "path": "../packages/core/src/data/identifier/Negative.js",
- "requires": [
- 162
- ],
- "uses": [],
- "idx": 258
- },
- {
- "path": "../packages/core/src/data/identifier/Uuid.js",
- "requires": [
- 161
- ],
- "uses": [],
- "idx": 259
- },
- {
- "path": "../packages/core/src/data/proxy/WebStorage.js",
- "requires": [
- 162,
- 168
- ],
- "uses": [
- 54,
- 95,
- 164
- ],
- "idx": 260
- },
- {
- "path": "../packages/core/src/data/proxy/LocalStorage.js",
- "requires": [
- 260
- ],
- "uses": [],
- "idx": 261
- },
- {
- "path": "../packages/core/src/data/proxy/Rest.js",
- "requires": [
- 175
- ],
- "uses": [],
- "idx": 262
- },
- {
- "path": "../packages/core/src/data/proxy/SessionStorage.js",
- "requires": [
- 260
- ],
- "uses": [],
- "idx": 263
- },
- {
- "path": "../packages/core/src/data/schema/BelongsTo.js",
- "requires": [],
- "uses": [],
- "idx": 264
- },
- {
- "path": "../packages/core/src/data/schema/HasMany.js",
- "requires": [],
- "uses": [],
- "idx": 265
- },
- {
- "path": "../packages/core/src/data/schema/HasOne.js",
- "requires": [],
- "uses": [],
- "idx": 266
- },
- {
- "path": "../packages/core/src/data/schema/Reference.js",
- "requires": [],
- "uses": [],
- "idx": 267
- },
- {
- "path": "../packages/core/src/data/summary/Sum.js",
- "requires": [
- 153
- ],
- "uses": [],
- "idx": 268
- },
- {
- "path": "../packages/core/src/data/summary/Average.js",
- "requires": [
- 268
- ],
- "uses": [],
- "idx": 269
- },
- {
- "path": "../packages/core/src/data/summary/Count.js",
- "requires": [
- 153
- ],
- "uses": [],
- "idx": 270
- },
- {
- "path": "../packages/core/src/data/summary/Max.js",
- "requires": [
- 153
- ],
- "uses": [],
- "idx": 271
- },
- {
- "path": "../packages/core/src/data/summary/Min.js",
- "requires": [
- 153
- ],
- "uses": [],
- "idx": 272
- },
- {
- "path": "../packages/core/src/data/summary/None.js",
- "requires": [
- 153
- ],
- "uses": [],
- "idx": 273
- },
- {
- "path": "../packages/core/src/data/summary/Variance.js",
- "requires": [
- 153,
- 269
- ],
- "uses": [
- 12
- ],
- "idx": 274
- },
- {
- "path": "../packages/core/src/data/summary/StdDev.js",
- "requires": [
- 274
- ],
- "uses": [],
- "idx": 275
- },
- {
- "path": "../packages/core/src/data/summary/VarianceP.js",
- "requires": [
- 274
- ],
- "uses": [],
- "idx": 276
- },
- {
- "path": "../packages/core/src/data/summary/StdDevP.js",
- "requires": [
- 276
- ],
- "uses": [],
- "idx": 277
- },
- {
- "path": "../packages/core/src/data/validator/AbstractDate.js",
- "requires": [
- 152
- ],
- "uses": [],
- "idx": 278
- },
- {
- "path": "../packages/core/src/data/validator/Bound.js",
- "requires": [
- 152
- ],
- "uses": [
- 95
- ],
- "idx": 279
- },
- {
- "path": "../packages/core/src/data/validator/Format.js",
- "requires": [
- 152
- ],
- "uses": [],
- "idx": 280
- },
- {
- "path": "../packages/core/src/data/validator/CIDRv4.js",
- "requires": [
- 280
- ],
- "uses": [],
- "idx": 281
- },
- {
- "path": "../packages/core/src/data/validator/CIDRv6.js",
- "requires": [
- 280
- ],
- "uses": [],
- "idx": 282
- },
- {
- "path": "../packages/core/src/data/validator/Number.js",
- "requires": [
- 152
- ],
- "uses": [
- 94
- ],
- "idx": 283
- },
- {
- "path": "../packages/core/src/data/validator/Currency.js",
- "requires": [
- 283
- ],
- "uses": [
- 94
- ],
- "idx": 284
- },
- {
- "path": "../packages/core/src/data/validator/CurrencyUS.js",
- "requires": [
- 284
- ],
- "uses": [],
- "idx": 285
- },
- {
- "path": "../packages/core/src/data/validator/Date.js",
- "requires": [
- 278
- ],
- "uses": [],
- "idx": 286
- },
- {
- "path": "../packages/core/src/data/validator/DateTime.js",
- "requires": [
- 278
- ],
- "uses": [],
- "idx": 287
- },
- {
- "path": "../packages/core/src/data/validator/Email.js",
- "requires": [
- 280
- ],
- "uses": [],
- "idx": 288
- },
- {
- "path": "../packages/core/src/data/validator/List.js",
- "requires": [
- 152
- ],
- "uses": [],
- "idx": 289
- },
- {
- "path": "../packages/core/src/data/validator/Exclusion.js",
- "requires": [
- 289
- ],
- "uses": [],
- "idx": 290
- },
- {
- "path": "../packages/core/src/data/validator/IPAddress.js",
- "requires": [
- 280
- ],
- "uses": [],
- "idx": 291
- },
- {
- "path": "../packages/core/src/data/validator/Inclusion.js",
- "requires": [
- 289
- ],
- "uses": [],
- "idx": 292
- },
- {
- "path": "../packages/core/src/data/validator/Length.js",
- "requires": [
- 279
- ],
- "uses": [],
- "idx": 293
- },
- {
- "path": "../packages/core/src/data/validator/Presence.js",
- "requires": [
- 152
- ],
- "uses": [],
- "idx": 294
- },
- {
- "path": "../packages/core/src/data/validator/NotNull.js",
- "requires": [
- 294
- ],
- "uses": [],
- "idx": 295
- },
- {
- "path": "../packages/core/src/data/validator/Phone.js",
- "requires": [
- 280
- ],
- "uses": [],
- "idx": 296
- },
- {
- "path": "../packages/core/src/data/validator/Range.js",
- "requires": [
- 279
- ],
- "uses": [],
- "idx": 297
- },
- {
- "path": "../packages/core/src/data/validator/Time.js",
- "requires": [
- 278
- ],
- "uses": [],
- "idx": 298
- },
- {
- "path": "../packages/core/src/data/validator/Url.js",
- "requires": [
- 280
- ],
- "uses": [],
- "idx": 299
- },
- {
- "path": "../packages/core/src/data/virtual/Group.js",
- "requires": [],
- "uses": [],
- "idx": 300
- },
- {
- "path": "../packages/core/src/data/virtual/Page.js",
- "requires": [],
- "uses": [],
- "idx": 301
- },
- {
- "path": "../packages/core/src/data/virtual/PageMap.js",
- "requires": [
- 301
- ],
- "uses": [],
- "idx": 302
- },
- {
- "path": "../packages/core/src/data/virtual/Range.js",
- "requires": [
- 133
- ],
- "uses": [],
- "idx": 303
- },
- {
- "path": "../packages/core/src/data/virtual/Store.js",
- "requires": [
- 170,
- 178,
- 179,
- 302,
- 303
- ],
- "uses": [
- 131,
- 132,
- 163,
- 300
- ],
- "idx": 304
- },
- {
- "path": "../packages/core/src/direct/Event.js",
- "requires": [],
- "uses": [],
- "idx": 305
- },
- {
- "path": "../packages/core/src/direct/RemotingEvent.js",
- "requires": [
- 305
- ],
- "uses": [
- 227
- ],
- "idx": 306
- },
- {
- "path": "../packages/core/src/direct/ExceptionEvent.js",
- "requires": [
- 306
- ],
- "uses": [],
- "idx": 307
- },
- {
- "path": "../packages/core/src/direct/JsonProvider.js",
- "requires": [
- 228
- ],
- "uses": [
- 227,
- 307
- ],
- "idx": 308
- },
- {
- "path": "../packages/core/src/direct/PollingProvider.js",
- "requires": [
- 18,
- 57,
- 307,
- 308
- ],
- "uses": [
- 227,
- 409
- ],
- "idx": 309
- },
- {
- "path": "../packages/core/src/direct/RemotingMethod.js",
- "requires": [],
- "uses": [],
- "idx": 310
- },
- {
- "path": "../packages/core/src/direct/Transaction.js",
- "requires": [],
- "uses": [],
- "idx": 311
- },
- {
- "path": "../packages/core/src/direct/RemotingProvider.js",
- "requires": [
- 1,
- 56,
- 227,
- 308,
- 310,
- 311
- ],
- "uses": [
- 79,
- 307
- ],
- "idx": 312
- },
- {
- "path": "../packages/core/src/dom/GarbageCollector.js",
- "requires": [],
- "uses": [
- 49
- ],
- "idx": 313
- },
- {
- "path": "../packages/core/src/dom/TouchAction.js",
- "requires": [
- 35,
- 49
- ],
- "uses": [],
- "idx": 314
- },
- {
- "path": "../packages/core/src/drag/Constraint.js",
- "requires": [
- 12
- ],
- "uses": [
- 34
- ],
- "idx": 315
- },
- {
- "path": "../packages/core/src/drag/Info.js",
- "requires": [
- 10
- ],
- "uses": [],
- "idx": 316
- },
- {
- "path": "../packages/core/src/drag/Item.js",
- "requires": [
- 3,
- 4
- ],
- "uses": [],
- "idx": 317
- },
- {
- "path": "../packages/core/src/drag/Manager.js",
- "requires": [],
- "uses": [
- 49,
- 81,
- 316
- ],
- "idx": 318
- },
- {
- "path": "../packages/core/src/drag/Source.js",
- "requires": [
- 77,
- 315,
- 317
- ],
- "uses": [
- 12,
- 316
- ],
- "idx": 319
- },
- {
- "path": "../packages/core/src/drag/Target.js",
- "requires": [
- 317,
- 318
- ],
- "uses": [],
- "idx": 320
- },
- {
- "path": "../packages/core/src/drag/proxy/None.js",
- "requires": [
- 12
- ],
- "uses": [],
- "idx": 321
- },
- {
- "path": "../packages/core/src/drag/proxy/Original.js",
- "requires": [
- 321
- ],
- "uses": [],
- "idx": 322
- },
- {
- "path": "../packages/core/src/drag/proxy/Placeholder.js",
- "requires": [
- 321
- ],
- "uses": [],
- "idx": 323
- },
- {
- "path": "../packages/core/src/event/gesture/Recognizer.js",
- "requires": [
- 3,
- 38
- ],
- "uses": [],
- "idx": 324
- },
- {
- "path": "../packages/core/src/event/gesture/SingleTouch.js",
- "requires": [
- 324
- ],
- "uses": [],
- "idx": 325
- },
- {
- "path": "../packages/core/src/event/gesture/DoubleTap.js",
- "requires": [
- 325
- ],
- "uses": [
- 49
- ],
- "idx": 326
- },
- {
- "path": "../packages/core/src/event/gesture/Drag.js",
- "requires": [
- 325
- ],
- "uses": [
- 49
- ],
- "idx": 327
- },
- {
- "path": "../packages/core/src/event/gesture/Swipe.js",
- "requires": [
- 325
- ],
- "uses": [],
- "idx": 328
- },
- {
- "path": "../packages/core/src/event/gesture/EdgeSwipe.js",
- "requires": [
- 328
- ],
- "uses": [
- 49
- ],
- "idx": 329
- },
- {
- "path": "../packages/core/src/event/gesture/LongPress.js",
- "requires": [
- 325
- ],
- "uses": [
- 38,
- 49,
- 327
- ],
- "idx": 330
- },
- {
- "path": "../packages/core/src/event/gesture/MultiTouch.js",
- "requires": [
- 324
- ],
- "uses": [],
- "idx": 331
- },
- {
- "path": "../packages/core/src/event/gesture/Pinch.js",
- "requires": [
- 331
- ],
- "uses": [],
- "idx": 332
- },
- {
- "path": "../packages/core/src/event/gesture/Rotate.js",
- "requires": [
- 331
- ],
- "uses": [],
- "idx": 333
- },
- {
- "path": "../packages/core/src/event/gesture/Tap.js",
- "requires": [
- 325
- ],
- "uses": [
- 49
- ],
- "idx": 334
- },
- {
- "path": "../packages/core/src/event/publisher/Focus.js",
- "requires": [
- 37,
- 49,
- 75,
- 77
- ],
- "uses": [
- 36
- ],
- "idx": 335
- },
- {
- "path": "../packages/core/src/field/InputMask.js",
- "requires": [],
- "uses": [],
- "idx": 336
- },
- {
- "path": "../packages/core/src/fx/State.js",
- "requires": [],
- "uses": [],
- "idx": 337
- },
- {
- "path": "../packages/core/src/fx/animation/Abstract.js",
- "requires": [
- 12,
- 25,
- 337
- ],
- "uses": [],
- "idx": 338
- },
- {
- "path": "../packages/core/src/fx/animation/Slide.js",
- "requires": [
- 338
- ],
- "uses": [],
- "idx": 339
- },
- {
- "path": "../packages/core/src/fx/animation/SlideOut.js",
- "requires": [
- 339
- ],
- "uses": [],
- "idx": 340
- },
- {
- "path": "../packages/core/src/fx/animation/Fade.js",
- "requires": [
- 338
- ],
- "uses": [],
- "idx": 341
- },
- {
- "path": "../packages/core/src/fx/animation/FadeOut.js",
- "requires": [
- 341
- ],
- "uses": [],
- "idx": 342
- },
- {
- "path": "../packages/core/src/fx/animation/Flip.js",
- "requires": [
- 338
- ],
- "uses": [],
- "idx": 343
- },
- {
- "path": "../packages/core/src/fx/animation/Pop.js",
- "requires": [
- 338
- ],
- "uses": [],
- "idx": 344
- },
- {
- "path": "../packages/core/src/fx/animation/PopOut.js",
- "requires": [
- 344
- ],
- "uses": [],
- "idx": 345
- },
- {
- "path": "../packages/core/src/fx/Animation.js",
- "requires": [
- 339,
- 340,
- 341,
- 342,
- 343,
- 344,
- 345
- ],
- "uses": [
- 338
- ],
- "idx": 346
- },
- {
- "path": "../packages/core/src/fx/runner/Css.js",
- "requires": [
- 25,
- 346
- ],
- "uses": [
- 49
- ],
- "idx": 347
- },
- {
- "path": "../packages/core/src/fx/runner/CssTransition.js",
- "requires": [
- 19,
- 347
- ],
- "uses": [
- 346
- ],
- "idx": 348
- },
- {
- "path": "../packages/core/src/fx/Runner.js",
- "requires": [
- 348
- ],
- "uses": [],
- "idx": 349
- },
- {
- "path": "../packages/core/src/fx/animation/Cube.js",
- "requires": [
- 338
- ],
- "uses": [],
- "idx": 350
- },
- {
- "path": "../packages/core/src/fx/animation/Wipe.js",
- "requires": [
- 346
- ],
- "uses": [],
- "idx": 351
- },
- {
- "path": "../packages/core/src/fx/animation/WipeOut.js",
- "requires": [
- 351
- ],
- "uses": [],
- "idx": 352
- },
- {
- "path": "../packages/core/src/fx/easing/Bounce.js",
- "requires": [
- 105
- ],
- "uses": [],
- "idx": 353
- },
- {
- "path": "../packages/core/src/fx/easing/Momentum.js",
- "requires": [
- 105
- ],
- "uses": [],
- "idx": 354
- },
- {
- "path": "../packages/core/src/fx/easing/BoundMomentum.js",
- "requires": [
- 105,
- 353,
- 354
- ],
- "uses": [],
- "idx": 355
- },
- {
- "path": "../packages/core/src/fx/easing/EaseIn.js",
- "requires": [
- 106
- ],
- "uses": [],
- "idx": 356
- },
- {
- "path": "../packages/core/src/fx/easing/EaseOut.js",
- "requires": [
- 106
- ],
- "uses": [],
- "idx": 357
- },
- {
- "path": "../packages/core/src/fx/easing/Easing.js",
- "requires": [
- 106
- ],
- "uses": [],
- "idx": 358
- },
- {
- "path": "../packages/core/src/fx/runner/CssAnimation.js",
- "requires": [
- 347
- ],
- "uses": [
- 346
- ],
- "idx": 359
- },
- {
- "path": "../packages/core/src/grid/AdvancedGroupStore.js",
- "requires": [
- 20,
- 52
- ],
- "uses": [
- 132
- ],
- "idx": 360
- },
- {
- "path": "../packages/core/src/grid/plugin/BaseFilterBar.js",
- "requires": [
- 84
- ],
- "uses": [
- 12
- ],
- "idx": 361
- },
- {
- "path": "../packages/core/src/grid/plugin/BaseGroupingPanel.js",
- "requires": [
- 84
- ],
- "uses": [],
- "idx": 362
- },
- {
- "path": "../packages/core/src/grid/plugin/BaseSummaries.js",
- "requires": [
- 84,
- 153,
- 268,
- 269,
- 270,
- 271,
- 272,
- 273,
- 274,
- 275,
- 276,
- 277
- ],
- "uses": [
- 12
- ],
- "idx": 363
- },
- {
- "path": "../packages/core/src/list/AbstractTreeItem.js",
- "requires": [
- 89
- ],
- "uses": [],
- "idx": 364
- },
- {
- "path": "../packages/core/src/list/RootTreeItem.js",
- "requires": [
- 364
- ],
- "uses": [],
- "idx": 365
- },
- {
- "path": "../packages/core/src/mixin/ItemRippler.js",
- "requires": [],
- "uses": [],
- "idx": 366
- },
- {
- "path": "../packages/core/src/list/TreeItem.js",
- "requires": [
- 89,
- 364
- ],
- "uses": [],
- "idx": 367
- },
- {
- "path": "../packages/core/src/list/Tree.js",
- "requires": [
- 89,
- 365,
- 366,
- 367
- ],
- "uses": [
- 163,
- 185
- ],
- "idx": 368
- },
- {
- "path": "../packages/core/src/mixin/ConfigProxy.js",
- "requires": [
- 0
- ],
- "uses": [],
- "idx": 369
- },
- {
- "path": "../packages/core/src/mixin/ConfigState.js",
- "requires": [
- 0
- ],
- "uses": [],
- "idx": 370
- },
- {
- "path": "../packages/core/src/mixin/Container.js",
- "requires": [
- 0
- ],
- "uses": [
- 21
- ],
- "idx": 371
- },
- {
- "path": "../packages/core/src/util/KeyMap.js",
- "requires": [],
- "uses": [],
- "idx": 372
- },
- {
- "path": "../packages/core/src/util/KeyNav.js",
- "requires": [
- 372
- ],
- "uses": [
- 36
- ],
- "idx": 373
- },
- {
- "path": "../packages/core/src/mixin/FocusableContainer.js",
- "requires": [
- 0,
- 373
- ],
- "uses": [
- 21
- ],
- "idx": 374
- },
- {
- "path": "../packages/core/src/mixin/Hookable.js",
- "requires": [
- 0
- ],
- "uses": [],
- "idx": 375
- },
- {
- "path": "../packages/core/src/mixin/Mashup.js",
- "requires": [
- 0
- ],
- "uses": [
- 95
- ],
- "idx": 376
- },
- {
- "path": "../packages/core/src/mixin/Selectable.js",
- "requires": [
- 0
- ],
- "uses": [
- 132
- ],
- "idx": 377
- },
- {
- "path": "../packages/core/src/mixin/StoreWatcher.js",
- "requires": [],
- "uses": [],
- "idx": 378
- },
- {
- "path": "../packages/core/src/mixin/StyleCacher.js",
- "requires": [
- 0
- ],
- "uses": [],
- "idx": 379
- },
- {
- "path": "../packages/core/src/mixin/Traversable.js",
- "requires": [
- 0
- ],
- "uses": [],
- "idx": 380
- },
- {
- "path": "../packages/core/src/perf/Accumulator.js",
- "requires": [
- 98
- ],
- "uses": [],
- "idx": 381
- },
- {
- "path": "../packages/core/src/perf/Monitor.js",
- "requires": [
- 381
- ],
- "uses": [],
- "idx": 382
- },
- {
- "path": "../packages/core/src/plugin/AbstractClipboard.js",
- "requires": [
- 84,
- 372
- ],
- "uses": [
- 49
- ],
- "idx": 383
- },
- {
- "path": "../packages/core/src/plugin/MouseEnter.js",
- "requires": [
- 84
- ],
- "uses": [],
- "idx": 384
- },
- {
- "path": "../packages/core/src/sparkline/Shape.js",
- "requires": [],
- "uses": [],
- "idx": 385
- },
- {
- "path": "../packages/core/src/sparkline/CanvasBase.js",
- "requires": [
- 385
- ],
- "uses": [],
- "idx": 386
- },
- {
- "path": "../packages/core/src/sparkline/CanvasCanvas.js",
- "requires": [
- 386
- ],
- "uses": [],
- "idx": 387
- },
- {
- "path": "../packages/core/src/sparkline/VmlCanvas.js",
- "requires": [
- 386
- ],
- "uses": [],
- "idx": 388
- },
- {
- "path": "../packages/core/src/util/Color.js",
- "requires": [],
- "uses": [],
- "idx": 389
- },
- {
- "path": "../packages/core/src/sparkline/Base.js",
- "requires": [
- 89,
- 98,
- 387,
- 388,
- 389
- ],
- "uses": [],
- "idx": 390
- },
- {
- "path": "../packages/core/src/sparkline/BarBase.js",
- "requires": [
- 390
- ],
- "uses": [],
- "idx": 391
- },
- {
- "path": "../packages/core/src/sparkline/RangeMap.js",
- "requires": [],
- "uses": [],
- "idx": 392
- },
- {
- "path": "../packages/core/src/sparkline/Bar.js",
- "requires": [
- 391,
- 392
- ],
- "uses": [],
- "idx": 393
- },
- {
- "path": "../packages/core/src/sparkline/Box.js",
- "requires": [
- 390
- ],
- "uses": [],
- "idx": 394
- },
- {
- "path": "../packages/core/src/sparkline/Bullet.js",
- "requires": [
- 390
- ],
- "uses": [],
- "idx": 395
- },
- {
- "path": "../packages/core/src/sparkline/Discrete.js",
- "requires": [
- 391
- ],
- "uses": [],
- "idx": 396
- },
- {
- "path": "../packages/core/src/sparkline/Line.js",
- "requires": [
- 390,
- 392
- ],
- "uses": [],
- "idx": 397
- },
- {
- "path": "../packages/core/src/sparkline/Pie.js",
- "requires": [
- 390
- ],
- "uses": [],
- "idx": 398
- },
- {
- "path": "../packages/core/src/sparkline/TriState.js",
- "requires": [
- 391,
- 392
- ],
- "uses": [],
- "idx": 399
- },
- {
- "path": "../packages/core/src/util/Base64.js",
- "requires": [],
- "uses": [],
- "idx": 400
- },
- {
- "path": "../packages/core/src/util/DelimitedValue.js",
- "requires": [],
- "uses": [],
- "idx": 401
- },
- {
- "path": "../packages/core/src/util/CSV.js",
- "requires": [
- 401
- ],
- "uses": [],
- "idx": 402
- },
- {
- "path": "../packages/core/src/util/ClickRepeater.js",
- "requires": [
- 4
- ],
- "uses": [],
- "idx": 403
- },
- {
- "path": "../packages/core/src/util/Cookies.js",
- "requires": [],
- "uses": [],
- "idx": 404
- },
- {
- "path": "../packages/core/src/util/ItemCollection.js",
- "requires": [
- 56
- ],
- "uses": [],
- "idx": 405
- },
- {
- "path": "../packages/core/src/util/LocalStorage.js",
- "requires": [],
- "uses": [],
- "idx": 406
- },
- {
- "path": "../packages/core/src/util/Spans.js",
- "requires": [],
- "uses": [],
- "idx": 407
- },
- {
- "path": "../packages/core/src/util/TSV.js",
- "requires": [
- 401
- ],
- "uses": [],
- "idx": 408
- },
- {
- "path": "../packages/core/src/util/TaskManager.js",
- "requires": [
- 57
- ],
- "uses": [],
- "idx": 409
- },
- {
- "path": "../packages/core/src/util/TextMetrics.js",
- "requires": [
- 49
- ],
- "uses": [
- 75
- ],
- "idx": 410
- },
- {
- "path": "../packages/core/src/util/paintmonitor/OverflowChange.js",
- "requires": [
- 45
- ],
- "uses": [],
- "idx": 411
- },
- {
- "path": "../packages/core/src/util/sizemonitor/OverflowChange.js",
- "requires": [
- 41
- ],
- "uses": [
- 40
- ],
- "idx": 412
- },
- {
- "path": "../packages/core/src/util/translatable/CssPosition.js",
- "requires": [
- 108
- ],
- "uses": [],
- "idx": 413
- },
- {
- "path": "../packages/core/src/util/translatable/CssTransform.js",
- "requires": [
- 108
- ],
- "uses": [],
- "idx": 414
- },
- {
- "path": "../packages/core/src/util/translatable/ScrollParent.js",
- "requires": [
- 108
- ],
- "uses": [],
- "idx": 415
- },
- {
- "path": "../classic/classic/src/Action.js",
- "requires": [],
- "uses": [],
- "idx": 416
- },
- {
- "path": "../classic/classic/src/ElementLoader.js",
- "requires": [
- 52
- ],
- "uses": [
- 17,
- 18
- ],
- "idx": 417
- },
- {
- "path": "../classic/classic/src/ComponentLoader.js",
- "requires": [
- 417
- ],
- "uses": [],
- "idx": 418
- },
- {
- "path": "../classic/classic/src/layout/SizeModel.js",
- "requires": [],
- "uses": [],
- "idx": 419
- },
- {
- "path": "../classic/classic/src/layout/Layout.js",
- "requires": [
- 12,
- 98,
- 419
- ],
- "uses": [
- 666
- ],
- "idx": 420
- },
- {
- "path": "../classic/classic/src/layout/container/Container.js",
- "requires": [
- 98,
- 112,
- 420
- ],
- "uses": [
- 253
- ],
- "idx": 421
- },
- {
- "path": "../classic/classic/src/layout/container/Auto.js",
- "requires": [
- 421
- ],
- "uses": [
- 98
- ],
- "idx": 422
- },
- {
- "path": "../classic/classic/src/ZIndexManager.js",
- "requires": [
- 77,
- 178,
- 179
- ],
- "uses": [
- 49,
- 132
- ],
- "idx": 423
- },
- {
- "path": "../classic/classic/src/container/Container.js",
- "requires": [
- 56,
- 117,
- 241,
- 371,
- 374,
- 405,
- 416,
- 422,
- 423
- ],
- "uses": [
- 12,
- 21,
- 24,
- 49
- ],
- "idx": 424
- },
- {
- "path": "../classic/classic/src/layout/container/Editor.js",
- "requires": [
- 421
- ],
- "uses": [],
- "idx": 425
- },
- {
- "path": "../classic/classic/src/Editor.js",
- "requires": [
- 424,
- 425
- ],
- "uses": [
- 1,
- 21
- ],
- "idx": 426
- },
- {
- "path": "../classic/classic/src/EventManager.js",
- "requires": [],
- "uses": [
- 77
- ],
- "idx": 427
- },
- {
- "path": "../classic/classic/src/Gadget.js",
- "requires": [],
- "uses": [],
- "idx": 428
- },
- {
- "path": "../classic/classic/src/Img.js",
- "requires": [
- 78,
- 117
- ],
- "uses": [],
- "idx": 429
- },
- {
- "path": "../classic/classic/src/util/StoreHolder.js",
- "requires": [
- 185
- ],
- "uses": [],
- "idx": 430
- },
- {
- "path": "../classic/classic/src/LoadMask.js",
- "requires": [
- 117,
- 430
- ],
- "uses": [
- 49,
- 77,
- 185
- ],
- "idx": 431
- },
- {
- "path": "../classic/classic/src/layout/component/Component.js",
- "requires": [
- 420
- ],
- "uses": [],
- "idx": 432
- },
- {
- "path": "../classic/classic/src/layout/component/Auto.js",
- "requires": [
- 432
- ],
- "uses": [],
- "idx": 433
- },
- {
- "path": "../classic/classic/src/layout/component/ProgressBar.js",
- "requires": [
- 433
- ],
- "uses": [],
- "idx": 434
- },
- {
- "path": "../classic/classic/src/ProgressBar.js",
- "requires": [
- 92,
- 95,
- 102,
- 117,
- 409,
- 434
- ],
- "uses": [
- 73
- ],
- "idx": 435
- },
- {
- "path": "../classic/classic/src/dom/ButtonElement.js",
- "requires": [
- 49
- ],
- "uses": [],
- "idx": 436
- },
- {
- "path": "../classic/classic/src/button/Manager.js",
- "requires": [],
- "uses": [],
- "idx": 437
- },
- {
- "path": "../classic/classic/src/menu/Manager.js",
- "requires": [],
- "uses": [
- 21,
- 110,
- 117,
- 613
- ],
- "idx": 438
- },
- {
- "path": "../classic/classic/src/button/Button.js",
- "requires": [
- 78,
- 117,
- 241,
- 403,
- 410,
- 436,
- 437,
- 438
- ],
- "uses": [
- 49,
- 553
- ],
- "idx": 439
- },
- {
- "path": "../classic/classic/src/button/Split.js",
- "requires": [
- 439
- ],
- "uses": [
- 49,
- 437
- ],
- "idx": 440
- },
- {
- "path": "../classic/classic/src/button/Cycle.js",
- "requires": [
- 440
- ],
- "uses": [],
- "idx": 441
- },
- {
- "path": "../classic/classic/src/layout/container/SegmentedButton.js",
- "requires": [
- 421
- ],
- "uses": [],
- "idx": 442
- },
- {
- "path": "../classic/classic/src/button/Segmented.js",
- "requires": [
- 424,
- 439,
- 442
- ],
- "uses": [],
- "idx": 443
- },
- {
- "path": "../classic/classic/src/panel/Bar.js",
- "requires": [
- 424
- ],
- "uses": [],
- "idx": 444
- },
- {
- "path": "../classic/classic/src/panel/Title.js",
- "requires": [
- 78,
- 117
- ],
- "uses": [],
- "idx": 445
- },
- {
- "path": "../classic/classic/src/panel/Tool.js",
- "requires": [
- 78,
- 117
- ],
- "uses": [
- 553
- ],
- "idx": 446
- },
- {
- "path": "../classic/classic/src/panel/Header.js",
- "requires": [
- 433,
- 444,
- 445,
- 446
- ],
- "uses": [
- 21
- ],
- "idx": 447
- },
- {
- "path": "../classic/classic/src/layout/container/boxOverflow/None.js",
- "requires": [
- 12
- ],
- "uses": [],
- "idx": 448
- },
- {
- "path": "../classic/classic/src/layout/container/boxOverflow/Scroller.js",
- "requires": [
- 4,
- 49,
- 403,
- 448
- ],
- "uses": [
- 117
- ],
- "idx": 449
- },
- {
- "path": "../classic/classic/src/dd/DragDropManager.js",
- "requires": [
- 34,
- 35
- ],
- "uses": [
- 49,
- 481,
- 553
- ],
- "idx": 450
- },
- {
- "path": "../classic/classic/src/resizer/Splitter.js",
- "requires": [
- 98,
- 117
- ],
- "uses": [
- 477
- ],
- "idx": 451
- },
- {
- "path": "../classic/classic/src/layout/container/Box.js",
- "requires": [
- 94,
- 421,
- 448,
- 449,
- 450,
- 451
- ],
- "uses": [
- 12,
- 419,
- 433
- ],
- "idx": 452
- },
- {
- "path": "../classic/classic/src/layout/container/HBox.js",
- "requires": [
- 452
- ],
- "uses": [],
- "idx": 453
- },
- {
- "path": "../classic/classic/src/layout/container/VBox.js",
- "requires": [
- 452
- ],
- "uses": [],
- "idx": 454
- },
- {
- "path": "../classic/classic/src/toolbar/Toolbar.js",
- "requires": [
- 424,
- 433,
- 453,
- 454
- ],
- "uses": [
- 117,
- 384,
- 535,
- 556,
- 702,
- 703
- ],
- "idx": 455
- },
- {
- "path": "../classic/classic/src/dd/DragDrop.js",
- "requires": [
- 450
- ],
- "uses": [
- 49
- ],
- "idx": 456
- },
- {
- "path": "../classic/classic/src/dd/DD.js",
- "requires": [
- 450,
- 456
- ],
- "uses": [
- 49
- ],
- "idx": 457
- },
- {
- "path": "../classic/classic/src/dd/DDProxy.js",
- "requires": [
- 457
- ],
- "uses": [
- 450
- ],
- "idx": 458
- },
- {
- "path": "../classic/classic/src/dd/StatusProxy.js",
- "requires": [
- 117
- ],
- "uses": [],
- "idx": 459
- },
- {
- "path": "../classic/classic/src/dd/DragSource.js",
- "requires": [
- 450,
- 458,
- 459
- ],
- "uses": [
- 433
- ],
- "idx": 460
- },
- {
- "path": "../classic/classic/src/panel/Proxy.js",
- "requires": [],
- "uses": [
- 49
- ],
- "idx": 461
- },
- {
- "path": "../classic/classic/src/panel/DD.js",
- "requires": [
- 460,
- 461
- ],
- "uses": [],
- "idx": 462
- },
- {
- "path": "../classic/classic/src/layout/component/Dock.js",
- "requires": [
- 432
- ],
- "uses": [
- 24,
- 49,
- 419
- ],
- "idx": 463
- },
- {
- "path": "../classic/classic/src/util/Memento.js",
- "requires": [],
- "uses": [],
- "idx": 464
- },
- {
- "path": "../classic/classic/src/container/DockingContainer.js",
- "requires": [
- 49,
- 56
- ],
- "uses": [
- 24,
- 253,
- 405
- ],
- "idx": 465
- },
- {
- "path": "../classic/classic/src/panel/Panel.js",
- "requires": [
- 49,
- 56,
- 73,
- 98,
- 424,
- 447,
- 455,
- 462,
- 463,
- 464,
- 465
- ],
- "uses": [
- 1,
- 21,
- 34,
- 94,
- 101,
- 102,
- 117,
- 253,
- 373,
- 422,
- 433,
- 446,
- 498
- ],
- "idx": 466
- },
- {
- "path": "../classic/classic/src/layout/container/Table.js",
- "requires": [
- 421
- ],
- "uses": [],
- "idx": 467
- },
- {
- "path": "../classic/classic/src/container/ButtonGroup.js",
- "requires": [
- 466,
- 467
- ],
- "uses": [],
- "idx": 468
- },
- {
- "path": "../classic/classic/src/container/Monitor.js",
- "requires": [],
- "uses": [
- 24,
- 56
- ],
- "idx": 469
- },
- {
- "path": "../classic/classic/src/plugin/Viewport.js",
- "requires": [
- 84,
- 118
- ],
- "uses": [
- 49,
- 90,
- 419
- ],
- "idx": 470
- },
- {
- "path": "../classic/classic/src/container/Viewport.js",
- "requires": [
- 118,
- 424,
- 470
- ],
- "uses": [],
- "idx": 471
- },
- {
- "path": "../classic/classic/src/layout/container/Anchor.js",
- "requires": [
- 422
- ],
- "uses": [],
- "idx": 472
- },
- {
- "path": "../classic/classic/src/dashboard/Panel.js",
- "requires": [
- 466
- ],
- "uses": [
- 21
- ],
- "idx": 473
- },
- {
- "path": "../classic/classic/src/dashboard/Column.js",
- "requires": [
- 424,
- 472,
- 473
- ],
- "uses": [],
- "idx": 474
- },
- {
- "path": "../classic/classic/src/layout/container/Column.js",
- "requires": [
- 422
- ],
- "uses": [],
- "idx": 475
- },
- {
- "path": "../classic/classic/src/dd/DragTracker.js",
- "requires": [
- 52
- ],
- "uses": [
- 34,
- 117,
- 373
- ],
- "idx": 476
- },
- {
- "path": "../classic/classic/src/resizer/SplitterTracker.js",
- "requires": [
- 34,
- 476
- ],
- "uses": [
- 49,
- 106
- ],
- "idx": 477
- },
- {
- "path": "../classic/classic/src/layout/container/ColumnSplitterTracker.js",
- "requires": [
- 477
- ],
- "uses": [],
- "idx": 478
- },
- {
- "path": "../classic/classic/src/layout/container/ColumnSplitter.js",
- "requires": [
- 451,
- 478
- ],
- "uses": [],
- "idx": 479
- },
- {
- "path": "../classic/classic/src/layout/container/Dashboard.js",
- "requires": [
- 475,
- 479
- ],
- "uses": [
- 433
- ],
- "idx": 480
- },
- {
- "path": "../classic/classic/src/dd/DDTarget.js",
- "requires": [
- 456
- ],
- "uses": [],
- "idx": 481
- },
- {
- "path": "../classic/classic/src/dd/ScrollManager.js",
- "requires": [
- 450
- ],
- "uses": [],
- "idx": 482
- },
- {
- "path": "../classic/classic/src/dd/DropTarget.js",
- "requires": [
- 481,
- 482
- ],
- "uses": [],
- "idx": 483
- },
- {
- "path": "../classic/classic/src/dashboard/DropZone.js",
- "requires": [
- 483
- ],
- "uses": [],
- "idx": 484
- },
- {
- "path": "../classic/classic/src/dashboard/Part.js",
- "requires": [
- 3,
- 12,
- 134
- ],
- "uses": [],
- "idx": 485
- },
- {
- "path": "../classic/classic/src/dashboard/Dashboard.js",
- "requires": [
- 466,
- 474,
- 480,
- 484,
- 485
- ],
- "uses": [
- 12,
- 115,
- 132
- ],
- "idx": 486
- },
- {
- "path": "../classic/classic/src/dd/DragZone.js",
- "requires": [
- 460
- ],
- "uses": [
- 482,
- 488
- ],
- "idx": 487
- },
- {
- "path": "../classic/classic/src/dd/Registry.js",
- "requires": [],
- "uses": [],
- "idx": 488
- },
- {
- "path": "../classic/classic/src/dd/DropZone.js",
- "requires": [
- 483,
- 488
- ],
- "uses": [
- 450
- ],
- "idx": 489
- },
- {
- "path": "../classic/classic/src/dom/Layer.js",
- "requires": [
- 49
- ],
- "uses": [
- 253
- ],
- "idx": 490
- },
- {
- "path": "../classic/classic/src/enums.js",
- "requires": [],
- "uses": [],
- "idx": 491
- },
- {
- "path": "../classic/classic/src/event/publisher/MouseEnterLeave.js",
- "requires": [
- 37
- ],
- "uses": [],
- "idx": 492
- },
- {
- "path": "../classic/classic/src/flash/Component.js",
- "requires": [
- 117
- ],
- "uses": [],
- "idx": 493
- },
- {
- "path": "../classic/classic/src/form/action/Action.js",
- "requires": [],
- "uses": [],
- "idx": 494
- },
- {
- "path": "../classic/classic/src/form/action/Load.js",
- "requires": [
- 17,
- 494
- ],
- "uses": [
- 18
- ],
- "idx": 495
- },
- {
- "path": "../classic/classic/src/form/action/Submit.js",
- "requires": [
- 494
- ],
- "uses": [
- 18,
- 253
- ],
- "idx": 496
- },
- {
- "path": "../classic/classic/src/form/action/StandardSubmit.js",
- "requires": [
- 496
- ],
- "uses": [],
- "idx": 497
- },
- {
- "path": "../classic/classic/src/util/ComponentDragger.js",
- "requires": [
- 476
- ],
- "uses": [
- 34,
- 49
- ],
- "idx": 498
- },
- {
- "path": "../classic/classic/src/window/Window.js",
- "requires": [
- 34,
- 466,
- 498
- ],
- "uses": [],
- "idx": 499
- },
- {
- "path": "../classic/classic/src/form/Labelable.js",
- "requires": [
- 0,
- 98
- ],
- "uses": [
- 49,
- 552
- ],
- "idx": 500
- },
- {
- "path": "../classic/classic/src/form/field/Field.js",
- "requires": [],
- "uses": [],
- "idx": 501
- },
- {
- "path": "../classic/classic/src/form/field/Base.js",
- "requires": [
- 1,
- 98,
- 117,
- 500,
- 501
- ],
- "uses": [
- 95,
- 253
- ],
- "idx": 502
- },
- {
- "path": "../classic/classic/src/layout/component/field/Text.js",
- "requires": [
- 433
- ],
- "uses": [],
- "idx": 503
- },
- {
- "path": "../classic/classic/src/form/field/VTypes.js",
- "requires": [],
- "uses": [],
- "idx": 504
- },
- {
- "path": "../classic/classic/src/form/trigger/Trigger.js",
- "requires": [
- 12,
- 403
- ],
- "uses": [
- 49,
- 98
- ],
- "idx": 505
- },
- {
- "path": "../classic/classic/src/form/field/Text.js",
- "requires": [
- 410,
- 419,
- 502,
- 503,
- 504,
- 505
- ],
- "uses": [
- 94,
- 95,
- 102
- ],
- "idx": 506
- },
- {
- "path": "../classic/classic/src/form/field/TextArea.js",
- "requires": [
- 1,
- 98,
- 506
- ],
- "uses": [
- 94,
- 410
- ],
- "idx": 507
- },
- {
- "path": "../classic/classic/src/window/MessageBox.js",
- "requires": [
- 435,
- 439,
- 453,
- 455,
- 472,
- 499,
- 506,
- 507
- ],
- "uses": [
- 117,
- 424,
- 433,
- 434
- ],
- "idx": 508
- },
- {
- "path": "../classic/classic/src/form/Basic.js",
- "requires": [
- 1,
- 52,
- 56,
- 145,
- 495,
- 496,
- 497,
- 508
- ],
- "uses": [
- 469
- ],
- "idx": 509
- },
- {
- "path": "../classic/classic/src/layout/component/field/FieldContainer.js",
- "requires": [
- 433
- ],
- "uses": [],
- "idx": 510
- },
- {
- "path": "../classic/classic/src/form/FieldAncestor.js",
- "requires": [
- 0,
- 469
- ],
- "uses": [],
- "idx": 511
- },
- {
- "path": "../classic/classic/src/form/FieldContainer.js",
- "requires": [
- 424,
- 500,
- 510,
- 511
- ],
- "uses": [],
- "idx": 512
- },
- {
- "path": "../classic/classic/src/layout/container/CheckboxGroup.js",
- "requires": [
- 421
- ],
- "uses": [
- 253
- ],
- "idx": 513
- },
- {
- "path": "../classic/classic/src/form/CheckboxManager.js",
- "requires": [
- 56
- ],
- "uses": [],
- "idx": 514
- },
- {
- "path": "../classic/classic/src/form/field/Checkbox.js",
- "requires": [
- 98,
- 502,
- 514
- ],
- "uses": [],
- "idx": 515
- },
- {
- "path": "../classic/classic/src/form/CheckboxGroup.js",
- "requires": [
- 501,
- 502,
- 512,
- 513,
- 515
- ],
- "uses": [],
- "idx": 516
- },
- {
- "path": "../classic/classic/src/form/FieldSet.js",
- "requires": [
- 424,
- 511
- ],
- "uses": [
- 49,
- 101,
- 117,
- 253,
- 433,
- 446,
- 472,
- 515,
- 669
- ],
- "idx": 517
- },
- {
- "path": "../classic/classic/src/form/Label.js",
- "requires": [
- 94,
- 117
- ],
- "uses": [],
- "idx": 518
- },
- {
- "path": "../classic/classic/src/form/Panel.js",
- "requires": [
- 57,
- 466,
- 509,
- 511
- ],
- "uses": [
- 409
- ],
- "idx": 519
- },
- {
- "path": "../classic/classic/src/form/RadioManager.js",
- "requires": [
- 56
- ],
- "uses": [],
- "idx": 520
- },
- {
- "path": "../classic/classic/src/form/field/Radio.js",
- "requires": [
- 515,
- 520
- ],
- "uses": [],
- "idx": 521
- },
- {
- "path": "../classic/classic/src/form/RadioGroup.js",
- "requires": [
- 516,
- 521
- ],
- "uses": [
- 520
- ],
- "idx": 522
- },
- {
- "path": "../classic/classic/src/form/action/DirectAction.js",
- "requires": [
- 0
- ],
- "uses": [
- 227
- ],
- "idx": 523
- },
- {
- "path": "../classic/classic/src/form/action/DirectLoad.js",
- "requires": [
- 227,
- 495,
- 523
- ],
- "uses": [],
- "idx": 524
- },
- {
- "path": "../classic/classic/src/form/action/DirectSubmit.js",
- "requires": [
- 227,
- 496,
- 523
- ],
- "uses": [],
- "idx": 525
- },
- {
- "path": "../classic/classic/src/form/field/Picker.js",
- "requires": [
- 373,
- 506
- ],
- "uses": [],
- "idx": 526
- },
- {
- "path": "../classic/classic/src/selection/Model.js",
- "requires": [
- 4,
- 12,
- 192,
- 430
- ],
- "uses": [],
- "idx": 527
- },
- {
- "path": "../classic/classic/src/selection/DataViewModel.js",
- "requires": [
- 373,
- 527
- ],
- "uses": [],
- "idx": 528
- },
- {
- "path": "../classic/classic/src/view/NavigationModel.js",
- "requires": [
- 12,
- 52,
- 430
- ],
- "uses": [
- 373
- ],
- "idx": 529
- },
- {
- "path": "../classic/classic/src/view/AbstractView.js",
- "requires": [
- 75,
- 76,
- 104,
- 117,
- 430,
- 431,
- 528,
- 529
- ],
- "uses": [
- 1,
- 12,
- 49,
- 95,
- 98,
- 185,
- 253
- ],
- "idx": 530
- },
- {
- "path": "../classic/classic/src/view/View.js",
- "requires": [
- 530
- ],
- "uses": [],
- "idx": 531
- },
- {
- "path": "../classic/classic/src/view/BoundListKeyNav.js",
- "requires": [
- 529
- ],
- "uses": [
- 36,
- 373
- ],
- "idx": 532
- },
- {
- "path": "../classic/classic/src/layout/component/BoundList.js",
- "requires": [
- 433
- ],
- "uses": [],
- "idx": 533
- },
- {
- "path": "../classic/classic/src/toolbar/Item.js",
- "requires": [
- 117,
- 455
- ],
- "uses": [],
- "idx": 534
- },
- {
- "path": "../classic/classic/src/toolbar/TextItem.js",
- "requires": [
- 98,
- 455,
- 534
- ],
- "uses": [],
- "idx": 535
- },
- {
- "path": "../classic/classic/src/form/trigger/Spinner.js",
- "requires": [
- 505
- ],
- "uses": [],
- "idx": 536
- },
- {
- "path": "../classic/classic/src/form/field/Spinner.js",
- "requires": [
- 373,
- 506,
- 536
- ],
- "uses": [],
- "idx": 537
- },
- {
- "path": "../classic/classic/src/form/field/Number.js",
- "requires": [
- 537
- ],
- "uses": [
- 94,
- 95
- ],
- "idx": 538
- },
- {
- "path": "../classic/classic/src/toolbar/Paging.js",
- "requires": [
- 430,
- 455,
- 535,
- 538
- ],
- "uses": [
- 95,
- 433,
- 503,
- 536
- ],
- "idx": 539
- },
- {
- "path": "../classic/classic/src/view/BoundList.js",
- "requires": [
- 49,
- 241,
- 531,
- 532,
- 533,
- 539
- ],
- "uses": [
- 98,
- 433
- ],
- "idx": 540
- },
- {
- "path": "../classic/classic/src/form/field/ComboBox.js",
- "requires": [
- 1,
- 185,
- 430,
- 526,
- 540
- ],
- "uses": [
- 49,
- 51,
- 98,
- 132,
- 163,
- 179,
- 253,
- 373,
- 528,
- 532,
- 533
- ],
- "idx": 541
- },
- {
- "path": "../classic/classic/src/picker/Month.js",
- "requires": [
- 98,
- 117,
- 403,
- 439
- ],
- "uses": [
- 433
- ],
- "idx": 542
- },
- {
- "path": "../classic/classic/src/picker/Date.js",
- "requires": [
- 67,
- 98,
- 117,
- 373,
- 403,
- 439,
- 440,
- 542
- ],
- "uses": [
- 95,
- 253,
- 433
- ],
- "idx": 543
- },
- {
- "path": "../classic/classic/src/form/field/Date.js",
- "requires": [
- 526,
- 543
- ],
- "uses": [
- 95,
- 433
- ],
- "idx": 544
- },
- {
- "path": "../classic/classic/src/form/field/Display.js",
- "requires": [
- 94,
- 98,
- 502
- ],
- "uses": [],
- "idx": 545
- },
- {
- "path": "../classic/classic/src/form/field/FileButton.js",
- "requires": [
- 439
- ],
- "uses": [],
- "idx": 546
- },
- {
- "path": "../classic/classic/src/form/trigger/Component.js",
- "requires": [
- 505
- ],
- "uses": [],
- "idx": 547
- },
- {
- "path": "../classic/classic/src/form/field/File.js",
- "requires": [
- 506,
- 546,
- 547
- ],
- "uses": [
- 433
- ],
- "idx": 548
- },
- {
- "path": "../classic/classic/src/form/field/Hidden.js",
- "requires": [
- 502
- ],
- "uses": [],
- "idx": 549
- },
- {
- "path": "../classic/classic/src/tip/Tip.js",
- "requires": [
- 466
- ],
- "uses": [
- 35,
- 117
- ],
- "idx": 550
- },
- {
- "path": "../classic/classic/src/tip/ToolTip.js",
- "requires": [
- 33,
- 550
- ],
- "uses": [
- 35,
- 75
- ],
- "idx": 551
- },
- {
- "path": "../classic/classic/src/tip/QuickTip.js",
- "requires": [
- 551
- ],
- "uses": [],
- "idx": 552
- },
- {
- "path": "../classic/classic/src/tip/QuickTipManager.js",
- "requires": [
- 552
- ],
- "uses": [],
- "idx": 553
- },
- {
- "path": "../classic/classic/src/picker/Color.js",
- "requires": [
- 98,
- 117
- ],
- "uses": [],
- "idx": 554
- },
- {
- "path": "../classic/classic/src/layout/component/field/HtmlEditor.js",
- "requires": [
- 510
- ],
- "uses": [],
- "idx": 555
- },
- {
- "path": "../classic/classic/src/toolbar/Separator.js",
- "requires": [
- 455,
- 534
- ],
- "uses": [],
- "idx": 556
- },
- {
- "path": "../classic/classic/src/layout/container/boxOverflow/Menu.js",
- "requires": [
- 439,
- 448,
- 556
- ],
- "uses": [
- 433,
- 449,
- 454,
- 463,
- 515,
- 611,
- 613,
- 702
- ],
- "idx": 557
- },
- {
- "path": "../classic/classic/src/form/field/HtmlEditor.js",
- "requires": [
- 94,
- 409,
- 454,
- 455,
- 501,
- 512,
- 534,
- 553,
- 554,
- 555,
- 557
- ],
- "uses": [
- 1,
- 95,
- 117,
- 253,
- 433,
- 449,
- 463,
- 613
- ],
- "idx": 558
- },
- {
- "path": "../classic/classic/src/view/TagKeyNav.js",
- "requires": [
- 532
- ],
- "uses": [],
- "idx": 559
- },
- {
- "path": "../classic/classic/src/form/field/Tag.js",
- "requires": [
- 182,
- 224,
- 527,
- 541,
- 559
- ],
- "uses": [
- 51,
- 95,
- 98,
- 169,
- 176,
- 177,
- 410
- ],
- "idx": 560
- },
- {
- "path": "../classic/classic/src/picker/Time.js",
- "requires": [
- 182,
- 540
- ],
- "uses": [
- 51
- ],
- "idx": 561
- },
- {
- "path": "../classic/classic/src/form/field/Time.js",
- "requires": [
- 532,
- 541,
- 544,
- 561
- ],
- "uses": [
- 95,
- 98,
- 528,
- 533
- ],
- "idx": 562
- },
- {
- "path": "../classic/classic/src/form/field/Trigger.js",
- "requires": [
- 253,
- 403,
- 506
- ],
- "uses": [],
- "idx": 563
- },
- {
- "path": "../classic/classic/src/grid/CellContext.js",
- "requires": [],
- "uses": [],
- "idx": 564
- },
- {
- "path": "../classic/classic/src/grid/CellEditor.js",
- "requires": [
- 426
- ],
- "uses": [
- 49,
- 424
- ],
- "idx": 565
- },
- {
- "path": "../classic/classic/src/grid/ColumnComponentLayout.js",
- "requires": [
- 433
- ],
- "uses": [],
- "idx": 566
- },
- {
- "path": "../classic/classic/src/layout/container/Fit.js",
- "requires": [
- 421
- ],
- "uses": [],
- "idx": 567
- },
- {
- "path": "../classic/classic/src/panel/Table.js",
- "requires": [
- 466,
- 567
- ],
- "uses": [
- 1,
- 77,
- 115,
- 185,
- 225,
- 253,
- 564,
- 571,
- 578,
- 588,
- 626,
- 627,
- 687,
- 688,
- 689
- ],
- "idx": 568
- },
- {
- "path": "../classic/classic/src/grid/ColumnLayout.js",
- "requires": [
- 453,
- 568
- ],
- "uses": [],
- "idx": 569
- },
- {
- "path": "../classic/classic/src/grid/ColumnManager.js",
- "requires": [],
- "uses": [],
- "idx": 570
- },
- {
- "path": "../classic/classic/src/grid/NavigationModel.js",
- "requires": [
- 529
- ],
- "uses": [
- 21,
- 36,
- 49,
- 75,
- 117,
- 373,
- 564
- ],
- "idx": 571
- },
- {
- "path": "../classic/classic/src/view/TableLayout.js",
- "requires": [
- 433
- ],
- "uses": [],
- "idx": 572
- },
- {
- "path": "../classic/classic/src/grid/locking/RowSynchronizer.js",
- "requires": [],
- "uses": [],
- "idx": 573
- },
- {
- "path": "../classic/classic/src/view/NodeCache.js",
- "requires": [
- 76
- ],
- "uses": [
- 49,
- 75
- ],
- "idx": 574
- },
- {
- "path": "../classic/classic/src/scroll/TableScroller.js",
- "requires": [
- 110
- ],
- "uses": [
- 10
- ],
- "idx": 575
- },
- {
- "path": "../classic/classic/src/view/Table.js",
- "requires": [
- 1,
- 56,
- 75,
- 241,
- 531,
- 564,
- 572,
- 573,
- 574,
- 575
- ],
- "uses": [
- 12,
- 49,
- 98,
- 117,
- 163,
- 588
- ],
- "idx": 576
- },
- {
- "path": "../classic/classic/src/grid/Panel.js",
- "requires": [
- 568,
- 576
- ],
- "uses": [],
- "idx": 577
- },
- {
- "path": "../classic/classic/src/grid/RowContext.js",
- "requires": [],
- "uses": [
- 12
- ],
- "idx": 578
- },
- {
- "path": "../classic/classic/src/grid/RowEditorButtons.js",
- "requires": [
- 424
- ],
- "uses": [
- 433,
- 439,
- 466
- ],
- "idx": 579
- },
- {
- "path": "../classic/classic/src/grid/RowEditor.js",
- "requires": [
- 373,
- 519,
- 551,
- 579
- ],
- "uses": [
- 49,
- 67,
- 77,
- 422,
- 424,
- 433,
- 463,
- 545,
- 564
- ],
- "idx": 580
- },
- {
- "path": "../classic/classic/src/grid/Scroller.js",
- "requires": [],
- "uses": [],
- "idx": 581
- },
- {
- "path": "../classic/classic/src/view/DropZone.js",
- "requires": [
- 489
- ],
- "uses": [
- 117,
- 433
- ],
- "idx": 582
- },
- {
- "path": "../classic/classic/src/grid/ViewDropZone.js",
- "requires": [
- 582
- ],
- "uses": [],
- "idx": 583
- },
- {
- "path": "../classic/classic/src/grid/plugin/HeaderResizer.js",
- "requires": [
- 34,
- 84,
- 476
- ],
- "uses": [
- 589
- ],
- "idx": 584
- },
- {
- "path": "../classic/classic/src/grid/header/DragZone.js",
- "requires": [
- 487
- ],
- "uses": [],
- "idx": 585
- },
- {
- "path": "../classic/classic/src/grid/header/DropZone.js",
- "requires": [
- 489
- ],
- "uses": [
- 450
- ],
- "idx": 586
- },
- {
- "path": "../classic/classic/src/grid/plugin/HeaderReorderer.js",
- "requires": [
- 84,
- 585,
- 586
- ],
- "uses": [],
- "idx": 587
- },
- {
- "path": "../classic/classic/src/grid/header/Container.js",
- "requires": [
- 373,
- 424,
- 569,
- 584,
- 587
- ],
- "uses": [
- 1,
- 117,
- 433,
- 449,
- 454,
- 463,
- 570,
- 589,
- 611,
- 612,
- 613
- ],
- "idx": 588
- },
- {
- "path": "../classic/classic/src/grid/column/Column.js",
- "requires": [
- 221,
- 566,
- 569,
- 588
- ],
- "uses": [
- 54,
- 94,
- 117,
- 131,
- 584
- ],
- "idx": 589
- },
- {
- "path": "../classic/classic/src/grid/column/ActionProxy.js",
- "requires": [],
- "uses": [],
- "idx": 590
- },
- {
- "path": "../classic/classic/src/grid/column/Action.js",
- "requires": [
- 78,
- 94,
- 589,
- 590
- ],
- "uses": [
- 49
- ],
- "idx": 591
- },
- {
- "path": "../classic/classic/src/grid/column/Boolean.js",
- "requires": [
- 589
- ],
- "uses": [],
- "idx": 592
- },
- {
- "path": "../classic/classic/src/grid/column/Check.js",
- "requires": [
- 589
- ],
- "uses": [
- 564
- ],
- "idx": 593
- },
- {
- "path": "../classic/classic/src/grid/column/Date.js",
- "requires": [
- 589
- ],
- "uses": [
- 94
- ],
- "idx": 594
- },
- {
- "path": "../classic/classic/src/grid/column/Groups.js",
- "requires": [
- 589
- ],
- "uses": [],
- "idx": 595
- },
- {
- "path": "../classic/classic/src/grid/column/Number.js",
- "requires": [
- 94,
- 589
- ],
- "uses": [],
- "idx": 596
- },
- {
- "path": "../classic/classic/src/grid/column/RowNumberer.js",
- "requires": [
- 589
- ],
- "uses": [
- 564
- ],
- "idx": 597
- },
- {
- "path": "../classic/classic/src/grid/column/Template.js",
- "requires": [
- 98,
- 589
- ],
- "uses": [
- 593
- ],
- "idx": 598
- },
- {
- "path": "../classic/classic/src/grid/column/Widget.js",
- "requires": [
- 379,
- 589
- ],
- "uses": [],
- "idx": 599
- },
- {
- "path": "../classic/classic/src/grid/feature/Feature.js",
- "requires": [
- 52
- ],
- "uses": [],
- "idx": 600
- },
- {
- "path": "../classic/classic/src/grid/feature/AbstractSummary.js",
- "requires": [
- 600
- ],
- "uses": [
- 12
- ],
- "idx": 601
- },
- {
- "path": "../classic/classic/src/grid/feature/AdvancedGroupStore.js",
- "requires": [
- 360
- ],
- "uses": [],
- "idx": 602
- },
- {
- "path": "../classic/classic/src/grid/feature/AdvancedGrouping.js",
- "requires": [
- 595,
- 600,
- 602
- ],
- "uses": [
- 98,
- 422,
- 566
- ],
- "idx": 603
- },
- {
- "path": "../classic/classic/src/grid/feature/AdvancedGroupingSummary.js",
- "requires": [
- 603
- ],
- "uses": [
- 1,
- 117,
- 433
- ],
- "idx": 604
- },
- {
- "path": "../classic/classic/src/grid/feature/GroupStore.js",
- "requires": [
- 52
- ],
- "uses": [
- 132
- ],
- "idx": 605
- },
- {
- "path": "../classic/classic/src/grid/feature/Grouping.js",
- "requires": [
- 600,
- 601,
- 605
- ],
- "uses": [
- 98,
- 163
- ],
- "idx": 606
- },
- {
- "path": "../classic/classic/src/grid/feature/GroupingSummary.js",
- "requires": [
- 606
- ],
- "uses": [],
- "idx": 607
- },
- {
- "path": "../classic/classic/src/grid/feature/RowBody.js",
- "requires": [
- 600
- ],
- "uses": [
- 98
- ],
- "idx": 608
- },
- {
- "path": "../classic/classic/src/grid/feature/Summary.js",
- "requires": [
- 601
- ],
- "uses": [
- 117,
- 163,
- 433
- ],
- "idx": 609
- },
- {
- "path": "../classic/classic/src/menu/Item.js",
- "requires": [
- 78,
- 117,
- 241
- ],
- "uses": [
- 438,
- 553
- ],
- "idx": 610
- },
- {
- "path": "../classic/classic/src/menu/CheckItem.js",
- "requires": [
- 610
- ],
- "uses": [
- 438
- ],
- "idx": 611
- },
- {
- "path": "../classic/classic/src/menu/Separator.js",
- "requires": [
- 610
- ],
- "uses": [],
- "idx": 612
- },
- {
- "path": "../classic/classic/src/menu/Menu.js",
- "requires": [
- 438,
- 454,
- 466,
- 610,
- 611,
- 612
- ],
- "uses": [
- 1,
- 21,
- 36,
- 49,
- 373,
- 433
- ],
- "idx": 613
- },
- {
- "path": "../classic/classic/src/grid/filters/filter/Base.js",
- "requires": [
- 12,
- 449,
- 454,
- 463,
- 613
- ],
- "uses": [
- 1,
- 51
- ],
- "idx": 614
- },
- {
- "path": "../classic/classic/src/grid/filters/filter/SingleFilter.js",
- "requires": [
- 614
- ],
- "uses": [],
- "idx": 615
- },
- {
- "path": "../classic/classic/src/grid/filters/filter/Boolean.js",
- "requires": [
- 615
- ],
- "uses": [],
- "idx": 616
- },
- {
- "path": "../classic/classic/src/grid/filters/filter/TriFilter.js",
- "requires": [
- 614
- ],
- "uses": [],
- "idx": 617
- },
- {
- "path": "../classic/classic/src/grid/filters/filter/Date.js",
- "requires": [
- 433,
- 611,
- 617
- ],
- "uses": [
- 449,
- 454,
- 463,
- 543,
- 679
- ],
- "idx": 618
- },
- {
- "path": "../classic/classic/src/grid/filters/filter/List.js",
- "requires": [
- 615
- ],
- "uses": [
- 182,
- 185
- ],
- "idx": 619
- },
- {
- "path": "../classic/classic/src/grid/filters/filter/Number.js",
- "requires": [
- 503,
- 536,
- 617
- ],
- "uses": [
- 538
- ],
- "idx": 620
- },
- {
- "path": "../classic/classic/src/grid/filters/filter/String.js",
- "requires": [
- 503,
- 506,
- 615
- ],
- "uses": [
- 51
- ],
- "idx": 621
- },
- {
- "path": "../classic/classic/src/grid/filters/Filters.js",
- "requires": [
- 84,
- 430,
- 614,
- 615,
- 616,
- 617,
- 618,
- 619,
- 620,
- 621
- ],
- "uses": [
- 12
- ],
- "idx": 622
- },
- {
- "path": "../classic/classic/src/grid/locking/HeaderContainer.js",
- "requires": [
- 570,
- 588
- ],
- "uses": [],
- "idx": 623
- },
- {
- "path": "../classic/classic/src/grid/locking/View.js",
- "requires": [
- 52,
- 87,
- 117,
- 430,
- 530,
- 576
- ],
- "uses": [
- 110,
- 431,
- 564
- ],
- "idx": 624
- },
- {
- "path": "../classic/classic/src/scroll/LockingScroller.js",
- "requires": [
- 110
- ],
- "uses": [
- 10
- ],
- "idx": 625
- },
- {
- "path": "../classic/classic/src/grid/locking/Lockable.js",
- "requires": [
- 117,
- 576,
- 588,
- 623,
- 624,
- 625
- ],
- "uses": [
- 1,
- 34,
- 110,
- 185,
- 422,
- 433,
- 451,
- 452,
- 466,
- 568
- ],
- "idx": 626
- },
- {
- "path": "../classic/classic/src/grid/plugin/BufferedRenderer.js",
- "requires": [
- 84,
- 573
- ],
- "uses": [
- 1,
- 49,
- 117
- ],
- "idx": 627
- },
- {
- "path": "../classic/classic/src/grid/plugin/Editing.js",
- "requires": [
- 4,
- 84,
- 373,
- 502,
- 576,
- 589
- ],
- "uses": [
- 21,
- 117,
- 433,
- 564
- ],
- "idx": 628
- },
- {
- "path": "../classic/classic/src/grid/plugin/CellEditing.js",
- "requires": [
- 1,
- 565,
- 628
- ],
- "uses": [
- 56,
- 425,
- 433,
- 564
- ],
- "idx": 629
- },
- {
- "path": "../classic/classic/src/grid/plugin/Clipboard.js",
- "requires": [
- 94,
- 383,
- 408
- ],
- "uses": [
- 564
- ],
- "idx": 630
- },
- {
- "path": "../classic/classic/src/grid/plugin/DragDrop.js",
- "requires": [
- 84
- ],
- "uses": [
- 583,
- 708
- ],
- "idx": 631
- },
- {
- "path": "../classic/classic/src/grid/plugin/grouping/Column.js",
- "requires": [
- 117,
- 610,
- 611,
- 612,
- 613
- ],
- "uses": [],
- "idx": 632
- },
- {
- "path": "../classic/classic/src/grid/plugin/grouping/DragZone.js",
- "requires": [
- 487
- ],
- "uses": [],
- "idx": 633
- },
- {
- "path": "../classic/classic/src/grid/plugin/grouping/DropZone.js",
- "requires": [
- 489
- ],
- "uses": [
- 131,
- 450
- ],
- "idx": 634
- },
- {
- "path": "../classic/classic/src/grid/plugin/grouping/Panel.js",
- "requires": [
- 374,
- 433,
- 466,
- 475,
- 632,
- 633,
- 634
- ],
- "uses": [
- 438,
- 612
- ],
- "idx": 635
- },
- {
- "path": "../classic/classic/src/grid/plugin/GroupingPanel.js",
- "requires": [
- 362,
- 635
- ],
- "uses": [],
- "idx": 636
- },
- {
- "path": "../classic/classic/src/grid/plugin/RowEditing.js",
- "requires": [
- 580,
- 628
- ],
- "uses": [],
- "idx": 637
- },
- {
- "path": "../classic/classic/src/grid/plugin/RowExpander.js",
- "requires": [
- 84,
- 608
- ],
- "uses": [
- 98,
- 589
- ],
- "idx": 638
- },
- {
- "path": "../classic/classic/src/grid/plugin/RowWidget.js",
- "requires": [
- 3,
- 379,
- 638
- ],
- "uses": [
- 84,
- 608
- ],
- "idx": 639
- },
- {
- "path": "../classic/classic/src/grid/plugin/Summaries.js",
- "requires": [
- 363
- ],
- "uses": [],
- "idx": 640
- },
- {
- "path": "../classic/classic/src/grid/plugin/filterbar/Operator.js",
- "requires": [
- 84
- ],
- "uses": [
- 449,
- 454,
- 463,
- 613
- ],
- "idx": 641
- },
- {
- "path": "../classic/classic/src/grid/plugin/filterbar/filters/Base.js",
- "requires": [
- 12,
- 503,
- 506,
- 641
- ],
- "uses": [
- 1,
- 51
- ],
- "idx": 642
- },
- {
- "path": "../classic/classic/src/grid/plugin/filterbar/filters/SingleFilter.js",
- "requires": [
- 642
- ],
- "uses": [],
- "idx": 643
- },
- {
- "path": "../classic/classic/src/grid/plugin/filterbar/filters/String.js",
- "requires": [
- 503,
- 506,
- 643
- ],
- "uses": [],
- "idx": 644
- },
- {
- "path": "../classic/classic/src/grid/plugin/filterbar/filters/Date.js",
- "requires": [
- 503,
- 544,
- 643
- ],
- "uses": [],
- "idx": 645
- },
- {
- "path": "../classic/classic/src/grid/plugin/filterbar/filters/Number.js",
- "requires": [
- 503,
- 536,
- 538,
- 643
- ],
- "uses": [],
- "idx": 646
- },
- {
- "path": "../classic/classic/src/grid/plugin/filterbar/filters/Boolean.js",
- "requires": [
- 503,
- 541,
- 643
- ],
- "uses": [],
- "idx": 647
- },
- {
- "path": "../classic/classic/src/grid/plugin/filterbar/filters/None.js",
- "requires": [
- 117,
- 433,
- 642
- ],
- "uses": [],
- "idx": 648
- },
- {
- "path": "../classic/classic/src/grid/plugin/filterbar/filters/List.js",
- "requires": [
- 503,
- 541,
- 643
- ],
- "uses": [],
- "idx": 649
- },
- {
- "path": "../classic/classic/src/grid/plugin/filterbar/filters/InList.js",
- "requires": [
- 649
- ],
- "uses": [],
- "idx": 650
- },
- {
- "path": "../classic/classic/src/grid/plugin/filterbar/FilterBar.js",
- "requires": [
- 361,
- 644,
- 645,
- 646,
- 647,
- 648,
- 649,
- 650
- ],
- "uses": [
- 424,
- 433,
- 453
- ],
- "idx": 651
- },
- {
- "path": "../classic/classic/src/grid/property/Grid.js",
- "requires": [
- 577
- ],
- "uses": [
- 21,
- 98,
- 163,
- 425,
- 433,
- 502,
- 503,
- 506,
- 536,
- 538,
- 541,
- 544,
- 564,
- 565,
- 576,
- 629,
- 653,
- 656
- ],
- "idx": 652
- },
- {
- "path": "../classic/classic/src/grid/property/HeaderContainer.js",
- "requires": [
- 94,
- 588
- ],
- "uses": [],
- "idx": 653
- },
- {
- "path": "../classic/classic/src/grid/property/Property.js",
- "requires": [
- 163
- ],
- "uses": [],
- "idx": 654
- },
- {
- "path": "../classic/classic/src/grid/property/Reader.js",
- "requires": [
- 165
- ],
- "uses": [
- 164
- ],
- "idx": 655
- },
- {
- "path": "../classic/classic/src/grid/property/Store.js",
- "requires": [
- 169,
- 182,
- 654,
- 655
- ],
- "uses": [
- 177
- ],
- "idx": 656
- },
- {
- "path": "../classic/classic/src/grid/selection/Selection.js",
- "requires": [],
- "uses": [],
- "idx": 657
- },
- {
- "path": "../classic/classic/src/grid/selection/Cells.js",
- "requires": [
- 657
- ],
- "uses": [
- 564
- ],
- "idx": 658
- },
- {
- "path": "../classic/classic/src/grid/selection/Columns.js",
- "requires": [
- 657
- ],
- "uses": [
- 564
- ],
- "idx": 659
- },
- {
- "path": "../classic/classic/src/grid/selection/Replicator.js",
- "requires": [
- 84
- ],
- "uses": [],
- "idx": 660
- },
- {
- "path": "../classic/classic/src/grid/selection/Rows.js",
- "requires": [
- 132,
- 657
- ],
- "uses": [
- 564
- ],
- "idx": 661
- },
- {
- "path": "../classic/classic/src/grid/selection/SelectionExtender.js",
- "requires": [
- 476
- ],
- "uses": [
- 49,
- 409
- ],
- "idx": 662
- },
- {
- "path": "../classic/classic/src/grid/selection/SpreadsheetModel.js",
- "requires": [
- 527,
- 597,
- 657,
- 658,
- 659,
- 661,
- 662
- ],
- "uses": [
- 409,
- 422,
- 482,
- 564,
- 566,
- 593
- ],
- "idx": 663
- },
- {
- "path": "../classic/classic/src/util/Queue.js",
- "requires": [],
- "uses": [],
- "idx": 664
- },
- {
- "path": "../classic/classic/src/layout/ContextItem.js",
- "requires": [],
- "uses": [
- 56,
- 67,
- 73,
- 419
- ],
- "idx": 665
- },
- {
- "path": "../classic/classic/src/layout/Context.js",
- "requires": [
- 67,
- 73,
- 382,
- 420,
- 664,
- 665
- ],
- "uses": [],
- "idx": 666
- },
- {
- "path": "../classic/classic/src/layout/SizePolicy.js",
- "requires": [],
- "uses": [],
- "idx": 667
- },
- {
- "path": "../classic/classic/src/layout/component/Body.js",
- "requires": [
- 433
- ],
- "uses": [],
- "idx": 668
- },
- {
- "path": "../classic/classic/src/layout/component/FieldSet.js",
- "requires": [
- 668
- ],
- "uses": [],
- "idx": 669
- },
- {
- "path": "../classic/classic/src/layout/container/Absolute.js",
- "requires": [
- 472
- ],
- "uses": [],
- "idx": 670
- },
- {
- "path": "../classic/classic/src/layout/container/Accordion.js",
- "requires": [
- 454
- ],
- "uses": [],
- "idx": 671
- },
- {
- "path": "../classic/classic/src/resizer/BorderSplitter.js",
- "requires": [
- 451
- ],
- "uses": [
- 683
- ],
- "idx": 672
- },
- {
- "path": "../classic/classic/src/layout/container/Border.js",
- "requires": [
- 73,
- 119,
- 421,
- 672
- ],
- "uses": [
- 94,
- 433
- ],
- "idx": 673
- },
- {
- "path": "../classic/classic/src/layout/container/Card.js",
- "requires": [
- 567
- ],
- "uses": [
- 49
- ],
- "idx": 674
- },
- {
- "path": "../classic/classic/src/layout/container/Center.js",
- "requires": [
- 567
- ],
- "uses": [],
- "idx": 675
- },
- {
- "path": "../classic/classic/src/layout/container/Form.js",
- "requires": [
- 422
- ],
- "uses": [],
- "idx": 676
- },
- {
- "path": "../classic/classic/src/menu/Bar.js",
- "requires": [
- 613
- ],
- "uses": [],
- "idx": 677
- },
- {
- "path": "../classic/classic/src/menu/ColorPicker.js",
- "requires": [
- 554,
- 613
- ],
- "uses": [
- 433,
- 438
- ],
- "idx": 678
- },
- {
- "path": "../classic/classic/src/menu/DatePicker.js",
- "requires": [
- 543,
- 613
- ],
- "uses": [
- 433,
- 438
- ],
- "idx": 679
- },
- {
- "path": "../classic/classic/src/panel/Pinnable.js",
- "requires": [
- 0
- ],
- "uses": [
- 433,
- 446
- ],
- "idx": 680
- },
- {
- "path": "../classic/classic/src/plugin/LazyItems.js",
- "requires": [
- 84
- ],
- "uses": [],
- "idx": 681
- },
- {
- "path": "../classic/classic/src/plugin/Responsive.js",
- "requires": [
- 84,
- 118
- ],
- "uses": [],
- "idx": 682
- },
- {
- "path": "../classic/classic/src/resizer/BorderSplitterTracker.js",
- "requires": [
- 34,
- 477
- ],
- "uses": [],
- "idx": 683
- },
- {
- "path": "../classic/classic/src/resizer/Handle.js",
- "requires": [
- 117
- ],
- "uses": [],
- "idx": 684
- },
- {
- "path": "../classic/classic/src/resizer/ResizeTracker.js",
- "requires": [
- 476
- ],
- "uses": [
- 49
- ],
- "idx": 685
- },
- {
- "path": "../classic/classic/src/resizer/Resizer.js",
- "requires": [
- 52
- ],
- "uses": [
- 49,
- 95,
- 117,
- 685
- ],
- "idx": 686
- },
- {
- "path": "../classic/classic/src/selection/CellModel.js",
- "requires": [
- 528,
- 564
- ],
- "uses": [],
- "idx": 687
- },
- {
- "path": "../classic/classic/src/selection/RowModel.js",
- "requires": [
- 528,
- 564
- ],
- "uses": [],
- "idx": 688
- },
- {
- "path": "../classic/classic/src/selection/CheckboxModel.js",
- "requires": [
- 593,
- 688
- ],
- "uses": [
- 422,
- 564,
- 566
- ],
- "idx": 689
- },
- {
- "path": "../classic/classic/src/selection/TreeModel.js",
- "requires": [
- 688
- ],
- "uses": [],
- "idx": 690
- },
- {
- "path": "../classic/classic/src/slider/Thumb.js",
- "requires": [
- 94,
- 476
- ],
- "uses": [
- 73
- ],
- "idx": 691
- },
- {
- "path": "../classic/classic/src/slider/Tip.js",
- "requires": [
- 550
- ],
- "uses": [],
- "idx": 692
- },
- {
- "path": "../classic/classic/src/slider/Multi.js",
- "requires": [
- 94,
- 95,
- 502,
- 691,
- 692
- ],
- "uses": [
- 253
- ],
- "idx": 693
- },
- {
- "path": "../classic/classic/src/slider/Single.js",
- "requires": [
- 693
- ],
- "uses": [],
- "idx": 694
- },
- {
- "path": "../classic/classic/src/slider/Widget.js",
- "requires": [
- 89,
- 693
- ],
- "uses": [
- 73,
- 94
- ],
- "idx": 695
- },
- {
- "path": "../classic/classic/src/state/CookieProvider.js",
- "requires": [
- 114
- ],
- "uses": [],
- "idx": 696
- },
- {
- "path": "../classic/classic/src/state/LocalStorageProvider.js",
- "requires": [
- 114,
- 406
- ],
- "uses": [],
- "idx": 697
- },
- {
- "path": "../classic/classic/src/tab/Tab.js",
- "requires": [
- 439
- ],
- "uses": [],
- "idx": 698
- },
- {
- "path": "../classic/classic/src/tab/Bar.js",
- "requires": [
- 35,
- 444,
- 668,
- 698
- ],
- "uses": [
- 34
- ],
- "idx": 699
- },
- {
- "path": "../classic/classic/src/tab/Panel.js",
- "requires": [
- 466,
- 674,
- 699
- ],
- "uses": [
- 433,
- 698
- ],
- "idx": 700
- },
- {
- "path": "../classic/classic/src/toolbar/Breadcrumb.js",
- "requires": [
- 250,
- 424,
- 440
- ],
- "uses": [
- 24,
- 185
- ],
- "idx": 701
- },
- {
- "path": "../classic/classic/src/toolbar/Fill.js",
- "requires": [
- 117,
- 455
- ],
- "uses": [],
- "idx": 702
- },
- {
- "path": "../classic/classic/src/toolbar/Spacer.js",
- "requires": [
- 117,
- 455
- ],
- "uses": [],
- "idx": 703
- },
- {
- "path": "../classic/classic/src/tree/Column.js",
- "requires": [
- 589
- ],
- "uses": [
- 78
- ],
- "idx": 704
- },
- {
- "path": "../classic/classic/src/tree/NavigationModel.js",
- "requires": [
- 571
- ],
- "uses": [
- 36
- ],
- "idx": 705
- },
- {
- "path": "../classic/classic/src/tree/View.js",
- "requires": [
- 576
- ],
- "uses": [
- 49
- ],
- "idx": 706
- },
- {
- "path": "../classic/classic/src/tree/Panel.js",
- "requires": [
- 250,
- 568,
- 690,
- 704,
- 705,
- 706
- ],
- "uses": [
- 185,
- 422,
- 566
- ],
- "idx": 707
- },
- {
- "path": "../classic/classic/src/view/DragZone.js",
- "requires": [
- 487
- ],
- "uses": [
- 49,
- 95
- ],
- "idx": 708
- },
- {
- "path": "../classic/classic/src/tree/ViewDragZone.js",
- "requires": [
- 708
- ],
- "uses": [
- 95
- ],
- "idx": 709
- },
- {
- "path": "../classic/classic/src/tree/ViewDropZone.js",
- "requires": [
- 582
- ],
- "uses": [],
- "idx": 710
- },
- {
- "path": "../classic/classic/src/tree/plugin/TreeViewDragDrop.js",
- "requires": [
- 84
- ],
- "uses": [
- 709,
- 710
- ],
- "idx": 711
- },
- {
- "path": "../classic/classic/src/view/MultiSelectorSearch.js",
- "requires": [
- 466
- ],
- "uses": [
- 51,
- 185,
- 463,
- 503,
- 506,
- 567,
- 577
- ],
- "idx": 712
- },
- {
- "path": "../classic/classic/src/view/MultiSelector.js",
- "requires": [
- 463,
- 567,
- 577,
- 712
- ],
- "uses": [],
- "idx": 713
- },
- {
- "path": "../classic/classic/src/window/Toast.js",
- "requires": [
- 499
- ],
- "uses": [
- 1
- ],
- "idx": 714
- }
- ],
- "classes": {
- "Ext.AbstractManager": {
- "idx": 6,
- "alias": [],
- "alternates": []
- },
- "Ext.Action": {
- "idx": 416,
- "alias": [],
- "alternates": []
- },
- "Ext.Ajax": {
- "idx": 18,
- "alias": [],
- "alternates": []
- },
- "Ext.AnimationQueue": {
- "idx": 19,
- "alias": [],
- "alternates": []
- },
- "Ext.Component": {
- "idx": 117,
- "alias": [
- "widget.box",
- "widget.component"
- ],
- "alternates": [
- "Ext.AbstractComponent"
- ]
- },
- "Ext.ComponentLoader": {
- "idx": 418,
- "alias": [],
- "alternates": []
- },
- "Ext.ComponentManager": {
- "idx": 21,
- "alias": [],
- "alternates": [
- "Ext.ComponentMgr"
- ]
- },
- "Ext.ComponentQuery": {
- "idx": 24,
- "alias": [],
- "alternates": []
- },
- "Ext.Deferred": {
- "idx": 11,
- "alias": [],
- "alternates": []
- },
- "Ext.Editor": {
- "idx": 426,
- "alias": [
- "widget.editor"
- ],
- "alternates": []
- },
- "Ext.ElementLoader": {
- "idx": 417,
- "alias": [],
- "alternates": []
- },
- "Ext.EventManager": {
- "idx": 427,
- "alias": [],
- "alternates": []
- },
- "Ext.Evented": {
- "idx": 25,
- "alias": [],
- "alternates": [
- "Ext.EventedBase"
- ]
- },
- "Ext.GlobalEvents": {
- "idx": 77,
- "alias": [],
- "alternates": [
- "Ext.globalEvents"
- ]
- },
- "Ext.Glyph": {
- "idx": 78,
- "alias": [],
- "alternates": []
- },
- "Ext.Img": {
- "idx": 429,
- "alias": [
- "widget.image",
- "widget.imagecomponent"
- ],
- "alternates": []
- },
- "Ext.LoadMask": {
- "idx": 431,
- "alias": [
- "widget.loadmask"
- ],
- "alternates": []
- },
- "Ext.Mixin": {
- "idx": 0,
- "alias": [],
- "alternates": []
- },
- "Ext.Progress": {
- "idx": 93,
- "alias": [
- "widget.progress",
- "widget.progressbarwidget"
- ],
- "alternates": [
- "Ext.ProgressBarWidget"
- ]
- },
- "Ext.ProgressBar": {
- "idx": 435,
- "alias": [
- "widget.progressbar"
- ],
- "alternates": []
- },
- "Ext.ProgressBase": {
- "idx": 92,
- "alias": [],
- "alternates": []
- },
- "Ext.Promise": {
- "idx": 10,
- "alias": [],
- "alternates": []
- },
- "Ext.Responsive": {
- "idx": 118,
- "alias": [],
- "alternates": []
- },
- "Ext.ResponsiveWidget": {
- "idx": 91,
- "alias": [],
- "alternates": []
- },
- "Ext.TaskQueue": {
- "idx": 40,
- "alias": [],
- "alternates": []
- },
- "Ext.Template": {
- "idx": 95,
- "alias": [],
- "alternates": []
- },
- "Ext.Widget": {
- "idx": 89,
- "alias": [
- "widget.widget"
- ],
- "alternates": [
- "Ext.Gadget"
- ]
- },
- "Ext.XTemplate": {
- "idx": 98,
- "alias": [],
- "alternates": []
- },
- "Ext.ZIndexManager": {
- "idx": 423,
- "alias": [],
- "alternates": [
- "Ext.WindowGroup"
- ]
- },
- "Ext.app.Application": {
- "idx": 188,
- "alias": [],
- "alternates": []
- },
- "Ext.app.BaseController": {
- "idx": 128,
- "alias": [],
- "alternates": []
- },
- "Ext.app.Controller": {
- "idx": 187,
- "alias": [],
- "alternates": []
- },
- "Ext.app.EventBus": {
- "idx": 120,
- "alias": [],
- "alternates": []
- },
- "Ext.app.EventDomain": {
- "idx": 99,
- "alias": [],
- "alternates": []
- },
- "Ext.app.Profile": {
- "idx": 189,
- "alias": [],
- "alternates": []
- },
- "Ext.app.Util": {
- "idx": 129,
- "alias": [],
- "alternates": []
- },
- "Ext.app.ViewController": {
- "idx": 191,
- "alias": [
- "controller.controller"
- ],
- "alternates": []
- },
- "Ext.app.ViewModel": {
- "idx": 225,
- "alias": [
- "viewmodel.default"
- ],
- "alternates": []
- },
- "Ext.app.bind.AbstractStub": {
- "idx": 206,
- "alias": [],
- "alternates": []
- },
- "Ext.app.bind.BaseBinding": {
- "idx": 204,
- "alias": [],
- "alternates": []
- },
- "Ext.app.bind.Binding": {
- "idx": 205,
- "alias": [],
- "alternates": []
- },
- "Ext.app.bind.Formula": {
- "idx": 211,
- "alias": [],
- "alternates": []
- },
- "Ext.app.bind.LinkStub": {
- "idx": 208,
- "alias": [],
- "alternates": []
- },
- "Ext.app.bind.Multi": {
- "idx": 210,
- "alias": [],
- "alternates": []
- },
- "Ext.app.bind.Parser": {
- "idx": 221,
- "alias": [],
- "alternates": []
- },
- "Ext.app.bind.RootStub": {
- "idx": 209,
- "alias": [],
- "alternates": []
- },
- "Ext.app.bind.Stub": {
- "idx": 207,
- "alias": [],
- "alternates": []
- },
- "Ext.app.bind.Template": {
- "idx": 222,
- "alias": [],
- "alternates": []
- },
- "Ext.app.bind.TemplateBinding": {
- "idx": 223,
- "alias": [],
- "alternates": []
- },
- "Ext.app.domain.Component": {
- "idx": 100,
- "alias": [],
- "alternates": []
- },
- "Ext.app.domain.Controller": {
- "idx": 226,
- "alias": [],
- "alternates": []
- },
- "Ext.app.domain.Direct": {
- "idx": 229,
- "alias": [],
- "alternates": []
- },
- "Ext.app.domain.Global": {
- "idx": 121,
- "alias": [],
- "alternates": []
- },
- "Ext.app.domain.Store": {
- "idx": 186,
- "alias": [],
- "alternates": []
- },
- "Ext.app.domain.View": {
- "idx": 190,
- "alias": [],
- "alternates": []
- },
- "Ext.button.Button": {
- "idx": 439,
- "alias": [
- "widget.button"
- ],
- "alternates": [
- "Ext.Button"
- ]
- },
- "Ext.button.Cycle": {
- "idx": 441,
- "alias": [
- "widget.cycle"
- ],
- "alternates": [
- "Ext.CycleButton"
- ]
- },
- "Ext.button.Manager": {
- "idx": 437,
- "alias": [],
- "alternates": [
- "Ext.ButtonToggleManager"
- ]
- },
- "Ext.button.Segmented": {
- "idx": 443,
- "alias": [
- "widget.segmentedbutton"
- ],
- "alternates": []
- },
- "Ext.button.Split": {
- "idx": 440,
- "alias": [
- "widget.splitbutton"
- ],
- "alternates": [
- "Ext.SplitButton"
- ]
- },
- "Ext.container.ButtonGroup": {
- "idx": 468,
- "alias": [
- "widget.buttongroup"
- ],
- "alternates": [
- "Ext.ButtonGroup"
- ]
- },
- "Ext.container.Container": {
- "idx": 424,
- "alias": [
- "widget.container"
- ],
- "alternates": [
- "Ext.Container",
- "Ext.AbstractContainer"
- ]
- },
- "Ext.container.DockingContainer": {
- "idx": 465,
- "alias": [],
- "alternates": []
- },
- "Ext.container.Monitor": {
- "idx": 469,
- "alias": [],
- "alternates": []
- },
- "Ext.container.Viewport": {
- "idx": 471,
- "alias": [
- "widget.viewport"
- ],
- "alternates": [
- "Ext.Viewport"
- ]
- },
- "Ext.dashboard.Column": {
- "idx": 474,
- "alias": [
- "widget.dashboard-column"
- ],
- "alternates": []
- },
- "Ext.dashboard.Dashboard": {
- "idx": 486,
- "alias": [
- "widget.dashboard"
- ],
- "alternates": []
- },
- "Ext.dashboard.DropZone": {
- "idx": 484,
- "alias": [],
- "alternates": []
- },
- "Ext.dashboard.Panel": {
- "idx": 473,
- "alias": [
- "widget.dashboard-panel"
- ],
- "alternates": []
- },
- "Ext.dashboard.Part": {
- "idx": 485,
- "alias": [
- "part.part"
- ],
- "alternates": []
- },
- "Ext.data.AbstractStore": {
- "idx": 143,
- "alias": [],
- "alternates": []
- },
- "Ext.data.ArrayStore": {
- "idx": 184,
- "alias": [
- "store.array"
- ],
- "alternates": [
- "Ext.data.SimpleStore"
- ]
- },
- "Ext.data.Batch": {
- "idx": 194,
- "alias": [],
- "alternates": []
- },
- "Ext.data.BufferedStore": {
- "idx": 231,
- "alias": [
- "store.buffered"
- ],
- "alternates": []
- },
- "Ext.data.ChainedStore": {
- "idx": 224,
- "alias": [
- "store.chained"
- ],
- "alternates": []
- },
- "Ext.data.ClientStore": {
- "idx": 232,
- "alias": [
- "store.clientstorage"
- ],
- "alternates": []
- },
- "Ext.data.Connection": {
- "idx": 17,
- "alias": [],
- "alternates": []
- },
- "Ext.data.DirectStore": {
- "idx": 234,
- "alias": [
- "store.direct"
- ],
- "alternates": []
- },
- "Ext.data.Error": {
- "idx": 144,
- "alias": [],
- "alternates": []
- },
- "Ext.data.ErrorCollection": {
- "idx": 145,
- "alias": [],
- "alternates": [
- "Ext.data.Errors"
- ]
- },
- "Ext.data.Group": {
- "idx": 172,
- "alias": [],
- "alternates": []
- },
- "Ext.data.JsonP": {
- "idx": 235,
- "alias": [],
- "alternates": []
- },
- "Ext.data.JsonPStore": {
- "idx": 237,
- "alias": [
- "store.jsonp"
- ],
- "alternates": []
- },
- "Ext.data.JsonStore": {
- "idx": 238,
- "alias": [
- "store.json"
- ],
- "alternates": []
- },
- "Ext.data.LocalStore": {
- "idx": 173,
- "alias": [],
- "alternates": []
- },
- "Ext.data.Model": {
- "idx": 163,
- "alias": [],
- "alternates": [
- "Ext.data.Record"
- ]
- },
- "Ext.data.ModelManager": {
- "idx": 239,
- "alias": [],
- "alternates": [
- "Ext.ModelMgr"
- ]
- },
- "Ext.data.NodeInterface": {
- "idx": 240,
- "alias": [],
- "alternates": []
- },
- "Ext.data.NodeStore": {
- "idx": 243,
- "alias": [
- "store.node"
- ],
- "alternates": []
- },
- "Ext.data.PageMap": {
- "idx": 230,
- "alias": [],
- "alternates": []
- },
- "Ext.data.ProxyStore": {
- "idx": 170,
- "alias": [],
- "alternates": []
- },
- "Ext.data.Query": {
- "idx": 248,
- "alias": [
- "query.default"
- ],
- "alternates": []
- },
- "Ext.data.Range": {
- "idx": 133,
- "alias": [],
- "alternates": []
- },
- "Ext.data.Request": {
- "idx": 249,
- "alias": [],
- "alternates": []
- },
- "Ext.data.ResultSet": {
- "idx": 164,
- "alias": [],
- "alternates": []
- },
- "Ext.data.Session": {
- "idx": 202,
- "alias": [],
- "alternates": []
- },
- "Ext.data.SortTypes": {
- "idx": 151,
- "alias": [],
- "alternates": []
- },
- "Ext.data.Store": {
- "idx": 182,
- "alias": [
- "store.store"
- ],
- "alternates": []
- },
- "Ext.data.StoreManager": {
- "idx": 185,
- "alias": [],
- "alternates": [
- "Ext.StoreMgr",
- "Ext.data.StoreMgr",
- "Ext.StoreManager"
- ]
- },
- "Ext.data.TreeModel": {
- "idx": 242,
- "alias": [],
- "alternates": []
- },
- "Ext.data.TreeStore": {
- "idx": 250,
- "alias": [
- "store.tree"
- ],
- "alternates": []
- },
- "Ext.data.Types": {
- "idx": 251,
- "alias": [],
- "alternates": []
- },
- "Ext.data.Validation": {
- "idx": 252,
- "alias": [],
- "alternates": []
- },
- "Ext.data.XmlStore": {
- "idx": 257,
- "alias": [
- "store.xml"
- ],
- "alternates": []
- },
- "Ext.data.field.Array": {
- "idx": 155,
- "alias": [
- "data.field.array"
- ],
- "alternates": []
- },
- "Ext.data.field.Boolean": {
- "idx": 156,
- "alias": [
- "data.field.bool",
- "data.field.boolean"
- ],
- "alternates": []
- },
- "Ext.data.field.Date": {
- "idx": 157,
- "alias": [
- "data.field.date"
- ],
- "alternates": []
- },
- "Ext.data.field.Field": {
- "idx": 154,
- "alias": [
- "data.field.auto"
- ],
- "alternates": [
- "Ext.data.Field"
- ]
- },
- "Ext.data.field.Integer": {
- "idx": 158,
- "alias": [
- "data.field.int",
- "data.field.integer"
- ],
- "alternates": []
- },
- "Ext.data.field.Number": {
- "idx": 159,
- "alias": [
- "data.field.float",
- "data.field.number"
- ],
- "alternates": []
- },
- "Ext.data.field.String": {
- "idx": 160,
- "alias": [
- "data.field.string"
- ],
- "alternates": []
- },
- "Ext.data.flash.BinaryXhr": {
- "idx": 14,
- "alias": [],
- "alternates": []
- },
- "Ext.data.identifier.Generator": {
- "idx": 161,
- "alias": [
- "data.identifier.default"
- ],
- "alternates": []
- },
- "Ext.data.identifier.Negative": {
- "idx": 258,
- "alias": [
- "data.identifier.negative"
- ],
- "alternates": []
- },
- "Ext.data.identifier.Sequential": {
- "idx": 162,
- "alias": [
- "data.identifier.sequential"
- ],
- "alternates": []
- },
- "Ext.data.identifier.Uuid": {
- "idx": 259,
- "alias": [
- "data.identifier.uuid"
- ],
- "alternates": []
- },
- "Ext.data.matrix.Matrix": {
- "idx": 197,
- "alias": [],
- "alternates": []
- },
- "Ext.data.matrix.Side": {
- "idx": 196,
- "alias": [],
- "alternates": []
- },
- "Ext.data.matrix.Slice": {
- "idx": 195,
- "alias": [],
- "alternates": []
- },
- "Ext.data.operation.Create": {
- "idx": 147,
- "alias": [
- "data.operation.create"
- ],
- "alternates": []
- },
- "Ext.data.operation.Destroy": {
- "idx": 148,
- "alias": [
- "data.operation.destroy"
- ],
- "alternates": []
- },
- "Ext.data.operation.Operation": {
- "idx": 146,
- "alias": [],
- "alternates": [
- "Ext.data.Operation"
- ]
- },
- "Ext.data.operation.Read": {
- "idx": 149,
- "alias": [
- "data.operation.read"
- ],
- "alternates": []
- },
- "Ext.data.operation.Update": {
- "idx": 150,
- "alias": [
- "data.operation.update"
- ],
- "alternates": []
- },
- "Ext.data.proxy.Ajax": {
- "idx": 175,
- "alias": [
- "proxy.ajax"
- ],
- "alternates": [
- "Ext.data.HttpProxy",
- "Ext.data.AjaxProxy"
- ]
- },
- "Ext.data.proxy.Client": {
- "idx": 168,
- "alias": [],
- "alternates": [
- "Ext.data.ClientProxy"
- ]
- },
- "Ext.data.proxy.Direct": {
- "idx": 233,
- "alias": [
- "proxy.direct"
- ],
- "alternates": [
- "Ext.data.DirectProxy"
- ]
- },
- "Ext.data.proxy.JsonP": {
- "idx": 236,
- "alias": [
- "proxy.jsonp",
- "proxy.scripttag"
- ],
- "alternates": [
- "Ext.data.ScriptTagProxy"
- ]
- },
- "Ext.data.proxy.LocalStorage": {
- "idx": 261,
- "alias": [
- "proxy.localstorage"
- ],
- "alternates": [
- "Ext.data.LocalStorageProxy"
- ]
- },
- "Ext.data.proxy.Memory": {
- "idx": 169,
- "alias": [
- "proxy.memory"
- ],
- "alternates": [
- "Ext.data.MemoryProxy"
- ]
- },
- "Ext.data.proxy.Proxy": {
- "idx": 167,
- "alias": [
- "proxy.proxy"
- ],
- "alternates": [
- "Ext.data.DataProxy",
- "Ext.data.Proxy"
- ]
- },
- "Ext.data.proxy.Rest": {
- "idx": 262,
- "alias": [
- "proxy.rest"
- ],
- "alternates": [
- "Ext.data.RestProxy"
- ]
- },
- "Ext.data.proxy.Server": {
- "idx": 174,
- "alias": [
- "proxy.server"
- ],
- "alternates": [
- "Ext.data.ServerProxy"
- ]
- },
- "Ext.data.proxy.SessionStorage": {
- "idx": 263,
- "alias": [
- "proxy.sessionstorage"
- ],
- "alternates": [
- "Ext.data.SessionStorageProxy"
- ]
- },
- "Ext.data.proxy.WebStorage": {
- "idx": 260,
- "alias": [],
- "alternates": [
- "Ext.data.WebStorageProxy"
- ]
- },
- "Ext.data.query.Compiler": {
- "idx": 244,
- "alias": [],
- "alternates": []
- },
- "Ext.data.query.Converter": {
- "idx": 245,
- "alias": [],
- "alternates": []
- },
- "Ext.data.query.Parser": {
- "idx": 247,
- "alias": [],
- "alternates": []
- },
- "Ext.data.query.Stringifier": {
- "idx": 246,
- "alias": [],
- "alternates": []
- },
- "Ext.data.reader.Array": {
- "idx": 183,
- "alias": [
- "reader.array"
- ],
- "alternates": [
- "Ext.data.ArrayReader"
- ]
- },
- "Ext.data.reader.Json": {
- "idx": 176,
- "alias": [
- "reader.json"
- ],
- "alternates": [
- "Ext.data.JsonReader"
- ]
- },
- "Ext.data.reader.Reader": {
- "idx": 165,
- "alias": [
- "reader.base"
- ],
- "alternates": [
- "Ext.data.Reader",
- "Ext.data.DataReader"
- ]
- },
- "Ext.data.reader.Xml": {
- "idx": 255,
- "alias": [
- "reader.xml"
- ],
- "alternates": [
- "Ext.data.XmlReader"
- ]
- },
- "Ext.data.request.Ajax": {
- "idx": 15,
- "alias": [
- "request.ajax"
- ],
- "alternates": []
- },
- "Ext.data.request.Base": {
- "idx": 13,
- "alias": [],
- "alternates": []
- },
- "Ext.data.request.Form": {
- "idx": 16,
- "alias": [
- "request.form"
- ],
- "alternates": []
- },
- "Ext.data.schema.Association": {
- "idx": 136,
- "alias": [],
- "alternates": []
- },
- "Ext.data.schema.ManyToMany": {
- "idx": 139,
- "alias": [],
- "alternates": []
- },
- "Ext.data.schema.ManyToOne": {
- "idx": 138,
- "alias": [],
- "alternates": []
- },
- "Ext.data.schema.Namer": {
- "idx": 141,
- "alias": [
- "namer.default"
- ],
- "alternates": []
- },
- "Ext.data.schema.OneToOne": {
- "idx": 137,
- "alias": [],
- "alternates": []
- },
- "Ext.data.schema.Role": {
- "idx": 135,
- "alias": [],
- "alternates": []
- },
- "Ext.data.schema.Schema": {
- "idx": 142,
- "alias": [
- "schema.default"
- ],
- "alternates": []
- },
- "Ext.data.session.BatchVisitor": {
- "idx": 200,
- "alias": [],
- "alternates": []
- },
- "Ext.data.session.ChangesVisitor": {
- "idx": 198,
- "alias": [],
- "alternates": []
- },
- "Ext.data.session.ChildChangesVisitor": {
- "idx": 199,
- "alias": [],
- "alternates": []
- },
- "Ext.data.summary.Average": {
- "idx": 269,
- "alias": [
- "data.summary.average"
- ],
- "alternates": []
- },
- "Ext.data.summary.Base": {
- "idx": 153,
- "alias": [
- "data.summary.base"
- ],
- "alternates": []
- },
- "Ext.data.summary.Count": {
- "idx": 270,
- "alias": [
- "data.summary.count"
- ],
- "alternates": []
- },
- "Ext.data.summary.Max": {
- "idx": 271,
- "alias": [
- "data.summary.max"
- ],
- "alternates": []
- },
- "Ext.data.summary.Min": {
- "idx": 272,
- "alias": [
- "data.summary.min"
- ],
- "alternates": []
- },
- "Ext.data.summary.None": {
- "idx": 273,
- "alias": [
- "data.summary.none"
- ],
- "alternates": []
- },
- "Ext.data.summary.StdDev": {
- "idx": 275,
- "alias": [
- "data.summary.stddev"
- ],
- "alternates": []
- },
- "Ext.data.summary.StdDevP": {
- "idx": 277,
- "alias": [
- "data.summary.stddevp"
- ],
- "alternates": []
- },
- "Ext.data.summary.Sum": {
- "idx": 268,
- "alias": [
- "data.summary.sum"
- ],
- "alternates": []
- },
- "Ext.data.summary.Variance": {
- "idx": 274,
- "alias": [
- "data.summary.variance"
- ],
- "alternates": []
- },
- "Ext.data.summary.VarianceP": {
- "idx": 276,
- "alias": [
- "data.summary.variancep"
- ],
- "alternates": []
- },
- "Ext.data.validator.AbstractDate": {
- "idx": 278,
- "alias": [],
- "alternates": []
- },
- "Ext.data.validator.Bound": {
- "idx": 279,
- "alias": [
- "data.validator.bound"
- ],
- "alternates": []
- },
- "Ext.data.validator.CIDRv4": {
- "idx": 281,
- "alias": [
- "data.validator.cidrv4"
- ],
- "alternates": []
- },
- "Ext.data.validator.CIDRv6": {
- "idx": 282,
- "alias": [
- "data.validator.cidrv6"
- ],
- "alternates": []
- },
- "Ext.data.validator.Currency": {
- "idx": 284,
- "alias": [
- "data.validator.currency"
- ],
- "alternates": []
- },
- "Ext.data.validator.CurrencyUS": {
- "idx": 285,
- "alias": [
- "data.validator.currency-us"
- ],
- "alternates": []
- },
- "Ext.data.validator.Date": {
- "idx": 286,
- "alias": [
- "data.validator.date"
- ],
- "alternates": []
- },
- "Ext.data.validator.DateTime": {
- "idx": 287,
- "alias": [
- "data.validator.datetime"
- ],
- "alternates": []
- },
- "Ext.data.validator.Email": {
- "idx": 288,
- "alias": [
- "data.validator.email"
- ],
- "alternates": []
- },
- "Ext.data.validator.Exclusion": {
- "idx": 290,
- "alias": [
- "data.validator.exclusion"
- ],
- "alternates": []
- },
- "Ext.data.validator.Format": {
- "idx": 280,
- "alias": [
- "data.validator.format"
- ],
- "alternates": []
- },
- "Ext.data.validator.IPAddress": {
- "idx": 291,
- "alias": [
- "data.validator.ipaddress"
- ],
- "alternates": []
- },
- "Ext.data.validator.Inclusion": {
- "idx": 292,
- "alias": [
- "data.validator.inclusion"
- ],
- "alternates": []
- },
- "Ext.data.validator.Length": {
- "idx": 293,
- "alias": [
- "data.validator.length"
- ],
- "alternates": []
- },
- "Ext.data.validator.List": {
- "idx": 289,
- "alias": [
- "data.validator.list"
- ],
- "alternates": []
- },
- "Ext.data.validator.NotNull": {
- "idx": 295,
- "alias": [
- "data.validator.notnull"
- ],
- "alternates": []
- },
- "Ext.data.validator.Number": {
- "idx": 283,
- "alias": [
- "data.validator.number"
- ],
- "alternates": []
- },
- "Ext.data.validator.Phone": {
- "idx": 296,
- "alias": [
- "data.validator.phone"
- ],
- "alternates": []
- },
- "Ext.data.validator.Presence": {
- "idx": 294,
- "alias": [
- "data.validator.presence"
- ],
- "alternates": []
- },
- "Ext.data.validator.Range": {
- "idx": 297,
- "alias": [
- "data.validator.range"
- ],
- "alternates": []
- },
- "Ext.data.validator.Time": {
- "idx": 298,
- "alias": [
- "data.validator.time"
- ],
- "alternates": []
- },
- "Ext.data.validator.Url": {
- "idx": 299,
- "alias": [
- "data.validator.url"
- ],
- "alternates": []
- },
- "Ext.data.validator.Validator": {
- "idx": 152,
- "alias": [
- "data.validator.base"
- ],
- "alternates": []
- },
- "Ext.data.virtual.Group": {
- "idx": 300,
- "alias": [],
- "alternates": []
- },
- "Ext.data.virtual.Page": {
- "idx": 301,
- "alias": [],
- "alternates": []
- },
- "Ext.data.virtual.PageMap": {
- "idx": 302,
- "alias": [],
- "alternates": []
- },
- "Ext.data.virtual.Range": {
- "idx": 303,
- "alias": [],
- "alternates": []
- },
- "Ext.data.virtual.Store": {
- "idx": 304,
- "alias": [
- "store.virtual"
- ],
- "alternates": []
- },
- "Ext.data.writer.Json": {
- "idx": 177,
- "alias": [
- "writer.json"
- ],
- "alternates": [
- "Ext.data.JsonWriter"
- ]
- },
- "Ext.data.writer.Writer": {
- "idx": 166,
- "alias": [
- "writer.base"
- ],
- "alternates": [
- "Ext.data.DataWriter",
- "Ext.data.Writer"
- ]
- },
- "Ext.data.writer.Xml": {
- "idx": 256,
- "alias": [
- "writer.xml"
- ],
- "alternates": [
- "Ext.data.XmlWriter"
- ]
- },
- "Ext.dd.DD": {
- "idx": 457,
- "alias": [],
- "alternates": []
- },
- "Ext.dd.DDProxy": {
- "idx": 458,
- "alias": [],
- "alternates": []
- },
- "Ext.dd.DDTarget": {
- "idx": 481,
- "alias": [],
- "alternates": []
- },
- "Ext.dd.DragDrop": {
- "idx": 456,
- "alias": [],
- "alternates": []
- },
- "Ext.dd.DragDropManager": {
- "idx": 450,
- "alias": [],
- "alternates": [
- "Ext.dd.DragDropMgr",
- "Ext.dd.DDM"
- ]
- },
- "Ext.dd.DragSource": {
- "idx": 460,
- "alias": [],
- "alternates": []
- },
- "Ext.dd.DragTracker": {
- "idx": 476,
- "alias": [],
- "alternates": []
- },
- "Ext.dd.DragZone": {
- "idx": 487,
- "alias": [],
- "alternates": []
- },
- "Ext.dd.DropTarget": {
- "idx": 483,
- "alias": [],
- "alternates": []
- },
- "Ext.dd.DropZone": {
- "idx": 489,
- "alias": [],
- "alternates": []
- },
- "Ext.dd.Registry": {
- "idx": 488,
- "alias": [],
- "alternates": []
- },
- "Ext.dd.ScrollManager": {
- "idx": 482,
- "alias": [],
- "alternates": []
- },
- "Ext.dd.StatusProxy": {
- "idx": 459,
- "alias": [],
- "alternates": []
- },
- "Ext.direct.Event": {
- "idx": 305,
- "alias": [
- "direct.event"
- ],
- "alternates": []
- },
- "Ext.direct.ExceptionEvent": {
- "idx": 307,
- "alias": [
- "direct.exception"
- ],
- "alternates": []
- },
- "Ext.direct.JsonProvider": {
- "idx": 308,
- "alias": [
- "direct.jsonprovider"
- ],
- "alternates": []
- },
- "Ext.direct.Manager": {
- "idx": 227,
- "alias": [],
- "alternates": []
- },
- "Ext.direct.PollingProvider": {
- "idx": 309,
- "alias": [
- "direct.pollingprovider"
- ],
- "alternates": []
- },
- "Ext.direct.Provider": {
- "idx": 228,
- "alias": [
- "direct.provider"
- ],
- "alternates": []
- },
- "Ext.direct.RemotingEvent": {
- "idx": 306,
- "alias": [
- "direct.rpc"
- ],
- "alternates": []
- },
- "Ext.direct.RemotingMethod": {
- "idx": 310,
- "alias": [],
- "alternates": []
- },
- "Ext.direct.RemotingProvider": {
- "idx": 312,
- "alias": [
- "direct.remotingprovider"
- ],
- "alternates": []
- },
- "Ext.direct.Transaction": {
- "idx": 311,
- "alias": [
- "direct.transaction"
- ],
- "alternates": []
- },
- "Ext.dom.ButtonElement": {
- "idx": 436,
- "alias": [],
- "alternates": []
- },
- "Ext.dom.CompositeElement": {
- "idx": 102,
- "alias": [],
- "alternates": [
- "Ext.CompositeElement"
- ]
- },
- "Ext.dom.CompositeElementLite": {
- "idx": 76,
- "alias": [],
- "alternates": [
- "Ext.CompositeElementLite"
- ]
- },
- "Ext.dom.Element": {
- "idx": 49,
- "alias": [],
- "alternates": [
- "Ext.Element"
- ]
- },
- "Ext.dom.ElementEvent": {
- "idx": 31,
- "alias": [],
- "alternates": []
- },
- "Ext.dom.Fly": {
- "idx": 75,
- "alias": [],
- "alternates": [
- "Ext.dom.Element.Fly"
- ]
- },
- "Ext.dom.GarbageCollector": {
- "idx": 313,
- "alias": [],
- "alternates": []
- },
- "Ext.dom.Helper": {
- "idx": 253,
- "alias": [],
- "alternates": [
- "Ext.DomHelper",
- "Ext.core.DomHelper"
- ]
- },
- "Ext.dom.Layer": {
- "idx": 490,
- "alias": [],
- "alternates": [
- "Ext.Layer"
- ]
- },
- "Ext.dom.Query": {
- "idx": 254,
- "alias": [],
- "alternates": [
- "Ext.core.DomQuery",
- "Ext.DomQuery"
- ]
- },
- "Ext.dom.Shadow": {
- "idx": 29,
- "alias": [],
- "alternates": [
- "Ext.Shadow"
- ]
- },
- "Ext.dom.Shim": {
- "idx": 30,
- "alias": [],
- "alternates": []
- },
- "Ext.dom.TouchAction": {
- "idx": 314,
- "alias": [],
- "alternates": []
- },
- "Ext.dom.Underlay": {
- "idx": 28,
- "alias": [],
- "alternates": []
- },
- "Ext.dom.UnderlayPool": {
- "idx": 27,
- "alias": [],
- "alternates": []
- },
- "Ext.drag.Constraint": {
- "idx": 315,
- "alias": [
- "drag.constraint.base"
- ],
- "alternates": []
- },
- "Ext.drag.Info": {
- "idx": 316,
- "alias": [],
- "alternates": []
- },
- "Ext.drag.Item": {
- "idx": 317,
- "alias": [],
- "alternates": []
- },
- "Ext.drag.Manager": {
- "idx": 318,
- "alias": [],
- "alternates": []
- },
- "Ext.drag.Source": {
- "idx": 319,
- "alias": [],
- "alternates": []
- },
- "Ext.drag.Target": {
- "idx": 320,
- "alias": [],
- "alternates": []
- },
- "Ext.drag.proxy.None": {
- "idx": 321,
- "alias": [
- "drag.proxy.none"
- ],
- "alternates": []
- },
- "Ext.drag.proxy.Original": {
- "idx": 322,
- "alias": [
- "drag.proxy.original"
- ],
- "alternates": []
- },
- "Ext.drag.proxy.Placeholder": {
- "idx": 323,
- "alias": [
- "drag.proxy.placeholder"
- ],
- "alternates": []
- },
- "Ext.event.Event": {
- "idx": 36,
- "alias": [],
- "alternates": [
- "Ext.EventObjectImpl"
- ]
- },
- "Ext.event.gesture.DoubleTap": {
- "idx": 326,
- "alias": [],
- "alternates": []
- },
- "Ext.event.gesture.Drag": {
- "idx": 327,
- "alias": [],
- "alternates": []
- },
- "Ext.event.gesture.EdgeSwipe": {
- "idx": 329,
- "alias": [],
- "alternates": []
- },
- "Ext.event.gesture.LongPress": {
- "idx": 330,
- "alias": [],
- "alternates": []
- },
- "Ext.event.gesture.MultiTouch": {
- "idx": 331,
- "alias": [],
- "alternates": []
- },
- "Ext.event.gesture.Pinch": {
- "idx": 332,
- "alias": [],
- "alternates": []
- },
- "Ext.event.gesture.Recognizer": {
- "idx": 324,
- "alias": [],
- "alternates": []
- },
- "Ext.event.gesture.Rotate": {
- "idx": 333,
- "alias": [],
- "alternates": []
- },
- "Ext.event.gesture.SingleTouch": {
- "idx": 325,
- "alias": [],
- "alternates": []
- },
- "Ext.event.gesture.Swipe": {
- "idx": 328,
- "alias": [],
- "alternates": []
- },
- "Ext.event.gesture.Tap": {
- "idx": 334,
- "alias": [],
- "alternates": []
- },
- "Ext.event.publisher.Dom": {
- "idx": 37,
- "alias": [],
- "alternates": []
- },
- "Ext.event.publisher.ElementPaint": {
- "idx": 48,
- "alias": [],
- "alternates": []
- },
- "Ext.event.publisher.ElementSize": {
- "idx": 44,
- "alias": [],
- "alternates": []
- },
- "Ext.event.publisher.Focus": {
- "idx": 335,
- "alias": [],
- "alternates": []
- },
- "Ext.event.publisher.Gesture": {
- "idx": 38,
- "alias": [],
- "alternates": []
- },
- "Ext.event.publisher.MouseEnterLeave": {
- "idx": 492,
- "alias": [],
- "alternates": []
- },
- "Ext.event.publisher.Publisher": {
- "idx": 32,
- "alias": [],
- "alternates": []
- },
- "Ext.field.InputMask": {
- "idx": 336,
- "alias": [],
- "alternates": []
- },
- "Ext.flash.Component": {
- "idx": 493,
- "alias": [
- "widget.flash"
- ],
- "alternates": [
- "Ext.FlashComponent"
- ]
- },
- "Ext.form.Basic": {
- "idx": 509,
- "alias": [],
- "alternates": [
- "Ext.form.BasicForm"
- ]
- },
- "Ext.form.CheckboxGroup": {
- "idx": 516,
- "alias": [
- "widget.checkboxgroup"
- ],
- "alternates": []
- },
- "Ext.form.CheckboxManager": {
- "idx": 514,
- "alias": [],
- "alternates": []
- },
- "Ext.form.FieldAncestor": {
- "idx": 511,
- "alias": [],
- "alternates": []
- },
- "Ext.form.FieldContainer": {
- "idx": 512,
- "alias": [
- "widget.fieldcontainer"
- ],
- "alternates": []
- },
- "Ext.form.FieldSet": {
- "idx": 517,
- "alias": [
- "widget.fieldset"
- ],
- "alternates": []
- },
- "Ext.form.Label": {
- "idx": 518,
- "alias": [
- "widget.label"
- ],
- "alternates": []
- },
- "Ext.form.Labelable": {
- "idx": 500,
- "alias": [],
- "alternates": []
- },
- "Ext.form.Panel": {
- "idx": 519,
- "alias": [
- "widget.form"
- ],
- "alternates": [
- "Ext.FormPanel",
- "Ext.form.FormPanel"
- ]
- },
- "Ext.form.RadioGroup": {
- "idx": 522,
- "alias": [
- "widget.radiogroup"
- ],
- "alternates": []
- },
- "Ext.form.RadioManager": {
- "idx": 520,
- "alias": [],
- "alternates": []
- },
- "Ext.form.action.Action": {
- "idx": 494,
- "alias": [],
- "alternates": [
- "Ext.form.Action"
- ]
- },
- "Ext.form.action.DirectAction": {
- "idx": 523,
- "alias": [],
- "alternates": []
- },
- "Ext.form.action.DirectLoad": {
- "idx": 524,
- "alias": [
- "formaction.directload"
- ],
- "alternates": [
- "Ext.form.Action.DirectLoad"
- ]
- },
- "Ext.form.action.DirectSubmit": {
- "idx": 525,
- "alias": [
- "formaction.directsubmit"
- ],
- "alternates": [
- "Ext.form.Action.DirectSubmit"
- ]
- },
- "Ext.form.action.Load": {
- "idx": 495,
- "alias": [
- "formaction.load"
- ],
- "alternates": [
- "Ext.form.Action.Load"
- ]
- },
- "Ext.form.action.StandardSubmit": {
- "idx": 497,
- "alias": [
- "formaction.standardsubmit"
- ],
- "alternates": []
- },
- "Ext.form.action.Submit": {
- "idx": 496,
- "alias": [
- "formaction.submit"
- ],
- "alternates": [
- "Ext.form.Action.Submit"
- ]
- },
- "Ext.form.field.Base": {
- "idx": 502,
- "alias": [
- "widget.field"
- ],
- "alternates": [
- "Ext.form.Field",
- "Ext.form.BaseField"
- ]
- },
- "Ext.form.field.Checkbox": {
- "idx": 515,
- "alias": [
- "widget.checkbox",
- "widget.checkboxfield"
- ],
- "alternates": [
- "Ext.form.Checkbox"
- ]
- },
- "Ext.form.field.ComboBox": {
- "idx": 541,
- "alias": [
- "widget.combo",
- "widget.combobox"
- ],
- "alternates": [
- "Ext.form.ComboBox"
- ]
- },
- "Ext.form.field.Date": {
- "idx": 544,
- "alias": [
- "widget.datefield"
- ],
- "alternates": [
- "Ext.form.DateField",
- "Ext.form.Date"
- ]
- },
- "Ext.form.field.Display": {
- "idx": 545,
- "alias": [
- "widget.displayfield"
- ],
- "alternates": [
- "Ext.form.DisplayField",
- "Ext.form.Display"
- ]
- },
- "Ext.form.field.Field": {
- "idx": 501,
- "alias": [],
- "alternates": []
- },
- "Ext.form.field.File": {
- "idx": 548,
- "alias": [
- "widget.filefield",
- "widget.fileuploadfield"
- ],
- "alternates": [
- "Ext.form.FileUploadField",
- "Ext.ux.form.FileUploadField",
- "Ext.form.File"
- ]
- },
- "Ext.form.field.FileButton": {
- "idx": 546,
- "alias": [
- "widget.filebutton"
- ],
- "alternates": []
- },
- "Ext.form.field.Hidden": {
- "idx": 549,
- "alias": [
- "widget.hidden",
- "widget.hiddenfield"
- ],
- "alternates": [
- "Ext.form.Hidden"
- ]
- },
- "Ext.form.field.HtmlEditor": {
- "idx": 558,
- "alias": [
- "widget.htmleditor"
- ],
- "alternates": [
- "Ext.form.HtmlEditor"
- ]
- },
- "Ext.form.field.Number": {
- "idx": 538,
- "alias": [
- "widget.numberfield"
- ],
- "alternates": [
- "Ext.form.NumberField",
- "Ext.form.Number"
- ]
- },
- "Ext.form.field.Picker": {
- "idx": 526,
- "alias": [
- "widget.pickerfield"
- ],
- "alternates": [
- "Ext.form.Picker"
- ]
- },
- "Ext.form.field.Radio": {
- "idx": 521,
- "alias": [
- "widget.radio",
- "widget.radiofield"
- ],
- "alternates": [
- "Ext.form.Radio"
- ]
- },
- "Ext.form.field.Spinner": {
- "idx": 537,
- "alias": [
- "widget.spinnerfield"
- ],
- "alternates": [
- "Ext.form.Spinner"
- ]
- },
- "Ext.form.field.Tag": {
- "idx": 560,
- "alias": [
- "widget.tagfield"
- ],
- "alternates": []
- },
- "Ext.form.field.Text": {
- "idx": 506,
- "alias": [
- "widget.textfield"
- ],
- "alternates": [
- "Ext.form.TextField",
- "Ext.form.Text"
- ]
- },
- "Ext.form.field.TextArea": {
- "idx": 507,
- "alias": [
- "widget.textarea",
- "widget.textareafield"
- ],
- "alternates": [
- "Ext.form.TextArea"
- ]
- },
- "Ext.form.field.Time": {
- "idx": 562,
- "alias": [
- "widget.timefield"
- ],
- "alternates": [
- "Ext.form.TimeField",
- "Ext.form.Time"
- ]
- },
- "Ext.form.field.Trigger": {
- "idx": 563,
- "alias": [
- "widget.trigger",
- "widget.triggerfield"
- ],
- "alternates": [
- "Ext.form.TriggerField",
- "Ext.form.TwinTriggerField",
- "Ext.form.Trigger"
- ]
- },
- "Ext.form.field.VTypes": {
- "idx": 504,
- "alias": [],
- "alternates": [
- "Ext.form.VTypes"
- ]
- },
- "Ext.form.trigger.Component": {
- "idx": 547,
- "alias": [
- "trigger.component"
- ],
- "alternates": []
- },
- "Ext.form.trigger.Spinner": {
- "idx": 536,
- "alias": [
- "trigger.spinner"
- ],
- "alternates": []
- },
- "Ext.form.trigger.Trigger": {
- "idx": 505,
- "alias": [
- "trigger.trigger"
- ],
- "alternates": []
- },
- "Ext.fx.Anim": {
- "idx": 73,
- "alias": [],
- "alternates": []
- },
- "Ext.fx.Animation": {
- "idx": 346,
- "alias": [],
- "alternates": []
- },
- "Ext.fx.Animator": {
- "idx": 68,
- "alias": [],
- "alternates": []
- },
- "Ext.fx.CubicBezier": {
- "idx": 69,
- "alias": [],
- "alternates": []
- },
- "Ext.fx.DrawPath": {
- "idx": 71,
- "alias": [],
- "alternates": []
- },
- "Ext.fx.Easing": {
- "idx": 70,
- "alias": [],
- "alternates": []
- },
- "Ext.fx.Manager": {
- "idx": 67,
- "alias": [],
- "alternates": []
- },
- "Ext.fx.PropertyHandler": {
- "idx": 72,
- "alias": [],
- "alternates": []
- },
- "Ext.fx.Queue": {
- "idx": 66,
- "alias": [],
- "alternates": []
- },
- "Ext.fx.Runner": {
- "idx": 349,
- "alias": [],
- "alternates": []
- },
- "Ext.fx.State": {
- "idx": 337,
- "alias": [],
- "alternates": []
- },
- "Ext.fx.animation.Abstract": {
- "idx": 338,
- "alias": [],
- "alternates": []
- },
- "Ext.fx.animation.Cube": {
- "idx": 350,
- "alias": [
- "animation.cube"
- ],
- "alternates": []
- },
- "Ext.fx.animation.Fade": {
- "idx": 341,
- "alias": [
- "animation.fade",
- "animation.fadeIn"
- ],
- "alternates": [
- "Ext.fx.animation.FadeIn"
- ]
- },
- "Ext.fx.animation.FadeOut": {
- "idx": 342,
- "alias": [
- "animation.fadeOut"
- ],
- "alternates": []
- },
- "Ext.fx.animation.Flip": {
- "idx": 343,
- "alias": [
- "animation.flip"
- ],
- "alternates": []
- },
- "Ext.fx.animation.Pop": {
- "idx": 344,
- "alias": [
- "animation.pop",
- "animation.popIn"
- ],
- "alternates": [
- "Ext.fx.animation.PopIn"
- ]
- },
- "Ext.fx.animation.PopOut": {
- "idx": 345,
- "alias": [
- "animation.popOut"
- ],
- "alternates": []
- },
- "Ext.fx.animation.Slide": {
- "idx": 339,
- "alias": [
- "animation.slide",
- "animation.slideIn"
- ],
- "alternates": [
- "Ext.fx.animation.SlideIn"
- ]
- },
- "Ext.fx.animation.SlideOut": {
- "idx": 340,
- "alias": [
- "animation.slideOut"
- ],
- "alternates": []
- },
- "Ext.fx.animation.Wipe": {
- "idx": 351,
- "alias": [],
- "alternates": [
- "Ext.fx.animation.WipeIn"
- ]
- },
- "Ext.fx.animation.WipeOut": {
- "idx": 352,
- "alias": [],
- "alternates": []
- },
- "Ext.fx.easing.Abstract": {
- "idx": 105,
- "alias": [],
- "alternates": []
- },
- "Ext.fx.easing.Bounce": {
- "idx": 353,
- "alias": [],
- "alternates": []
- },
- "Ext.fx.easing.BoundMomentum": {
- "idx": 355,
- "alias": [],
- "alternates": []
- },
- "Ext.fx.easing.EaseIn": {
- "idx": 356,
- "alias": [
- "easing.ease-in"
- ],
- "alternates": []
- },
- "Ext.fx.easing.EaseOut": {
- "idx": 357,
- "alias": [
- "easing.ease-out"
- ],
- "alternates": []
- },
- "Ext.fx.easing.Easing": {
- "idx": 358,
- "alias": [],
- "alternates": []
- },
- "Ext.fx.easing.Linear": {
- "idx": 106,
- "alias": [
- "easing.linear"
- ],
- "alternates": []
- },
- "Ext.fx.easing.Momentum": {
- "idx": 354,
- "alias": [],
- "alternates": []
- },
- "Ext.fx.runner.Css": {
- "idx": 347,
- "alias": [],
- "alternates": []
- },
- "Ext.fx.runner.CssAnimation": {
- "idx": 359,
- "alias": [],
- "alternates": []
- },
- "Ext.fx.runner.CssTransition": {
- "idx": 348,
- "alias": [],
- "alternates": [
- "Ext.Animator"
- ]
- },
- "Ext.fx.target.Component": {
- "idx": 65,
- "alias": [],
- "alternates": []
- },
- "Ext.fx.target.CompositeElement": {
- "idx": 61,
- "alias": [],
- "alternates": []
- },
- "Ext.fx.target.CompositeElementCSS": {
- "idx": 62,
- "alias": [],
- "alternates": []
- },
- "Ext.fx.target.CompositeSprite": {
- "idx": 64,
- "alias": [],
- "alternates": []
- },
- "Ext.fx.target.Element": {
- "idx": 59,
- "alias": [],
- "alternates": []
- },
- "Ext.fx.target.ElementCSS": {
- "idx": 60,
- "alias": [],
- "alternates": []
- },
- "Ext.fx.target.Sprite": {
- "idx": 63,
- "alias": [],
- "alternates": []
- },
- "Ext.fx.target.Target": {
- "idx": 58,
- "alias": [],
- "alternates": []
- },
- "Ext.grid.AdvancedGroupStore": {
- "idx": 360,
- "alias": [],
- "alternates": []
- },
- "Ext.grid.CellContext": {
- "idx": 564,
- "alias": [],
- "alternates": []
- },
- "Ext.grid.CellEditor": {
- "idx": 565,
- "alias": [
- "widget.celleditor"
- ],
- "alternates": []
- },
- "Ext.grid.ColumnComponentLayout": {
- "idx": 566,
- "alias": [
- "layout.columncomponent"
- ],
- "alternates": []
- },
- "Ext.grid.ColumnLayout": {
- "idx": 569,
- "alias": [
- "layout.gridcolumn"
- ],
- "alternates": []
- },
- "Ext.grid.ColumnManager": {
- "idx": 570,
- "alias": [],
- "alternates": [
- "Ext.grid.ColumnModel"
- ]
- },
- "Ext.grid.NavigationModel": {
- "idx": 571,
- "alias": [
- "view.navigation.grid"
- ],
- "alternates": []
- },
- "Ext.grid.Panel": {
- "idx": 577,
- "alias": [
- "widget.grid",
- "widget.gridpanel"
- ],
- "alternates": [
- "Ext.list.ListView",
- "Ext.ListView",
- "Ext.grid.GridPanel"
- ]
- },
- "Ext.grid.RowContext": {
- "idx": 578,
- "alias": [],
- "alternates": []
- },
- "Ext.grid.RowEditor": {
- "idx": 580,
- "alias": [
- "widget.roweditor"
- ],
- "alternates": []
- },
- "Ext.grid.RowEditorButtons": {
- "idx": 579,
- "alias": [
- "widget.roweditorbuttons"
- ],
- "alternates": []
- },
- "Ext.grid.Scroller": {
- "idx": 581,
- "alias": [],
- "alternates": []
- },
- "Ext.grid.ViewDropZone": {
- "idx": 583,
- "alias": [],
- "alternates": []
- },
- "Ext.grid.column.Action": {
- "idx": 591,
- "alias": [
- "widget.actioncolumn"
- ],
- "alternates": [
- "Ext.grid.ActionColumn"
- ]
- },
- "Ext.grid.column.ActionProxy": {
- "idx": 590,
- "alias": [],
- "alternates": []
- },
- "Ext.grid.column.Boolean": {
- "idx": 592,
- "alias": [
- "widget.booleancolumn"
- ],
- "alternates": [
- "Ext.grid.BooleanColumn"
- ]
- },
- "Ext.grid.column.Check": {
- "idx": 593,
- "alias": [
- "widget.checkcolumn"
- ],
- "alternates": [
- "Ext.ux.CheckColumn",
- "Ext.grid.column.CheckColumn"
- ]
- },
- "Ext.grid.column.Column": {
- "idx": 589,
- "alias": [
- "widget.gridcolumn"
- ],
- "alternates": [
- "Ext.grid.Column"
- ]
- },
- "Ext.grid.column.Date": {
- "idx": 594,
- "alias": [
- "widget.datecolumn"
- ],
- "alternates": [
- "Ext.grid.DateColumn"
- ]
- },
- "Ext.grid.column.Groups": {
- "idx": 595,
- "alias": [
- "widget.groupscolumn"
- ],
- "alternates": []
- },
- "Ext.grid.column.Number": {
- "idx": 596,
- "alias": [
- "widget.numbercolumn"
- ],
- "alternates": [
- "Ext.grid.NumberColumn"
- ]
- },
- "Ext.grid.column.RowNumberer": {
- "idx": 597,
- "alias": [
- "widget.rownumberer"
- ],
- "alternates": [
- "Ext.grid.RowNumberer"
- ]
- },
- "Ext.grid.column.Template": {
- "idx": 598,
- "alias": [
- "widget.templatecolumn"
- ],
- "alternates": [
- "Ext.grid.TemplateColumn"
- ]
- },
- "Ext.grid.column.Widget": {
- "idx": 599,
- "alias": [
- "widget.widgetcolumn"
- ],
- "alternates": []
- },
- "Ext.grid.feature.AbstractSummary": {
- "idx": 601,
- "alias": [
- "feature.abstractsummary"
- ],
- "alternates": []
- },
- "Ext.grid.feature.AdvancedGroupStore": {
- "idx": 602,
- "alias": [],
- "alternates": []
- },
- "Ext.grid.feature.AdvancedGrouping": {
- "idx": 603,
- "alias": [
- "feature.advancedgrouping"
- ],
- "alternates": []
- },
- "Ext.grid.feature.AdvancedGroupingSummary": {
- "idx": 604,
- "alias": [
- "feature.advancedgroupingsummary"
- ],
- "alternates": []
- },
- "Ext.grid.feature.Feature": {
- "idx": 600,
- "alias": [
- "feature.feature"
- ],
- "alternates": []
- },
- "Ext.grid.feature.GroupStore": {
- "idx": 605,
- "alias": [],
- "alternates": []
- },
- "Ext.grid.feature.Grouping": {
- "idx": 606,
- "alias": [
- "feature.grouping"
- ],
- "alternates": []
- },
- "Ext.grid.feature.GroupingSummary": {
- "idx": 607,
- "alias": [
- "feature.groupingsummary"
- ],
- "alternates": []
- },
- "Ext.grid.feature.RowBody": {
- "idx": 608,
- "alias": [
- "feature.rowbody"
- ],
- "alternates": []
- },
- "Ext.grid.feature.Summary": {
- "idx": 609,
- "alias": [
- "feature.summary"
- ],
- "alternates": []
- },
- "Ext.grid.filters.Filters": {
- "idx": 622,
- "alias": [
- "plugin.gridfilters"
- ],
- "alternates": []
- },
- "Ext.grid.filters.filter.Base": {
- "idx": 614,
- "alias": [],
- "alternates": []
- },
- "Ext.grid.filters.filter.Boolean": {
- "idx": 616,
- "alias": [
- "grid.filter.boolean"
- ],
- "alternates": []
- },
- "Ext.grid.filters.filter.Date": {
- "idx": 618,
- "alias": [
- "grid.filter.date"
- ],
- "alternates": []
- },
- "Ext.grid.filters.filter.List": {
- "idx": 619,
- "alias": [
- "grid.filter.list"
- ],
- "alternates": []
- },
- "Ext.grid.filters.filter.Number": {
- "idx": 620,
- "alias": [
- "grid.filter.number",
- "grid.filter.numeric"
- ],
- "alternates": []
- },
- "Ext.grid.filters.filter.SingleFilter": {
- "idx": 615,
- "alias": [],
- "alternates": []
- },
- "Ext.grid.filters.filter.String": {
- "idx": 621,
- "alias": [
- "grid.filter.string"
- ],
- "alternates": []
- },
- "Ext.grid.filters.filter.TriFilter": {
- "idx": 617,
- "alias": [],
- "alternates": []
- },
- "Ext.grid.header.Container": {
- "idx": 588,
- "alias": [
- "widget.headercontainer"
- ],
- "alternates": []
- },
- "Ext.grid.header.DragZone": {
- "idx": 585,
- "alias": [],
- "alternates": []
- },
- "Ext.grid.header.DropZone": {
- "idx": 586,
- "alias": [],
- "alternates": []
- },
- "Ext.grid.locking.HeaderContainer": {
- "idx": 623,
- "alias": [],
- "alternates": []
- },
- "Ext.grid.locking.Lockable": {
- "idx": 626,
- "alias": [],
- "alternates": [
- "Ext.grid.Lockable"
- ]
- },
- "Ext.grid.locking.RowSynchronizer": {
- "idx": 573,
- "alias": [],
- "alternates": []
- },
- "Ext.grid.locking.View": {
- "idx": 624,
- "alias": [],
- "alternates": [
- "Ext.grid.LockingView"
- ]
- },
- "Ext.grid.plugin.BaseFilterBar": {
- "idx": 361,
- "alias": [],
- "alternates": []
- },
- "Ext.grid.plugin.BaseGroupingPanel": {
- "idx": 362,
- "alias": [],
- "alternates": []
- },
- "Ext.grid.plugin.BaseSummaries": {
- "idx": 363,
- "alias": [],
- "alternates": []
- },
- "Ext.grid.plugin.BufferedRenderer": {
- "idx": 627,
- "alias": [
- "plugin.bufferedrenderer"
- ],
- "alternates": []
- },
- "Ext.grid.plugin.CellEditing": {
- "idx": 629,
- "alias": [
- "plugin.cellediting"
- ],
- "alternates": []
- },
- "Ext.grid.plugin.Clipboard": {
- "idx": 630,
- "alias": [
- "plugin.clipboard"
- ],
- "alternates": []
- },
- "Ext.grid.plugin.DragDrop": {
- "idx": 631,
- "alias": [
- "plugin.gridviewdragdrop"
- ],
- "alternates": []
- },
- "Ext.grid.plugin.Editing": {
- "idx": 628,
- "alias": [
- "editing.editing"
- ],
- "alternates": []
- },
- "Ext.grid.plugin.GroupingPanel": {
- "idx": 636,
- "alias": [
- "plugin.groupingpanel"
- ],
- "alternates": []
- },
- "Ext.grid.plugin.HeaderReorderer": {
- "idx": 587,
- "alias": [
- "plugin.gridheaderreorderer"
- ],
- "alternates": []
- },
- "Ext.grid.plugin.HeaderResizer": {
- "idx": 584,
- "alias": [
- "plugin.gridheaderresizer"
- ],
- "alternates": []
- },
- "Ext.grid.plugin.RowEditing": {
- "idx": 637,
- "alias": [
- "plugin.rowediting"
- ],
- "alternates": []
- },
- "Ext.grid.plugin.RowExpander": {
- "idx": 638,
- "alias": [
- "plugin.rowexpander"
- ],
- "alternates": []
- },
- "Ext.grid.plugin.RowWidget": {
- "idx": 639,
- "alias": [
- "plugin.rowwidget"
- ],
- "alternates": []
- },
- "Ext.grid.plugin.Summaries": {
- "idx": 640,
- "alias": [
- "plugin.gridsummaries"
- ],
- "alternates": []
- },
- "Ext.grid.plugin.filterbar.FilterBar": {
- "idx": 651,
- "alias": [
- "plugin.gridfilterbar"
- ],
- "alternates": []
- },
- "Ext.grid.plugin.filterbar.Operator": {
- "idx": 641,
- "alias": [
- "plugin.operator"
- ],
- "alternates": []
- },
- "Ext.grid.plugin.filterbar.filters.Base": {
- "idx": 642,
- "alias": [],
- "alternates": []
- },
- "Ext.grid.plugin.filterbar.filters.Boolean": {
- "idx": 647,
- "alias": [
- "grid.filterbar.boolean"
- ],
- "alternates": []
- },
- "Ext.grid.plugin.filterbar.filters.Date": {
- "idx": 645,
- "alias": [
- "grid.filterbar.date"
- ],
- "alternates": []
- },
- "Ext.grid.plugin.filterbar.filters.InList": {
- "idx": 650,
- "alias": [
- "grid.filterbar.inlist"
- ],
- "alternates": []
- },
- "Ext.grid.plugin.filterbar.filters.List": {
- "idx": 649,
- "alias": [
- "grid.filterbar.list"
- ],
- "alternates": []
- },
- "Ext.grid.plugin.filterbar.filters.None": {
- "idx": 648,
- "alias": [
- "grid.filterbar.none"
- ],
- "alternates": []
- },
- "Ext.grid.plugin.filterbar.filters.Number": {
- "idx": 646,
- "alias": [
- "grid.filterbar.number"
- ],
- "alternates": []
- },
- "Ext.grid.plugin.filterbar.filters.SingleFilter": {
- "idx": 643,
- "alias": [],
- "alternates": []
- },
- "Ext.grid.plugin.filterbar.filters.String": {
- "idx": 644,
- "alias": [
- "grid.filterbar.string"
- ],
- "alternates": []
- },
- "Ext.grid.plugin.grouping.Column": {
- "idx": 632,
- "alias": [
- "widget.groupingpanelcolumn"
- ],
- "alternates": []
- },
- "Ext.grid.plugin.grouping.DragZone": {
- "idx": 633,
- "alias": [],
- "alternates": []
- },
- "Ext.grid.plugin.grouping.DropZone": {
- "idx": 634,
- "alias": [],
- "alternates": []
- },
- "Ext.grid.plugin.grouping.Panel": {
- "idx": 635,
- "alias": [
- "widget.groupingpanel"
- ],
- "alternates": []
- },
- "Ext.grid.property.Grid": {
- "idx": 652,
- "alias": [
- "widget.propertygrid"
- ],
- "alternates": [
- "Ext.grid.PropertyGrid"
- ]
- },
- "Ext.grid.property.HeaderContainer": {
- "idx": 653,
- "alias": [],
- "alternates": [
- "Ext.grid.PropertyColumnModel"
- ]
- },
- "Ext.grid.property.Property": {
- "idx": 654,
- "alias": [],
- "alternates": [
- "Ext.PropGridProperty"
- ]
- },
- "Ext.grid.property.Reader": {
- "idx": 655,
- "alias": [],
- "alternates": []
- },
- "Ext.grid.property.Store": {
- "idx": 656,
- "alias": [],
- "alternates": [
- "Ext.grid.PropertyStore"
- ]
- },
- "Ext.grid.selection.Cells": {
- "idx": 658,
- "alias": [],
- "alternates": []
- },
- "Ext.grid.selection.Columns": {
- "idx": 659,
- "alias": [],
- "alternates": []
- },
- "Ext.grid.selection.Replicator": {
- "idx": 660,
- "alias": [
- "plugin.selectionreplicator"
- ],
- "alternates": []
- },
- "Ext.grid.selection.Rows": {
- "idx": 661,
- "alias": [],
- "alternates": []
- },
- "Ext.grid.selection.Selection": {
- "idx": 657,
- "alias": [],
- "alternates": []
- },
- "Ext.grid.selection.SelectionExtender": {
- "idx": 662,
- "alias": [],
- "alternates": []
- },
- "Ext.grid.selection.SpreadsheetModel": {
- "idx": 663,
- "alias": [
- "selection.spreadsheet"
- ],
- "alternates": []
- },
- "Ext.layout.Context": {
- "idx": 666,
- "alias": [],
- "alternates": []
- },
- "Ext.layout.ContextItem": {
- "idx": 665,
- "alias": [],
- "alternates": []
- },
- "Ext.layout.Layout": {
- "idx": 420,
- "alias": [],
- "alternates": []
- },
- "Ext.layout.SizeModel": {
- "idx": 419,
- "alias": [],
- "alternates": []
- },
- "Ext.layout.component.Auto": {
- "idx": 433,
- "alias": [
- "layout.autocomponent"
- ],
- "alternates": []
- },
- "Ext.layout.component.Body": {
- "idx": 668,
- "alias": [
- "layout.body"
- ],
- "alternates": []
- },
- "Ext.layout.component.BoundList": {
- "idx": 533,
- "alias": [
- "layout.boundlist"
- ],
- "alternates": []
- },
- "Ext.layout.component.Component": {
- "idx": 432,
- "alias": [],
- "alternates": []
- },
- "Ext.layout.component.Dock": {
- "idx": 463,
- "alias": [
- "layout.dock"
- ],
- "alternates": [
- "Ext.layout.component.AbstractDock"
- ]
- },
- "Ext.layout.component.FieldSet": {
- "idx": 669,
- "alias": [
- "layout.fieldset"
- ],
- "alternates": []
- },
- "Ext.layout.component.ProgressBar": {
- "idx": 434,
- "alias": [
- "layout.progressbar"
- ],
- "alternates": []
- },
- "Ext.layout.component.field.FieldContainer": {
- "idx": 510,
- "alias": [
- "layout.fieldcontainer"
- ],
- "alternates": []
- },
- "Ext.layout.component.field.HtmlEditor": {
- "idx": 555,
- "alias": [
- "layout.htmleditor"
- ],
- "alternates": []
- },
- "Ext.layout.component.field.Text": {
- "idx": 503,
- "alias": [
- "layout.textfield"
- ],
- "alternates": []
- },
- "Ext.layout.container.Absolute": {
- "idx": 670,
- "alias": [
- "layout.absolute"
- ],
- "alternates": [
- "Ext.layout.AbsoluteLayout"
- ]
- },
- "Ext.layout.container.Accordion": {
- "idx": 671,
- "alias": [
- "layout.accordion"
- ],
- "alternates": [
- "Ext.layout.AccordionLayout"
- ]
- },
- "Ext.layout.container.Anchor": {
- "idx": 472,
- "alias": [
- "layout.anchor"
- ],
- "alternates": [
- "Ext.layout.AnchorLayout"
- ]
- },
- "Ext.layout.container.Auto": {
- "idx": 422,
- "alias": [
- "layout.auto",
- "layout.autocontainer"
- ],
- "alternates": []
- },
- "Ext.layout.container.Border": {
- "idx": 673,
- "alias": [
- "layout.border"
- ],
- "alternates": [
- "Ext.layout.BorderLayout"
- ]
- },
- "Ext.layout.container.Box": {
- "idx": 452,
- "alias": [
- "layout.box"
- ],
- "alternates": [
- "Ext.layout.BoxLayout"
- ]
- },
- "Ext.layout.container.Card": {
- "idx": 674,
- "alias": [
- "layout.card"
- ],
- "alternates": [
- "Ext.layout.CardLayout"
- ]
- },
- "Ext.layout.container.Center": {
- "idx": 675,
- "alias": [
- "layout.center",
- "layout.ux.center"
- ],
- "alternates": [
- "Ext.ux.layout.Center"
- ]
- },
- "Ext.layout.container.CheckboxGroup": {
- "idx": 513,
- "alias": [
- "layout.checkboxgroup"
- ],
- "alternates": []
- },
- "Ext.layout.container.Column": {
- "idx": 475,
- "alias": [
- "layout.column"
- ],
- "alternates": [
- "Ext.layout.ColumnLayout"
- ]
- },
- "Ext.layout.container.ColumnSplitter": {
- "idx": 479,
- "alias": [
- "widget.columnsplitter"
- ],
- "alternates": []
- },
- "Ext.layout.container.ColumnSplitterTracker": {
- "idx": 478,
- "alias": [],
- "alternates": []
- },
- "Ext.layout.container.Container": {
- "idx": 421,
- "alias": [
- "layout.container"
- ],
- "alternates": [
- "Ext.layout.ContainerLayout"
- ]
- },
- "Ext.layout.container.Dashboard": {
- "idx": 480,
- "alias": [
- "layout.dashboard"
- ],
- "alternates": []
- },
- "Ext.layout.container.Editor": {
- "idx": 425,
- "alias": [
- "layout.editor"
- ],
- "alternates": []
- },
- "Ext.layout.container.Fit": {
- "idx": 567,
- "alias": [
- "layout.fit"
- ],
- "alternates": [
- "Ext.layout.FitLayout",
- "Ext.layout.Fit"
- ]
- },
- "Ext.layout.container.Form": {
- "idx": 676,
- "alias": [
- "layout.form"
- ],
- "alternates": [
- "Ext.layout.FormLayout"
- ]
- },
- "Ext.layout.container.HBox": {
- "idx": 453,
- "alias": [
- "layout.hbox"
- ],
- "alternates": [
- "Ext.layout.HBoxLayout"
- ]
- },
- "Ext.layout.container.SegmentedButton": {
- "idx": 442,
- "alias": [
- "layout.segmentedbutton"
- ],
- "alternates": []
- },
- "Ext.layout.container.Table": {
- "idx": 467,
- "alias": [
- "layout.table"
- ],
- "alternates": [
- "Ext.layout.TableLayout"
- ]
- },
- "Ext.layout.container.VBox": {
- "idx": 454,
- "alias": [
- "layout.vbox"
- ],
- "alternates": [
- "Ext.layout.VBoxLayout"
- ]
- },
- "Ext.layout.container.border.Region": {
- "idx": 119,
- "alias": [],
- "alternates": []
- },
- "Ext.layout.container.boxOverflow.Menu": {
- "idx": 557,
- "alias": [
- "box.overflow.Menu",
- "box.overflow.menu"
- ],
- "alternates": [
- "Ext.layout.boxOverflow.Menu"
- ]
- },
- "Ext.layout.container.boxOverflow.None": {
- "idx": 448,
- "alias": [
- "box.overflow.None",
- "box.overflow.none"
- ],
- "alternates": [
- "Ext.layout.boxOverflow.None"
- ]
- },
- "Ext.layout.container.boxOverflow.Scroller": {
- "idx": 449,
- "alias": [
- "box.overflow.Scroller",
- "box.overflow.scroller"
- ],
- "alternates": [
- "Ext.layout.boxOverflow.Scroller"
- ]
- },
- "Ext.list.AbstractTreeItem": {
- "idx": 364,
- "alias": [],
- "alternates": []
- },
- "Ext.list.RootTreeItem": {
- "idx": 365,
- "alias": [],
- "alternates": []
- },
- "Ext.list.Tree": {
- "idx": 368,
- "alias": [
- "widget.treelist"
- ],
- "alternates": []
- },
- "Ext.list.TreeItem": {
- "idx": 367,
- "alias": [
- "widget.treelistitem"
- ],
- "alternates": []
- },
- "Ext.menu.Bar": {
- "idx": 677,
- "alias": [
- "widget.menubar"
- ],
- "alternates": []
- },
- "Ext.menu.CheckItem": {
- "idx": 611,
- "alias": [
- "widget.menucheckitem"
- ],
- "alternates": []
- },
- "Ext.menu.ColorPicker": {
- "idx": 678,
- "alias": [
- "widget.colormenu"
- ],
- "alternates": []
- },
- "Ext.menu.DatePicker": {
- "idx": 679,
- "alias": [
- "widget.datemenu"
- ],
- "alternates": []
- },
- "Ext.menu.Item": {
- "idx": 610,
- "alias": [
- "widget.menuitem"
- ],
- "alternates": [
- "Ext.menu.TextItem"
- ]
- },
- "Ext.menu.Manager": {
- "idx": 438,
- "alias": [],
- "alternates": [
- "Ext.menu.MenuMgr"
- ]
- },
- "Ext.menu.Menu": {
- "idx": 613,
- "alias": [
- "widget.menu"
- ],
- "alternates": []
- },
- "Ext.menu.Separator": {
- "idx": 612,
- "alias": [
- "widget.menuseparator"
- ],
- "alternates": []
- },
- "Ext.mixin.Accessible": {
- "idx": 88,
- "alias": [],
- "alternates": []
- },
- "Ext.mixin.Bindable": {
- "idx": 82,
- "alias": [],
- "alternates": []
- },
- "Ext.mixin.Bufferable": {
- "idx": 20,
- "alias": [],
- "alternates": []
- },
- "Ext.mixin.ComponentDelegation": {
- "idx": 83,
- "alias": [],
- "alternates": []
- },
- "Ext.mixin.ConfigProxy": {
- "idx": 369,
- "alias": [],
- "alternates": []
- },
- "Ext.mixin.ConfigState": {
- "idx": 370,
- "alias": [],
- "alternates": []
- },
- "Ext.mixin.Container": {
- "idx": 371,
- "alias": [],
- "alternates": []
- },
- "Ext.mixin.Dirty": {
- "idx": 201,
- "alias": [],
- "alternates": []
- },
- "Ext.mixin.Factoryable": {
- "idx": 12,
- "alias": [],
- "alternates": []
- },
- "Ext.mixin.Focusable": {
- "idx": 87,
- "alias": [],
- "alternates": []
- },
- "Ext.mixin.FocusableContainer": {
- "idx": 374,
- "alias": [],
- "alternates": []
- },
- "Ext.mixin.Hookable": {
- "idx": 375,
- "alias": [],
- "alternates": []
- },
- "Ext.mixin.Identifiable": {
- "idx": 3,
- "alias": [],
- "alternates": []
- },
- "Ext.mixin.Inheritable": {
- "idx": 81,
- "alias": [],
- "alternates": []
- },
- "Ext.mixin.ItemRippler": {
- "idx": 366,
- "alias": [],
- "alternates": []
- },
- "Ext.mixin.Keyboard": {
- "idx": 86,
- "alias": [],
- "alternates": []
- },
- "Ext.mixin.Mashup": {
- "idx": 376,
- "alias": [],
- "alternates": []
- },
- "Ext.mixin.Observable": {
- "idx": 4,
- "alias": [],
- "alternates": []
- },
- "Ext.mixin.Pluggable": {
- "idx": 85,
- "alias": [],
- "alternates": []
- },
- "Ext.mixin.Queryable": {
- "idx": 241,
- "alias": [],
- "alternates": []
- },
- "Ext.mixin.Responsive": {
- "idx": 90,
- "alias": [],
- "alternates": []
- },
- "Ext.mixin.Selectable": {
- "idx": 377,
- "alias": [],
- "alternates": []
- },
- "Ext.mixin.StoreWatcher": {
- "idx": 378,
- "alias": [],
- "alternates": []
- },
- "Ext.mixin.StyleCacher": {
- "idx": 379,
- "alias": [],
- "alternates": []
- },
- "Ext.mixin.Templatable": {
- "idx": 39,
- "alias": [],
- "alternates": []
- },
- "Ext.mixin.Traversable": {
- "idx": 380,
- "alias": [],
- "alternates": []
- },
- "Ext.panel.Bar": {
- "idx": 444,
- "alias": [],
- "alternates": []
- },
- "Ext.panel.DD": {
- "idx": 462,
- "alias": [],
- "alternates": []
- },
- "Ext.panel.Header": {
- "idx": 447,
- "alias": [
- "widget.header"
- ],
- "alternates": []
- },
- "Ext.panel.Panel": {
- "idx": 466,
- "alias": [
- "widget.panel"
- ],
- "alternates": [
- "Ext.Panel"
- ]
- },
- "Ext.panel.Pinnable": {
- "idx": 680,
- "alias": [],
- "alternates": []
- },
- "Ext.panel.Proxy": {
- "idx": 461,
- "alias": [],
- "alternates": [
- "Ext.dd.PanelProxy"
- ]
- },
- "Ext.panel.Table": {
- "idx": 568,
- "alias": [
- "widget.tablepanel"
- ],
- "alternates": []
- },
- "Ext.panel.Title": {
- "idx": 445,
- "alias": [
- "widget.title"
- ],
- "alternates": []
- },
- "Ext.panel.Tool": {
- "idx": 446,
- "alias": [
- "widget.tool"
- ],
- "alternates": []
- },
- "Ext.parse.Parser": {
- "idx": 220,
- "alias": [],
- "alternates": []
- },
- "Ext.parse.Symbol": {
- "idx": 214,
- "alias": [],
- "alternates": []
- },
- "Ext.parse.Tokenizer": {
- "idx": 213,
- "alias": [],
- "alternates": []
- },
- "Ext.parse.symbol.Constant": {
- "idx": 215,
- "alias": [],
- "alternates": []
- },
- "Ext.parse.symbol.Infix": {
- "idx": 216,
- "alias": [],
- "alternates": []
- },
- "Ext.parse.symbol.InfixRight": {
- "idx": 217,
- "alias": [],
- "alternates": []
- },
- "Ext.parse.symbol.Paren": {
- "idx": 218,
- "alias": [],
- "alternates": []
- },
- "Ext.parse.symbol.Prefix": {
- "idx": 219,
- "alias": [],
- "alternates": []
- },
- "Ext.perf.Accumulator": {
- "idx": 381,
- "alias": [],
- "alternates": []
- },
- "Ext.perf.Monitor": {
- "idx": 382,
- "alias": [],
- "alternates": [
- "Ext.Perf"
- ]
- },
- "Ext.picker.Color": {
- "idx": 554,
- "alias": [
- "widget.colorpicker"
- ],
- "alternates": [
- "Ext.ColorPalette"
- ]
- },
- "Ext.picker.Date": {
- "idx": 543,
- "alias": [
- "widget.datepicker"
- ],
- "alternates": [
- "Ext.DatePicker"
- ]
- },
- "Ext.picker.Month": {
- "idx": 542,
- "alias": [
- "widget.monthpicker"
- ],
- "alternates": [
- "Ext.MonthPicker"
- ]
- },
- "Ext.picker.Time": {
- "idx": 561,
- "alias": [
- "widget.timepicker"
- ],
- "alternates": []
- },
- "Ext.plugin.Abstract": {
- "idx": 84,
- "alias": [],
- "alternates": [
- "Ext.AbstractPlugin"
- ]
- },
- "Ext.plugin.AbstractClipboard": {
- "idx": 383,
- "alias": [],
- "alternates": []
- },
- "Ext.plugin.LazyItems": {
- "idx": 681,
- "alias": [
- "plugin.lazyitems"
- ],
- "alternates": []
- },
- "Ext.plugin.Manager": {
- "idx": 103,
- "alias": [],
- "alternates": [
- "Ext.PluginManager",
- "Ext.PluginMgr"
- ]
- },
- "Ext.plugin.MouseEnter": {
- "idx": 384,
- "alias": [
- "plugin.mouseenter"
- ],
- "alternates": []
- },
- "Ext.plugin.Responsive": {
- "idx": 682,
- "alias": [
- "plugin.responsive"
- ],
- "alternates": []
- },
- "Ext.plugin.Viewport": {
- "idx": 470,
- "alias": [
- "plugin.viewport"
- ],
- "alternates": []
- },
- "Ext.promise.Consequence": {
- "idx": 7,
- "alias": [],
- "alternates": []
- },
- "Ext.promise.Deferred": {
- "idx": 8,
- "alias": [],
- "alternates": []
- },
- "Ext.promise.Promise": {
- "idx": 9,
- "alias": [],
- "alternates": []
- },
- "Ext.resizer.BorderSplitter": {
- "idx": 672,
- "alias": [
- "widget.bordersplitter"
- ],
- "alternates": []
- },
- "Ext.resizer.BorderSplitterTracker": {
- "idx": 683,
- "alias": [],
- "alternates": []
- },
- "Ext.resizer.Handle": {
- "idx": 684,
- "alias": [],
- "alternates": []
- },
- "Ext.resizer.ResizeTracker": {
- "idx": 685,
- "alias": [],
- "alternates": []
- },
- "Ext.resizer.Resizer": {
- "idx": 686,
- "alias": [],
- "alternates": [
- "Ext.Resizable"
- ]
- },
- "Ext.resizer.Splitter": {
- "idx": 451,
- "alias": [
- "widget.splitter"
- ],
- "alternates": []
- },
- "Ext.resizer.SplitterTracker": {
- "idx": 477,
- "alias": [],
- "alternates": []
- },
- "Ext.route.Action": {
- "idx": 123,
- "alias": [],
- "alternates": []
- },
- "Ext.route.Handler": {
- "idx": 122,
- "alias": [],
- "alternates": []
- },
- "Ext.route.Mixin": {
- "idx": 127,
- "alias": [],
- "alternates": []
- },
- "Ext.route.Route": {
- "idx": 124,
- "alias": [],
- "alternates": []
- },
- "Ext.route.Router": {
- "idx": 126,
- "alias": [],
- "alternates": []
- },
- "Ext.scroll.LockingScroller": {
- "idx": 625,
- "alias": [
- "scroller.locking"
- ],
- "alternates": []
- },
- "Ext.scroll.Scroller": {
- "idx": 110,
- "alias": [
- "scroller.scroller"
- ],
- "alternates": [
- "Ext.scroll.NativeScroller"
- ]
- },
- "Ext.scroll.TableScroller": {
- "idx": 575,
- "alias": [
- "scroller.table"
- ],
- "alternates": []
- },
- "Ext.selection.CellModel": {
- "idx": 687,
- "alias": [
- "selection.cellmodel"
- ],
- "alternates": []
- },
- "Ext.selection.CheckboxModel": {
- "idx": 689,
- "alias": [
- "selection.checkboxmodel"
- ],
- "alternates": []
- },
- "Ext.selection.DataViewModel": {
- "idx": 528,
- "alias": [
- "selection.dataviewmodel"
- ],
- "alternates": []
- },
- "Ext.selection.Model": {
- "idx": 527,
- "alias": [
- "selection.abstract"
- ],
- "alternates": [
- "Ext.AbstractSelectionModel"
- ]
- },
- "Ext.selection.RowModel": {
- "idx": 688,
- "alias": [
- "selection.rowmodel"
- ],
- "alternates": []
- },
- "Ext.selection.TreeModel": {
- "idx": 690,
- "alias": [
- "selection.treemodel"
- ],
- "alternates": []
- },
- "Ext.slider.Multi": {
- "idx": 693,
- "alias": [
- "widget.multislider"
- ],
- "alternates": [
- "Ext.slider.MultiSlider"
- ]
- },
- "Ext.slider.Single": {
- "idx": 694,
- "alias": [
- "widget.slider",
- "widget.sliderfield"
- ],
- "alternates": [
- "Ext.Slider",
- "Ext.form.SliderField",
- "Ext.slider.SingleSlider",
- "Ext.slider.Slider"
- ]
- },
- "Ext.slider.Thumb": {
- "idx": 691,
- "alias": [],
- "alternates": []
- },
- "Ext.slider.Tip": {
- "idx": 692,
- "alias": [
- "widget.slidertip"
- ],
- "alternates": []
- },
- "Ext.slider.Widget": {
- "idx": 695,
- "alias": [
- "widget.sliderwidget"
- ],
- "alternates": []
- },
- "Ext.sparkline.Bar": {
- "idx": 393,
- "alias": [
- "widget.sparklinebar"
- ],
- "alternates": []
- },
- "Ext.sparkline.BarBase": {
- "idx": 391,
- "alias": [],
- "alternates": []
- },
- "Ext.sparkline.Base": {
- "idx": 390,
- "alias": [
- "widget.sparkline"
- ],
- "alternates": []
- },
- "Ext.sparkline.Box": {
- "idx": 394,
- "alias": [
- "widget.sparklinebox"
- ],
- "alternates": []
- },
- "Ext.sparkline.Bullet": {
- "idx": 395,
- "alias": [
- "widget.sparklinebullet"
- ],
- "alternates": []
- },
- "Ext.sparkline.CanvasBase": {
- "idx": 386,
- "alias": [],
- "alternates": []
- },
- "Ext.sparkline.CanvasCanvas": {
- "idx": 387,
- "alias": [],
- "alternates": []
- },
- "Ext.sparkline.Discrete": {
- "idx": 396,
- "alias": [
- "widget.sparklinediscrete"
- ],
- "alternates": []
- },
- "Ext.sparkline.Line": {
- "idx": 397,
- "alias": [
- "widget.sparklineline"
- ],
- "alternates": []
- },
- "Ext.sparkline.Pie": {
- "idx": 398,
- "alias": [
- "widget.sparklinepie"
- ],
- "alternates": []
- },
- "Ext.sparkline.RangeMap": {
- "idx": 392,
- "alias": [],
- "alternates": []
- },
- "Ext.sparkline.Shape": {
- "idx": 385,
- "alias": [],
- "alternates": []
- },
- "Ext.sparkline.TriState": {
- "idx": 399,
- "alias": [
- "widget.sparklinetristate"
- ],
- "alternates": []
- },
- "Ext.sparkline.VmlCanvas": {
- "idx": 388,
- "alias": [],
- "alternates": []
- },
- "Ext.state.CookieProvider": {
- "idx": 696,
- "alias": [],
- "alternates": []
- },
- "Ext.state.LocalStorageProvider": {
- "idx": 697,
- "alias": [
- "state.localstorage"
- ],
- "alternates": []
- },
- "Ext.state.Manager": {
- "idx": 115,
- "alias": [],
- "alternates": []
- },
- "Ext.state.Provider": {
- "idx": 114,
- "alias": [],
- "alternates": []
- },
- "Ext.state.Stateful": {
- "idx": 116,
- "alias": [],
- "alternates": []
- },
- "Ext.tab.Bar": {
- "idx": 699,
- "alias": [
- "widget.tabbar"
- ],
- "alternates": []
- },
- "Ext.tab.Panel": {
- "idx": 700,
- "alias": [
- "widget.tabpanel"
- ],
- "alternates": [
- "Ext.TabPanel"
- ]
- },
- "Ext.tab.Tab": {
- "idx": 698,
- "alias": [
- "widget.tab"
- ],
- "alternates": []
- },
- "Ext.tip.QuickTip": {
- "idx": 552,
- "alias": [
- "widget.quicktip"
- ],
- "alternates": [
- "Ext.QuickTip"
- ]
- },
- "Ext.tip.QuickTipManager": {
- "idx": 553,
- "alias": [],
- "alternates": [
- "Ext.QuickTips"
- ]
- },
- "Ext.tip.Tip": {
- "idx": 550,
- "alias": [
- "widget.tip"
- ],
- "alternates": [
- "Ext.Tip"
- ]
- },
- "Ext.tip.ToolTip": {
- "idx": 551,
- "alias": [
- "widget.tooltip"
- ],
- "alternates": [
- "Ext.ToolTip"
- ]
- },
- "Ext.toolbar.Breadcrumb": {
- "idx": 701,
- "alias": [
- "widget.breadcrumb"
- ],
- "alternates": []
- },
- "Ext.toolbar.Fill": {
- "idx": 702,
- "alias": [
- "widget.tbfill"
- ],
- "alternates": [
- "Ext.Toolbar.Fill"
- ]
- },
- "Ext.toolbar.Item": {
- "idx": 534,
- "alias": [
- "widget.tbitem"
- ],
- "alternates": [
- "Ext.Toolbar.Item"
- ]
- },
- "Ext.toolbar.Paging": {
- "idx": 539,
- "alias": [
- "widget.pagingtoolbar"
- ],
- "alternates": [
- "Ext.PagingToolbar"
- ]
- },
- "Ext.toolbar.Separator": {
- "idx": 556,
- "alias": [
- "widget.tbseparator"
- ],
- "alternates": [
- "Ext.Toolbar.Separator"
- ]
- },
- "Ext.toolbar.Spacer": {
- "idx": 703,
- "alias": [
- "widget.tbspacer"
- ],
- "alternates": [
- "Ext.Toolbar.Spacer"
- ]
- },
- "Ext.toolbar.TextItem": {
- "idx": 535,
- "alias": [
- "widget.tbtext"
- ],
- "alternates": [
- "Ext.Toolbar.TextItem"
- ]
- },
- "Ext.toolbar.Toolbar": {
- "idx": 455,
- "alias": [
- "widget.toolbar"
- ],
- "alternates": [
- "Ext.Toolbar"
- ]
- },
- "Ext.tree.Column": {
- "idx": 704,
- "alias": [
- "widget.treecolumn"
- ],
- "alternates": []
- },
- "Ext.tree.NavigationModel": {
- "idx": 705,
- "alias": [
- "view.navigation.tree"
- ],
- "alternates": []
- },
- "Ext.tree.Panel": {
- "idx": 707,
- "alias": [
- "widget.treepanel"
- ],
- "alternates": [
- "Ext.tree.TreePanel",
- "Ext.TreePanel"
- ]
- },
- "Ext.tree.View": {
- "idx": 706,
- "alias": [
- "widget.treeview"
- ],
- "alternates": []
- },
- "Ext.tree.ViewDragZone": {
- "idx": 709,
- "alias": [],
- "alternates": []
- },
- "Ext.tree.ViewDropZone": {
- "idx": 710,
- "alias": [],
- "alternates": []
- },
- "Ext.tree.plugin.TreeViewDragDrop": {
- "idx": 711,
- "alias": [
- "plugin.treeviewdragdrop"
- ],
- "alternates": []
- },
- "Ext.util.AbstractMixedCollection": {
- "idx": 53,
- "alias": [],
- "alternates": []
- },
- "Ext.util.Animate": {
- "idx": 74,
- "alias": [],
- "alternates": []
- },
- "Ext.util.Bag": {
- "idx": 192,
- "alias": [],
- "alternates": []
- },
- "Ext.util.Base64": {
- "idx": 400,
- "alias": [],
- "alternates": []
- },
- "Ext.util.BasicFilter": {
- "idx": 50,
- "alias": [],
- "alternates": []
- },
- "Ext.util.CSS": {
- "idx": 104,
- "alias": [],
- "alternates": []
- },
- "Ext.util.CSV": {
- "idx": 402,
- "alias": [],
- "alternates": []
- },
- "Ext.util.ClickRepeater": {
- "idx": 403,
- "alias": [],
- "alternates": [
- "Ext.util.TapRepeater"
- ]
- },
- "Ext.util.Collection": {
- "idx": 132,
- "alias": [],
- "alternates": []
- },
- "Ext.util.CollectionKey": {
- "idx": 130,
- "alias": [],
- "alternates": []
- },
- "Ext.util.Color": {
- "idx": 389,
- "alias": [],
- "alternates": [
- "Ext.draw.Color"
- ]
- },
- "Ext.util.ComponentDragger": {
- "idx": 498,
- "alias": [],
- "alternates": []
- },
- "Ext.util.Cookies": {
- "idx": 404,
- "alias": [],
- "alternates": []
- },
- "Ext.util.DelimitedValue": {
- "idx": 401,
- "alias": [],
- "alternates": []
- },
- "Ext.util.ElementContainer": {
- "idx": 112,
- "alias": [],
- "alternates": []
- },
- "Ext.util.Event": {
- "idx": 2,
- "alias": [],
- "alternates": []
- },
- "Ext.util.Filter": {
- "idx": 51,
- "alias": [],
- "alternates": []
- },
- "Ext.util.FilterCollection": {
- "idx": 179,
- "alias": [],
- "alternates": []
- },
- "Ext.util.Floating": {
- "idx": 111,
- "alias": [],
- "alternates": []
- },
- "Ext.util.Fly": {
- "idx": 212,
- "alias": [],
- "alternates": []
- },
- "Ext.util.Format": {
- "idx": 94,
- "alias": [],
- "alternates": []
- },
- "Ext.util.Group": {
- "idx": 171,
- "alias": [],
- "alternates": []
- },
- "Ext.util.GroupCollection": {
- "idx": 181,
- "alias": [],
- "alternates": []
- },
- "Ext.util.Grouper": {
- "idx": 131,
- "alias": [],
- "alternates": []
- },
- "Ext.util.GrouperCollection": {
- "idx": 180,
- "alias": [],
- "alternates": []
- },
- "Ext.util.HashMap": {
- "idx": 5,
- "alias": [],
- "alternates": []
- },
- "Ext.util.History": {
- "idx": 125,
- "alias": [],
- "alternates": [
- "Ext.History"
- ]
- },
- "Ext.util.Inflector": {
- "idx": 140,
- "alias": [],
- "alternates": []
- },
- "Ext.util.ItemCollection": {
- "idx": 405,
- "alias": [],
- "alternates": [
- "Ext.ItemCollection"
- ]
- },
- "Ext.util.KeyMap": {
- "idx": 372,
- "alias": [],
- "alternates": [
- "Ext.KeyMap"
- ]
- },
- "Ext.util.KeyNav": {
- "idx": 373,
- "alias": [],
- "alternates": [
- "Ext.KeyNav"
- ]
- },
- "Ext.util.LocalStorage": {
- "idx": 406,
- "alias": [],
- "alternates": []
- },
- "Ext.util.LruCache": {
- "idx": 23,
- "alias": [],
- "alternates": []
- },
- "Ext.util.Memento": {
- "idx": 464,
- "alias": [],
- "alternates": []
- },
- "Ext.util.MixedCollection": {
- "idx": 56,
- "alias": [],
- "alternates": []
- },
- "Ext.util.ObjectTemplate": {
- "idx": 134,
- "alias": [],
- "alternates": []
- },
- "Ext.util.Observable": {
- "idx": 52,
- "alias": [],
- "alternates": []
- },
- "Ext.util.Offset": {
- "idx": 33,
- "alias": [],
- "alternates": []
- },
- "Ext.util.PaintMonitor": {
- "idx": 47,
- "alias": [],
- "alternates": []
- },
- "Ext.util.Point": {
- "idx": 35,
- "alias": [],
- "alternates": []
- },
- "Ext.util.Positionable": {
- "idx": 26,
- "alias": [],
- "alternates": []
- },
- "Ext.util.ProtoElement": {
- "idx": 101,
- "alias": [],
- "alternates": []
- },
- "Ext.util.Queue": {
- "idx": 664,
- "alias": [],
- "alternates": []
- },
- "Ext.util.Region": {
- "idx": 34,
- "alias": [],
- "alternates": []
- },
- "Ext.util.Renderable": {
- "idx": 113,
- "alias": [],
- "alternates": []
- },
- "Ext.util.Schedulable": {
- "idx": 203,
- "alias": [],
- "alternates": []
- },
- "Ext.util.Scheduler": {
- "idx": 193,
- "alias": [],
- "alternates": []
- },
- "Ext.util.SizeMonitor": {
- "idx": 43,
- "alias": [],
- "alternates": []
- },
- "Ext.util.Sortable": {
- "idx": 55,
- "alias": [],
- "alternates": []
- },
- "Ext.util.Sorter": {
- "idx": 54,
- "alias": [],
- "alternates": []
- },
- "Ext.util.SorterCollection": {
- "idx": 178,
- "alias": [],
- "alternates": []
- },
- "Ext.util.Spans": {
- "idx": 407,
- "alias": [],
- "alternates": []
- },
- "Ext.util.StoreHolder": {
- "idx": 430,
- "alias": [],
- "alternates": []
- },
- "Ext.util.TaskManager": {
- "idx": 409,
- "alias": [],
- "alternates": [
- "Ext.TaskManager"
- ]
- },
- "Ext.util.TaskRunner": {
- "idx": 57,
- "alias": [],
- "alternates": []
- },
- "Ext.util.TextMetrics": {
- "idx": 410,
- "alias": [],
- "alternates": []
- },
- "Ext.util.TsvDecoder": {
- "idx": 408,
- "alias": [],
- "alternates": [
- "Ext.util.TSV"
- ]
- },
- "Ext.util.XTemplateCompiler": {
- "idx": 97,
- "alias": [],
- "alternates": []
- },
- "Ext.util.XTemplateParser": {
- "idx": 96,
- "alias": [],
- "alternates": []
- },
- "Ext.util.paintmonitor.Abstract": {
- "idx": 45,
- "alias": [],
- "alternates": []
- },
- "Ext.util.paintmonitor.CssAnimation": {
- "idx": 46,
- "alias": [],
- "alternates": []
- },
- "Ext.util.paintmonitor.OverflowChange": {
- "idx": 411,
- "alias": [],
- "alternates": []
- },
- "Ext.util.sizemonitor.Abstract": {
- "idx": 41,
- "alias": [],
- "alternates": []
- },
- "Ext.util.sizemonitor.OverflowChange": {
- "idx": 412,
- "alias": [],
- "alternates": []
- },
- "Ext.util.sizemonitor.Scroll": {
- "idx": 42,
- "alias": [],
- "alternates": []
- },
- "Ext.util.translatable.Abstract": {
- "idx": 107,
- "alias": [],
- "alternates": []
- },
- "Ext.util.translatable.CssPosition": {
- "idx": 413,
- "alias": [
- "translatable.cssposition"
- ],
- "alternates": []
- },
- "Ext.util.translatable.CssTransform": {
- "idx": 414,
- "alias": [
- "translatable.csstransform"
- ],
- "alternates": []
- },
- "Ext.util.translatable.Dom": {
- "idx": 108,
- "alias": [
- "translatable.dom"
- ],
- "alternates": []
- },
- "Ext.util.translatable.ScrollParent": {
- "idx": 415,
- "alias": [
- "translatable.scrollparent"
- ],
- "alternates": []
- },
- "Ext.util.translatable.ScrollPosition": {
- "idx": 109,
- "alias": [
- "translatable.scrollposition"
- ],
- "alternates": []
- },
- "Ext.view.AbstractView": {
- "idx": 530,
- "alias": [],
- "alternates": []
- },
- "Ext.view.BoundList": {
- "idx": 540,
- "alias": [
- "widget.boundlist"
- ],
- "alternates": [
- "Ext.BoundList"
- ]
- },
- "Ext.view.BoundListKeyNav": {
- "idx": 532,
- "alias": [
- "view.navigation.boundlist"
- ],
- "alternates": []
- },
- "Ext.view.DragZone": {
- "idx": 708,
- "alias": [],
- "alternates": []
- },
- "Ext.view.DropZone": {
- "idx": 582,
- "alias": [],
- "alternates": []
- },
- "Ext.view.MultiSelector": {
- "idx": 713,
- "alias": [
- "widget.multiselector"
- ],
- "alternates": []
- },
- "Ext.view.MultiSelectorSearch": {
- "idx": 712,
- "alias": [
- "widget.multiselector-search"
- ],
- "alternates": []
- },
- "Ext.view.NavigationModel": {
- "idx": 529,
- "alias": [
- "view.navigation.default"
- ],
- "alternates": []
- },
- "Ext.view.NodeCache": {
- "idx": 574,
- "alias": [],
- "alternates": []
- },
- "Ext.view.Table": {
- "idx": 576,
- "alias": [
- "widget.gridview",
- "widget.tableview"
- ],
- "alternates": [
- "Ext.grid.View"
- ]
- },
- "Ext.view.TableLayout": {
- "idx": 572,
- "alias": [
- "layout.tableview"
- ],
- "alternates": []
- },
- "Ext.view.TagKeyNav": {
- "idx": 559,
- "alias": [
- "view.navigation.tagfield"
- ],
- "alternates": []
- },
- "Ext.view.View": {
- "idx": 531,
- "alias": [
- "widget.dataview"
- ],
- "alternates": [
- "Ext.DataView"
- ]
- },
- "Ext.window.MessageBox": {
- "idx": 508,
- "alias": [
- "widget.messagebox"
- ],
- "alternates": []
- },
- "Ext.window.Toast": {
- "idx": 714,
- "alias": [
- "widget.toast"
- ],
- "alternates": []
- },
- "Ext.window.Window": {
- "idx": 499,
- "alias": [
- "widget.window"
- ],
- "alternates": [
- "Ext.Window"
- ]
- }
- },
- "packages": {
- "classic": {
- "css": true,
- "included": true,
- "language": {
- "js": {
- "input": {
- "version": "ES5"
- }
- }
- },
- "namespace": "Ext",
- "properties": {
- "skip.sass": 1,
- "skip.pkg": 1,
- "skip.slice": 1
- },
- "required": true,
- "requires": [
- "ext",
- "core",
- "classic"
- ],
- "version": "7.4.0.42"
- },
- "cmd": {
- "version": "7.4.0.39"
- },
- "core": {
- "css": true,
- "included": true,
- "properties": {
- "skip.slice": 1,
- "skip.style": 1,
- "skip.pkg": 1,
- "package.tags.classdefs": "class"
- },
- "required": true,
- "requires": [
- "ext"
- ],
- "version": "7.4.0.42"
- },
- "ext": {
- "css": true,
- "included": true,
- "language": {
- "js": {
- "input": {
- "version": "ES5"
- }
- }
- },
- "license": "commercial",
- "namespace": "Ext",
- "properties": {
- "skip.sass": 1,
- "skip.slice": 1
- },
- "required": true,
- "requires": [],
- "version": "7.4.0.42"
- }
- },
- "bootRelative": true
- });
- // @tag core
- // @define Ext.Boot
- var Ext = Ext || {};
- //<editor-fold desc="Boot">
- /**
- * @class Ext.Boot
- * @singleton
- * @private
- */
- Ext.Boot = Ext.Boot || (function(emptyFn) {
- var doc = document,
- _emptyArray = [],
- _config = {
- /**
- * @cfg {Boolean} [disableCaching=true]
- * If `true` current timestamp is added to script URL's to prevent caching.
- * In debug builds, adding a "cache" or "disableCacheBuster" query parameter
- * to the page's URL will set this to `false`.
- */
- disableCaching: (/[?&](?:cache|disableCacheBuster)\b/i.test(location.search) || !(/http[s]?\:/i.test(location.href)) || /(^|[ ;])ext-cache=1/.test(doc.cookie)) ? false : true,
- /**
- * @cfg {String} [disableCachingParam="_dc"]
- * The query parameter name for the cache buster's timestamp.
- */
- disableCachingParam: '_dc',
- /**
- * @cfg {Boolean} loadDelay
- * Millisecond delay between asynchronous script injection (prevents stack
- * overflow on some user agents) 'false' disables delay but potentially
- * increases stack load.
- */
- loadDelay: false,
- /**
- * @cfg {Boolean} preserveScripts
- * `false` to remove asynchronously loaded scripts, `true` to retain script
- * element for browser debugger compatibility and improved load performance.
- */
- preserveScripts: true,
- /**
- * @cfg {String} [charset=UTF-8]
- * Optional charset to specify encoding of dynamic content.
- */
- charset: 'UTF-8'
- },
- _assetConfig = {},
- cssRe = /\.css(?:\?|$)/i,
- resolverEl = doc.createElement('a'),
- isBrowser = typeof window !== 'undefined',
- _environment = {
- browser: isBrowser,
- node: !isBrowser && (typeof require === 'function'),
- phantom: (window && (window._phantom || window.callPhantom)) || /PhantomJS/.test(window.navigator.userAgent)
- },
- _tags = (Ext.platformTags = {}),
- // All calls to _debug are commented out to speed up old browsers a bit;
- // yes that makes a difference because the cost of concatenating strings
- // and passing them into _debug() adds up pretty quickly.
- _debug = function(message) {},
- //console.log(message);
- _apply = function(object, config, defaults) {
- if (defaults) {
- _apply(object, defaults);
- }
- if (object && config && typeof config === 'object') {
- for (var i in config) {
- object[i] = config[i];
- }
- }
- return object;
- },
- _merge = function() {
- var lowerCase = false,
- obj = Array.prototype.shift.call(arguments),
- index, i, len, value;
- if (typeof arguments[arguments.length - 1] === 'boolean') {
- lowerCase = Array.prototype.pop.call(arguments);
- }
- len = arguments.length;
- for (index = 0; index < len; index++) {
- value = arguments[index];
- if (typeof value === 'object') {
- for (i in value) {
- obj[lowerCase ? i.toLowerCase() : i] = value[i];
- }
- }
- }
- return obj;
- },
- _getKeys = (typeof Object.keys == 'function') ? function(object) {
- if (!object) {
- return [];
- }
- return Object.keys(object);
- } : function(object) {
- var keys = [],
- property;
- for (property in object) {
- if (object.hasOwnProperty(property)) {
- keys.push(property);
- }
- }
- return keys;
- },
- /*
- * The Boot loader class manages Request objects that contain one or
- * more individual urls that need to be loaded. Requests can be performed
- * synchronously or asynchronously, but will always evaluate urls in the
- * order specified on the request object.
- */
- Boot = {
- loading: 0,
- loaded: 0,
- apply: _apply,
- env: _environment,
- config: _config,
- /**
- * @cfg {Object} assetConfig
- * A map (url->assetConfig) that contains information about assets loaded by the Microlaoder.
- */
- assetConfig: _assetConfig,
- // Keyed by absolute URL this object holds "true" if that URL is already loaded
- // or an array of callbacks to call once it loads.
- scripts: {},
- /*
- Entry objects
- 'http://foo.com/bar/baz/Thing.js': {
- done: true,
- el: scriptEl || linkEl,
- preserve: true,
- requests: [ request1, ... ]
- }
- */
- /**
- * contains the current script name being loaded
- * (loadSync or sequential load only)
- */
- currentFile: null,
- suspendedQueue: [],
- currentRequest: null,
- // when loadSync is called, need to cause subsequent load requests to also be loadSync,
- // eg, when Ext.require(...) is called
- syncMode: false,
- /*
- * simple helper method for debugging
- */
- debug: _debug,
- /**
- * enables / disables loading scripts via script / link elements rather
- * than using ajax / eval
- */
- useElements: true,
- listeners: [],
- Request: Request,
- Entry: Entry,
- allowMultipleBrowsers: false,
- browserNames: {
- ie: 'IE',
- firefox: 'Firefox',
- safari: 'Safari',
- chrome: 'Chrome',
- opera: 'Opera',
- dolfin: 'Dolfin',
- edge: 'Edge',
- webosbrowser: 'webOSBrowser',
- chromeMobile: 'ChromeMobile',
- chromeiOS: 'ChromeiOS',
- silk: 'Silk',
- other: 'Other'
- },
- osNames: {
- ios: 'iOS',
- android: 'Android',
- windowsPhone: 'WindowsPhone',
- webos: 'webOS',
- blackberry: 'BlackBerry',
- rimTablet: 'RIMTablet',
- mac: 'MacOS',
- win: 'Windows',
- tizen: 'Tizen',
- linux: 'Linux',
- bada: 'Bada',
- chromeOS: 'ChromeOS',
- other: 'Other'
- },
- browserPrefixes: {
- ie: 'MSIE ',
- edge: 'Edge/',
- firefox: 'Firefox/',
- chrome: 'Chrome/',
- safari: 'Version/',
- opera: 'OPR/',
- dolfin: 'Dolfin/',
- webosbrowser: 'wOSBrowser/',
- chromeMobile: 'CrMo/',
- chromeiOS: 'CriOS/',
- silk: 'Silk/'
- },
- // When a UA reports multiple browsers this list is used to prioritize the 'real' browser
- // lower index number will win
- browserPriority: [
- 'edge',
- 'opera',
- 'dolfin',
- 'webosbrowser',
- 'silk',
- 'chromeiOS',
- 'chromeMobile',
- 'ie',
- 'firefox',
- 'safari',
- 'chrome'
- ],
- osPrefixes: {
- tizen: '(Tizen )',
- ios: 'i(?:Pad|Phone|Pod)(?:.*)CPU(?: iPhone)? OS ',
- android: '(Android |HTC_|Silk/)',
- // Some HTC devices ship with an OSX userAgent by default,
- // so we need to add a direct check for HTC_
- windowsPhone: 'Windows Phone ',
- blackberry: '(?:BlackBerry|BB)(?:.*)Version/',
- rimTablet: 'RIM Tablet OS ',
- webos: '(?:webOS|hpwOS)/',
- bada: 'Bada/',
- chromeOS: 'CrOS '
- },
- fallbackOSPrefixes: {
- windows: 'win',
- mac: 'mac',
- linux: 'linux'
- },
- devicePrefixes: {
- iPhone: 'iPhone',
- iPod: 'iPod',
- iPad: 'iPad'
- },
- maxIEVersion: 12,
- /**
- * The default function that detects various platforms and sets tags
- * in the platform map accordingly. Examples are iOS, android, tablet, etc.
- * @param tags the set of tags to populate
- */
- detectPlatformTags: function() {
- var me = this,
- ua = navigator.userAgent,
- isMobile = /Mobile(\/|\s)/.test(ua),
- element = document.createElement('div'),
- isEventSupported = function(name, tag) {
- if (tag === undefined) {
- tag = window;
- }
- var eventName = 'on' + name.toLowerCase(),
- isSupported = (eventName in element);
- if (!isSupported) {
- if (element.setAttribute && element.removeAttribute) {
- element.setAttribute(eventName, '');
- isSupported = typeof element[eventName] === 'function';
- if (typeof element[eventName] !== 'undefined') {
- element[eventName] = undefined;
- }
- element.removeAttribute(eventName);
- }
- }
- return isSupported;
- },
- // Browser Detection
- getBrowsers = function() {
- var browsers = {},
- maxIEVersion, prefix, value, key, index, len, match, version, matched;
- // MS Edge browser (and possibly others) can report multiple browsers in the UserAgent
- // "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 Edge/12.10240"
- // we use this to prioritize the actual browser in this situation
- len = me.browserPriority.length;
- for (index = 0; index < len; index++) {
- key = me.browserPriority[index];
- if (!matched) {
- value = me.browserPrefixes[key];
- match = ua.match(new RegExp('(' + value + ')([\\w\\._]+)'));
- version = match && match.length > 1 ? parseInt(match[2]) : 0;
- if (version) {
- matched = true;
- }
- } else {
- version = 0;
- }
- browsers[key] = version;
- }
- //Deal with IE document mode
- if (browsers.ie) {
- var mode = document.documentMode;
- if (mode >= 8) {
- browsers.ie = mode;
- }
- }
- // Fancy IE greater than and less then quick tags
- version = browsers.ie || false;
- maxIEVersion = Math.max(version, me.maxIEVersion);
- for (index = 8; index <= maxIEVersion; ++index) {
- prefix = 'ie' + index;
- browsers[prefix + 'm'] = version ? version <= index : 0;
- browsers[prefix] = version ? version === index : 0;
- browsers[prefix + 'p'] = version ? version >= index : 0;
- }
- return browsers;
- },
- //OS Detection
- getOperatingSystems = function() {
- var systems = {},
- value, key, keys, index, len, match, matched, version, activeCount;
- keys = _getKeys(me.osPrefixes);
- len = keys.length;
- for (index = 0 , activeCount = 0; index < len; index++) {
- key = keys[index];
- value = me.osPrefixes[key];
- match = ua.match(new RegExp('(' + value + ')([^\\s;]+)'));
- matched = match ? match[1] : null;
- // This is here because some HTC android devices show an OSX Snow Leopard userAgent by default.
- // And the Kindle Fire doesn't have any indicator of Android as the OS in its User Agent
- if (matched && (matched === 'HTC_' || matched === 'Silk/')) {
- version = 2.3;
- } else {
- version = match && match.length > 1 ? parseFloat(match[match.length - 1]) : 0;
- }
- if (version) {
- activeCount++;
- }
- systems[key] = version;
- }
- keys = _getKeys(me.fallbackOSPrefixes);
- // If no OS could be found we resort to the fallbacks, otherwise we just
- // falsify the fallbacks
- len = keys.length;
- for (index = 0; index < len; index++) {
- key = keys[index];
- // No OS was detected from osPrefixes
- if (activeCount === 0) {
- value = me.fallbackOSPrefixes[key];
- match = ua.toLowerCase().match(new RegExp(value));
- systems[key] = match ? true : 0;
- } else {
- systems[key] = 0;
- }
- }
- return systems;
- },
- // Device Detection
- getDevices = function() {
- var devices = {},
- value, key, keys, index, len, match;
- keys = _getKeys(me.devicePrefixes);
- len = keys.length;
- for (index = 0; index < len; index++) {
- key = keys[index];
- value = me.devicePrefixes[key];
- match = ua.match(new RegExp(value));
- devices[key] = match ? true : 0;
- }
- return devices;
- },
- browsers = getBrowsers(),
- systems = getOperatingSystems(),
- devices = getDevices(),
- platformParams = Boot.loadPlatformsParam();
- // We apply platformParams from the query here first to allow for forced user valued
- // to be used in calculation of generated tags
- _merge(_tags, browsers, systems, devices, platformParams, true);
- _tags.phone = !!((_tags.iphone || _tags.ipod) || (!_tags.silk && (_tags.android && (_tags.android < 3 || isMobile))) || (_tags.blackberry && isMobile) || (_tags.windowsphone));
- _tags.tablet = !!(!_tags.phone && (_tags.ipad || _tags.android || _tags.silk || _tags.rimtablet || (_tags.ie10 && /; Touch/.test(ua))));
- _tags.touch = // if the browser has touch events we can be reasonably sure the device has
- // a touch screen
- isEventSupported('touchend') || // browsers that use pointer event have maxTouchPoints > 0 if the
- // device supports touch input
- // http://www.w3.org/TR/pointerevents/#widl-Navigator-maxTouchPoints
- navigator.maxTouchPoints || // IE10 uses a vendor-prefixed maxTouchPoints property
- navigator.msMaxTouchPoints;
- _tags.desktop = !_tags.phone && !_tags.tablet;
- _tags.cordova = _tags.phonegap = !!(window.PhoneGap || window.Cordova || window.cordova);
- _tags.webview = /(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)(?!.*FBAN)/i.test(ua);
- _tags.androidstock = (_tags.android <= 4.3) && (_tags.safari || _tags.silk);
- // Re-apply any query params here to allow for user override of generated tags (desktop, touch, tablet, etc)
- _merge(_tags, platformParams, true);
- },
- /**
- * Extracts user supplied platform tags from the "platformTags" query parameter
- * of the form:
- *
- * ?platformTags=name:state,name:state,...
- *
- * (each tag defaults to true when state is unspecified)
- *
- * Example:
- *
- * ?platformTags=isTablet,isPhone:false,isDesktop:0,iOS:1,Safari:true, ...
- *
- * @returns {Object} the platform tags supplied by the query string
- */
- loadPlatformsParam: function() {
- // Check if the ?platform parameter is set in the URL
- var paramsString = window.location.search.substr(1),
- paramsArray = paramsString.split("&"),
- params = {},
- i,
- platforms = {},
- tmpArray, tmplen, platform, name, enabled;
- for (i = 0; i < paramsArray.length; i++) {
- tmpArray = paramsArray[i].split("=");
- params[tmpArray[0]] = tmpArray[1];
- }
- if (params.platformTags) {
- tmpArray = params.platformTags.split(",");
- for (tmplen = tmpArray.length , i = 0; i < tmplen; i++) {
- platform = tmpArray[i].split(":");
- name = platform[0];
- enabled = true;
- if (platform.length > 1) {
- enabled = platform[1];
- if (enabled === 'false' || enabled === '0') {
- enabled = false;
- }
- }
- platforms[name] = enabled;
- }
- }
- return platforms;
- },
- filterPlatform: function(platform, excludes) {
- platform = _emptyArray.concat(platform || _emptyArray);
- excludes = _emptyArray.concat(excludes || _emptyArray);
- var plen = platform.length,
- elen = excludes.length,
- include = (!plen && elen),
- // default true if only excludes specified
- i, tag;
- for (i = 0; i < plen && !include; i++) {
- tag = platform[i];
- include = !!_tags[tag];
- }
- for (i = 0; i < elen && include; i++) {
- tag = excludes[i];
- include = !_tags[tag];
- }
- return include;
- },
- init: function() {
- var scriptEls = doc.getElementsByTagName('script'),
- script = scriptEls[0],
- len = scriptEls.length,
- re = /\/ext(\-[a-z\-]+)?\.js$/,
- entry, src, state, baseUrl, key, n, origin;
- // No check for script definedness because there always should be at least one
- Boot.hasReadyState = ("readyState" in script);
- Boot.hasAsync = ("async" in script);
- Boot.hasDefer = ("defer" in script);
- Boot.hasOnLoad = ("onload" in script);
- // Feature detecting IE
- Boot.isIE8 = Boot.hasReadyState && !Boot.hasAsync && Boot.hasDefer && !Boot.hasOnLoad;
- Boot.isIE9 = Boot.hasReadyState && !Boot.hasAsync && Boot.hasDefer && Boot.hasOnLoad;
- Boot.isIE10p = Boot.hasReadyState && Boot.hasAsync && Boot.hasDefer && Boot.hasOnLoad;
- if (Boot.isIE8) {
- Boot.isIE10 = false;
- Boot.isIE10m = true;
- } else {
- Boot.isIE10 = navigator.appVersion.indexOf('MSIE 10') !== -1;
- Boot.isIE10m = Boot.isIE10 || Boot.isIE9 || Boot.isIE8;
- }
- // IE11 does not support conditional compilation so we detect it by exclusion
- Boot.isIE11 = Boot.isIE10p && !Boot.isIE10;
- // Since we are loading after other scripts, and we needed to gather them
- // anyway, we track them in _scripts so we don't have to ask for them all
- // repeatedly.
- for (n = 0; n < len; n++) {
- src = (script = scriptEls[n]).src;
- if (!src) {
-
- continue;
- }
- state = script.readyState || null;
- // If we find a script file called "ext-*.js", then the base path is that file's base path.
- if (!baseUrl && re.test(src)) {
- baseUrl = src;
- }
- if (!Boot.scripts[key = Boot.canonicalUrl(src)]) {
- // _debug("creating entry " + key + " in Boot.init");
- entry = new Entry({
- key: key,
- url: src,
- done: state === null || // non-IE
- state === 'loaded' || state === 'complete',
- // IE only
- el: script,
- prop: 'src'
- });
- }
- }
- if (!baseUrl) {
- script = scriptEls[scriptEls.length - 1];
- baseUrl = script.src;
- }
- Boot.baseUrl = baseUrl.substring(0, baseUrl.lastIndexOf('/') + 1);
- origin = window.location.origin || window.location.protocol + "//" + window.location.hostname + (window.location.port ? ':' + window.location.port : '');
- Boot.origin = origin;
- Boot.detectPlatformTags();
- Ext.filterPlatform = Boot.filterPlatform;
- },
- /**
- * This method returns a canonical URL for the given URL.
- *
- * For example, the following all produce the same canonical URL (which is the
- * last one):
- *
- * http://foo.com/bar/baz/zoo/derp/../../goo/Thing.js?_dc=12345
- * http://foo.com/bar/baz/zoo/derp/../../goo/Thing.js
- * http://foo.com/bar/baz/zoo/derp/../jazz/../../goo/Thing.js
- * http://foo.com/bar/baz/zoo/../goo/Thing.js
- * http://foo.com/bar/baz/goo/Thing.js
- *
- * @private
- */
- canonicalUrl: function(url) {
- // *WARNING WARNING WARNING*
- // This method yields the most correct result we can get but it is EXPENSIVE!
- // In ALL browsers! When called multiple times in a sequence, as if when
- // we resolve dependencies for entries, it will cause garbage collection events
- // and overall painful slowness. This is why we try to avoid it as much as we can.
- //
- // @TODO - see if we need this fallback logic
- // http://stackoverflow.com/questions/470832/getting-an-absolute-url-from-a-relative-one-ie6-issue
- resolverEl.href = url;
- var ret = resolverEl.href,
- dc = _config.disableCachingParam,
- pos = dc ? ret.indexOf(dc + '=') : -1,
- c, end;
- // If we have a _dc query parameter we need to remove it from the canonical
- // URL.
- if (pos > 0 && ((c = ret.charAt(pos - 1)) === '?' || c === '&')) {
- end = ret.indexOf('&', pos);
- end = (end < 0) ? '' : ret.substring(end);
- if (end && c === '?') {
- ++pos;
- // keep the '?'
- end = end.substring(1);
- }
- // remove the '&'
- ret = ret.substring(0, pos - 1) + end;
- }
- return ret;
- },
- /**
- * Get the config value corresponding to the specified name. If no name is given, will return the config object
- * @param {String} name The config property name
- * @return {Object}
- */
- getConfig: function(name) {
- return name ? Boot.config[name] : Boot.config;
- },
- /**
- * Set the configuration.
- * @param {Object} config The config object to override the default values.
- * @return {Ext.Boot} this
- */
- setConfig: function(name, value) {
- if (typeof name === 'string') {
- Boot.config[name] = value;
- } else {
- for (var s in name) {
- Boot.setConfig(s, name[s]);
- }
- }
- return Boot;
- },
- getHead: function() {
- return Boot.docHead || (Boot.docHead = doc.head || doc.getElementsByTagName('head')[0]);
- },
- create: function(url, key, cfg) {
- var config = cfg || {};
- config.url = url;
- config.key = key;
- return Boot.scripts[key] = new Entry(config);
- },
- getEntry: function(url, cfg, canonicalPath) {
- var key, entry;
- // Canonicalizing URLs via anchor element href yields the most correct result
- // but is *extremely* resource heavy so we need to avoid it whenever possible
- key = canonicalPath ? url : Boot.canonicalUrl(url);
- entry = Boot.scripts[key];
- if (!entry) {
- entry = Boot.create(url, key, cfg);
- if (canonicalPath) {
- entry.canonicalPath = true;
- }
- }
- return entry;
- },
- registerContent: function(url, type, content) {
- var cfg = {
- content: content,
- loaded: true,
- css: type === 'css'
- };
- return Boot.getEntry(url, cfg);
- },
- processRequest: function(request, sync) {
- request.loadEntries(sync);
- },
- load: function(request) {
- // _debug("Boot.load called");
- var request = new Request(request);
- if (request.sync || Boot.syncMode) {
- return Boot.loadSync(request);
- }
- // If there is a request in progress, we must
- // queue this new request to be fired when the current request completes.
- if (Boot.currentRequest) {
- // _debug("current active request, suspending this request");
- // trigger assignment of entries now to ensure that overlapping
- // entries with currently running requests will synchronize state
- // with this pending one as they complete
- request.getEntries();
- Boot.suspendedQueue.push(request);
- } else {
- Boot.currentRequest = request;
- Boot.processRequest(request, false);
- }
- return Boot;
- },
- loadSync: function(request) {
- // _debug("Boot.loadSync called");
- var request = new Request(request);
- Boot.syncMode++;
- Boot.processRequest(request, true);
- Boot.syncMode--;
- return Boot;
- },
- loadBasePrefix: function(request) {
- request = new Request(request);
- request.prependBaseUrl = true;
- return Boot.load(request);
- },
- loadSyncBasePrefix: function(request) {
- request = new Request(request);
- request.prependBaseUrl = true;
- return Boot.loadSync(request);
- },
- requestComplete: function(request) {
- var next;
- if (Boot.currentRequest === request) {
- Boot.currentRequest = null;
- while (Boot.suspendedQueue.length > 0) {
- next = Boot.suspendedQueue.shift();
- if (!next.done) {
- // _debug("resuming suspended request");
- Boot.load(next);
- break;
- }
- }
- }
- if (!Boot.currentRequest && Boot.suspendedQueue.length == 0) {
- Boot.fireListeners();
- }
- },
- isLoading: function() {
- return !Boot.currentRequest && Boot.suspendedQueue.length == 0;
- },
- fireListeners: function() {
- var listener;
- while (Boot.isLoading() && (listener = Boot.listeners.shift())) {
- listener();
- }
- },
- onBootReady: function(listener) {
- if (!Boot.isLoading()) {
- listener();
- } else {
- Boot.listeners.push(listener);
- }
- },
- /**
- * this is a helper function used by Ext.Loader to flush out
- * 'uses' arrays for classes in some Ext versions
- */
- getPathsFromIndexes: function(indexMap, loadOrder) {
- // In older versions indexMap was an object instead of a sparse array
- if (!('length' in indexMap)) {
- var indexArray = [],
- index;
- for (index in indexMap) {
- if (!isNaN(+index)) {
- indexArray[+index] = indexMap[index];
- }
- }
- indexMap = indexArray;
- }
- return Request.prototype.getPathsFromIndexes(indexMap, loadOrder);
- },
- createLoadOrderMap: function(loadOrder) {
- return Request.prototype.createLoadOrderMap(loadOrder);
- },
- fetch: function(url, complete, scope, async) {
- async = (async === undefined) ? !!complete : async;
- var xhr = new XMLHttpRequest(),
- result, status, content,
- exception = false,
- readyStateChange = function() {
- if (xhr && xhr.readyState == 4) {
- status = (xhr.status === 1223) ? 204 : (xhr.status === 0 && ((self.location || {}).protocol === 'file:' || (self.location || {}).protocol === 'ionp:')) ? 200 : xhr.status;
- content = xhr.responseText;
- result = {
- content: content,
- status: status,
- exception: exception
- };
- if (complete) {
- complete.call(scope, result);
- }
- xhr.onreadystatechange = emptyFn;
- xhr = null;
- }
- };
- if (async) {
- xhr.onreadystatechange = readyStateChange;
- }
- try {
- // _debug("fetching " + url + " " + (async ? "async" : "sync"));
- xhr.open('GET', url, async);
- xhr.send(null);
- } catch (err) {
- exception = err;
- readyStateChange();
- return result;
- }
- if (!async) {
- readyStateChange();
- }
- return result;
- },
- notifyAll: function(entry) {
- entry.notifyRequests();
- }
- };
- function Request(cfg) {
- //The request class encapsulates a series of Entry objects
- //and provides notification around the completion of all Entries
- //in this request.
- if (cfg.$isRequest) {
- return cfg;
- }
- var cfg = cfg.url ? cfg : {
- url: cfg
- },
- url = cfg.url,
- urls = url.charAt ? [
- url
- ] : url,
- charset = cfg.charset || Boot.config.charset;
- _apply(this, cfg);
- delete this.url;
- this.urls = urls;
- this.charset = charset;
- }
-
- Request.prototype = {
- $isRequest: true,
- createLoadOrderMap: function(loadOrder) {
- var len = loadOrder.length,
- loadOrderMap = {},
- i, element;
- for (i = 0; i < len; i++) {
- element = loadOrder[i];
- loadOrderMap[element.path] = element;
- }
- return loadOrderMap;
- },
- getLoadIndexes: function(item, indexMap, loadOrder, includeUses, skipLoaded) {
- var resolved = [],
- queue = [
- item
- ],
- itemIndex = item.idx,
- queue, entry, dependencies, depIndex, i, len;
- if (indexMap[itemIndex]) {
- // prevent cycles
- return resolved;
- }
- // Both indexMap and resolved are sparse arrays keyed by indexes.
- // This gives us a naturally sorted sequence of indexes later on
- // when we need to convert them to paths.
- // indexMap is the map of all indexes we have visited at least once
- // per the current expandUrls() invocation, and resolved is the map
- // of all dependencies for the current item that are not included
- // in indexMap.
- indexMap[itemIndex] = resolved[itemIndex] = true;
- while (item = queue.shift()) {
- // Canonicalizing URLs is expensive, we try to avoid it
- if (item.canonicalPath) {
- entry = Boot.getEntry(item.path, null, true);
- } else {
- entry = Boot.getEntry(this.prepareUrl(item.path));
- }
- if (!(skipLoaded && entry.done)) {
- if (includeUses && item.uses && item.uses.length) {
- dependencies = item.requires.concat(item.uses);
- } else {
- dependencies = item.requires;
- }
- for (i = 0 , len = dependencies.length; i < len; i++) {
- depIndex = dependencies[i];
- if (!indexMap[depIndex]) {
- indexMap[depIndex] = resolved[depIndex] = true;
- queue.push(loadOrder[depIndex]);
- }
- }
- }
- }
- return resolved;
- },
- getPathsFromIndexes: function(indexes, loadOrder) {
- var paths = [],
- index, len;
- // indexes is a sparse array with values being true for defined indexes
- for (index = 0 , len = indexes.length; index < len; index++) {
- if (indexes[index]) {
- paths.push(loadOrder[index].path);
- }
- }
- return paths;
- },
- expandUrl: function(url, loadOrder, loadOrderMap, indexMap, includeUses, skipLoaded) {
- var item, resolved;
- if (loadOrder) {
- item = loadOrderMap[url];
- if (item) {
- resolved = this.getLoadIndexes(item, indexMap, loadOrder, includeUses, skipLoaded);
- if (resolved.length) {
- return this.getPathsFromIndexes(resolved, loadOrder);
- }
- }
- }
- return [
- url
- ];
- },
- expandUrls: function(urls, includeUses) {
- var me = this,
- loadOrder = me.loadOrder,
- expanded = [],
- expandMap = {},
- indexMap = [],
- loadOrderMap, tmpExpanded, i, len, t, tlen, tUrl;
- if (typeof urls === "string") {
- urls = [
- urls
- ];
- }
- if (loadOrder) {
- loadOrderMap = me.loadOrderMap;
- if (!loadOrderMap) {
- loadOrderMap = me.loadOrderMap = me.createLoadOrderMap(loadOrder);
- }
- }
- for (i = 0 , len = urls.length; i < len; i++) {
- // We don't want to skip loaded entries (last argument === false).
- // There are some overrides that get loaded before their respective classes,
- // and when the class dependencies are processed we don't want to skip over
- // the overrides' dependencies just because they were loaded first.
- tmpExpanded = this.expandUrl(urls[i], loadOrder, loadOrderMap, indexMap, includeUses, false);
- for (t = 0 , tlen = tmpExpanded.length; t < tlen; t++) {
- tUrl = tmpExpanded[t];
- if (!expandMap[tUrl]) {
- expandMap[tUrl] = true;
- expanded.push(tUrl);
- }
- }
- }
- if (expanded.length === 0) {
- expanded = urls;
- }
- return expanded;
- },
- expandLoadOrder: function() {
- var me = this,
- urls = me.urls,
- expanded;
- if (!me.expanded) {
- expanded = this.expandUrls(urls, true);
- me.expanded = true;
- } else {
- expanded = urls;
- }
- me.urls = expanded;
- // if we added some urls to the request to honor the indicated
- // load order, the request needs to be sequential
- if (urls.length != expanded.length) {
- me.sequential = true;
- }
- return me;
- },
- getUrls: function() {
- this.expandLoadOrder();
- return this.urls;
- },
- prepareUrl: function(url) {
- if (this.prependBaseUrl) {
- return Boot.baseUrl + url;
- }
- return url;
- },
- getEntries: function() {
- var me = this,
- entries = me.entries,
- loadOrderMap, item, i, entry, urls, url;
- if (!entries) {
- entries = [];
- urls = me.getUrls();
- // If we have loadOrder array then the map will be expanded by now
- if (me.loadOrder) {
- loadOrderMap = me.loadOrderMap;
- }
- for (i = 0; i < urls.length; i++) {
- url = me.prepareUrl(urls[i]);
- if (loadOrderMap) {
- item = loadOrderMap[url];
- }
- entry = Boot.getEntry(url, {
- buster: me.buster,
- charset: me.charset
- }, item && item.canonicalPath);
- entry.requests.push(me);
- entries.push(entry);
- }
- me.entries = entries;
- }
- return entries;
- },
- loadEntries: function(sync) {
- var me = this,
- entries = me.getEntries(),
- len = entries.length,
- start = me.loadStart || 0,
- continueLoad, entries, entry, i;
- if (sync !== undefined) {
- me.sync = sync;
- }
- me.loaded = me.loaded || 0;
- me.loading = me.loading || len;
- for (i = start; i < len; i++) {
- entry = entries[i];
- if (!entry.loaded) {
- continueLoad = entries[i].load(me.sync);
- } else {
- continueLoad = true;
- }
- if (!continueLoad) {
- me.loadStart = i;
- entry.onDone(function() {
- me.loadEntries(sync);
- });
- break;
- }
- }
- me.processLoadedEntries();
- },
- processLoadedEntries: function() {
- var me = this,
- entries = me.getEntries(),
- len = entries.length,
- start = me.startIndex || 0,
- i, entry;
- if (!me.done) {
- for (i = start; i < len; i++) {
- entry = entries[i];
- if (!entry.loaded) {
- me.startIndex = i;
- return;
- }
- if (!entry.evaluated) {
- entry.evaluate();
- }
- if (entry.error) {
- me.error = true;
- }
- }
- me.notify();
- }
- },
- notify: function() {
- var me = this;
- if (!me.done) {
- var error = me.error,
- fn = me[error ? 'failure' : 'success'],
- delay = ('delay' in me) ? me.delay : (error ? 1 : Boot.config.chainDelay),
- scope = me.scope || me;
- me.done = true;
- if (fn) {
- if (delay === 0 || delay > 0) {
- // Free the stack (and defer the next script)
- setTimeout(function() {
- fn.call(scope, me);
- }, delay);
- } else {
- fn.call(scope, me);
- }
- }
- me.fireListeners();
- Boot.requestComplete(me);
- }
- },
- onDone: function(listener) {
- var me = this,
- listeners = me.listeners || (me.listeners = []);
- if (me.done) {
- listener(me);
- } else {
- listeners.push(listener);
- }
- },
- fireListeners: function() {
- var listeners = this.listeners,
- listener;
- if (listeners) {
- // _debug("firing request listeners");
- while ((listener = listeners.shift())) {
- listener(this);
- }
- }
- }
- };
- function Entry(cfg) {
- //The Entry class is a token to manage the load and evaluation
- //state of a particular url. It is used to notify all Requests
- //interested in this url that the content is available.
- if (cfg.$isEntry) {
- return cfg;
- }
- // _debug("creating entry for " + cfg.url);
- var charset = cfg.charset || Boot.config.charset,
- manifest = Ext.manifest,
- loader = manifest && manifest.loader,
- cache = (cfg.cache !== undefined) ? cfg.cache : (loader && loader.cache),
- buster, busterParam;
- if (Boot.config.disableCaching) {
- if (cache === undefined) {
- cache = !Boot.config.disableCaching;
- }
- if (cache === false) {
- buster = +new Date();
- } else if (cache !== true) {
- buster = cache;
- }
- if (buster) {
- busterParam = (loader && loader.cacheParam) || Boot.config.disableCachingParam;
- buster = busterParam + "=" + buster;
- }
- }
- _apply(this, cfg);
- this.charset = charset;
- this.buster = buster;
- this.requests = [];
- }
-
- Entry.prototype = {
- $isEntry: true,
- done: false,
- evaluated: false,
- loaded: false,
- isCrossDomain: function() {
- var me = this;
- if (me.crossDomain === undefined) {
- // _debug("checking " + me.getLoadUrl() + " for prefix " + Boot.origin);
- me.crossDomain = (me.getLoadUrl().indexOf(Boot.origin) !== 0);
- }
- return me.crossDomain;
- },
- isCss: function() {
- var me = this;
- if (me.css === undefined) {
- if (me.url) {
- var assetConfig = Boot.assetConfig[me.url];
- me.css = assetConfig ? assetConfig.type === "css" : cssRe.test(me.url);
- } else {
- me.css = false;
- }
- }
- return this.css;
- },
- getElement: function(tag) {
- var me = this,
- el = me.el;
- if (!el) {
- // _debug("creating element for " + me.url);
- if (me.isCss()) {
- tag = tag || "link";
- el = doc.createElement(tag);
- if (tag == "link") {
- el.rel = 'stylesheet';
- me.prop = 'href';
- } else {
- me.prop = "textContent";
- }
- el.type = "text/css";
- } else {
- tag = tag || "script";
- el = doc.createElement(tag);
- el.type = 'text/javascript';
- me.prop = 'src';
- if (me.charset) {
- el.charset = me.charset;
- }
- if (Boot.hasAsync) {
- el.async = false;
- }
- }
- me.el = el;
- }
- return el;
- },
- getLoadUrl: function() {
- var me = this,
- url;
- url = me.canonicalPath ? me.url : Boot.canonicalUrl(me.url);
- if (!me.loadUrl) {
- me.loadUrl = !!me.buster ? (url + (url.indexOf('?') === -1 ? '?' : '&') + me.buster) : url;
- }
- return me.loadUrl;
- },
- fetch: function(req) {
- var url = this.getLoadUrl(),
- async = !!req.async,
- complete = req.complete;
- Boot.fetch(url, complete, this, async);
- },
- onContentLoaded: function(response) {
- var me = this,
- status = response.status,
- content = response.content,
- exception = response.exception,
- url = this.getLoadUrl();
- me.loaded = true;
- if ((exception || status === 0) && !_environment.phantom) {
- me.error = ("Failed loading synchronously via XHR: '" + url + "'. It's likely that the file is either being loaded from a " + "different domain or from the local file system where cross " + "origin requests are not allowed for security reasons. Try " + "asynchronous loading instead.") || true;
- me.evaluated = true;
- } else if ((status >= 200 && status < 300) || status === 304 || _environment.phantom || (status === 0 && content.length > 0)) {
- me.content = content;
- } else {
- me.error = ("Failed loading synchronously via XHR: '" + url + "'. Please verify that the file exists. XHR status code: " + status) || true;
- me.evaluated = true;
- }
- },
- createLoadElement: function(callback) {
- var me = this,
- el = me.getElement();
- me.preserve = true;
- el.onerror = function() {
- me.error = true;
- if (callback) {
- callback();
- callback = null;
- }
- };
- if (Boot.isIE10m) {
- el.onreadystatechange = function() {
- if (this.readyState === 'loaded' || this.readyState === 'complete') {
- if (callback) {
- callback();
- callback = this.onreadystatechange = this.onerror = null;
- }
- }
- };
- } else {
- el.onload = function() {
- callback();
- callback = this.onload = this.onerror = null;
- };
- }
- // IE starts loading here
- el[me.prop] = me.getLoadUrl();
- },
- onLoadElementReady: function() {
- Boot.getHead().appendChild(this.getElement());
- this.evaluated = true;
- },
- inject: function(content, asset) {
- // _debug("injecting content for " + this.url);
- var me = this,
- head = Boot.getHead(),
- url = me.url,
- key = me.key,
- base, el, ieMode, basePath;
- if (me.isCss()) {
- me.preserve = true;
- basePath = key.substring(0, key.lastIndexOf("/") + 1);
- base = doc.createElement('base');
- base.href = basePath;
- if (head.firstChild) {
- head.insertBefore(base, head.firstChild);
- } else {
- head.appendChild(base);
- }
- // reset the href attribute to cuase IE to pick up the change
- base.href = base.href;
- if (url) {
- content += "\n/*# sourceURL=" + key + " */";
- }
- // create element after setting base
- el = me.getElement("style");
- ieMode = ('styleSheet' in el);
- head.appendChild(base);
- if (ieMode) {
- head.appendChild(el);
- el.styleSheet.cssText = content;
- } else {
- el.textContent = content;
- head.appendChild(el);
- }
- head.removeChild(base);
- } else {
- // Debugger friendly, file names are still shown even though they're
- // eval'ed code. Breakpoints work on both Firebug and Chrome's Web
- // Inspector.
- if (url) {
- content += "\n//# sourceURL=" + key;
- }
- Ext.globalEval(content);
- }
- return me;
- },
- loadCrossDomain: function() {
- var me = this,
- complete = function() {
- me.el.onerror = me.el.onload = emptyFn;
- me.el = null;
- me.loaded = me.evaluated = me.done = true;
- me.notifyRequests();
- };
- me.createLoadElement(function() {
- complete();
- });
- me.evaluateLoadElement();
- // at this point, we need sequential evaluation,
- // which means we can't advance the load until
- // this entry has fully completed
- return false;
- },
- loadElement: function() {
- var me = this,
- complete = function() {
- me.el.onerror = me.el.onload = emptyFn;
- me.el = null;
- me.loaded = me.evaluated = me.done = true;
- me.notifyRequests();
- };
- me.createLoadElement(function() {
- complete();
- });
- me.evaluateLoadElement();
- return true;
- },
- loadSync: function() {
- var me = this;
- me.fetch({
- async: false,
- complete: function(response) {
- me.onContentLoaded(response);
- }
- });
- me.evaluate();
- me.notifyRequests();
- },
- load: function(sync) {
- var me = this;
- if (!me.loaded) {
- if (me.loading) {
- // if we're calling back through load and we're loading but haven't
- // yet loaded, then we should be in a sequential, cross domain
- // load scenario which means we can't continue the load on the
- // request until this entry has fully evaluated, which will mean
- // loaded = evaluated = done = true in one step. For css files, this
- // will happen immediately upon <link> element creation / insertion,
- // but <script> elements will set this upon load notification
- return false;
- }
- me.loading = true;
- // for async modes, we have some options
- if (!sync) {
- // if cross domain, just inject the script tag and let the onload
- // events drive the progression.
- // IE10 also needs sequential loading because of a bug that makes it
- // fire readystate event prematurely:
- // https://connect.microsoft.com/IE/feedback/details/729164/ie10-dynamic-script-element-fires-loaded-readystate-prematurely
- if (Boot.isIE10 || me.isCrossDomain()) {
- return me.loadCrossDomain();
- }
- // for IE, use the readyStateChange allows us to load scripts in parallel
- // but serialize the evaluation by appending the script node to the
- // document
- else if (!me.isCss() && Boot.hasReadyState) {
- me.createLoadElement(function() {
- me.loaded = true;
- me.notifyRequests();
- });
- } else if (Boot.useElements && // older webkit, phantomjs included, won't fire load for link elements
- !(me.isCss() && _environment.phantom)) {
- return me.loadElement();
- } else // for other browsers, just ajax the content down in parallel, and use
- // globalEval to serialize evaluation
- {
- me.fetch({
- async: !sync,
- complete: function(response) {
- me.onContentLoaded(response);
- me.notifyRequests();
- }
- });
- }
- } else // for sync mode in js, global eval FTW. IE won't honor the comment
- // paths in the debugger, so eventually we need a sync mode for IE that
- // uses the readyStateChange mechanism
- {
- me.loadSync();
- }
- }
- // signal that the load process can continue
- return true;
- },
- evaluateContent: function() {
- this.inject(this.content);
- this.content = null;
- },
- evaluateLoadElement: function() {
- Boot.getHead().appendChild(this.getElement());
- },
- evaluate: function() {
- var me = this;
- if (!me.evaluated) {
- if (me.evaluating) {
- return;
- }
- me.evaluating = true;
- if (me.content !== undefined) {
- me.evaluateContent();
- } else if (!me.error) {
- me.evaluateLoadElement();
- }
- me.evaluated = me.done = true;
- me.cleanup();
- }
- },
- cleanup: function() {
- var me = this,
- el = me.el,
- prop;
- if (!el) {
- return;
- }
- if (!me.preserve) {
- me.el = null;
- el.parentNode.removeChild(el);
- // Remove, since its useless now
- for (prop in el) {
- try {
- if (prop !== me.prop) {
- // If we set the src property to null IE
- // will try and request a script at './null'
- el[prop] = null;
- }
- delete el[prop];
- } // and prepare for GC
- catch (cleanEx) {}
- }
- }
- //ignore
- // Setting to null can cause exceptions if IE ever needs to call these
- // again (like onreadystatechange). This emptyFn has nothing locked in
- // closure scope so it is about as safe as null for memory leaks.
- el.onload = el.onerror = el.onreadystatechange = emptyFn;
- },
- notifyRequests: function() {
- var requests = this.requests,
- len = requests.length,
- i, request;
- for (i = 0; i < len; i++) {
- request = requests[i];
- request.processLoadedEntries();
- }
- if (this.done) {
- this.fireListeners();
- }
- },
- onDone: function(listener) {
- var me = this,
- listeners = me.listeners || (me.listeners = []);
- if (me.done) {
- listener(me);
- } else {
- listeners.push(listener);
- }
- },
- fireListeners: function() {
- var listeners = this.listeners,
- listener;
- if (listeners && listeners.length > 0) {
- // _debug("firing event listeners for url " + this.url);
- while ((listener = listeners.shift())) {
- listener(this);
- }
- }
- }
- };
- /**
- * Turns on or off the "cache buster" applied to dynamically loaded scripts. Normally
- * dynamically loaded scripts have an extra query parameter appended to avoid stale
- * cached scripts. This method can be used to disable this mechanism, and is primarily
- * useful for testing. This is done using a cookie.
- * @param {Boolean} disable True to disable the cache buster.
- * @param {String} [path="/"] An optional path to scope the cookie.
- */
- Ext.disableCacheBuster = function(disable, path) {
- var date = new Date();
- date.setTime(date.getTime() + (disable ? 10 * 365 : -1) * 24 * 60 * 60 * 1000);
- date = date.toGMTString();
- doc.cookie = 'ext-cache=1; expires=' + date + '; path=' + (path || '/');
- };
- Boot.init();
- return Boot;
- }(// NOTE: We run the eval at global scope to protect the body of the function and allow
- // compressors to still process it.
- function() {}));
- //(eval("/*@cc_on!@*/!1"));
- /**
- * This method evaluates the given code free of any local variable. This
- * will be at global scope, in others it will be in a function.
- * @param {String} code The code to evaluate.
- * @private
- * @method
- * @member Ext
- */
- Ext.globalEval = Ext.globalEval || (this.execScript ? function(code) {
- execScript(code);
- } : function($$code) {
- eval.call(window, $$code);
- });
- /*
- * Only IE8 & IE/Quirks lack Function.prototype.bind so we polyfill that here.
- */
- if (!Function.prototype.bind) {
- (function() {
- var slice = Array.prototype.slice,
- // To reduce overhead on call of the bound fn we have two flavors based on
- // whether we have args to prepend or not:
- bind = function(me) {
- var args = slice.call(arguments, 1),
- method = this;
- if (args.length) {
- return function() {
- var t = arguments;
- // avoid the slice/concat if the caller does not supply args
- return method.apply(me, t.length ? args.concat(slice.call(t)) : args);
- };
- }
- // this is the majority use case - just fn.bind(this) and no args
- args = null;
- return function() {
- return method.apply(me, arguments);
- };
- };
- Function.prototype.bind = bind;
- bind.$extjs = true;
- }());
- }
- // to detect this polyfill if one want to improve it
- //</editor-fold>
- Ext.setResourcePath = function(poolName, path) {
- var manifest = Ext.manifest || (Ext.manifest = {}),
- paths = manifest.resources || (manifest.resources = {});
- if (manifest) {
- if (typeof poolName !== 'string') {
- Ext.apply(paths, poolName);
- } else {
- paths[poolName] = path;
- }
- manifest.resources = paths;
- }
- };
- Ext.getResourcePath = function(path, poolName, packageName) {
- if (typeof path !== 'string') {
- poolName = path.pool;
- packageName = path.packageName;
- path = path.path;
- }
- var manifest = Ext.manifest,
- paths = manifest && manifest.resources,
- poolPath = paths[poolName],
- output = [];
- if (poolPath == null) {
- poolPath = paths.path;
- if (poolPath == null) {
- poolPath = 'resources';
- }
- }
- if (poolPath) {
- output.push(poolPath);
- }
- if (packageName) {
- output.push(packageName);
- }
- output.push(path);
- return output.join('/');
- };
- // @tag core
- /**
- * @class Ext
- *
- * The Ext namespace (global object) encapsulates all classes, singletons, and
- * utility methods provided by Sencha's libraries.
- *
- * Most user interface Components are at a lower level of nesting in the namespace,
- * but many common utility functions are provided as direct properties of the Ext namespace.
- *
- * Also many frequently used methods from other classes are provided as shortcuts
- * within the Ext namespace. For example {@link Ext#getCmp Ext.getCmp} aliases
- * {@link Ext.ComponentManager#get Ext.ComponentManager.get}.
- *
- * Many applications are initiated with {@link Ext#application Ext.application} which is
- * called once the DOM is ready. This ensures all scripts have been loaded, preventing
- * dependency issues. For example:
- *
- * Ext.application({
- * name: 'MyApp',
- *
- * launch: function () {
- * Ext.Msg.alert(this.getName(), 'Ready to go!');
- * }
- * });
- *
- * <b><a href="http://www.sencha.com/products/sencha-cmd/">Sencha Cmd</a></b> is a free tool
- * for helping you generate and build Ext JS (and Sencha Touch) applications. See
- * `{@link Ext.app.Application Application}` for more information about creating an app.
- *
- * A lower-level technique that does not use the `Ext.app.Application` architecture is
- * {@link Ext#onReady Ext.onReady}.
- *
- * You can also discuss concepts and issues with others on the
- * <a href="http://www.sencha.com/forum/">Sencha Forums</a>.
- *
- * @singleton
- */
- var Ext = Ext || {};
- // @define Ext
- /* eslint indent: "off" */
- (function() {
- var global = this,
- objectPrototype = Object.prototype,
- toString = objectPrototype.toString,
- enumerables = [
- // 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable',
- 'valueOf',
- 'toLocaleString',
- 'toString',
- 'constructor'
- ],
- emptyFn = Ext.fireIdle = function() {},
- // see GlobalEvents for true fireIdle
- privateFn = function() {},
- identityFn = function(o) {
- return o;
- },
- // eslint-disable-line
- // This is the "$previous" method of a hook function on an instance. When called, it
- // calls through the class prototype by the name of the called method.
- callOverrideParent = function() {
- var method = callOverrideParent.caller.caller;
- // skip callParent (our caller)
- return method.$owner.prototype[method.$name].apply(this, arguments);
- },
- manifest = Ext.manifest || {},
- iterableRe = /\[object\s*(?:Array|Arguments|\w*Collection|\w*List|HTML\s+document\.all\s+class)\]/,
- MSDateRe = /^\\?\/Date\(([-+])?(\d+)(?:[+-]\d{4})?\)\\?\/$/,
- /* eslint-disable-next-line no-unused-vars */
- elevateArgs, elevateFn, elevateRet, elevateScope, i;
- Ext.global = global;
- Ext.$nextIid = 0;
- /**
- * Returns the current timestamp.
- * @return {Number} Milliseconds since UNIX epoch.
- * @method now
- * @member Ext
- */
- Ext.now = Date.now || (Date.now = function() {
- return +new Date();
- });
- /**
- * Returns the current high-resolution timestamp.
- * @return {Number} Milliseconds ellapsed since arbitrary epoch.
- * @method ticks
- * @member Ext
- * @since 6.0.1
- */
- Ext.ticks = (global.performance && global.performance.now) ? function() {
- return performance.now();
- } : Ext.now;
- Ext._startTime = Ext.ticks();
- // Mark these special fn's for easy identification:
- emptyFn.$nullFn = identityFn.$nullFn = emptyFn.$emptyFn = identityFn.$identityFn = privateFn.$nullFn = true;
- privateFn.$privacy = 'framework';
- // We also want to prevent these functions from being cleaned up on destroy
- emptyFn.$noClearOnDestroy = identityFn.$noClearOnDestroy = true;
- privateFn.$noClearOnDestroy = true;
- // These are emptyFn's in core and are redefined only in Ext JS (we use this syntax
- // so Cmd does not detect them):
- /* eslint-disable-next-line dot-notation */
- Ext['suspendLayouts'] = Ext['resumeLayouts'] = emptyFn;
- for (i in {
- toString: 1
- }) {
- enumerables = null;
- }
- /**
- * An array containing extra enumerables for old browsers
- * @property {String[]}
- */
- Ext.enumerables = enumerables;
- /**
- * Copies all the properties of `config` to the specified `object`. There are two levels
- * of defaulting supported:
- *
- * Ext.apply(obj, { a: 1 }, { a: 2 });
- * //obj.a === 1
- *
- * Ext.apply(obj, { }, { a: 2 });
- * //obj.a === 2
- *
- * Note that if recursive merging and cloning without referencing the original objects
- * or arrays is needed, use {@link Ext.Object#merge} instead.
- *
- * @param {Object} object The receiver of the properties.
- * @param {Object} config The primary source of the properties.
- * @param {Object} [defaults] An object that will also be applied for default values.
- * @return {Object} returns `object`.
- */
- Ext.apply = function(object, config, defaults) {
- var i, j, k;
- if (object) {
- if (defaults) {
- Ext.apply(object, defaults);
- }
- if (config && typeof config === 'object') {
- for (i in config) {
- object[i] = config[i];
- }
- if (enumerables) {
- for (j = enumerables.length; j--; ) {
- k = enumerables[j];
- if (config.hasOwnProperty(k)) {
- object[k] = config[k];
- }
- }
- }
- }
- }
- return object;
- };
- // Used by Ext.override
- function addInstanceOverrides(target, owner, overrides) {
- var name, value;
- for (name in overrides) {
- if (overrides.hasOwnProperty(name)) {
- value = overrides[name];
- if (typeof value === 'function') {
- if (owner.$className) {
- value.name = owner.$className + '#' + name;
- }
- value.$name = name;
- value.$owner = owner;
- value.$previous = target.hasOwnProperty(name) ? target[name] : // already hooked, so call previous hook
- callOverrideParent;
- }
- // calls by name on prototype
- target[name] = value;
- }
- }
- }
- Ext.buildSettings = Ext.apply({
- baseCSSPrefix: 'x-'
- }, Ext.buildSettings || {});
- Ext.apply(Ext, {
- /**
- * @private
- */
- idSeed: 0,
- /**
- * @private
- */
- idPrefix: 'ext-',
- /**
- * @private
- */
- isRobot: false,
- /**
- * @property {Boolean} isSecure
- * True if the page is running over SSL
- * @readonly
- */
- isSecure: /^https/i.test(window.location.protocol),
- /**
- * `true` to automatically uncache orphaned Ext.Elements periodically. If set to
- * `false`, the application will be required to clean up orphaned Ext.Elements and
- * it's listeners as to not cause memory leakage.
- */
- enableGarbageCollector: false,
- /**
- * True to automatically purge event listeners during garbageCollection.
- */
- enableListenerCollection: true,
- /**
- * @property {String} [name='Ext']
- * The name of the property in the global namespace (The `window` in browser
- * environments) which refers to the current instance of Ext.
- * This is usually `"Ext"`, but if a sandboxed build of ExtJS is being used, this will be
- * an alternative name.
- * If code is being generated for use by `eval` or to create a `new Function`, and the
- * global instance of Ext must be referenced, this is the name that should be built
- * into the code.
- */
- name: Ext.sandboxName || 'Ext',
- /**
- * @property {Function}
- * A reusable empty function for use as `privates` members.
- *
- * Ext.define('MyClass', {
- * nothing: Ext.emptyFn,
- *
- * privates: {
- * privateNothing: Ext.privateFn
- * }
- * });
- *
- */
- privateFn: privateFn,
- /**
- * @property {Function}
- * A reusable empty function.
- */
- emptyFn: emptyFn,
- /**
- * @property {Function}
- * A reusable identity function that simply returns its first argument.
- */
- identityFn: identityFn,
- /**
- * This indicate the start timestamp of current cycle.
- * It is only reliable during dom-event-initiated cycles and
- * {@link Ext.draw.Animator} initiated cycles.
- */
- frameStartTime: Ext.now(),
- /**
- * This object is initialized prior to loading the framework
- * and contains settings and other information describing the application.
- *
- * For applications built using Sencha Cmd, this is produced from the `"app.json"`
- * file with information extracted from all of the required packages' `"package.json"`
- * files. This can be set to a string when your application is using the
- * (microloader)[#/guide/microloader]. In this case, the string of "foo" will be
- * requested as `"foo.json"` and the object in that JSON file will parsed and set
- * as this object.
- *
- * @cfg {String/Ext.Manifest} manifest
- * @since 5.0.0
- */
- manifest: manifest,
- /**
- * @cfg {Object} [debugConfig]
- * This object is used to enable or disable debugging for classes or namespaces. The
- * default instance looks like this:
- *
- * Ext.debugConfig = {
- * hooks: {
- * '*': true
- * }
- * };
- *
- * Typically applications will set this in their `"app.json"` like so:
- *
- * {
- * "debug": {
- * "hooks": {
- * // Default for all namespaces:
- * '*': true,
- *
- * // Except for Ext namespace which is disabled
- * 'Ext': false,
- *
- * // Except for Ext.layout namespace which is enabled
- * 'Ext.layout': true
- * }
- * }
- * }
- *
- * Alternatively, because this property is consumed very early in the load process of
- * the framework, this can be set in a `script` tag that is defined prior to loading
- * the framework itself.
- *
- * For example, to enable debugging for the `Ext.layout` namespace only:
- *
- * var Ext = Ext || {};
- * Ext.debugConfig = {
- * hooks: {
- * //...
- * }
- * };
- *
- * For any class declared, the longest matching namespace specified determines if its
- * `debugHooks` will be enabled. The default setting is specified by the '*' property.
- *
- * **NOTE:** This option only applies to debug builds. All debugging is disabled in
- * production builds.
- */
- debugConfig: Ext.debugConfig || manifest.debug || {
- hooks: {
- '*': true
- }
- },
- /**
- * @property {Boolean} [enableAria=true] This property is provided for backward
- * compatibility with previous versions of Ext JS. Accessibility is always enabled
- * in Ext JS 6.0+.
- *
- * This property is deprecated. To disable WAI-ARIA compatibility warnings,
- * override `Ext.ariaWarn` function in your application startup code:
- *
- * Ext.application({
- * launch: function() {
- * Ext.ariaWarn = Ext.emptyFn;
- * }
- * });
- *
- * For stricter compatibility with WAI-ARIA requirements, replace `Ext.ariaWarn`
- * with a function that will raise an error instead:
- *
- * Ext.application({
- * launch: function() {
- * Ext.ariaWarn = function(target, msg) {
- * Ext.raise({
- * msg: msg,
- * component: target
- * });
- * };
- * }
- * });
- *
- * @since 6.0.0
- * @deprecated 6.0.2 This property is no longer necessary, so no replacement is required.
- */
- enableAria: true,
- startsWithHashRe: /^#/,
- /**
- * @property {RegExp}
- * @private
- * Regular expression used for validating identifiers.
- */
- validIdRe: /^[a-z_][a-z0-9\-_]*$/i,
- /**
- * @property {String} BLANK_IMAGE_URL
- * URL to a 1x1 transparent gif image used by Ext to create inline icons with
- * CSS background images.
- */
- /* eslint-disable-next-line max-len */
- BLANK_IMAGE_URL: 'data:image/gif;base64,R0lGODlhAQABAID/AMDAwAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==',
- /**
- * Converts an id (`'foo'`) into an id selector (`'#foo'`). This method is used
- * internally by the framework whenever an id needs to be converted into a selector
- * and is provided as a hook for those that need to escape IDs selectors since,
- * as of Ext 5.0, the framework no longer escapes IDs by default.
- * @private
- * @param {String} id
- * @return {String}
- */
- makeIdSelector: function(id) {
- if (!Ext.validIdRe.test(id)) {
- Ext.raise('Invalid id selector: "' + id + '"');
- }
- return '#' + id;
- },
- /**
- * Generates unique ids. If the object/element is passes and it already has an `id`, it is
- * unchanged.
- * @param {Object} [o] The object to generate an id for.
- * @param {String} [prefix=ext-gen] (optional) The `id` prefix.
- * @return {String} The generated `id`.
- */
- id: function(o, prefix) {
- if (o && o.id) {
- return o.id;
- }
- /* eslint-disable-next-line vars-on-top */
- var id = (prefix || Ext.idPrefix) + (++Ext.idSeed);
- if (o) {
- o.id = id;
- }
- return id;
- },
- /**
- * A reusable function which returns the value of `getId()` called upon a single passed
- * parameter. Useful when creating a {@link Ext.util.MixedCollection} of objects keyed
- * by an identifier returned from a `getId` method.
- */
- returnId: function(o) {
- return o.getId();
- },
- /**
- * A reusable function which returns `true`.
- */
- returnTrue: function() {
- return true;
- },
- /**
- * A zero length string which will pass a truth test. Useful for passing to methods
- * which use a truth test to reject <i>falsy</i> values where a string value must be
- * cleared.
- */
- emptyString: new String(),
- /**
- * An immutable empty array if Object.freeze is supported by the browser
- * @since 6.5.0
- * @private
- */
- emptyArray: Object.freeze ? Object.freeze([]) : [],
- /**
- * @property {String} [baseCSSPrefix='x-']
- * The base prefix to use for all `Ext` components. To configure this property, you should
- * use the Ext.buildSettings object before the framework is loaded:
- *
- * Ext.buildSettings = {
- * baseCSSPrefix : 'abc-'
- * };
- *
- * or you can change it before any components are rendered:
- *
- * Ext.baseCSSPrefix = Ext.buildSettings.baseCSSPrefix = 'abc-';
- *
- * This will change what CSS classes components will use and you should
- * then recompile the SASS changing the `$prefix` SASS variable to match.
- */
- baseCSSPrefix: Ext.buildSettings.baseCSSPrefix,
- /**
- * @property {Object} $eventNameMap
- * A map of event names which contained the lower-cased versions of any mixed
- * case event names.
- * @private
- */
- $eventNameMap: {},
- // Vendor-specific events do not work if lower-cased. This regex specifies event
- // prefixes for names that should NOT be lower-cased by Ext.canonicalEventName()
- $vendorEventRe: /^(DOMMouse|Moz.+|MS.+|webkit.+)/,
- // TODO: inlinable function - SDKTOOLS-686
- /**
- * @private
- */
- canonicalEventName: function(name) {
- return Ext.$eventNameMap[name] || (Ext.$eventNameMap[name] = (Ext.$vendorEventRe.test(name) ? name : name.toLowerCase()));
- },
- /**
- * Copies all the properties of config to object if they don't already exist.
- * @param {Object} object The receiver of the properties
- * @param {Object} config The source of the properties
- * @return {Object} returns obj
- */
- applyIf: function(object, config) {
- var property;
- if (object && config && typeof config === 'object') {
- for (property in config) {
- if (object[property] === undefined) {
- object[property] = config[property];
- }
- }
- }
- return object;
- },
- /**
- * Destroys all of the given objects. If arrays are passed, the elements of these
- * are destroyed recursively.
- *
- * What it means to "destroy" an object depends on the type of object.
- *
- * * `Array`: Each element of the array is destroyed recursively.
- * * `Object`: Any object with a `destroy` method will have that method called.
- *
- * @param {Mixed...} args Any number of objects or arrays.
- */
- destroy: function() {
- var ln = arguments.length,
- i, arg;
- for (i = 0; i < ln; i++) {
- arg = arguments[i];
- if (arg) {
- if (Ext.isArray(arg)) {
- this.destroy.apply(this, arg);
- } else if (Ext.isFunction(arg.destroy) && !arg.destroyed) {
- arg.destroy();
- }
- }
- }
- return null;
- },
- /**
- * Destroys the specified named members of the given object using `Ext.destroy`. These
- * properties will be set to `null`.
- * @param {Object} object The object who's properties you wish to destroy.
- * @param {String...} args One or more names of the properties to destroy and remove from
- * the object.
- */
- destroyMembers: function(object) {
- /* eslint-disable-next-line vars-on-top */
- for (var ref, name,
- i = 1,
- a = arguments,
- len = a.length; i < len; i++) {
- ref = object[name = a[i]];
- // Avoid adding the property if it does not already exist
- if (ref != null) {
- object[name] = Ext.destroy(ref);
- }
- }
- },
- /**
- * Overrides members of the specified `target` with the given values.
- *
- * If the `target` is a class declared using {@link Ext#define Ext.define}, the
- * `override` method of that class is called (see {@link Ext.Base#override}) given
- * the `overrides`.
- *
- * If the `target` is a function, it is assumed to be a constructor and the contents
- * of `overrides` are applied to its `prototype` using {@link Ext#apply Ext.apply}.
- *
- * If the `target` is an instance of a class declared using {@link Ext#define Ext.define},
- * the `overrides` are applied to only that instance. In this case, methods are
- * specially processed to allow them to use {@link Ext.Base#method!callParent}.
- *
- * var panel = new Ext.Panel({ ... });
- *
- * Ext.override(panel, {
- * initComponent: function () {
- * // extra processing...
- *
- * this.callParent();
- * }
- * });
- *
- * If the `target` is none of these, the `overrides` are applied to the `target`
- * using {@link Ext#apply Ext.apply}.
- *
- * Please refer to {@link Ext#define Ext.define} and {@link Ext.Base#override} for
- * further details.
- *
- * @param {Object} target The target to override.
- * @param {Object} overrides The properties to add or replace on `target`.
- * @method override
- */
- override: function(target, overrides) {
- if (target.$isClass) {
- target.override(overrides);
- } else if (typeof target === 'function') {
- Ext.apply(target.prototype, overrides);
- } else {
- /* eslint-disable-next-line vars-on-top */
- var owner = target.self,
- privates;
- if (owner && owner.$isClass) {
- // if (instance of Ext.define'd class)
- privates = overrides.privates;
- if (privates) {
- overrides = Ext.apply({}, overrides);
- delete overrides.privates;
- addInstanceOverrides(target, owner, privates);
- }
- addInstanceOverrides(target, owner, overrides);
- } else {
- Ext.apply(target, overrides);
- }
- }
- return target;
- },
- /**
- * Returns the given value itself if it's not empty, as described in {@link Ext#isEmpty};
- * returns the default value (second argument) otherwise.
- *
- * @param {Object} value The value to test.
- * @param {Object} defaultValue The value to return if the original value is empty.
- * @param {Boolean} [allowBlank=false] `true` to allow zero length strings to qualify
- * as non-empty.
- * @return {Object} value, if non-empty, else defaultValue.
- */
- valueFrom: function(value, defaultValue, allowBlank) {
- return Ext.isEmpty(value, allowBlank) ? defaultValue : value;
- },
- /**
- * Returns true if the passed value is empty, false otherwise. The value is deemed to be
- * empty if it is either:
- *
- * - `null`
- * - `undefined`
- * - a zero-length array
- * - a zero-length string (Unless the `allowEmptyString` parameter is set to `true`)
- *
- * @param {Object} value The value to test.
- * @param {Boolean} [allowEmptyString=false] `true` to allow empty strings.
- * @return {Boolean}
- */
- isEmpty: function(value, allowEmptyString) {
- return (value == null) || (!allowEmptyString ? value === '' : false) || (Ext.isArray(value) && value.length === 0);
- },
- /**
- * Returns `true` if the passed value is a JavaScript Array, `false` otherwise.
- *
- * @param {Object} target The target to test.
- * @return {Boolean}
- * @method
- */
- isArray: ('isArray' in Array) ? Array.isArray : function(value) {
- return toString.call(value) === '[object Array]';
- },
- /**
- * Returns `true` if the passed value is a JavaScript Date object, `false` otherwise.
- * @param {Object} obj The object to test.
- * @return {Boolean}
- */
- isDate: function(obj) {
- return toString.call(obj) === '[object Date]';
- },
- /**
- * Returns 'true' if the passed value is a String that matches the MS Date JSON
- * encoding format.
- * @param {String} value The string to test.
- * @return {Boolean}
- */
- isMSDate: function(value) {
- if (!Ext.isString(value)) {
- return false;
- }
- return MSDateRe.test(value);
- },
- /**
- * Returns `true` if the passed value is a JavaScript Object, `false` otherwise.
- * @param {Object} value The value to test.
- * @return {Boolean}
- * @method
- */
- isObject: (toString.call(null) === '[object Object]') ? function(value) {
- // check ownerDocument here as well to exclude DOM nodes
- return value != null && toString.call(value) === '[object Object]' && value.ownerDocument === undefined;
- } : function(value) {
- return toString.call(value) === '[object Object]';
- },
- /**
- * @private
- */
- isSimpleObject: function(value) {
- return value instanceof Object && value.constructor === Object;
- },
- /**
- * Returns `true` if the passed value is a JavaScript 'primitive', a string, number
- * or boolean.
- * @param {Object} value The value to test.
- * @return {Boolean}
- */
- isPrimitive: function(value) {
- var type = typeof value;
- return type === 'string' || type === 'number' || type === 'boolean';
- },
- /**
- * Returns `true` if the passed value is a JavaScript Function, `false` otherwise.
- * @param {Object} value The value to test.
- * @return {Boolean}
- * @method
- */
- isFunction: // Safari 3.x and 4.x returns 'function' for typeof <NodeList>, hence we need to fall back
- // to using Object.prototype.toString (slower)
- (typeof document !== 'undefined' && typeof document.getElementsByTagName('body') === 'function') ? function(value) {
- return !!value && toString.call(value) === '[object Function]';
- } : function(value) {
- return !!value && typeof value === 'function';
- },
- /**
- * Returns `true` if the passed value is a number. Returns `false` for non-finite numbers.
- * @param {Object} value The value to test.
- * @return {Boolean}
- */
- isNumber: function(value) {
- return typeof value === 'number' && isFinite(value);
- },
- /**
- * Validates that a value is numeric.
- * @param {Object} value Examples: 1, '1', '2.34'
- * @return {Boolean} True if numeric, false otherwise
- */
- isNumeric: function(value) {
- return !isNaN(parseFloat(value)) && isFinite(value);
- },
- /**
- * Returns `true `if the passed value is a string.
- * @param {Object} value The value to test.
- * @return {Boolean}
- */
- isString: function(value) {
- return typeof value === 'string';
- },
- /**
- * Returns `true` if the passed value is a boolean.
- *
- * @param {Object} value The value to test.
- * @return {Boolean}
- */
- isBoolean: function(value) {
- return typeof value === 'boolean';
- },
- /**
- * Returns `true` if the passed value is an HTMLElement
- * @param {Object} value The value to test.
- * @return {Boolean}
- */
- isElement: function(value) {
- return value ? value.nodeType === 1 : false;
- },
- /**
- * Returns `true` if the passed value is a TextNode
- * @param {Object} value The value to test.
- * @return {Boolean}
- */
- isTextNode: function(value) {
- return value ? value.nodeName === "#text" : false;
- },
- /**
- * Returns `true` if the passed value is defined.
- * @param {Object} value The value to test.
- * @return {Boolean}
- */
- isDefined: function(value) {
- return typeof value !== 'undefined';
- },
- /**
- * Returns `true` if the passed value is iterable, that is, if elements of it are
- * addressable using array notation with numeric indices, `false` otherwise.
- *
- * Arrays and function `arguments` objects are iterable. Also HTML collections such as
- * `NodeList` and `HTMLCollection' are iterable.
- *
- * @param {Object} value The value to test
- * @return {Boolean}
- */
- isIterable: function(value) {
- // To be iterable, the object must have a numeric length property and must not be
- // a string or function.
- if (!value || typeof value.length !== 'number' || typeof value === 'string' || Ext.isFunction(value)) {
- return false;
- }
- // Certain "standard" collections in IE (such as document.images) do not offer
- // the correct Javascript Object interface; specifically, they lack the
- // propertyIsEnumerable method.
- // And the item property while it does exist is not typeof "function"
- if (!value.propertyIsEnumerable) {
- return !!value.item;
- }
- // If it is a regular, interrogatable JS object (not an IE ActiveX object), then...
- // If it has its own property called "length", but not enumerable, it's iterable
- if (value.hasOwnProperty('length') && !value.propertyIsEnumerable('length')) {
- return true;
- }
- // Test against whitelist which includes known iterable collection types
- return iterableRe.test(toString.call(value));
- },
- /**
- * This method returns `true` if debug is enabled for the specified class. This is
- * done by checking the `Ext.debugConfig.hooks` config for the closest match to the
- * given `className`.
- * @param {String} className The name of the class.
- * @return {Boolean} `true` if debug is enabled for the specified class.
- * @method
- */
- isDebugEnabled: function(className, defaultEnabled) {
- var debugConfig = Ext.debugConfig.hooks;
- if (debugConfig.hasOwnProperty(className)) {
- return debugConfig[className];
- }
- /* eslint-disable-next-line vars-on-top */
- var enabled = debugConfig['*'],
- prefixLength = 0;
- if (defaultEnabled !== undefined) {
- enabled = defaultEnabled;
- }
- if (!className) {
- return enabled;
- }
- /* eslint-disable-next-line vars-on-top */
- for (var prefix in debugConfig) {
- var value = debugConfig[prefix];
- // eslint-disable-line vars-on-top
- // if prefix=='Ext' match 'Ext.foo.Bar' but not 'Ext4.foo.Bar'
- if (className.charAt(prefix.length) === '.') {
- if (className.substring(0, prefix.length) === prefix) {
- if (prefixLength < prefix.length) {
- prefixLength = prefix.length;
- enabled = value;
- }
- }
- }
- }
- return enabled;
- } || emptyFn,
- /**
- * Clone simple variables including array, {}-like objects, DOM nodes and Date without
- * keeping the old reference. A reference for the object itself is returned if it's not
- * a direct descendant of Object. For model cloning, see
- * {@link Ext.data.Model#copy Model.copy}.
- *
- * @param {Object} item The variable to clone
- * @param {Boolean} [cloneDom=true] `true` to clone DOM nodes.
- * @return {Object} clone
- */
- clone: function(item, cloneDom) {
- if (item == null) {
- return item;
- }
- // DOM nodes
- // TODO proxy this to Ext.Element.clone to handle automatic id attribute changing
- // recursively
- if (cloneDom !== false && item.nodeType && item.cloneNode) {
- return item.cloneNode(true);
- }
- /* eslint-disable-next-line vars-on-top */
- var type = toString.call(item),
- i, j, k, clone, key;
- // Date
- if (type === '[object Date]') {
- return new Date(item.getTime());
- }
- // Array
- if (type === '[object Array]') {
- i = item.length;
- clone = [];
- while (i--) {
- clone[i] = Ext.clone(item[i], cloneDom);
- }
- }
- // Object
- else if (type === '[object Object]' && item.constructor === Object) {
- clone = {};
- for (key in item) {
- clone[key] = Ext.clone(item[key], cloneDom);
- }
- if (enumerables) {
- for (j = enumerables.length; j--; ) {
- k = enumerables[j];
- if (item.hasOwnProperty(k)) {
- clone[k] = item[k];
- }
- }
- }
- }
- return clone || item;
- },
- /**
- * @private
- * Generate a unique reference of Ext in the global scope, useful for sandboxing
- */
- getUniqueGlobalNamespace: function() {
- var uniqueGlobalNamespace = this.uniqueGlobalNamespace,
- i;
- if (uniqueGlobalNamespace === undefined) {
- i = 0;
- do {
- uniqueGlobalNamespace = 'ExtBox' + (++i);
- } while (global[uniqueGlobalNamespace] !== undefined);
- global[uniqueGlobalNamespace] = Ext;
- this.uniqueGlobalNamespace = uniqueGlobalNamespace;
- }
- return uniqueGlobalNamespace;
- },
- /**
- * @private
- */
- functionFactoryCache: {},
- cacheableFunctionFactory: function() {
- var me = this,
- args = Array.prototype.slice.call(arguments),
- cache = me.functionFactoryCache,
- idx, fn, ln;
- if (Ext.isSandboxed) {
- ln = args.length;
- if (ln > 0) {
- ln--;
- args[ln] = 'var Ext=window.' + Ext.name + ';' + args[ln];
- }
- }
- idx = args.join('');
- fn = cache[idx];
- if (!fn) {
- fn = Function.prototype.constructor.apply(Function.prototype, args);
- cache[idx] = fn;
- }
- return fn;
- },
- functionFactory: function() {
- var args = Array.prototype.slice.call(arguments),
- ln;
- if (Ext.isSandboxed) {
- ln = args.length;
- if (ln > 0) {
- ln--;
- args[ln] = 'var Ext=window.' + Ext.name + ';' + args[ln];
- }
- }
- return Function.prototype.constructor.apply(Function.prototype, args);
- },
- /**
- * @private
- */
- Logger: {
- log: function(message, priority) {
- if (message && global.console) {
- if (!priority || !(priority in global.console)) {
- priority = 'log';
- }
- message = '[' + priority.toUpperCase() + '] ' + message;
- global.console[priority](message);
- }
- },
- verbose: function(message) {
- this.log(message, 'verbose');
- },
- info: function(message) {
- this.log(message, 'info');
- },
- warn: function(message) {
- this.log(message, 'warn');
- },
- error: function(message) {
- throw new Error(message);
- },
- deprecate: function(message) {
- this.log(message, 'warn');
- }
- } || {
- verbose: emptyFn,
- log: emptyFn,
- info: emptyFn,
- warn: emptyFn,
- error: function(message) {
- throw new Error(message);
- },
- deprecate: emptyFn
- },
- ariaWarn: function(target, msg) {
- // The checks still can be disabled by setting Ext.enableAria to false;
- // this is for backwards compatibility. Also make sure we're not running
- // under the slicer, warnings are pointless in that case.
- if (Ext.enableAria && !Ext.slicer) {
- if (!Ext.ariaWarn.first) {
- Ext.ariaWarn.first = true;
- Ext.log.warn("WAI-ARIA compatibility warnings can be suppressed " + "by adding the following to application startup code:");
- Ext.log.warn(" Ext.ariaWarn = Ext.emptyFn;");
- }
- Ext.log.warn({
- msg: msg,
- dump: target
- });
- }
- },
- /**
- * @private
- */
- getElementById: function(id) {
- return document.getElementById(id);
- },
- /**
- * @member Ext
- * @private
- */
- splitAndUnescape: (function() {
- var cache = {};
- return function(origin, delimiter) {
- if (!origin) {
- return [];
- } else if (!delimiter) {
- return [
- origin
- ];
- }
- /* eslint-disable-next-line vars-on-top, max-len */
- var replaceRe = cache[delimiter] || (cache[delimiter] = new RegExp('\\\\' + delimiter, 'g')),
- result = [],
- parts, part;
- parts = origin.split(delimiter);
- while ((part = parts.shift()) !== undefined) {
- // If any of the parts ends with the delimiter that means
- // the delimiter was escaped and the split was invalid. Roll back.
- while (part.charAt(part.length - 1) === '\\' && parts.length > 0) {
- part = part + delimiter + parts.shift();
- }
- // Now that we have split the parts, unescape the delimiter char
- part = part.replace(replaceRe, delimiter);
- result.push(part);
- }
- return result;
- };
- })(),
- /**
- * This is the target of the user-supplied `Ext.elevateFunction`. It wraps the
- * call to a function and concludes by calling {@link Ext#fireIdle}.
- * @since 6.5.1
- * @private
- */
- doElevate: function() {
- var fn = elevateFn,
- args = elevateArgs,
- scope = elevateScope;
- // We really should never re-enter here, but we'll latch these vars just
- // in case.
- elevateFn = elevateArgs = elevateScope = null;
- elevateRet = args ? fn.apply(scope, args) : fn.call(scope);
- // Be sure to fire the idle event while elevated or its handlers will
- // be running in an unprivileged context.
- Ext.fireIdle();
- },
- /**
- * Runs the given `fn` directly or using the user-provided `Ext.elevateFunction`
- * (if present). After calling the `fn` the global `idle` event is fired using
- * the {@link Ext#fireIdle} method.
- *
- * @param {Function} fn
- * @param {Object} [scope]
- * @param {Array} [args]
- * @param {Object} [timer]
- * @return {Mixed}
- * @since 6.5.1
- * @private
- */
- elevate: function(fn, scope, args, timer) // eslint-disable-line comma-style
- {
- var ret;
- if (args && !args.length) {
- args = null;
- }
- Ext._suppressIdle = false;
- if (timer) {
- timer.tick();
- }
- if (Ext.elevateFunction) {
- elevateFn = fn;
- elevateScope = scope;
- elevateArgs = args;
- // We reuse the same fn here to avoid GC pressure.
- Ext.elevateFunction(Ext.doElevate);
- ret = elevateRet;
- elevateRet = null;
- } else {
- ret = args ? fn.apply(scope, args) : fn.call(scope);
- Ext.fireIdle();
- }
- if (timer) {
- timer.tock();
- }
- return ret;
- },
- Timer: {
- all: {},
- track: false,
- captureStack: true,
- created: function(kind, id, info) {
- if (!Ext.Timer.track) {
- return null;
- }
- /* eslint-disable-next-line vars-on-top */
- var timer = Ext.apply({
- kind: kind,
- id: id,
- done: false,
- firing: false,
- creator: Ext.Timer.captureStack ? new Error().stack : null,
- tick: Ext.Timer.tick,
- tock: Ext.Timer.tock
- }, info);
- /* eslint-disable-next-line vars-on-top, one-var */
- var timers = Ext.Timer.all[kind] || (Ext.Timer.all[kind] = {});
- timers[timer.id] = timer;
- if (Ext.Timer.hook) {
- Ext.Timer.hook(timer);
- }
- return timer;
- },
- get: function(id, kind) {
- kind = kind || 'timeout';
- /* eslint-disable-next-line vars-on-top */
- var timers = Ext.Timer.all[kind];
- return timers && timers[id] || null;
- },
- cancel: function(kind, id) {
- var timers = Ext.Timer.all[kind],
- timer = timers && timers[id];
- if (timer) {
- timer.cancelled = true;
- timers[id] = null;
- delete timers[id];
- }
- },
- tick: function() {
- if (Ext.Timer.firing) {
- // One reason for Ext.Timer.firing to get stuck is exception thrown
- // in timer handler. In that case the timer is never tock()ed
- // and will be left hanging. Just clean it up.
- Ext.log.error('Previous timer state not cleaned up properly: ' + Ext.Timer.firing.creator);
- }
- if (this.kind !== 'interval') {
- this.done = true;
- Ext.Timer.all[this.kind][this.id] = null;
- delete Ext.Timer.all[this.kind][this.id];
- }
- this.firing = true;
- Ext.Timer.firing = this;
- },
- tock: function() {
- this.firing = false;
- if (Ext.Timer.firing === this) {
- Ext.Timer.firing = null;
- }
- }
- },
- /**
- * @private
- */
- getExpando: function(target, id) {
- var expandos = target.$expandos;
- return expandos && expandos[id] || null;
- },
- /**
- * @private
- */
- setExpando: function(target, id, value) {
- var expandos = target.$expandos;
- if (value !== undefined) {
- (expandos || (target.$expandos = {}))[id] = value;
- } else if (expandos) {
- delete expandos[id];
- }
- return value;
- }
- });
- Ext.returnTrue.$nullFn = Ext.returnId.$nullFn = true;
- }());
- // @override Ext
- // This file is order extremely early (typically right after Ext.js) due to the
- // above Cmd directive. This ensures that the "modern" and "classic" platform tags
- // are properly set up as soon as possible.
- Ext.platformTags.modern = !(Ext.platformTags.classic = Ext.isClassic = true);
- /* eslint-disable max-len */
- /**
- * A helper class for the native JavaScript Error object that adds a few useful capabilities for handling
- * errors in an application. When you use Ext.Error to {@link #raise} an error from within any class that
- * uses the Class System, the Error class can automatically add the source class and method from which
- * the error was raised. It also includes logic to automatically log the error to the console, if available,
- * with additional metadata about the error. In all cases, the error will always be thrown at the end so that
- * execution will halt.
- *
- * Ext.Error also offers a global error {@link #handle handling} method that can be overridden in order to
- * handle application-wide errors in a single spot. You can optionally {@link #ignore} errors altogether,
- * although in a real application it's usually a better idea to override the handling function and perform
- * logging or some other method of reporting the errors in a way that is meaningful to the application.
- *
- * At its simplest you can simply raise an error as a simple string from within any code:
- *
- * Example usage:
- *
- * Ext.raise('Something bad happened!');
- *
- * If raised from plain JavaScript code, the error will be logged to the console (if available) and the message
- * displayed. In most cases however you'll be raising errors from within a class, and it may often be useful to add
- * additional metadata about the error being raised. The {@link #raise} method can also take a config object.
- * In this form the `msg` attribute becomes the error description, and any other data added to the config gets
- * added to the error object and, if the console is available, logged to the console for inspection.
- *
- * Example usage:
- *
- * Ext.define('Ext.Foo', {
- * doSomething: function(option){
- * if (someCondition === false) {
- * Ext.raise({
- * msg: 'You cannot do that!',
- * option: option, // whatever was passed into the method
- * 'error code': 100 // other arbitrary info
- * });
- * }
- * }
- * });
- *
- * If a console is available (that supports the `console.dir` function) you'll see console output like:
- *
- * An error was raised with the following data:
- * option: Object { foo: "bar"}
- * foo: "bar"
- * error code: 100
- * msg: "You cannot do that!"
- * sourceClass: "Ext.Foo"
- * sourceMethod: "doSomething"
- *
- * uncaught exception: You cannot do that!
- *
- * As you can see, the error will report exactly where it was raised and will include as much information as the
- * raising code can usefully provide.
- *
- * If you want to handle all application errors globally you can simply override the static {@link #handle} method
- * and provide whatever handling logic you need. If the method returns true then the error is considered handled
- * and will not be thrown to the browser. If anything but true is returned then the error will be thrown normally.
- *
- * Example usage:
- *
- * Ext.Error.handle = function(err) {
- * if (err.someProperty == 'NotReallyAnError') {
- * // maybe log something to the application here if applicable
- * return true;
- * }
- * // any non-true return value (including none) will cause the error to be thrown
- * }
- *
- * @class Ext.Error
- */
- /* eslint-enable max-len */
- /* eslint-disable indent */
- (function() {
- // @define Ext.lang.Error
- // @define Ext.Error
- // @require Ext
- function toString() {
- var me = this,
- cls = me.sourceClass,
- method = me.sourceMethod,
- msg = me.msg;
- if (method) {
- if (msg) {
- method += '(): ';
- method += msg;
- } else {
- method += '()';
- }
- }
- if (cls) {
- method = method ? (cls + '.' + method) : cls;
- }
- return method || msg || '';
- }
- Ext.Error = function(config) {
- var error = new Error();
- if (Ext.isString(config)) {
- config = {
- msg: config
- };
- }
- Ext.apply(error, config);
- error.message = error.message || error.msg;
- // 'message' is standard ('msg' is non-standard)
- // note: the above does not work in old WebKit (me.message is readonly) (Safari 4)
- error.toString = toString;
- return error;
- };
- Ext.apply(Ext.Error, {
- /**
- * @property {Boolean} ignore
- * Static flag that can be used to globally disable error reporting to the browser if set
- * to true (defaults to false). Note that if you ignore Ext errors it's likely that some
- * other code may fail and throw a native JavaScript error thereafter, so use with caution.
- * In most cases it will probably be preferable to supply a custom error
- * {@link #handle handling} function instead.
- *
- * Example usage:
- *
- * Ext.Error.ignore = true;
- *
- * @static
- */
- ignore: false,
- /**
- * This method is called internally by {@link Ext#raise}. Application code should
- * call {@link Ext#raise} instead of calling this method directly.
- *
- * @static
- * @deprecated 6.0.0 Use {@link Ext#raise} instead.
- */
- raise: function(err) {
- var me = this,
- method = me.raise.caller,
- msg, name;
- err = err || {};
- if (Ext.isString(err)) {
- err = {
- msg: err
- };
- }
- if (method === Ext.raise) {
- method = method.caller;
- }
- if (method) {
- if (!err.sourceMethod && (name = method.$name)) {
- err.sourceMethod = name;
- }
- if (!err.sourceClass && (name = method.$owner) && (name = name.$className)) {
- err.sourceClass = name;
- }
- }
- if (me.handle(err) !== true) {
- msg = toString.call(err);
- Ext.log({
- msg: msg,
- level: 'error',
- dump: err,
- stack: true
- });
- throw new Ext.Error(err);
- }
- },
- /**
- * Globally handle any Ext errors that may be raised, optionally providing custom logic
- * to handle different errors individually. Return true from the function to bypass
- * throwing the error to the browser, otherwise the error will be thrown and execution
- * will halt.
- *
- * Example usage:
- *
- * Ext.Error.handle = function(err) {
- * if (err.someProperty == 'NotReallyAnError') {
- * // maybe log something to the application here if applicable
- * return true;
- * }
- * // any non-true return value (including none) will cause the error to be thrown
- * }
- *
- * @param {Object} err The error being raised. It will contain any attributes that were
- * originally raised with it, plus properties about the method and class from which
- * the error originated (if raised from a class that uses the Class System).
- * @static
- */
- handle: function() {
- return this.ignore;
- }
- });
- })();
- /**
- * Create a function that will throw an error if called (in debug mode) with a message that
- * indicates the method has been removed.
- * @param {String} suggestion Optional text to include in the message (a workaround perhaps).
- * @return {Function} The generated function.
- * @private
- */
- Ext.deprecated = function(suggestion) {
- if (!suggestion) {
- suggestion = '';
- }
- function fail() {
- Ext.raise('The method "' + fail.$owner.$className + '.' + fail.$name + '" has been removed. ' + suggestion);
- }
- return fail;
- return Ext.emptyFn;
- };
- // eslint-disable-line no-unreachable
- /**
- * Raise an error that can include additional data and supports automatic console logging
- * if available. You can pass a string error message or an object with the `msg` attribute
- * which will be used as the error message. The object can contain any other name-value
- * attributes (or objects) to be logged along with the error.
- *
- * Note that after displaying the error message a JavaScript error will ultimately be
- * thrown so that execution will halt.
- *
- * Example usage:
- *
- * Ext.raise('A simple string error message');
- *
- * // or...
- *
- * Ext.define('Ext.Foo', {
- * doSomething: function(option){
- * if (someCondition === false) {
- * Ext.raise({
- * msg: 'You cannot do that!',
- * option: option, // whatever was passed into the method
- * code: 100 // other arbitrary info
- * });
- * }
- * }
- * });
- *
- * @param {String/Object} err The error message string, or an object containing the
- * attribute "msg" that will be used as the error message. Any other data included in the
- * object will also be logged to the browser console, if available.
- * @method raise
- * @member Ext
- */
- Ext.raise = function() {
- Ext.Error.raise.apply(Ext.Error, arguments);
- };
- /*
- * This mechanism is used to notify the user of the first error encountered on the page. In
- * most cases errors go unobserved especially on IE. This mechanism pushes this information
- * to the status bar so that users don't miss it.
- */
- (function(skipNotify) {
- if (skipNotify || typeof window === 'undefined') {
- return;
- }
- // build system or some such environment...
- // eslint-disable-next-line vars-on-top
- var last = 0,
- // This method is called to notify the user of the current error status.
- notify = function() {
- var cnt = Ext.log && Ext.log.counters,
- n = cnt && (cnt.error + cnt.warn + cnt.info + cnt.log),
- msg;
- // Put log counters to the status bar (for most browsers):
- if (n && last !== n) {
- msg = [];
- if (cnt.error) {
- msg.push('Errors: ' + cnt.error);
- }
- if (cnt.warn) {
- msg.push('Warnings: ' + cnt.warn);
- }
- if (cnt.info) {
- msg.push('Info: ' + cnt.info);
- }
- if (cnt.log) {
- msg.push('Log: ' + cnt.log);
- }
- window.status = '*** ' + msg.join(' -- ');
- last = n;
- }
- };
- // Allow unit tests to skip this when checking for dangling timers
- notify.$skipTimerCheck = true;
- // window.onerror sounds ideal but it prevents the built-in error dialog from doing
- // its (better) thing. We deliberately use setInterval() here instead of going with
- // Ext.interval() to keep it basic and simple.
- setInterval(notify, 1000);
- }(!!window.__UNIT_TESTING__));
- /**
- * @class Ext.Array
- * @singleton
- *
- * A set of useful static methods to deal with arrays; provide missing methods for
- * older browsers.
- */
- Ext.Array = (function() {
- /* eslint-disable indent */
- // @define Ext.lang.Array
- // @define Ext.Array
- // @require Ext
- // @require Ext.lang.Error
- var arrayPrototype = Array.prototype,
- slice = arrayPrototype.slice,
- supportsSplice = (function() {
- var array = [],
- lengthBefore,
- j = 20;
- if (!array.splice) {
- return false;
- }
- // This detects a bug in IE8 splice method:
- // see http://social.msdn.microsoft.com/Forums/en-US/iewebdevelopment/thread/
- // 6e946d03-e09f-4b22-a4dd-cd5e276bf05a/
- while (j--) {
- array.push("A");
- }
- array.splice(15, 0, "F", "F", "F", "F", "F", "F", "F", "F", "F", "F", "F", "F", "F", "F", "F", "F", "F", "F", "F", "F", "F");
- lengthBefore = array.length;
- // 41
- array.splice(13, 0, "XXX");
- // add one element
- if (lengthBefore + 1 !== array.length) {
- return false;
- }
- // end IE8 bug
- return true;
- }()),
- supportsIndexOf = 'indexOf' in arrayPrototype,
- supportsSliceOnNodeList = true;
- // Sort an array using the comparator, but if the comparator returns zero, use the objects'
- // original indices to tiebreak This results in a stable sort.
- function stableSort(array, userComparator) {
- var len = array.length,
- indices = new Array(len),
- i;
- // generate 0-n index map from original array
- for (i = 0; i < len; i++) {
- indices[i] = i;
- }
- // Sort indices array using a comparator which compares the original values at the two
- // indices, and uses those indices as a tiebreaker
- indices.sort(function(index1, index2) {
- return userComparator(array[index1], array[index2]) || (index1 - index2);
- });
- // Reconsitute a sorted array using the array that the indices have been sorted into
- for (i = 0; i < len; i++) {
- indices[i] = array[indices[i]];
- }
- // Rebuild the original array
- for (i = 0; i < len; i++) {
- array[i] = indices[i];
- }
- return array;
- }
- try {
- // IE 6 - 8 will throw an error when using Array.prototype.slice on NodeList
- if (typeof document !== 'undefined') {
- slice.call(document.getElementsByTagName('body'));
- }
- } catch (e) {
- supportsSliceOnNodeList = false;
- }
- /* eslint-disable-next-line vars-on-top */
- var fixArrayIndex = function(array, index) {
- return (index < 0) ? Math.max(0, array.length + index) : Math.min(array.length, index);
- },
- /*
- Does the same work as splice, but with a slightly more convenient signature. The splice
- method has bugs in IE8, so this is the implementation we use on that platform.
- The rippling of items in the array can be tricky. Consider two use cases:
- index=2
- removeCount=2
- /=====\
- +---+---+---+---+---+---+---+---+
- | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
- +---+---+---+---+---+---+---+---+
- / \/ \/ \/ \
- / /\ /\ /\ \
- / / \/ \/ \ +--------------------------+
- / / /\ /\ +--------------------------+ \
- / / / \/ +--------------------------+ \ \
- / / / /+--------------------------+ \ \ \
- / / / / \ \ \ \
- v v v v v v v v
- +---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+---+
- | 0 | 1 | 4 | 5 | 6 | 7 | | 0 | 1 | a | b | c | 4 | 5 | 6 | 7 |
- +---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+---+
- A B \=========/
- insert=[a,b,c]
- In case A, it is obvious that copying of [4,5,6,7] must be left-to-right so
- that we don't end up with [0,1,6,7,6,7]. In case B, we have the opposite; we
- must go right-to-left or else we would end up with [0,1,a,b,c,4,4,4,4].
- */
- replaceSim = function(array, index, removeCount, insert) {
- var add = insert ? insert.length : 0,
- length = array.length,
- pos = fixArrayIndex(array, index);
- // we try to use Array.push when we can for efficiency...
- if (pos === length) {
- if (add) {
- array.push.apply(array, insert);
- }
- } else {
- /* eslint-disable-next-line vars-on-top */
- var remove = Math.min(removeCount, length - pos),
- tailOldPos = pos + remove,
- tailNewPos = tailOldPos + add - remove,
- tailCount = length - tailOldPos,
- lengthAfterRemove = length - remove,
- i;
- if (tailNewPos < tailOldPos) {
- // case A
- for (i = 0; i < tailCount; ++i) {
- array[tailNewPos + i] = array[tailOldPos + i];
- }
- } else if (tailNewPos > tailOldPos) {
- // case B
- for (i = tailCount; i--; ) {
- array[tailNewPos + i] = array[tailOldPos + i];
- }
- }
- // else, add == remove (nothing to do)
- if (add && pos === lengthAfterRemove) {
- array.length = lengthAfterRemove;
- // truncate array
- array.push.apply(array, insert);
- } else {
- array.length = lengthAfterRemove + add;
- // reserves space
- for (i = 0; i < add; ++i) {
- array[pos + i] = insert[i];
- }
- }
- }
- return array;
- },
- replaceNative = function(array, index, removeCount, insert) {
- if (insert && insert.length) {
- // Inserting at index zero with no removing: use unshift
- if (index === 0 && !removeCount) {
- array.unshift.apply(array, insert);
- }
- // Inserting/replacing in middle of array
- else if (index < array.length) {
- array.splice.apply(array, [
- index,
- removeCount
- ].concat(insert));
- } else // Appending to array
- {
- array.push.apply(array, insert);
- }
- } else {
- array.splice(index, removeCount);
- }
- return array;
- },
- eraseSim = function(array, index, removeCount) {
- return replaceSim(array, index, removeCount);
- },
- eraseNative = function(array, index, removeCount) {
- array.splice(index, removeCount);
- return array;
- },
- spliceSim = function(array, index, removeCount) {
- var len = arguments.length,
- pos = fixArrayIndex(array, index),
- removed;
- if (len < 3) {
- removeCount = array.length - pos;
- }
- removed = array.slice(index, fixArrayIndex(array, pos + removeCount));
- if (len < 4) {
- replaceSim(array, pos, removeCount);
- } else {
- replaceSim(array, pos, removeCount, slice.call(arguments, 3));
- }
- return removed;
- },
- spliceNative = function(array) {
- return array.splice.apply(array, slice.call(arguments, 1));
- },
- erase = supportsSplice ? eraseNative : eraseSim,
- replace = supportsSplice ? replaceNative : replaceSim,
- splice = supportsSplice ? spliceNative : spliceSim,
- // NOTE: from here on, use erase, replace or splice (not native methods)...
- ExtArray = {
- /**
- * This method returns the index that a given item would be inserted into the
- * given (sorted) `array`. Note that the given `item` may or may not be in the
- * array. This method will return the index of where the item *should* be.
- *
- * For example:
- *
- * var array = [ 'A', 'D', 'G', 'K', 'O', 'R', 'X' ];
- * var index = Ext.Array.binarySearch(array, 'E');
- *
- * console.log('index: ' + index);
- * // logs "index: 2"
- *
- * array.splice(index, 0, 'E');
- *
- * console.log('array : ' + array.join(''));
- * // logs "array: ADEGKORX"
- *
- * @param {Object[]} array The array to search.
- * @param {Object} item The item that you want to insert into the `array`.
- * @param {Number} [begin=0] The first index in the `array` to consider.
- * @param {Number} [end=array.length] The index that marks the end of the range
- * to consider. The item at this index is *not* considered.
- * @param {Function} [compareFn] The comparison function that matches the sort
- * order of the `array`. The default `compareFn` compares items using less-than
- * and greater-than operators.
- * @return {Number} The index for the given item in the given array based on
- * the current sorters.
- */
- binarySearch: function(array, item, begin, end, compareFn) {
- var length = array.length,
- middle, comparison;
- if (begin instanceof Function) {
- compareFn = begin;
- begin = 0;
- end = length;
- } else if (end instanceof Function) {
- compareFn = end;
- end = length;
- } else {
- if (begin === undefined) {
- begin = 0;
- }
- if (end === undefined) {
- end = length;
- }
- compareFn = compareFn || ExtArray.lexicalCompare;
- }
- --end;
- while (begin <= end) {
- middle = (begin + end) >> 1;
- comparison = compareFn(item, array[middle]);
- if (comparison >= 0) {
- begin = middle + 1;
- } else if (comparison < 0) {
- end = middle - 1;
- }
- }
- return begin;
- },
- defaultCompare: function(lhs, rhs) {
- return (lhs < rhs) ? -1 : ((lhs > rhs) ? 1 : 0);
- },
- // Default comparator to use when no comparator is specified for the sort method.
- // Javascript sort does LEXICAL comparison.
- lexicalCompare: function(lhs, rhs) {
- lhs = String(lhs);
- rhs = String(rhs);
- return (lhs < rhs) ? -1 : ((lhs > rhs) ? 1 : 0);
- },
- /**
- * Iterates an array or an iterable value and invoke the given callback function for each
- * item.
- *
- * var countries = ['Vietnam', 'Singapore', 'United States', 'Russia'];
- *
- * Ext.Array.each(countries, function(name, index, countriesItSelf) {
- * console.log(name);
- * });
- *
- * var sum = function() {
- * var sum = 0;
- *
- * Ext.Array.each(arguments, function(value) {
- * sum += value;
- * });
- *
- * return sum;
- * };
- *
- * sum(1, 2, 3); // returns 6
- *
- * The iteration can be stopped by returning `false` from the callback function.
- * Returning `undefined` (i.e `return;`) will only exit the callback function and
- * proceed with the next iteration of the loop.
- *
- * Ext.Array.each(countries, function(name, index, countriesItSelf) {
- * if (name === 'Singapore') {
- * return false; // break here
- * }
- * });
- *
- * {@link Ext#each Ext.each} is alias for {@link Ext.Array#each Ext.Array.each}
- *
- * @param {Array/NodeList/Object} array The value to be iterated. If this
- * argument is not iterable, the callback function is called once.
- * @param {Function} fn The callback function. If it returns `false`, the iteration
- * stops and this method returns the current `index`. Returning `undefined` (i.e
- * `return;`) will only exit the callback function and proceed with the next iteration
- * in the loop.
- * @param {Object} fn.item The item at the current `index` in the passed `array`
- * @param {Number} fn.index The current `index` within the `array`
- * @param {Array} fn.allItems The `array` itself which was passed as the first argument
- * @param {Boolean} fn.return Return `false` to stop iteration.
- * @param {Object} [scope] The scope (`this` reference) in which the specified function is
- * executed.
- * @param {Boolean} [reverse=false] Reverse the iteration order (loop from the end to the
- * beginning).
- * @return {Boolean/Number} If all array entries were iterated, this will be `true. If
- * iteration was halted early because the passed fuction returned `false`, this will
- * be the index at which iteration was halted.
- */
- each: function(array, fn, scope, reverse) {
- var i, ln;
- array = ExtArray.from(array);
- ln = array.length;
- if (reverse !== true) {
- for (i = 0; i < ln; i++) {
- if (fn.call(scope || array[i], array[i], i, array) === false) {
- return i;
- }
- }
- } else {
- for (i = ln - 1; i > -1; i--) {
- if (fn.call(scope || array[i], array[i], i, array) === false) {
- return i;
- }
- }
- }
- return true;
- },
- /*
- * Calculates the the insertion index of a passed object into the passed Array according
- * to the passed comparator function. Note that the passed Array *MUST* already be ordered.
- * @param {Object} item The item to calculate the insertion index for.
- * @param {Array} The array into which the item is to be inserted.
- * @param {Function} comparatorFn The comparison function. Must return -1 or 0 or 1.
- * @param {Object} comparatorFn.lhs The left object to compare.
- * @param {Object} comparatorFn.rhs The right object to compare.
- * @param {Number} index The possible correct index to try first before a binary
- * search is instigated.
- */
- findInsertionIndex: function(item, items, comparatorFn, index) {
- var len = items.length,
- beforeCheck, afterCheck;
- comparatorFn = comparatorFn || ExtArray.lexicalCompare;
- if (0 <= index && index < len) {
- beforeCheck = index > 0 ? comparatorFn(item, items[index - 1]) : 0;
- afterCheck = (index < len) ? comparatorFn(item, items[index]) : 0;
- if (0 <= beforeCheck && afterCheck < 1) {
- return index;
- }
- }
- return ExtArray.binarySearch(items, item, comparatorFn);
- },
- /**
- * @method
- * Iterates an array and invoke the given callback function for each item. Note that this
- * will simply delegate to the native `Array.prototype.forEach` method if supported. It
- * doesn't support stopping the iteration by returning `false` in the callback function
- * like {@link Ext.Array#each}. However, performance could be much better in modern
- * browsers comparing with {@link Ext.Array#each}
- *
- * @param {Array} array The array to iterate.
- * @param {Function} fn The callback function.
- * @param {Object} fn.item The item at the current `index` in the passed `array`.
- * @param {Number} fn.index The current `index` within the `array`.
- * @param {Array} fn.allItems The `array` itself which was passed as the first argument.
- * @param {Object} scope (Optional) The execution scope (`this`) in which the
- * specified function is executed.
- */
- forEach: ('forEach' in arrayPrototype) ? function(array, fn, scope) {
- array.forEach(fn, scope);
- } : function(array, fn, scope) {
- var i, ln;
- for (i = 0 , ln = array.length; i < ln; i++) {
- fn.call(scope, array[i], i, array);
- }
- },
- /**
- * @method
- * Get the index of the provided `item` in the given `array`, a supplement for the
- * missing arrayPrototype.indexOf in Internet Explorer.
- *
- * @param {Array} array The array to check.
- * @param {Object} item The item to find.
- * @param {Number} from (Optional) The index at which to begin the search.
- * @return {Number} The index of item in the array (or -1 if it is not found).
- */
- indexOf: supportsIndexOf ? function(array, item, from) {
- // May be called with no array which causes an error.
- return array ? arrayPrototype.indexOf.call(array, item, from) : -1;
- } : function(array, item, from) {
- var i,
- length = array ? array.length : 0;
- for (i = (from < 0) ? Math.max(0, length + from) : from || 0; i < length; i++) {
- if (array[i] === item) {
- return i;
- }
- }
- return -1;
- },
- /**
- * @method
- * Checks whether or not the given `array` contains the specified `item`.
- *
- * @param {Array} array The array to check.
- * @param {Object} item The item to find.
- * @return {Boolean} `true` if the array contains the item, `false` otherwise.
- */
- contains: supportsIndexOf ? function(array, item) {
- return arrayPrototype.indexOf.call(array, item) !== -1;
- } : function(array, item) {
- var i, ln;
- for (i = 0 , ln = array.length; i < ln; i++) {
- if (array[i] === item) {
- return true;
- }
- }
- return false;
- },
- /**
- * Converts any iterable (numeric indices and a length property) into a true array.
- *
- * function test() {
- * var args = Ext.Array.toArray(arguments),
- * fromSecondToLastArgs = Ext.Array.toArray(arguments, 1);
- *
- * alert(args.join(' '));
- * alert(fromSecondToLastArgs.join(' '));
- * }
- *
- * test('just', 'testing', 'here'); // alerts 'just testing here';
- * // alerts 'testing here';
- *
- * // will convert the NodeList into an array
- * Ext.Array.toArray(document.getElementsByTagName('div'));
- * Ext.Array.toArray('splitted'); // returns ['s', 'p', 'l', 'i', 't', 't', 'e', 'd']
- * Ext.Array.toArray('splitted', 0, 3); // returns ['s', 'p', 'l']
- *
- * {@link Ext#toArray Ext.toArray} is alias for {@link Ext.Array#toArray Ext.Array.toArray}
- *
- * @param {Object} iterable the iterable object to be turned into a true Array.
- * @param {Number} [start=0] a zero-based index that specifies the start of extraction.
- * @param {Number} [end=-1] a 1-based index that specifies the end of extraction.
- * @return {Array}
- */
- toArray: function(iterable, start, end) {
- var array = [],
- i;
- if (!iterable || !iterable.length) {
- return array;
- }
- if (typeof iterable === 'string') {
- iterable = iterable.split('');
- }
- if (supportsSliceOnNodeList) {
- return slice.call(iterable, start || 0, end || iterable.length);
- }
- start = start || 0;
- end = end ? ((end < 0) ? iterable.length + end : end) : iterable.length;
- for (i = start; i < end; i++) {
- array.push(iterable[i]);
- }
- return array;
- },
- /**
- * Plucks the value of a property from each item in the Array. Example:
- *
- * // [el1.className, el2.className, ..., elN.className]
- * Ext.Array.pluck(Ext.query("p"), "className");
- *
- * @param {Array/NodeList} array The Array of items to pluck the value from.
- * @param {String} propertyName The property name to pluck from each element.
- * @return {Array} The value from each item in the Array.
- */
- pluck: function(array, propertyName) {
- var ret = [],
- i, ln, item;
- for (i = 0 , ln = array.length; i < ln; i++) {
- item = array[i];
- ret.push(item[propertyName]);
- }
- return ret;
- },
- /**
- * @method
- * Creates a new array with the results of calling a provided function on every element
- * in this array.
- *
- * @param {Array} array
- * @param {Function} fn Callback function for each item.
- * @param {Mixed} fn.item Current item.
- * @param {Number} fn.index Index of the item.
- * @param {Array} fn.array The whole array that's being iterated.
- * @param {Object} [scope] Callback function scope
- * @return {Array} results
- */
- map: ('map' in arrayPrototype) ? function(array, fn, scope) {
- Ext.Assert.isFunction(fn, 'Ext.Array.map must have a callback function passed as second argument.');
- return array.map(fn, scope);
- } : function(array, fn, scope) {
- Ext.Assert.isFunction(fn, 'Ext.Array.map must have a callback function passed as second argument.');
- /* eslint-disable-next-line vars-on-top */
- var len = array.length,
- results = new Array(len),
- i;
- for (i = 0; i < len; i++) {
- results[i] = fn.call(scope, array[i], i, array);
- }
- return results;
- },
- /**
- * @method
- * Executes the specified function for each array element until the function returns
- * a falsy value. If such an item is found, the function will return `false` immediately.
- * Otherwise, it will return `true`.
- *
- * @param {Array} array
- * @param {Function} fn Callback function for each item.
- * @param {Mixed} fn.item Current item.
- * @param {Number} fn.index Index of the item.
- * @param {Array} fn.array The whole array that's being iterated.
- * @param {Object} scope Callback function scope.
- * @return {Boolean} `true` if no false value is returned by the callback function.
- */
- every: ('every' in arrayPrototype) ? function(array, fn, scope) {
- Ext.Assert.isFunction(fn, 'Ext.Array.every must have a callback function passed as second argument.');
- return array.every(fn, scope);
- } : function(array, fn, scope) {
- var i, ln;
- Ext.Assert.isFunction(fn, 'Ext.Array.every must have a callback function passed as second argument.');
- for (i = 0 , ln = array.length; i < ln; ++i) {
- if (!fn.call(scope, array[i], i, array)) {
- return false;
- }
- }
- return true;
- },
- /**
- * @method
- * Executes the specified function for each array element until the function returns
- * a truthy value. If such an item is found, the function will return `true` immediately.
- * Otherwise, it will return `false`.
- *
- * @param {Array} array
- * @param {Function} fn Callback function for each item.
- * @param {Mixed} fn.item Current item.
- * @param {Number} fn.index Index of the item.
- * @param {Array} fn.array The whole array that's being iterated.
- * @param {Object} scope Callback function scope.
- * @return {Boolean} `true` if the callback function returns a truthy value.
- */
- some: ('some' in arrayPrototype) ? function(array, fn, scope) {
- Ext.Assert.isFunction(fn, 'Ext.Array.some must have a callback function passed as second argument.');
- return array.some(fn, scope);
- } : function(array, fn, scope) {
- var i, ln;
- Ext.Assert.isFunction(fn, 'Ext.Array.some must have a callback function passed as second argument.');
- for (i = 0 , ln = array.length; i < ln; ++i) {
- if (fn.call(scope, array[i], i, array)) {
- return true;
- }
- }
- return false;
- },
- /**
- * Shallow compares the contents of 2 arrays using strict equality.
- * @param {Array} array1
- * @param {Array} array2
- * @return {Boolean} `true` if the arrays are equal.
- */
- equals: function(array1, array2) {
- var len1 = array1.length,
- len2 = array2.length,
- i;
- // Short circuit if the same array is passed twice
- if (array1 === array2) {
- return true;
- }
- if (len1 !== len2) {
- return false;
- }
- for (i = 0; i < len1; ++i) {
- if (array1[i] !== array2[i]) {
- return false;
- }
- }
- return true;
- },
- /**
- * Filter through an array and remove empty item as defined in
- * {@link Ext#isEmpty Ext.isEmpty}.
- *
- * See {@link Ext.Array#filter}
- *
- * @param {Array} array
- * @return {Array} results
- */
- clean: function(array) {
- var results = [],
- i, ln, item;
- for (i = 0 , ln = array.length; i < ln; i++) {
- item = array[i];
- if (!Ext.isEmpty(item)) {
- results.push(item);
- }
- }
- return results;
- },
- /**
- * Returns a new array with unique items.
- *
- * @param {Array} array
- * @return {Array} results
- */
- unique: function(array) {
- var clone = [],
- i, ln, item;
- for (i = 0 , ln = array.length; i < ln; i++) {
- item = array[i];
- if (ExtArray.indexOf(clone, item) === -1) {
- clone.push(item);
- }
- }
- return clone;
- },
- /**
- * @method
- * Creates a new array with all of the elements of this array for which
- * the provided filtering function returns a truthy value.
- *
- * @param {Array} array
- * @param {Function} fn Callback function for each item.
- * @param {Mixed} fn.item Current item.
- * @param {Number} fn.index Index of the item.
- * @param {Array} fn.array The whole array that's being iterated.
- * @param {Object} scope Callback function scope.
- * @return {Array} results
- */
- filter: ('filter' in arrayPrototype) ? function(array, fn, scope) {
- Ext.Assert.isFunction(fn, 'Ext.Array.filter must have a filter function passed as second argument.');
- return array.filter(fn, scope);
- } : function(array, fn, scope) {
- var results = [],
- i, ln;
- Ext.Assert.isFunction(fn, 'Ext.Array.filter must have a filter function passed as second argument.');
- for (i = 0 , ln = array.length; i < ln; i++) {
- if (fn.call(scope, array[i], i, array)) {
- results.push(array[i]);
- }
- }
- return results;
- },
- /**
- * Returns the first item in the array which elicits a truthy return value from the
- * passed selection function.
- * @param {Array} array The array to search
- * @param {Function} fn The selection function to execute for each item.
- * @param {Mixed} fn.item The array item.
- * @param {Number} fn.index The index of the array item.
- * @param {Object} scope (optional) The scope (<code>this</code> reference) in which the
- * function is executed. Defaults to the array
- * @return {Object} The first item in the array which returned true from the selection
- * function, or null if none was found.
- */
- findBy: function(array, fn, scope) {
- var i, len;
- for (i = 0 , len = array.length; i < len; i++) {
- if (fn.call(scope || array, array[i], i)) {
- return array[i];
- }
- }
- return null;
- },
- /**
- * Converts a value to an array if it's not already an array; returns:
- *
- * - An empty array if given value is `undefined` or `null`
- * - Itself if given value is already an array
- * - An array copy if given value is {@link Ext#isIterable iterable} (arguments, NodeList
- * and alike)
- * - An array with one item which is the given value, otherwise
- *
- * @param {Object} value The value to convert to an array if it's not already is an array.
- * @param {Boolean} [newReference] `true` to clone the given array and return a new
- * reference if necessary.
- * @return {Array} array
- */
- from: function(value, newReference) {
- var type;
- if (value === undefined || value === null) {
- return [];
- }
- if (Ext.isArray(value)) {
- return (newReference) ? slice.call(value) : value;
- }
- type = typeof value;
- // Both strings and functions will have a length property. In phantomJS, NodeList
- // instances report typeof=='function' but don't have an apply method...
- if (value && value.length !== undefined && type !== 'string' && (type !== 'function' || !value.apply)) {
- return ExtArray.toArray(value);
- }
- return [
- value
- ];
- },
- /**
- * Removes the specified item from the array if it exists.
- *
- * @param {Array} array The array.
- * @param {Object} item The item to remove.
- * @return {Array} The passed array.
- */
- remove: function(array, item) {
- var index = ExtArray.indexOf(array, item);
- if (index !== -1) {
- erase(array, index, 1);
- }
- return array;
- },
- /**
- * Removes item/s at the specified index.
- *
- * @param {Array} array The array.
- * @param {Number} index The index of the item to be removed.
- * @param {Number} [count=1] The number of items to be removed.
- * @return {Array} The passed array.
- */
- removeAt: function(array, index, count) {
- var len = array.length;
- if (index >= 0 && index < len) {
- count = count || 1;
- count = Math.min(count, len - index);
- erase(array, index, count);
- }
- return array;
- },
- /**
- * Push an item into the array only if the array doesn't contain it yet.
- *
- * @param {Array} array The array.
- * @param {Object} item The item to include.
- */
- include: function(array, item) {
- if (!ExtArray.contains(array, item)) {
- array.push(item);
- }
- },
- /**
- * Clone a flat array without referencing the previous one. Note that this is different
- * from `Ext.clone` since it doesn't handle recursive cloning. It's simply a convenient,
- * easy-to-remember method for `Array.prototype.slice.call(array)`.
- *
- * @param {Array} array The array.
- * @return {Array} The clone array.
- */
- clone: function(array) {
- return slice.call(array);
- },
- /**
- * Merge multiple arrays into one with unique items.
- *
- * {@link Ext.Array#union} is alias for {@link Ext.Array#merge}
- *
- * @param {Array} array1
- * @param {Array} array2
- * @param {Array} etc
- * @return {Array} merged
- */
- merge: function() {
- var args = slice.call(arguments),
- array = [],
- i, ln;
- for (i = 0 , ln = args.length; i < ln; i++) {
- array = array.concat(args[i]);
- }
- return ExtArray.unique(array);
- },
- /**
- * Merge multiple arrays into one with unique items that exist in all of the arrays.
- *
- * @param {Array} array1
- * @param {Array} array2
- * @param {Array} etc
- * @return {Array} intersect
- */
- intersect: function() {
- var intersection = [],
- arrays = slice.call(arguments),
- arraysLength, array, arrayLength, minArray, minArrayIndex, minArrayCandidate, minArrayLength, element, elementCandidate, elementCount, i, j, k;
- if (!arrays.length) {
- return intersection;
- }
- // Find the smallest array
- arraysLength = arrays.length;
- for (i = minArrayIndex = 0; i < arraysLength; i++) {
- minArrayCandidate = arrays[i];
- if (!minArray || minArrayCandidate.length < minArray.length) {
- minArray = minArrayCandidate;
- minArrayIndex = i;
- }
- }
- minArray = ExtArray.unique(minArray);
- erase(arrays, minArrayIndex, 1);
- // Use the smallest unique'd array as the anchor loop. If the other array(s) do contain
- // an item in the small array, we're likely to find it before reaching the end
- // of the inner loop and can terminate the search early.
- minArrayLength = minArray.length;
- arraysLength = arrays.length;
- for (i = 0; i < minArrayLength; i++) {
- element = minArray[i];
- elementCount = 0;
- for (j = 0; j < arraysLength; j++) {
- array = arrays[j];
- arrayLength = array.length;
- for (k = 0; k < arrayLength; k++) {
- elementCandidate = array[k];
- if (element === elementCandidate) {
- elementCount++;
- break;
- }
- }
- }
- if (elementCount === arraysLength) {
- intersection.push(element);
- }
- }
- return intersection;
- },
- /**
- * Perform a set difference A-B by subtracting all items in array B from array A.
- *
- * @param {Array} arrayA
- * @param {Array} arrayB
- * @return {Array} difference
- */
- difference: function(arrayA, arrayB) {
- var clone = slice.call(arrayA),
- ln = clone.length,
- i, j, lnB;
- for (i = 0 , lnB = arrayB.length; i < lnB; i++) {
- for (j = 0; j < ln; j++) {
- if (clone[j] === arrayB[i]) {
- erase(clone, j, 1);
- j--;
- ln--;
- }
- }
- }
- return clone;
- },
- /**
- * This method applies the `reduceFn` function against an accumulator and each
- * value of the `array` (from left-to-right) to reduce it to a single value.
- *
- * If no `initialValue` is specified, the first element of the array is used as
- * the initial value. For example:
- *
- * function reducer (previous, value, index) {
- * console.log('[' + index + ']: (' + previous + ',' + value + '}');
- * return previous * 10 + value;
- * }
- *
- * v = Ext.Array.reduce([2, 3, 4], reducer);
- * console.log('v = ' + v);
- *
- * > [1]: (2, 3)
- * > [2]: (23, 4)
- * > v = 234
- *
- * v = Ext.Array.reduce([2, 3, 4], reducer, 1);
- * console.log('v = ' + v);
- *
- * > [0]: (1, 2)
- * > [1]: (12, 3)
- * > [2]: (123, 4)
- * > v = 1234
- *
- * @param {Array} array The array to process.
- * @param {Function} reduceFn The reducing callback function.
- * @param {Mixed} reduceFn.previous The previous value.
- * @param {Mixed} reduceFn.value The current value.
- * @param {Number} reduceFn.index The index in the array of the current `value`.
- * @param {Array} reduceFn.array The array to being processed.
- * @param {Mixed} [initialValue] The starting value.
- * @return {Mixed} The reduced value.
- * @method reduce
- * @since 6.0.0
- */
- reduce: Array.prototype.reduce ? function(array, reduceFn, initialValue) {
- if (arguments.length === 3) {
- return Array.prototype.reduce.call(array, reduceFn, initialValue);
- }
- return Array.prototype.reduce.call(array, reduceFn);
- } : function(array, reduceFn, initialValue) {
- array = Object(array);
- if (!Ext.isFunction(reduceFn)) {
- Ext.raise('Invalid parameter: expected a function.');
- }
- /* eslint-disable-next-line vars-on-top */
- var index = 0,
- length = array.length >>> 0,
- reduced = initialValue;
- if (arguments.length < 3) {
- while (true) {
- // eslint-disable-line no-constant-condition
- if (index in array) {
- reduced = array[index++];
- break;
- }
- if (++index >= length) {
- throw new TypeError('Reduce of empty array with no initial value');
- }
- }
- }
- for (; index < length; ++index) {
- if (index in array) {
- reduced = reduceFn(reduced, array[index], index, array);
- }
- }
- return reduced;
- },
- /**
- * Returns a shallow copy of a part of an array. This is equivalent to the native
- * call `Array.prototype.slice.call(array, begin, end)`. This is often used when "array"
- * is "arguments" since the arguments object does not supply a slice method but can
- * be the context object to `Array.prototype.slice`.
- *
- * @param {Array} array The array (or arguments object).
- * @param {Number} begin The index at which to begin. Negative values are offsets from
- * the end of the array.
- * @param {Number} end The index at which to end. The copied items do not include
- * end. Negative values are offsets from the end of the array. If end is omitted,
- * all items up to the end of the array are copied.
- * @return {Array} The copied piece of the array.
- * @method slice
- */
- // Note: IE8 will return [] on slice.call(x, undefined).
- slice: ([
- 1,
- 2
- ].slice(1, undefined).length ? function(array, begin, end) {
- return slice.call(array, begin, end);
- } : function(array, begin, end) {
- // see http://jsperf.com/slice-fix
- if (typeof begin === 'undefined') {
- return slice.call(array);
- }
- if (typeof end === 'undefined') {
- return slice.call(array, begin);
- }
- return slice.call(array, begin, end);
- }),
- /**
- * Sorts the elements of an Array in a stable manner (equivalently keyed values do not move
- * relative to each other). By default, this method sorts the elements alphabetically and
- * ascending.
- * **Note:** This method modifies the passed array, in the same manner as the
- * native javascript Array.sort.
- *
- * @param {Array} array The array to sort.
- * @param {Function} [sortFn] The comparison function.
- * @param {Mixed} sortFn.a The first item to compare.
- * @param {Mixed} sortFn.b The second item to compare.
- * @param {Number} sortFn.return `-1` if a < b, `1` if a > b, otherwise `0`.
- * @return {Array} The sorted array.
- */
- sort: function(array, sortFn) {
- return stableSort(array, sortFn || ExtArray.lexicalCompare);
- },
- /**
- * Recursively flattens into 1-d Array. Injects Arrays inline.
- *
- * @param {Array} array The array to flatten
- * @return {Array} The 1-d array.
- */
- flatten: function(array) {
- var worker = [];
- function rFlatten(a) {
- var i, ln, v;
- for (i = 0 , ln = a.length; i < ln; i++) {
- v = a[i];
- if (Ext.isArray(v)) {
- rFlatten(v);
- } else {
- worker.push(v);
- }
- }
- return worker;
- }
- return rFlatten(array);
- },
- /**
- * Returns the minimum value in the Array.
- *
- * @param {Array/NodeList} array The Array from which to select the minimum value.
- * @param {Function} comparisonFn (optional) a function to perform the comparison which
- * determines minimization.
- * If omitted the "<" operator will be used.
- * __Note:__ gt = 1; eq = 0; lt = -1
- * @param {Mixed} comparisonFn.min Current minimum value.
- * @param {Mixed} comparisonFn.item The value to compare with the current minimum.
- * @return {Object} minValue The minimum value.
- */
- min: function(array, comparisonFn) {
- var min = array[0],
- i, ln, item;
- for (i = 0 , ln = array.length; i < ln; i++) {
- item = array[i];
- if (comparisonFn) {
- if (comparisonFn(min, item) === 1) {
- min = item;
- }
- } else {
- if (item < min) {
- min = item;
- }
- }
- }
- return min;
- },
- /**
- * Returns the maximum value in the Array.
- *
- * @param {Array/NodeList} array The Array from which to select the maximum value.
- * @param {Function} comparisonFn (optional) a function to perform the comparison which
- * determines maximization.
- * If omitted the ">" operator will be used.
- * __Note:__ gt = 1; eq = 0; lt = -1
- * @param {Mixed} comparisonFn.max Current maximum value.
- * @param {Mixed} comparisonFn.item The value to compare with the current maximum.
- * @return {Object} maxValue The maximum value.
- */
- max: function(array, comparisonFn) {
- var max = array[0],
- i, ln, item;
- for (i = 0 , ln = array.length; i < ln; i++) {
- item = array[i];
- if (comparisonFn) {
- if (comparisonFn(max, item) === -1) {
- max = item;
- }
- } else {
- if (item > max) {
- max = item;
- }
- }
- }
- return max;
- },
- /**
- * Calculates the mean of all items in the array.
- *
- * @param {Array} array The Array to calculate the mean value of.
- * @return {Number} The mean.
- */
- mean: function(array) {
- return array.length > 0 ? ExtArray.sum(array) / array.length : undefined;
- },
- /**
- * Calculates the sum of all items in the given array.
- *
- * @param {Array} array The Array to calculate the sum value of.
- * @return {Number} The sum.
- */
- sum: function(array) {
- var sum = 0,
- i, ln, item;
- for (i = 0 , ln = array.length; i < ln; i++) {
- item = array[i];
- sum += item;
- }
- return sum;
- },
- /**
- * Creates a map (object) keyed by the elements of the given array. The values in
- * the map are the index+1 of the array element. For example:
- *
- * var map = Ext.Array.toMap(['a','b','c']);
- *
- * // map = { a: 1, b: 2, c: 3 };
- *
- * Or a key property can be specified:
- *
- * var map = Ext.Array.toMap([
- * { name: 'a' },
- * { name: 'b' },
- * { name: 'c' }
- * ], 'name');
- *
- * // map = { a: 1, b: 2, c: 3 };
- *
- * Lastly, a key extractor can be provided:
- *
- * var map = Ext.Array.toMap([
- * { name: 'a' },
- * { name: 'b' },
- * { name: 'c' }
- * ], function(obj) { return obj.name.toUpperCase(); });
- *
- * // map = { A: 1, B: 2, C: 3 };
- *
- * @param {String/String[]} strings The strings from which to create the map.
- * @param {String/Function} [getKey] Name of the object property to use
- * as a key or a function to extract the key.
- * @param {Object} [scope] Value of `this` inside callback specified for `getKey`.
- * @return {Object} The resulting map.
- */
- toMap: function(strings, getKey, scope) {
- var map, i;
- if (!strings) {
- return null;
- }
- map = {};
- i = strings.length;
- if (typeof strings === 'string') {
- map[strings] = 1;
- } else if (!getKey) {
- while (i--) {
- map[strings[i]] = i + 1;
- }
- } else if (typeof getKey === 'string') {
- while (i--) {
- map[strings[i][getKey]] = i + 1;
- }
- } else {
- while (i--) {
- map[getKey.call(scope, strings[i])] = i + 1;
- }
- }
- return map;
- },
- /**
- * Creates a map (object) keyed by a property of elements of the given array. The values in
- * the map are the array element. For example:
- *
- * var map = Ext.Array.toValueMap(['a','b','c']);
- *
- * // map = { a: 'a', b: 'b', c: 'c' };
- *
- * Or a key property can be specified:
- *
- * var map = Ext.Array.toValueMap([
- * { name: 'a' },
- * { name: 'b' },
- * { name: 'c' }
- * ], 'name');
- *
- * // map = { a: {name: 'a'}, b: {name: 'b'}, c: {name: 'c'} };
- *
- * Lastly, a key extractor can be provided:
- *
- * var map = Ext.Array.toValueMap([
- * { name: 'a' },
- * { name: 'b' },
- * { name: 'c' }
- * ], function(obj) { return obj.name.toUpperCase(); });
- *
- * // map = { A: {name: 'a'}, B: {name: 'b'}, C: {name: 'c'} };
- *
- * @param {Array} array The Array to create the map from.
- * @param {String/Function} [getKey] Name of the object property to use
- * as a key or a function to extract the key.
- * @param {Object} [scope] Value of this inside callback. This parameter is only
- * passed when `getKey` is a function. If `getKey` is not a function, the 3rd
- * argument is `arrayify`.
- * @param {Number} [arrayify] Pass `1` to create arrays for all map entries
- * or `2` to create arrays for map entries that have 2 or more items with the
- * same key. This only applies when `getKey` is specified. By default the map will
- * hold the last entry with a given key.
- * @return {Object} The resulting map.
- */
- toValueMap: function(array, getKey, scope, arrayify) {
- var map = {},
- i = array.length,
- autoArray, alwaysArray, entry, fn, key, value;
- if (!getKey) {
- while (i--) {
- value = array[i];
- map[value] = value;
- }
- } else {
- if (!(fn = (typeof getKey !== 'string'))) {
- arrayify = scope;
- }
- alwaysArray = arrayify === 1;
- autoArray = arrayify === 2;
- while (i--) {
- value = array[i];
- key = fn ? getKey.call(scope, value) : value[getKey];
- if (alwaysArray) {
- if (key in map) {
- map[key].push(value);
- } else {
- map[key] = [
- value
- ];
- }
- } else if (autoArray && (key in map)) {
- if ((entry = map[key]) instanceof Array) {
- entry.push(value);
- } else {
- map[key] = [
- entry,
- value
- ];
- }
- } else {
- map[key] = value;
- }
- }
- }
- return map;
- },
- _replaceSim: replaceSim,
- // for unit testing
- _spliceSim: spliceSim,
- /**
- * Removes items from an array. This is functionally equivalent to the splice method
- * of Array, but works around bugs in IE8's splice method and does not copy the
- * removed elements in order to return them (because very often they are ignored).
- *
- * @param {Array} array The Array on which to replace.
- * @param {Number} index The index in the array at which to operate.
- * @param {Number} removeCount The number of items to remove at index.
- * @return {Array} The array passed.
- * @method
- */
- erase: erase,
- /**
- * Inserts items in to an array.
- *
- * @param {Array} array The Array in which to insert.
- * @param {Number} index The index in the array at which to operate.
- * @param {Array} items The array of items to insert at index.
- * @return {Array} The array passed.
- */
- insert: function(array, index, items) {
- return replace(array, index, 0, items);
- },
- move: function(array, fromIdx, toIdx) {
- if (toIdx === fromIdx) {
- return;
- }
- /* eslint-disable-next-line vars-on-top */
- var item = array[fromIdx],
- incr = toIdx > fromIdx ? 1 : -1,
- i;
- for (i = fromIdx; i !== toIdx; i += incr) {
- array[i] = array[i + incr];
- }
- array[toIdx] = item;
- },
- /**
- * Replaces items in an array. This is functionally equivalent to the splice method
- * of Array, but works around bugs in IE8's splice method and is often more convenient
- * to call because it accepts an array of items to insert rather than use a variadic
- * argument list.
- *
- * @param {Array} array The Array on which to replace.
- * @param {Number} index The index in the array at which to operate.
- * @param {Number} removeCount The number of items to remove at index (can be 0).
- * @param {Array} insert (optional) An array of items to insert at index.
- * @return {Array} The array passed.
- * @method
- */
- replace: replace,
- /**
- * Replaces items in an array. This is equivalent to the splice method of Array, but
- * works around bugs in IE8's splice method. The signature is exactly the same as the
- * splice method except that the array is the first argument. All arguments following
- * removeCount are inserted in the array at index.
- *
- * @param {Array} array The Array on which to replace.
- * @param {Number} index The index in the array at which to operate.
- * @param {Number} removeCount The number of items to remove at index (can be 0).
- * @param {Object...} elements The elements to add to the array. If you don't specify
- * any elements, splice simply removes elements from the array.
- * @return {Array} An array containing the removed items.
- * @method
- */
- splice: splice,
- /**
- * Pushes new items onto the end of an Array.
- *
- * Passed parameters may be single items, or arrays of items. If an Array is found in the
- * argument list, all its elements are pushed into the end of the target Array.
- *
- * @param {Array} target The Array onto which to push new items
- * @param {Object...} elements The elements to add to the array. Each parameter may
- * be an Array, in which case all the elements of that Array will be pushed into the end
- * of the destination Array.
- * @return {Array} An array containing all the new items push onto the end.
- */
- push: function(target) {
- var args = arguments,
- len = args.length,
- i, newItem;
- if (target === undefined) {
- target = [];
- } else if (!Ext.isArray(target)) {
- target = [
- target
- ];
- }
- for (i = 1; i < len; i++) {
- newItem = args[i];
- Array.prototype.push[Ext.isIterable(newItem) ? 'apply' : 'call'](target, newItem);
- }
- return target;
- },
- /**
- * A function used to sort an array by numeric value. By default, javascript array values
- * are coerced to strings when sorting, which can be problematic when using numeric values.
- * To ensure that the values are sorted numerically, this method can be passed to the sort
- * method:
- *
- * Ext.Array.sort(myArray, Ext.Array.numericSortFn);
- */
- numericSortFn: function(a, b) {
- return a - b;
- }
- };
- /**
- * @method each
- * @member Ext
- * @inheritdoc Ext.Array#each
- */
- Ext.each = ExtArray.each;
- /**
- * @method union
- * @member Ext.Array
- * @inheritdoc Ext.Array#merge
- */
- ExtArray.union = ExtArray.merge;
- /**
- * Old alias to {@link Ext.Array#min}
- * @deprecated 4.0.0 Use {@link Ext.Array#min} instead
- * @method min
- * @member Ext
- * @inheritdoc Ext.Array#min
- */
- Ext.min = ExtArray.min;
- /**
- * Old alias to {@link Ext.Array#max}
- * @deprecated 4.0.0 Use {@link Ext.Array#max} instead
- * @method max
- * @member Ext
- * @inheritdoc Ext.Array#max
- */
- Ext.max = ExtArray.max;
- /**
- * Old alias to {@link Ext.Array#sum}
- * @deprecated 4.0.0 Use {@link Ext.Array#sum} instead
- * @method sum
- * @member Ext
- * @inheritdoc Ext.Array#sum
- */
- Ext.sum = ExtArray.sum;
- /**
- * Old alias to {@link Ext.Array#mean}
- * @deprecated 4.0.0 Use {@link Ext.Array#mean} instead
- * @method mean
- * @member Ext
- * @inheritdoc Ext.Array#mean
- */
- Ext.mean = ExtArray.mean;
- /**
- * Old alias to {@link Ext.Array#flatten}
- * @deprecated 4.0.0 Use {@link Ext.Array#flatten} instead
- * @method flatten
- * @member Ext
- * @inheritdoc Ext.Array#flatten
- */
- Ext.flatten = ExtArray.flatten;
- /**
- * Old alias to {@link Ext.Array#clean}
- * @deprecated 4.0.0 Use {@link Ext.Array#clean} instead
- * @method clean
- * @member Ext
- * @inheritdoc Ext.Array#clean
- */
- Ext.clean = ExtArray.clean;
- /**
- * Old alias to {@link Ext.Array#unique}
- * @deprecated 4.0.0 Use {@link Ext.Array#unique} instead
- * @method unique
- * @member Ext
- * @inheritdoc Ext.Array#unique
- */
- Ext.unique = ExtArray.unique;
- /**
- * Old alias to {@link Ext.Array#pluck Ext.Array.pluck}
- * @deprecated 4.0.0 Use {@link Ext.Array#pluck Ext.Array.pluck} instead
- * @method pluck
- * @member Ext
- * @inheritdoc Ext.Array#pluck
- */
- Ext.pluck = ExtArray.pluck;
- /**
- * @method toArray
- * @member Ext
- * @inheritdoc Ext.Array#toArray
- */
- Ext.toArray = function() {
- return ExtArray.toArray.apply(ExtArray, arguments);
- };
- return ExtArray;
- }());
- // @define Ext.lang.Assert
- // @define Ext.Assert
- // @require Ext.lang.Error
- /**
- * @class Ext.Assert
- * This class provides help value testing methods useful for diagnostics. These are often
- * used in `debugHooks`:
- *
- * Ext.define('Foo.bar.Class', {
- *
- * debugHooks: {
- * method: function (a) {
- * Ext.Assert.truthy(a, 'Expected "a" to be truthy');
- * },
- *
- * foo: function (object) {
- * Ext.Assert.isFunctionProp(object, 'doSomething');
- * }
- * }
- * });
- *
- * **NOTE:** This class is entirely removed in production builds so all uses of it should
- * be either in `debug` conditional comments or `debugHooks`.
- *
- * The following type detection methods from the `Ext` object are wrapped as assertions
- * by this class:
- *
- * * `isEmpty`
- * * `isArray`
- * * `isDate`
- * * `isObject`
- * * `isSimpleObject`
- * * `isPrimitive`
- * * `isFunction`
- * * `isNumber`
- * * `isNumeric`
- * * `isString`
- * * `isBoolean`
- * * `isElement`
- * * `isTextNode`
- * * `isDefined`
- * * `isIterable`
- *
- * These appear both their exact name and with a "Prop" suffix for checking a property on
- * an object. For example, these are almost identical:
- *
- * Ext.Assert.isFunction(object.foo);
- *
- * Ext.Assert.isFunctionProp(object, 'foo');
- *
- * The difference is the default error message generated is better in the second use case
- * than the first.
- *
- * The above list are also expanded for "Not" flavors (and "Not...Prop"):
- *
- * * `isNotEmpty`
- * * `isNotArray`
- * * `isNotDate`
- * * `isNotObject`
- * * `isNotSimpleObject`
- * * `isNotPrimitive`
- * * `isNotFunction`
- * * `isNotNumber`
- * * `isNotNumeric`
- * * `isNotString`
- * * `isNotBoolean`
- * * `isNotElement`
- * * `isNotTextNode`
- * * `isNotDefined`
- * * `isNotIterable`
- */
- Ext.Assert = {
- /**
- * Checks that the first argument is falsey and throws an `Error` if it is not.
- */
- falsey: function(b, msg) {
- if (b) {
- Ext.raise(msg || ('Expected a falsey value but was ' + b));
- }
- },
- /**
- * Checks that the first argument is falsey and throws an `Error` if it is not.
- */
- falseyProp: function(object, property) {
- var b;
- Ext.Assert.truthy(object);
- b = object[property];
- if (b) {
- if (object.$className) {
- property = object.$className + '#' + property;
- }
- Ext.raise('Expected a falsey value for ' + property + ' but was ' + b);
- }
- },
- /**
- * Checks that the first argument is truthy and throws an `Error` if it is not.
- */
- truthy: function(b, msg) {
- if (!b) {
- Ext.raise(msg || ('Expected a truthy value but was ' + typeof b));
- }
- },
- /**
- * Checks that the first argument is truthy and throws an `Error` if it is not.
- */
- truthyProp: function(object, property) {
- var b;
- Ext.Assert.truthy(object);
- b = object[property];
- if (!b) {
- if (object.$className) {
- property = object.$className + '#' + property;
- }
- Ext.raise('Expected a truthy value for ' + property + ' but was ' + typeof b);
- }
- }
- };
- /* eslint-disable indent */
- (function() {
- var name, kind;
- function makeAssert(name, kind) {
- var testFn = Ext[name],
- def;
- return function(value, msg) {
- if (!testFn(value)) {
- Ext.raise(msg || def || (def = 'Expected value to be ' + kind));
- }
- };
- }
- function makeAssertProp(name, kind) {
- var testFn = Ext[name],
- def;
- return function(object, prop) {
- Ext.Assert.truthy(object);
- if (!testFn(object[prop])) {
- Ext.raise(def || (def = 'Expected ' + (object.$className ? object.$className + '#' : '') + prop + ' to be ' + kind));
- }
- };
- }
- function makeNotAssert(name, kind) {
- var testFn = Ext[name],
- def;
- return function(value, msg) {
- if (testFn(value)) {
- Ext.raise(msg || def || (def = 'Expected value to NOT be ' + kind));
- }
- };
- }
- function makeNotAssertProp(name, kind) {
- var testFn = Ext[name],
- def;
- return function(object, prop) {
- Ext.Assert.truthy(object);
- if (testFn(object[prop])) {
- Ext.raise(def || (def = 'Expected ' + (object.$className ? object.$className + '#' : '') + prop + ' to NOT be ' + kind));
- }
- };
- }
- for (name in Ext) {
- if (name.substring(0, 2) === "is" && Ext.isFunction(Ext[name])) {
- kind = name.substring(2);
- Ext.Assert[name] = makeAssert(name, kind);
- Ext.Assert[name + 'Prop'] = makeAssertProp(name, kind);
- Ext.Assert['isNot' + kind] = makeNotAssert(name, kind);
- Ext.Assert['isNot' + kind + 'Prop'] = makeNotAssertProp(name, kind);
- }
- }
- }());
- /**
- * @class Ext.String
- *
- * A collection of useful static methods to deal with strings.
- * @singleton
- */
- /* eslint-disable indent */
- Ext.String = (function() {
- // @define Ext.lang.String
- // @define Ext.String
- // @require Ext
- // @require Ext.lang.Array
- // eslint-disable-next-line no-control-regex
- var trimRegex = /^[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u2028\u2029\u202f\u205f\u3000]+|[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u2028\u2029\u202f\u205f\u3000]+$/g,
- escapeRe = /('|\\)/g,
- // eslint-disable-next-line no-useless-escape
- escapeRegexRe = /([-.*+?\^${}()|\[\]\/\\])/g,
- basicTrimRe = /^\s+|\s+$/g,
- whitespaceRe = /\s+/,
- varReplace = /(^[^a-z]*|[^\w])/gi,
- charToEntity, entityToChar, charToEntityRegex, entityToCharRegex,
- htmlEncodeReplaceFn = function(match, capture) {
- return charToEntity[capture];
- },
- htmlDecodeReplaceFn = function(match, capture) {
- return (capture in entityToChar) ? entityToChar[capture] : String.fromCharCode(parseInt(capture.substr(2), 10));
- },
- boundsCheck = function(s, other) {
- if (s === null || s === undefined || other === null || other === undefined) {
- return false;
- }
- return other.length <= s.length;
- },
- fromCharCode = String.fromCharCode,
- ExtString;
- return ExtString = {
- /**
- * @method
- * Creates a string created by using the specified sequence of code points.
- * @param {Number...} codePoint Codepoints from which to build the string.
- * @return {String} A string built from the sequence of code points passed.
- */
- fromCodePoint: String.fromCodePoint || function() {
- var codePoint,
- result = '',
- codeUnits = [],
- index = -1,
- length = arguments.length;
- while (++index < length) {
- codePoint = Number(arguments[index]);
- if (!isFinite(codePoint) || // `NaN`, `+Infinity`, or `-Infinity`
- codePoint < 0 || // not a valid Unicode code point
- codePoint > 1114111 || // not a valid Unicode code point
- Math.floor(codePoint) !== codePoint) // not an integer
- {
- Ext.raise('Invalid code point: ' + codePoint);
- }
- if (codePoint <= 65535) {
- // BMP code point
- codeUnits.push(codePoint);
- } else {
- // Astral code point; split in surrogate halves
- // http://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae
- codePoint -= 65536;
- codeUnits.push((codePoint >> 10) + 55296, (codePoint % 1024) + 56320);
- }
- if (index + 1 === length) {
- result += fromCharCode(codeUnits);
- codeUnits.length = 0;
- }
- }
- return result;
- },
- /**
- * Inserts a substring into a string.
- * @param {String} s The original string.
- * @param {String} value The substring to insert.
- * @param {Number} index The index to insert the substring. Negative indexes will insert
- * from the end of the string. Example:
- *
- * Ext.String.insert("abcdefg", "h", -1); // abcdefhg
- *
- * @return {String} The value with the inserted substring
- */
- insert: function(s, value, index) {
- var len;
- if (!s) {
- return value;
- }
- if (!value) {
- return s;
- }
- len = s.length;
- if (!index && index !== 0) {
- index = len;
- }
- if (index < 0) {
- index *= -1;
- if (index >= len) {
- // negative overflow, insert at start
- index = 0;
- } else {
- index = len - index;
- }
- }
- if (index === 0) {
- s = value + s;
- } else if (index >= s.length) {
- s += value;
- } else {
- s = s.substr(0, index) + value + s.substr(index);
- }
- return s;
- },
- /**
- * Checks if a string starts with a substring
- * @param {String} s The original string
- * @param {String} start The substring to check
- * @param {Boolean} [ignoreCase=false] True to ignore the case in the comparison
- */
- startsWith: function(s, start, ignoreCase) {
- var result = boundsCheck(s, start);
- if (result) {
- if (ignoreCase) {
- s = s.toLowerCase();
- start = start.toLowerCase();
- }
- result = s.lastIndexOf(start, 0) === 0;
- }
- return result;
- },
- /**
- * Checks if a string ends with a substring
- * @param {String} s The original string
- * @param {String} end The substring to check
- * @param {Boolean} [ignoreCase=false] True to ignore the case in the comparison
- */
- endsWith: function(s, end, ignoreCase) {
- var result = boundsCheck(s, end);
- if (result) {
- if (ignoreCase) {
- s = s.toLowerCase();
- end = end.toLowerCase();
- }
- result = s.indexOf(end, s.length - end.length) !== -1;
- }
- return result;
- },
- /**
- * Converts a string of characters into a legal, parse-able JavaScript `var` name
- * as long as the passed string contains at least one alphabetic character.
- * Non alphanumeric characters, and *leading* non alphabetic characters will be removed.
- * @param {String} s A string to be converted into a `var` name.
- * @return {String} A legal JavaScript `var` name.
- */
- createVarName: function(s) {
- return s.replace(varReplace, '');
- },
- /**
- * Convert certain characters (&, <, >, ', and ") to their HTML character equivalents
- * for literal display in web pages.
- * @param {String} value The string to encode.
- * @return {String} The encoded text.
- * @method
- */
- htmlEncode: function(value) {
- return (!value) ? value : String(value).replace(charToEntityRegex, htmlEncodeReplaceFn);
- },
- /**
- * Convert certain characters (&, <, >, ', and ") from their HTML character equivalents.
- * @param {String} value The string to decode.
- * @return {String} The decoded text.
- * @method
- */
- htmlDecode: function(value) {
- return (!value) ? value : String(value).replace(entityToCharRegex, htmlDecodeReplaceFn);
- },
- /**
- * Checks if a string has values needing to be html encoded.
- * @private
- * @param {String} s The string to test
- * @return {Boolean} `true` if the string contains HTML characters
- */
- hasHtmlCharacters: function(s) {
- return charToEntityRegex.test(s);
- },
- /**
- * Adds a set of character entity definitions to the set used by
- * {@link Ext.String#htmlEncode} and {@link Ext.String#htmlDecode}.
- *
- * This object should be keyed by the entity name sequence,
- * with the value being the textual representation of the entity.
- *
- * Ext.String.addCharacterEntities({
- * '&Uuml;':'Ü',
- * '&ccedil;':'ç',
- * '&ntilde;':'ñ',
- * '&egrave;':'è'
- * });
- * var s = Ext.String.htmlEncode("A string with entities: èÜçñ");
- *
- * __Note:__ the values of the character entities defined on this object are expected
- * to be single character values. As such, the actual values represented by the
- * characters are sensitive to the character encoding of the JavaScript source
- * file when defined in string literal form. Script tags referencing server
- * resources with character entities must ensure that the 'charset' attribute
- * of the script node is consistent with the actual character encoding of the
- * server resource.
- *
- * The set of character entities may be reset back to the default state by using
- * the {@link Ext.String#resetCharacterEntities} method
- *
- * @param {Object} newEntities The set of character entities to add to the current
- * definitions.
- */
- addCharacterEntities: function(newEntities) {
- var charKeys = [],
- entityKeys = [],
- key, echar;
- for (key in newEntities) {
- echar = newEntities[key];
- entityToChar[key] = echar;
- charToEntity[echar] = key;
- charKeys.push(echar);
- entityKeys.push(key);
- }
- charToEntityRegex = new RegExp('(' + charKeys.join('|') + ')', 'g');
- entityToCharRegex = new RegExp('(' + entityKeys.join('|') + '|&#[0-9]{1,5};' + ')', 'g');
- },
- /**
- * Resets the set of character entity definitions used by
- * {@link Ext.String#htmlEncode} and {@link Ext.String#htmlDecode} back to the
- * default state.
- */
- resetCharacterEntities: function() {
- charToEntity = {};
- entityToChar = {};
- // add the default set
- this.addCharacterEntities({
- '&': '&',
- '>': '>',
- '<': '<',
- '"': '"',
- ''': "'"
- });
- },
- /**
- * Appends content to the query string of a URL, handling logic for whether to place
- * a question mark or ampersand.
- * @param {String} url The URL to append to.
- * @param {String} string The content to append to the URL.
- * @return {String} The resulting URL
- */
- urlAppend: function(url, string) {
- if (!Ext.isEmpty(string)) {
- return url + (url.indexOf('?') === -1 ? '?' : '&') + string;
- }
- return url;
- },
- /**
- * Trims whitespace from either end of a string, leaving spaces within the string intact.
- * Example:
- *
- * var s = ' foo bar ';
- * alert('-' + s + '-'); //alerts "- foo bar -"
- * alert('-' + Ext.String.trim(s) + '-'); //alerts "-foo bar-"
- *
- * @param {String} string The string to trim.
- * @return {String} The trimmed string.
- */
- trim: function(string) {
- if (string) {
- string = string.replace(trimRegex, "");
- }
- return string || '';
- },
- /**
- * Capitalize the first letter of the given string.
- * @param {String} string
- * @return {String}
- */
- capitalize: function(string) {
- if (string) {
- string = string.charAt(0).toUpperCase() + string.substr(1);
- }
- return string || '';
- },
- /**
- * Uncapitalize the first letter of a given string.
- * @param {String} string
- * @return {String}
- */
- uncapitalize: function(string) {
- if (string) {
- string = string.charAt(0).toLowerCase() + string.substr(1);
- }
- return string || '';
- },
- /**
- * Truncate a string and add an ellipsis ('...') to the end if it exceeds
- * the specified length.
- * @param {String} value The string to truncate.
- * @param {Number} length The maximum length to allow before truncating.
- * @param {Boolean} [word=false] `true` to try to find a common word break.
- * @return {String} The converted text.
- */
- ellipsis: function(value, length, word) {
- var vs, index;
- if (value && value.length > length) {
- if (word) {
- vs = value.substr(0, length - 2);
- index = Math.max(vs.lastIndexOf(' '), vs.lastIndexOf('.'), vs.lastIndexOf('!'), vs.lastIndexOf('?'));
- if (index !== -1 && index >= (length - 15)) {
- return vs.substr(0, index) + "...";
- }
- }
- return value.substr(0, length - 3) + "...";
- }
- return value;
- },
- /**
- * Escapes the passed string for use in a regular expression.
- * @param {String} string The string to escape.
- * @return {String} The escaped string.
- */
- escapeRegex: function(string) {
- return string.replace(escapeRegexRe, "\\$1");
- },
- /**
- * Creates a `RegExp` given a string `value` and optional flags. For example, the
- * following two regular expressions are equivalent.
- *
- * var regex1 = Ext.String.createRegex('hello');
- *
- * var regex2 = /^hello$/i;
- *
- * The following two regular expressions are also equivalent:
- *
- * var regex1 = Ext.String.createRegex('world', false, false, false);
- *
- * var regex2 = /world/;
- *
- * @param {String/RegExp} value The String to convert to a `RegExp`.
- * @param {Boolean} [startsWith=true] Pass `false` to allow a match to start
- * anywhere in the string. By default the `value` will match only at the start
- * of the string.
- * @param {Boolean} [endsWith=true] Pass `false` to allow the match to end before
- * the end of the string. By default the `value` will match only at the end of the
- * string.
- * @param {Boolean} [ignoreCase=true] Pass `false` to make the `RegExp` case
- * sensitive (removes the 'i' flag).
- * @since 5.0.0
- * @return {RegExp}
- */
- createRegex: function(value, startsWith, endsWith, ignoreCase) {
- var ret = value;
- if (value != null && !value.exec) {
- // not a regex
- ret = ExtString.escapeRegex(String(value));
- if (startsWith !== false) {
- ret = '^' + ret;
- }
- if (endsWith !== false) {
- ret += '$';
- }
- ret = new RegExp(ret, (ignoreCase !== false) ? 'i' : '');
- }
- return ret;
- },
- /**
- * Escapes the passed string for ' and \.
- * @param {String} string The string to escape.
- * @return {String} The escaped string.
- */
- escape: function(string) {
- return string.replace(escapeRe, "\\$1");
- },
- /**
- * Utility function that allows you to easily switch a string between two alternating
- * values. The passed value is compared to the current string, and if they are equal,
- * the other value that was passed in is returned. If they are already different,
- * the first value passed in is returned. Note that this method returns the new value
- * but does not change the current string.
- *
- * // alternate sort directions
- * sort = Ext.String.toggle(sort, 'ASC', 'DESC');
- *
- * // instead of conditional logic:
- * sort = (sort === 'ASC' ? 'DESC' : 'ASC');
- *
- * @param {String} string The current string.
- * @param {String} value The value to compare to the current string.
- * @param {String} other The new value to use if the string already equals the first value
- * passed in.
- * @return {String} The new value.
- */
- toggle: function(string, value, other) {
- return string === value ? other : value;
- },
- /**
- * Pads the left side of a string with a specified character. This is especially useful
- * for normalizing number and date strings. Example usage:
- *
- * var s = Ext.String.leftPad('123', 5, '0');
- * // s now contains the string: '00123'
- *
- * @param {String} string The original string.
- * @param {Number} size The total length of the output string.
- * @param {String} [character=' '] (optional) The character with which to pad the original
- * string.
- * @return {String} The padded string.
- */
- leftPad: function(string, size, character) {
- var result = String(string);
- character = character || " ";
- while (result.length < size) {
- result = character + result;
- }
- return result;
- },
- /**
- * Returns a string with a specified number of repetitions a given string pattern.
- * The pattern be separated by a different string.
- *
- * var s = Ext.String.repeat('---', 4); // = '------------'
- * var t = Ext.String.repeat('--', 3, '/'); // = '--/--/--'
- *
- * @param {String} pattern The pattern to repeat.
- * @param {Number} count The number of times to repeat the pattern (may be 0).
- * @param {String} sep An option string to separate each pattern.
- */
- repeat: function(pattern, count, sep) {
- var buf = [],
- i;
- if (count < 1) {
- count = 0;
- }
- for (i = count; i--; ) {
- buf.push(pattern);
- }
- return buf.join(sep || '');
- },
- /**
- * Splits a string of space separated words into an array, trimming as needed. If the
- * words are already an array, it is returned.
- *
- * @param {String/Array} words
- */
- splitWords: function(words) {
- if (words && typeof words === 'string') {
- return words.replace(basicTrimRe, '').split(whitespaceRe);
- }
- return words || [];
- }
- };
- }());
- // initialize the default encode / decode entities
- Ext.String.resetCharacterEntities();
- /**
- * @method htmlEncode
- * @member Ext
- * @inheritdoc Ext.String#htmlEncode
- */
- Ext.htmlEncode = Ext.String.htmlEncode;
- /**
- * @method htmlDecode
- * @member Ext
- * @inheritdoc Ext.String#htmlDecode
- */
- Ext.htmlDecode = Ext.String.htmlDecode;
- /**
- * @method urlAppend
- * @member Ext
- * @inheritdoc Ext.String#urlAppend
- */
- Ext.urlAppend = Ext.String.urlAppend;
- /* eslint-disable max-len */
- /**
- * @class Ext.Date
- * This class defines some basic methods for handling dates.
- *
- * The date parsing and formatting syntax contains a subset of
- * [PHP's `date()` function](http://www.php.net/date), and the formats that are
- * supported will provide results equivalent to their PHP versions.
- *
- * The following is a list of all currently supported formats:
- *
- * Format Description Example returned values
- * ------ ----------------------------------------------------------------------- -----------------------
- * d Day of the month, 2 digits with leading zeros 01 to 31
- * D A short textual representation of the day of the week Mon to Sun
- * j Day of the month without leading zeros 1 to 31
- * l A full textual representation of the day of the week Sunday to Saturday
- * N ISO-8601 numeric representation of the day of the week 1 (for Monday) through 7 (for Sunday)
- * S English ordinal suffix for the day of the month, 2 characters st, nd, rd or th. Works well with j
- * w Numeric representation of the day of the week 0 (for Sunday) to 6 (for Saturday)
- * z The day of the year (starting from 0) 0 to 364 (365 in leap years)
- * W ISO-8601 week number of year, weeks starting on Monday 01 to 53
- * F A full textual representation of a month, such as January or March January to December
- * m Numeric representation of a month, with leading zeros 01 to 12
- * M A short textual representation of a month Jan to Dec
- * n Numeric representation of a month, without leading zeros 1 to 12
- * t Number of days in the given month 28 to 31
- * L Whether it's a leap year 1 if it is a leap year, 0 otherwise.
- * o ISO-8601 year number (identical to (Y), but if the ISO week number (W) Examples: 1998 or 2004
- * belongs to the previous or next year, that year is used instead)
- * Y A full numeric representation of a year, 4 digits Examples: 1999 or 2003
- * y A two digit representation of a year Examples: 99 or 03
- * a Lowercase Ante meridiem and Post meridiem am or pm
- * A Uppercase Ante meridiem and Post meridiem AM or PM
- * g 12-hour format of an hour without leading zeros 1 to 12
- * G 24-hour format of an hour without leading zeros 0 to 23
- * h 12-hour format of an hour with leading zeros 01 to 12
- * H 24-hour format of an hour with leading zeros 00 to 23
- * i Minutes, with leading zeros 00 to 59
- * s Seconds, with leading zeros 00 to 59
- * u Decimal fraction of a second Examples:
- * (minimum 1 digit, arbitrary number of digits allowed) 001 (i.e. 0.001s) or
- * 100 (i.e. 0.100s) or
- * 999 (i.e. 0.999s) or
- * 999876543210 (i.e. 0.999876543210s)
- * O Difference to Greenwich time (GMT) in hours and minutes Example: +1030
- * P Difference to Greenwich time (GMT) with colon between hours and minutes Example: -08:00
- * T Timezone abbreviation of the machine running the code Examples: EST, MDT, PDT ...
- * Z Timezone offset in seconds (negative if west of UTC, positive if east) -43200 to 50400
- * c ISO 8601 date represented as the local time with an offset to UTC appended.
- * Notes: Examples:
- * 1) If unspecified, the month / day defaults to the current month / day, 1991 or
- * the time defaults to midnight, while the timezone defaults to the 1992-10 or
- * browser's timezone. If a time is specified, it must include both hours 1993-09-20 or
- * and minutes. The "T" delimiter, seconds, milliseconds and timezone 1994-08-19T16:20+01:00 or
- * are optional. 1995-07-18T17:21:28-02:00 or
- * 2) The decimal fraction of a second, if specified, must contain at 1996-06-17T18:22:29.98765+03:00 or
- * least 1 digit (there is no limit to the maximum number 1997-05-16T19:23:30,12345-0400 or
- * of digits allowed), and may be delimited by either a '.' or a ',' 1998-04-15T20:24:31.2468Z or
- * Refer to the examples on the right for the various levels of 1999-03-14T20:24:32Z or
- * date-time granularity which are supported, or see 2000-02-13T21:25:33
- * http://www.w3.org/TR/NOTE-datetime for more info. 2001-01-12 22:26:34
- * C An ISO date string as implemented by the native Date object's 1962-06-17T09:21:34.125Z
- * [Date.toISOString](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString)
- * method. This outputs the numeric part with *UTC* hour and minute
- * values, and indicates this by appending the `'Z'` timezone
- * identifier.
- * U Seconds since the Unix Epoch (January 1 1970 00:00:00 GMT) 1193432466 or -2138434463
- * MS Microsoft AJAX serialized dates \/Date(1238606590509)\/ (i.e. UTC milliseconds since epoch) or
- * \/Date(1238606590509+0800)\/
- * time A javascript millisecond timestamp 1350024476440
- * timestamp A UNIX timestamp (same as U) 1350024866
- *
- * Example usage (note that you must escape format specifiers with '\\' to render them as character literals):
- *
- * // Sample date:
- * // 'Wed Jan 10 2007 15:05:01 GMT-0600 (Central Standard Time)'
- *
- * var dt = new Date('1/10/2007 03:05:01 PM GMT-0600');
- * console.log(Ext.Date.format(dt, 'Y-m-d')); // 2007-01-10
- * console.log(Ext.Date.format(dt, 'F j, Y, g:i a')); // January 10, 2007, 3:05 pm
- * console.log(Ext.Date.format(dt, 'l, \\t\\he jS \\of F Y h:i:s A')); // Wednesday, the 10th of January 2007 03:05:01 PM
- *
- * Here are some standard date/time patterns that you might find helpful. They
- * are not part of the source of Ext.Date, but to use them you can simply copy this
- * block of code into any script that is included after Ext.Date and they will also become
- * globally available on the Date object. Feel free to add or remove patterns as needed in your code.
- *
- * Ext.Date.patterns = {
- * ISO8601Long:"Y-m-d H:i:s",
- * ISO8601Short:"Y-m-d",
- * ShortDate: "n/j/Y",
- * LongDate: "l, F d, Y",
- * FullDateTime: "l, F d, Y g:i:s A",
- * MonthDay: "F d",
- * ShortTime: "g:i A",
- * LongTime: "g:i:s A",
- * SortableDateTime: "Y-m-d\\TH:i:s",
- * UniversalSortableDateTime: "Y-m-d H:i:sO",
- * YearMonth: "F, Y"
- * };
- *
- * Example usage:
- *
- * var dt = new Date();
- * console.log(Ext.Date.format(dt, Ext.Date.patterns.ShortDate));
- *
- * Developer-written, custom formats may be used by supplying both a formatting and a parsing function
- * which perform to specialized requirements. The functions are stored in {@link #parseFunctions} and {@link #formatFunctions}.
- * @singleton
- */
- Ext.Date = (function() {
- /* eslint-disable indent */
- // @define Ext.lang.Date
- // @define Ext.Date
- // @require Ext
- // @require Ext.lang.String
- var utilDate,
- nativeDate = Date,
- stripEscapeRe = /(\\.)/g,
- hourInfoRe = /([gGhHisucUOPZ]|MS)/,
- dateInfoRe = /([djzmnYycU]|MS)/,
- slashRe = /\\/gi,
- numberTokenRe = /\{(\d+)\}/g,
- MSFormatRe = new RegExp('\\/Date\\(([-+])?(\\d+)(?:[+-]\\d{4})?\\)\\/'),
- datePartsRe = /^(?:(\d{1,4})|(\w{3,}))[/\-.\\\s](?:(\d{1,2})|(\w{3,}))[/\-.\\\s](\d{1,4})$/,
- pad = Ext.String.leftPad,
- dayInfo = {
- d: true,
- j: true
- },
- monthInfo = {
- F: true,
- m: true,
- M: true,
- n: true
- },
- yearInfo = {
- o: true,
- Y: true,
- y: true
- },
- // Most of the date-formatting functions below are the excellent work of Baron Schwartz.
- // (see http://www.xaprb.com/blog/2005/12/12/javascript-closures-for-runtime-efficiency/)
- // They generate precompiled functions from format patterns instead of parsing and
- // processing each pattern every time a date is formatted.
- code = [
- // date calculations (note: the code below creates a dependency on Ext.Number.from())
- "var me = this, dt, y, m, d, h, i, s, ms, o, O, z, zz, u, v, W, year, jan4, week1monday, daysInMonth, dayMatched,",
- "def = me.defaults,",
- "from = Ext.Number.from,",
- "results = String(input).match(me.parseRegexes[{0}]);",
- // either null, or an array of matched strings
- "if(results){",
- "{1}",
- "if(u != null){",
- // i.e. unix time is defined
- "v = new Date(u * 1000);",
- // give top priority to UNIX time
- "}else{",
- // create Date object representing midnight of the current day;
- // this will provide us with our date defaults
- // (note: clearTime() handles Daylight Saving Time automatically)
- "dt = me.clearTime(new Date);",
- "y = from(y, from(def.y, dt.getFullYear()));",
- "m = from(m, from(def.m - 1, dt.getMonth()));",
- "dayMatched = d !== undefined;",
- "d = from(d, from(def.d, dt.getDate()));",
- // Attempt to validate the day. Since it defaults to today, it may go out
- // of range, for example parsing m/Y where the value is 02/2000 on the 31st of May.
- // It will attempt to parse 2000/02/31, which will overflow to March and end up
- // returning 03/2000. We only do this when we default the day. If an invalid day value
- // was set to be parsed by the user, continue on and either let it overflow or return null
- // depending on the strict value. This will be in line with the normal Date behaviour.
- "if (!dayMatched) {",
- "dt.setDate(1);",
- "dt.setMonth(m);",
- "dt.setFullYear(y);",
- "daysInMonth = me.getDaysInMonth(dt);",
- "if (d > daysInMonth) {",
- "d = daysInMonth;",
- "}",
- "}",
- "h = from(h, from(def.h, dt.getHours()));",
- "i = from(i, from(def.i, dt.getMinutes()));",
- "s = from(s, from(def.s, dt.getSeconds()));",
- "ms = from(ms, from(def.ms, dt.getMilliseconds()));",
- "if(z >= 0 && y >= 0){",
- // both the year and zero-based day of year are defined and >= 0.
- // these 2 values alone provide sufficient info to create a full date object
- // create Date object representing January 1st for the given year
- // handle years < 100 appropriately
- "v = me.add(new Date(y < 100 ? 100 : y, 0, 1, h, i, s, ms), me.YEAR, y < 100 ? y - 100 : 0);",
- // then add day of year, checking for Date "rollover" if necessary
- "v = !strict? v : (strict === true && (z <= 364 || (me.isLeapYear(v) && z <= 365))? me.add(v, me.DAY, z) : null);",
- "}else if(strict === true && !me.isValid(y, m + 1, d, h, i, s, ms)){",
- // check for Date "rollover"
- "v = null;",
- // invalid date, so return null
- "}else{",
- "if (W) {",
- // support ISO-8601
- // http://en.wikipedia.org/wiki/ISO_week_date
- //
- // Mutually equivalent definitions for week 01 are:
- // a. the week starting with the Monday which is nearest in time to 1 January
- // b. the week with 4 January in it
- // ... there are many others ...
- //
- // We'll use letter b above to determine the first week of the year.
- //
- // So, first get a Date object for January 4th of whatever calendar year is desired.
- //
- // Then, the first Monday of the year can easily be determined by (operating on this Date):
- // 1. Getting the day of the week.
- // 2. Subtracting that by one.
- // 3. Multiplying that by 86400000 (one day in ms).
- // 4. Subtracting this number of days (in ms) from the January 4 date (represented in ms).
- //
- // Example #1 ...
- //
- // January 2012
- // Su Mo Tu We Th Fr Sa
- // 1 2 3 4 5 6 7
- // 8 9 10 11 12 13 14
- // 15 16 17 18 19 20 21
- // 22 23 24 25 26 27 28
- // 29 30 31
- //
- // 1. January 4th is a Wednesday.
- // 2. Its day number is 3.
- // 3. Simply substract 2 days from Wednesday.
- // 4. The first week of the year begins on Monday, January 2. Simple!
- //
- // Example #2 ...
- // January 1992
- // Su Mo Tu We Th Fr Sa
- // 1 2 3 4
- // 5 6 7 8 9 10 11
- // 12 13 14 15 16 17 18
- // 19 20 21 22 23 24 25
- // 26 27 28 29 30 31
- //
- // 1. January 4th is a Saturday.
- // 2. Its day number is 6.
- // 3. Simply subtract 5 days from Saturday.
- // 4. The first week of the year begins on Monday, December 30. Simple!
- //
- // v = Ext.Date.clearTime(new Date(week1monday.getTime() + ((W - 1) * 604800000 + 43200000)));
- // (This is essentially doing the same thing as above but for the week rather than the day)
- "year = y || (new Date()).getFullYear();",
- "jan4 = new Date(year, 0, 4, 0, 0, 0);",
- "d = jan4.getDay();",
- // If the 1st is a Thursday, then the 4th will be a Sunday, so we need the appropriate
- // day number here, which is why we use the day === checks.
- "week1monday = new Date(jan4.getTime() - ((d === 0 ? 6 : d - 1) * 86400000));",
- // The reason for adding 43200000 (12 hours) is to avoid any complication with daylight saving
- // switch overs. For example, if the clock is rolled back, an hour will repeat, so adding 7 days
- // will leave us 1 hour short (Sun <date> 23:00:00). By setting is to 12:00, subtraction
- // or addition of an hour won't make any difference.
- "v = Ext.Date.clearTime(new Date(week1monday.getTime() + ((W - 1) * 604800000 + 43200000)));",
- "} else {",
- // plain old Date object
- // handle years < 100 properly
- "v = me.add(new Date(y < 100 ? 100 : y, m, d, h, i, s, ms), me.YEAR, y < 100 ? y - 100 : 0);",
- "}",
- "}",
- "}",
- "}",
- "if(v){",
- // favor UTC offset over GMT offset
- "if(zz != null){",
- // reset to UTC, then add offset
- "v = me.add(v, me.SECOND, -v.getTimezoneOffset() * 60 - zz);",
- "}else if(o){",
- // reset to GMT, then add offset
- "v = me.add(v, me.MINUTE, -v.getTimezoneOffset() + (sn == '+'? -1 : 1) * (hr * 60 + mn));",
- "}",
- "}",
- "return (v != null) ? v : null;"
- ].join('\n');
- // Polyfill Date's toISOString instance method where not implemented.
- // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString
- // TODO: Remove this when IE8 retires.
- if (!Date.prototype.toISOString) {
- Date.prototype.toISOString = function() {
- var me = this;
- return pad(me.getUTCFullYear(), 4, '0') + '-' + pad(me.getUTCMonth() + 1, 2, '0') + '-' + pad(me.getUTCDate(), 2, '0') + 'T' + pad(me.getUTCHours(), 2, '0') + ':' + pad(me.getUTCMinutes(), 2, '0') + ':' + pad(me.getUTCSeconds(), 2, '0') + '.' + pad(me.getUTCMilliseconds(), 3, '0') + 'Z';
- };
- }
- /**
- * @method xf
- * @private
- * @param format
- * Create private copy of Ext JS's `Ext.util.Format.format()` method
- * + to remove unnecessary dependency
- * + to resolve namespace conflict with MS-Ajax's implementation
- */
- function xf(format) {
- var args = Array.prototype.slice.call(arguments, 1);
- return format.replace(numberTokenRe, function(m, i) {
- return args[i];
- });
- }
- /* eslint-enable indent, max-len */
- utilDate = {
- /** @ignore */
- now: nativeDate.now,
- // always available due to polyfill in Ext.js
- /**
- * @private
- */
- toString: function(date) {
- if (!date) {
- date = new nativeDate();
- }
- return date.getFullYear() + "-" + pad(date.getMonth() + 1, 2, '0') + "-" + pad(date.getDate(), 2, '0') + "T" + pad(date.getHours(), 2, '0') + ":" + pad(date.getMinutes(), 2, '0') + ":" + pad(date.getSeconds(), 2, '0');
- },
- /**
- * Returns the number of milliseconds between two dates.
- * @param {Date} dateA The first date.
- * @param {Date} [dateB=new Date()] (optional) The second date.
- * @return {Number} The difference in milliseconds
- */
- getElapsed: function(dateA, dateB) {
- return Math.abs(dateA - (dateB || utilDate.now()));
- },
- /**
- * Global flag which determines if strict date parsing should be used.
- * Strict date parsing will not roll-over invalid dates, which is the
- * default behavior of JavaScript Date objects.
- * (see {@link #parse} for more information)
- * @type Boolean
- */
- useStrict: false,
- /**
- * @private
- */
- formatCodeToRegex: function(character, currentGroup) {
- // Note: currentGroup - position in regex result array (see notes for
- // Ext.Date.parseCodes below)
- var p = utilDate.parseCodes[character];
- if (p) {
- p = typeof p === 'function' ? p() : p;
- // reassign function result to prevent repeated execution
- utilDate.parseCodes[character] = p;
- }
- return p ? Ext.applyIf({
- c: p.c ? xf(p.c, currentGroup || "{0}") : p.c
- }, p) : {
- g: 0,
- c: null,
- s: Ext.String.escapeRegex(character)
- };
- },
- // treat unrecognized characters as literals
- /**
- * An object hash in which each property is a date parsing function. The property name is the
- * format string which that function parses.
- *
- * This object is automatically populated with date parsing functions as
- * date formats are requested for Ext standard formatting strings.
- *
- * Custom parsing functions may be inserted into this object, keyed by a name which from then on
- * may be used as a format string to {@link #parse}.
- *
- * Example:
- *
- * Ext.Date.parseFunctions['x-date-format'] = myDateParser;
- *
- * A parsing function should return a Date object, and is passed the following parameters:
- *
- * - `date`: {@link String} - The date string to parse.
- * - `strict`: {@link Boolean} - `true` to validate date strings while parsing
- * (i.e. prevent JavaScript Date "rollover"). __The default must be `false`.__
- * Invalid date strings should return `null` when parsed.
- *
- * To enable Dates to also be _formatted_ according to that format, a corresponding
- * formatting function must be placed into the {@link #formatFunctions} property.
- * @property parseFunctions
- * @type Object
- */
- parseFunctions: {
- "MS": function(input, strict) {
- // note: the timezone offset is ignored since the MS Ajax server sends
- // a UTC milliseconds-since-Unix-epoch value (negative values are allowed)
- var r = (input || '').match(MSFormatRe);
- return r ? new nativeDate(((r[1] || '') + r[2]) * 1) : null;
- },
- "time": function(input, strict) {
- var num = parseInt(input, 10);
- if (num || num === 0) {
- return new nativeDate(num);
- }
- return null;
- },
- "timestamp": function(input, strict) {
- var num = parseInt(input, 10);
- if (num || num === 0) {
- return new nativeDate(num * 1000);
- }
- return null;
- }
- },
- parseRegexes: [],
- /**
- * An object hash in which each property is a date formatting function. The property name is the
- * format string which corresponds to the produced formatted date string.
- *
- * This object is automatically populated with date formatting functions as
- * date formats are requested for Ext standard formatting strings.
- *
- * Custom formatting functions may be inserted into this object, keyed by a name which
- * from then on may be used as a format string to {@link #format}.
- *
- * Example:
- *
- * Ext.Date.formatFunctions['x-date-format'] = myDateFormatter;
- *
- * A formatting function should return a string representation of the Date object which
- * is the scope (this) of the function.
- *
- * To enable date strings to also be _parsed_ according to that format, a corresponding
- * parsing function must be placed into the {@link #parseFunctions} property.
- * @property formatFunctions
- * @type Object
- */
- formatFunctions: {
- "MS": function() {
- // UTC milliseconds since Unix epoch (MS-AJAX serialized date format (MRSF))
- return '\\/Date(' + this.getTime() + ')\\/';
- },
- "time": function() {
- return this.getTime().toString();
- },
- "timestamp": function() {
- return utilDate.format(this, 'U');
- }
- },
- y2kYear: 50,
- /**
- * Date interval constant.
- * @type String
- */
- MILLI: "ms",
- /**
- * Date interval constant.
- * @type String
- */
- SECOND: "s",
- /**
- * Date interval constant.
- * @type String
- */
- MINUTE: "mi",
- /**
- * Date interval constant.
- * @type String
- */
- HOUR: "h",
- /**
- * Date interval constant.
- * @type String
- */
- DAY: "d",
- /**
- * Date interval constant.
- * @type String
- */
- MONTH: "mo",
- /**
- * Date interval constant.
- * @type String
- */
- YEAR: "y",
- /**
- * The number of days in a week.
- * @type Number
- */
- DAYS_IN_WEEK: 7,
- /**
- * The number of months in a year.
- * @type Number
- */
- MONTHS_IN_YEAR: 12,
- /**
- * The maximum number of days in a month.
- * @type {Number}
- */
- MAX_DAYS_IN_MONTH: 31,
- SUNDAY: 0,
- MONDAY: 1,
- TUESDAY: 2,
- WEDNESDAY: 3,
- THURSDAY: 4,
- FRIDAY: 5,
- SATURDAY: 6,
- /**
- * An object hash containing default date values used during date parsing.
- *
- * The following properties are available:
- *
- * - `y`: {@link Number} - The default year value. Defaults to `undefined`.
- * - `m`: {@link Number} - The default 1-based month value. Defaults to `undefined`.
- * - `d`: {@link Number} - The default day value. Defaults to `undefined`.
- * - `h`: {@link Number} - The default hour value. Defaults to `undefined`.
- * - `i`: {@link Number} - The default minute value. Defaults to `undefined`.
- * - `s`: {@link Number} - The default second value. Defaults to `undefined`.
- * - `ms`: {@link Number} - The default millisecond value. Defaults to `undefined`.
- *
- * Override these properties to customize the default date values used by the {@link #parse}
- * method.
- *
- * __Note:__ In countries which experience Daylight Saving Time (i.e. DST), the `h`, `i`, `s`
- * and `ms` properties may coincide with the exact time in which DST takes effect.
- * It is the responsibility of the developer to account for this.
- *
- * Example Usage:
- *
- * // set default day value to the first day of the month
- * Ext.Date.defaults.d = 1;
- *
- * // parse a February date string containing only year and month values.
- * // setting the default day value to 1 prevents weird date rollover issues
- * // when attempting to parse the following date string on, for example, March 31st 2009
- * Ext.Date.parse('2009-02', 'Y-m'); // returns a Date object representing February 1st 2009
- *
- * @property defaults
- * @type Object
- */
- defaults: {},
- /**
- * @property {String[]} dayNames
- * An array of textual day names.
- * Override these values for international dates.
- *
- * Example:
- *
- * Ext.Date.dayNames = [
- * 'SundayInYourLang',
- * 'MondayInYourLang'
- * // ...
- * ];
- * @locale
- */
- dayNames: [
- "Sunday",
- "Monday",
- "Tuesday",
- "Wednesday",
- "Thursday",
- "Friday",
- "Saturday"
- ],
- /**
- * @property {String[]} monthNames
- * An array of textual month names.
- * Override these values for international dates.
- *
- * Example:
- *
- * Ext.Date.monthNames = [
- * 'JanInYourLang',
- * 'FebInYourLang'
- * // ...
- * ];
- * @locale
- */
- monthNames: [
- "January",
- "February",
- "March",
- "April",
- "May",
- "June",
- "July",
- "August",
- "September",
- "October",
- "November",
- "December"
- ],
- /**
- * @property {Object} monthNumbers
- * An object hash of zero-based JavaScript month numbers (with short month names as keys).
- *
- * __Note:__ keys are case-sensitive.
- *
- * Override these values for international dates.
- *
- * Example:
- *
- * Ext.Date.monthNumbers = {
- * 'LongJanNameInYourLang': 0,
- * 'ShortJanNameInYourLang':0,
- * 'LongFebNameInYourLang':1,
- * 'ShortFebNameInYourLang':1
- * // ...
- * };
- * @locale
- */
- monthNumbers: {
- January: 0,
- Jan: 0,
- February: 1,
- Feb: 1,
- March: 2,
- Mar: 2,
- April: 3,
- Apr: 3,
- May: 4,
- June: 5,
- Jun: 5,
- July: 6,
- Jul: 6,
- August: 7,
- Aug: 7,
- September: 8,
- Sep: 8,
- October: 9,
- Oct: 9,
- November: 10,
- Nov: 10,
- December: 11,
- Dec: 11
- },
- /**
- * @property {String} defaultFormat
- * The date format string that the {@link Ext.util.Format#dateRenderer}
- * and {@link Ext.util.Format#date} functions use. See {@link Ext.Date} for details.
- *
- * This is the format that {@link #method!flexParse} uses to disambiguate all-numeric
- * input dates.
- *
- * This may be overridden in a locale file.
- * @locale
- */
- defaultFormat: 'm/d/Y',
- /**
- * @property {String} defaultTimeFormat
- * The default time format.
- *
- * This may be overridden in a locale file.
- * @locale
- */
- defaultTimeFormat: 'h:i A',
- /**
- * @property {Number} firstDayOfWeek
- * The day on which the week starts. `0` being Sunday, through `6` being Saturday.
- *
- * This may be overridden in a locale file.
- * @locale
- */
- firstDayOfWeek: 0,
- /**
- * @property {Number[]} weekendDays
- * The days on which weekend falls. `0` being Sunday, through `6` being Saturday.
- *
- * This may be overridden in a locale file.
- * @locale
- */
- weekendDays: [
- 0,
- 6
- ],
- /**
- * Get the short month name for the given month number.
- * Override this function for international dates.
- * @param {Number} month A zero-based JavaScript month number.
- * @return {String} The short month name.
- * @locale
- */
- getShortMonthName: function(month) {
- return utilDate.monthNames[month].substring(0, 3);
- },
- /**
- * Get the short day name for the given day number.
- * Override this function for international dates.
- * @param {Number} day A zero-based JavaScript day number.
- * @return {String} The short day name.
- * @locale
- */
- getShortDayName: function(day) {
- return utilDate.dayNames[day].substring(0, 3);
- },
- /**
- * Get the zero-based JavaScript month number for the given short/full month name.
- * Override this function for international dates.
- * @param {String} name The short/full month name.
- * @return {Number} The zero-based JavaScript month number.
- * @locale
- */
- getMonthNumber: function(name) {
- // handle camel casing for English month names (since the keys for
- // the Ext.Date.monthNumbers hash are case sensitive)
- return utilDate.monthNumbers[name.substring(0, 1).toUpperCase() + name.substring(1, 3).toLowerCase()];
- },
- /**
- * Checks if the specified format contains hour information
- * @param {String} format The format to check
- * @return {Boolean} True if the format contains hour information
- * @method
- */
- formatContainsHourInfo: function(format) {
- return hourInfoRe.test(format.replace(stripEscapeRe, ''));
- },
- /**
- * Checks if the specified format contains information about
- * anything other than the time.
- * @param {String} format The format to check
- * @return {Boolean} True if the format contains information about
- * date/day information.
- * @method
- */
- formatContainsDateInfo: function(format) {
- return dateInfoRe.test(format.replace(stripEscapeRe, ''));
- },
- /**
- * @private
- * Checks if the specified format contains only month information.
- *
- * @param {String} format Format to check
- *
- * @return {Boolean}
- */
- isMonthFormat: function(format) {
- return !!monthInfo[format];
- },
- /**
- * @private
- * Checks if the specified format contains only year information.
- *
- * @param {String} format Format to check.
- *
- * @return {Boolean}
- */
- isYearFormat: function(format) {
- return !!yearInfo[format];
- },
- /**
- * Removes all escaping for a date format string. In date formats,
- * using a '\' can be used to escape special characters.
- * @param {String} format The format to unescape
- * @return {String} The unescaped format
- * @method
- */
- unescapeFormat: function(format) {
- // Escape the format, since \ can be used to escape special
- // characters in a date format. For example, in a Spanish
- // locale the format may be: 'd \\de F \\de Y'
- return format.replace(slashRe, '');
- },
- /**
- * The base format-code to formatting-function hashmap used by the {@link #format} method.
- * Formatting functions are strings (or functions which return strings) which
- * will return the appropriate value when evaluated in the context of the Date object
- * from which the {@link #format} method is called.
- * Add to / override these mappings for custom date formatting.
- *
- * __Note:__ `Ext.Date.format()` treats characters as literals if an appropriate mapping
- * cannot be found.
- *
- * Example:
- *
- * Ext.Date.formatCodes.x = "Ext.util.Format.leftPad(this.getDate(), 2, '0')";
- * console.log(Ext.Date.format(new Date(), 'X'); // returns the current day of the month
- * @type Object
- */
- formatCodes: {
- /* eslint-disable max-len */
- d: "Ext.String.leftPad(m.getDate(), 2, '0')",
- D: "Ext.Date.getShortDayName(m.getDay())",
- // get localized short day name
- j: "m.getDate()",
- l: "Ext.Date.dayNames[m.getDay()]",
- N: "(m.getDay() ? m.getDay() : 7)",
- S: "Ext.Date.getSuffix(m)",
- w: "m.getDay()",
- z: "Ext.Date.getDayOfYear(m)",
- W: "Ext.String.leftPad(Ext.Date.getWeekOfYear(m), 2, '0')",
- F: "Ext.Date.monthNames[m.getMonth()]",
- m: "Ext.String.leftPad(m.getMonth() + 1, 2, '0')",
- M: "Ext.Date.getShortMonthName(m.getMonth())",
- // get localized short month name
- n: "(m.getMonth() + 1)",
- t: "Ext.Date.getDaysInMonth(m)",
- L: "(Ext.Date.isLeapYear(m) ? 1 : 0)",
- o: "(m.getFullYear() + (Ext.Date.getWeekOfYear(m) == 1 && m.getMonth() > 0 ? +1 : (Ext.Date.getWeekOfYear(m) >= 52 && m.getMonth() < 11 ? -1 : 0)))",
- Y: "Ext.String.leftPad(m.getFullYear(), 4, '0')",
- y: "('' + m.getFullYear()).substring(2, 4)",
- a: "(m.getHours() < 12 ? 'am' : 'pm')",
- A: "(m.getHours() < 12 ? 'AM' : 'PM')",
- g: "((m.getHours() % 12) ? m.getHours() % 12 : 12)",
- G: "m.getHours()",
- h: "Ext.String.leftPad((m.getHours() % 12) ? m.getHours() % 12 : 12, 2, '0')",
- H: "Ext.String.leftPad(m.getHours(), 2, '0')",
- i: "Ext.String.leftPad(m.getMinutes(), 2, '0')",
- s: "Ext.String.leftPad(m.getSeconds(), 2, '0')",
- u: "Ext.String.leftPad(m.getMilliseconds(), 3, '0')",
- O: "Ext.Date.getGMTOffset(m)",
- P: "Ext.Date.getGMTOffset(m, true)",
- T: "Ext.Date.getTimezone(m)",
- Z: "(m.getTimezoneOffset() * -60)",
- /* eslint-enable max-len */
- c: function() {
- // ISO-8601 -- GMT format
- var c = "Y-m-dTH:i:sP",
- code = [],
- l = c.length,
- i, e;
- for (i = 0; i < l; ++i) {
- e = c.charAt(i);
- // treat T as a character literal
- code.push(e === "T" ? "'T'" : utilDate.getFormatCode(e));
- }
- return code.join(" + ");
- },
- C: function() {
- // ISO-1601 -- browser format. UTC numerics with the 'Z' TZ id.
- return 'm.toISOString()';
- },
- U: "Math.round(m.getTime() / 1000)"
- },
- /**
- * Checks if the passed Date parameters will cause a JavaScript Date "rollover".
- * @param {Number} year 4-digit year.
- * @param {Number} month 1-based month-of-year.
- * @param {Number} day Day of month.
- * @param {Number} hour (optional) Hour.
- * @param {Number} minute (optional) Minute.
- * @param {Number} second (optional) Second.
- * @param {Number} millisecond (optional) Millisecond.
- * @return {Boolean} `true` if the passed parameters do not cause a Date "rollover",
- * `false` otherwise.
- */
- isValid: function(year, month, day, hour, minute, second, millisecond) {
- var dt;
- // setup defaults
- hour = hour || 0;
- minute = minute || 0;
- second = second || 0;
- millisecond = millisecond || 0;
- // Special handling for year < 100
- /* eslint-disable-next-line max-len */
- dt = utilDate.add(new nativeDate(year < 100 ? 100 : year, month - 1, day, hour, minute, second, millisecond), utilDate.YEAR, year < 100 ? year - 100 : 0);
- return year === dt.getFullYear() && month === dt.getMonth() + 1 && day === dt.getDate() && hour === dt.getHours() && minute === dt.getMinutes() && second === dt.getSeconds() && millisecond === dt.getMilliseconds();
- },
- /**
- * Parses the passed string using the specified date format.
- * Note that this function expects normal calendar dates, meaning that months are 1-based
- * (i.e. 1 = January). The {@link #defaults} hash will be used for any date value (i.e. year,
- * month, day, hour, minute, second or millisecond) which cannot be found in the passed string.
- * If a corresponding default date value has not been specified in the {@link #defaults} hash,
- * the current date's year, month, day or DST-adjusted zero-hour time value will be used
- * instead. Keep in mind that the input date string must precisely match the specified format
- * string in order for the parse operation to be successful (failed parse operations return a
- * `null` value).
- *
- * Example:
- *
- * //dt = Fri May 25 2007 (current date)
- * var dt = new Date();
- *
- * //dt = Thu May 25 2006 (today's month/day in 2006)
- * dt = Ext.Date.parse("2006", "Y");
- *
- * //dt = Sun Jan 15 2006 (all date parts specified)
- * dt = Ext.Date.parse("2006-01-15", "Y-m-d");
- *
- * //dt = Sun Jan 15 2006 15:20:01
- * dt = Ext.Date.parse("2006-01-15 3:20:01 PM", "Y-m-d g:i:s A");
- *
- * // attempt to parse Sun Feb 29 2006 03:20:01 in strict mode
- * dt = Ext.Date.parse("2006-02-29 03:20:01", "Y-m-d H:i:s", true); // returns null
- *
- * ## Heuristic Parsing
- * When no `format` is specified, this method parses the date in a flexible way allowing
- * for different delimiters and textual month names to infer the position of the other
- * parts.
- *
- * Supported inferred date orders when alphabetic month names are used are:
- *
- * - `D,M,Y`
- * - `M,D,Y`
- * - `Y,M,D`
- *
- * If the passed in date consists of all numeric tokens then the relative magnitude of
- * the first two tokens is used to make an inference about the user's intention.
- * If one token is less than 13 and the other is greater than 12, then the user's
- * intention is known.
- *
- * Failing this, the {@link #defaultFormat} is used to determine the input order for
- * the current locale.
- *
- * Part delimiters may be any of these:
- *
- * - `'/'`
- * - `'-'`
- * - `'.'`
- * - `'\'`
- * - `' '` (space)
- *
- * For example, the inputs `"Jun 1 62"` and `"1 Jun 62"` would be understood as the
- * first of June, 1962 in all English locales regardless of the locale's default date
- * ordering.
- *
- * If `"25/1/62"` was passed in, it's obvious that the user means the twenty fifth
- * of January.
- *
- * If, however, `"1/6/62"` was passed in, the {@link #defaultFormat} would be consulted
- * to disambiguate the meaning of those first two tokens.
- *
- * @param {String} input The date string to parse.
- * @param {String} [format] The expected date string format. If not passed, the date
- * string will be parsed heuristically as described above.
- * @param {Boolean} [strict=false] Pass `true` to validate date strings while parsing
- * (i.e. prevents JavaScript Date "rollover"). Invalid date strings will return `null`
- * when parsed.
- * @return {Date} The parsed Date, or `null` if an invalid date string.
- */
- parse: function(input, format, strict) {
- var p;
- if (!format) {
- return utilDate.flexParse(input);
- }
- p = utilDate.parseFunctions;
- if (p[format] == null) {
- utilDate.createParser(format);
- }
- return p[format].call(utilDate, input, Ext.isDefined(strict) ? strict : utilDate.useStrict);
- },
- // Backwards compat
- parseDate: function(input, format, strict) {
- return utilDate.parse(input, format, strict);
- },
- /**
- * @private
- */
- getFormatCode: function(character) {
- var f = utilDate.formatCodes[character];
- if (f) {
- f = typeof f === 'function' ? f() : f;
- // reassign function result to prevent repeated execution
- utilDate.formatCodes[character] = f;
- }
- // note: unknown characters are treated as literals
- return f || ("'" + Ext.String.escape(character) + "'");
- },
- /**
- * @private
- */
- createFormat: function(format) {
- var code = [],
- special = false,
- ch = '',
- i;
- for (i = 0; i < format.length; ++i) {
- ch = format.charAt(i);
- if (!special && ch === "\\") {
- special = true;
- } else if (special) {
- special = false;
- code.push("'" + Ext.String.escape(ch) + "'");
- } else {
- if (ch === '\n') {
- code.push("'\\n'");
- } else {
- code.push(utilDate.getFormatCode(ch));
- }
- }
- }
- utilDate.formatFunctions[format] = Ext.functionFactory("var m = this; return " + code.join('+'));
- },
- /**
- * @private
- */
- createParser: function(format) {
- var regexNum = utilDate.parseRegexes.length,
- currentGroup = 1,
- calc = [],
- regex = [],
- special = false,
- ch = "",
- i = 0,
- len = format.length,
- atEnd = [],
- obj;
- for (; i < len; ++i) {
- ch = format.charAt(i);
- if (!special && ch === "\\") {
- special = true;
- } else if (special) {
- special = false;
- regex.push(Ext.String.escape(ch));
- } else {
- obj = utilDate.formatCodeToRegex(ch, currentGroup);
- currentGroup += obj.g;
- regex.push(obj.s);
- if (obj.g && obj.c) {
- if (obj.calcAtEnd) {
- atEnd.push(obj.c);
- } else {
- calc.push(obj.c);
- }
- }
- }
- }
- calc = calc.concat(atEnd);
- utilDate.parseRegexes[regexNum] = new RegExp("^" + regex.join('') + "$", 'i');
- utilDate.parseFunctions[format] = Ext.functionFactory("input", "strict", xf(code, regexNum, calc.join('')));
- },
- /**
- * @private
- */
- parseCodes: {
- // Notes:
- // g = {Number} calculation group (0 or 1. only group 1 contributes to
- // date calculations.)
- // c = {String} calculation method (required for group 1. null for group 0.
- // {0} = currentGroup - position in regex result array)
- // s = {String} regex pattern. all matches are stored in results[], and are
- // accessible by the calculation mapped to 'c'
- d: {
- g: 1,
- c: "d = parseInt(results[{0}], 10);\n",
- s: "(3[0-1]|[1-2][0-9]|0[1-9])"
- },
- // day of month with leading zeroes (01 - 31)
- j: {
- g: 1,
- c: "d = parseInt(results[{0}], 10);\n",
- s: "(3[0-1]|[1-2][0-9]|[1-9])"
- },
- // day of month without leading zeroes (1 - 31)
- D: function() {
- var a = [],
- i;
- // get localised short day names
- for (i = 0; i < 7; i++) {
- a.push(utilDate.getShortDayName(i));
- }
- return {
- g: 0,
- c: null,
- s: "(?:" + a.join("|") + ")"
- };
- },
- l: function() {
- return {
- g: 0,
- c: null,
- s: "(?:" + utilDate.dayNames.join("|") + ")"
- };
- },
- N: {
- g: 0,
- c: null,
- s: "[1-7]"
- },
- // ISO-8601 day number (1 (monday) - 7 (sunday))
- //<locale type="object" property="parseCodes">
- S: {
- g: 0,
- c: null,
- s: "(?:st|nd|rd|th)"
- },
- //</locale>
- w: {
- g: 0,
- c: null,
- s: "[0-6]"
- },
- // JavaScript day number (0 (sunday) - 6 (saturday))
- z: {
- g: 1,
- c: "z = parseInt(results[{0}], 10);\n",
- s: "(\\d{1,3})"
- },
- // day of the year (0 - 364 (365 in leap years))
- W: {
- g: 1,
- c: "W = parseInt(results[{0}], 10);\n",
- s: "(\\d{2})"
- },
- // ISO-8601 week number (with leading zero)
- F: function() {
- return {
- g: 1,
- c: "m = parseInt(me.getMonthNumber(results[{0}]), 10);\n",
- s: "(" + utilDate.monthNames.join("|") + ")"
- };
- },
- M: function() {
- var a = [],
- i;
- // get localised short month names
- for (i = 0; i < 12; i++) {
- a.push(utilDate.getShortMonthName(i));
- }
- return Ext.applyIf({
- s: "(" + a.join("|") + ")"
- }, utilDate.formatCodeToRegex("F"));
- },
- m: {
- g: 1,
- c: "m = parseInt(results[{0}], 10) - 1;\n",
- s: "(1[0-2]|0[1-9])"
- },
- // month number with leading zeros (01 - 12)
- n: {
- g: 1,
- c: "m = parseInt(results[{0}], 10) - 1;\n",
- s: "(1[0-2]|[1-9])"
- },
- // month number without leading zeros (1 - 12)
- t: {
- g: 0,
- c: null,
- s: "(?:\\d{2})"
- },
- // no. of days in the month (28 - 31)
- L: {
- g: 0,
- c: null,
- s: "(?:1|0)"
- },
- o: {
- g: 1,
- c: "y = parseInt(results[{0}], 10);\n",
- s: "(\\d{4})"
- },
- // ISO-8601 year number (with leading zero)
- Y: {
- g: 1,
- c: "y = parseInt(results[{0}], 10);\n",
- s: "(\\d{4})"
- },
- // 4-digit year
- y: {
- g: 1,
- c: "var ty = parseInt(results[{0}], 10);\n" + "y = ty > me.y2kYear ? 1900 + ty : 2000 + ty;\n",
- // 2-digit year
- s: "(\\d{2})"
- },
- // In the am/pm parsing routines, we allow both upper and lower case
- // even though it doesn't exactly match the spec. It gives much more flexibility
- // in being able to specify case insensitive regexes.
- /* eslint-disable indent */
- //<locale type="object" property="parseCodes">
- a: {
- g: 1,
- c: "if (/(am)/i.test(results[{0}])) {\n" + "if (!h || h == 12) { h = 0; }\n" + "} else { if (!h || h < 12) { h = (h || 0) + 12; }}",
- s: "(am|pm|AM|PM)",
- calcAtEnd: true
- },
- //</locale>
- //<locale type="object" property="parseCodes">
- A: {
- g: 1,
- c: "if (/(am)/i.test(results[{0}])) {\n" + "if (!h || h == 12) { h = 0; }\n" + "} else { if (!h || h < 12) { h = (h || 0) + 12; }}",
- s: "(AM|PM|am|pm)",
- calcAtEnd: true
- },
- //</locale>
- g: {
- g: 1,
- c: "h = parseInt(results[{0}], 10);\n",
- s: "(1[0-2]|[1-9])"
- },
- // 12-hr format of an hour without leading zeroes (1 - 12)
- G: {
- g: 1,
- c: "h = parseInt(results[{0}], 10);\n",
- s: "(2[0-3]|1[0-9]|[0-9])"
- },
- // 24-hr format of an hour without leading zeroes (0 - 23)
- h: {
- g: 1,
- c: "h = parseInt(results[{0}], 10);\n",
- s: "(1[0-2]|0[1-9])"
- },
- // 12-hr format of an hour with leading zeroes (01 - 12)
- H: {
- g: 1,
- c: "h = parseInt(results[{0}], 10);\n",
- s: "(2[0-3]|[0-1][0-9])"
- },
- // 24-hr format of an hour with leading zeroes (00 - 23)
- i: {
- g: 1,
- c: "i = parseInt(results[{0}], 10);\n",
- s: "([0-5][0-9])"
- },
- // minutes with leading zeros (00 - 59)
- s: {
- g: 1,
- c: "s = parseInt(results[{0}], 10);\n",
- s: "([0-5][0-9])"
- },
- // seconds with leading zeros (00 - 59)
- u: {
- g: 1,
- c: "ms = results[{0}]; ms = parseInt(ms, 10)/Math.pow(10, ms.length - 3);\n",
- s: "(\\d+)"
- },
- // decimal fraction of a second (minimum = 1 digit, maximum = unlimited)
- /* eslint-disable max-len */
- O: {
- g: 1,
- c: [
- "o = results[{0}];",
- "var sn = o.substring(0,1),",
- // get + / - sign
- "hr = o.substring(1,3)*1 + Math.floor(o.substring(3,5) / 60),",
- // get hours (performs minutes-to-hour conversion also, just in case)
- "mn = o.substring(3,5) % 60;",
- // get minutes
- "o = ((-12 <= (hr*60 + mn)/60) && ((hr*60 + mn)/60 <= 14))? (sn + Ext.String.leftPad(hr, 2, '0') + Ext.String.leftPad(mn, 2, '0')) : null;\n"
- ].// -12hrs <= GMT offset <= 14hrs
- join("\n"),
- s: "([+-]\\d{4})"
- },
- // GMT offset in hrs and mins
- P: {
- g: 1,
- c: [
- "o = results[{0}];",
- "var sn = o.substring(0,1),",
- // get + / - sign
- "hr = o.substring(1,3)*1 + Math.floor(o.substring(4,6) / 60),",
- // get hours (performs minutes-to-hour conversion also, just in case)
- "mn = o.substring(4,6) % 60;",
- // get minutes
- "o = ((-12 <= (hr*60 + mn)/60) && ((hr*60 + mn)/60 <= 14))? (sn + Ext.String.leftPad(hr, 2, '0') + Ext.String.leftPad(mn, 2, '0')) : null;\n"
- ].// -12hrs <= GMT offset <= 14hrs
- join("\n"),
- s: "([+-]\\d{2}:\\d{2})"
- },
- // GMT offset in hrs and mins (with colon separator)
- T: {
- g: 0,
- c: null,
- s: "[A-Z]{1,5}"
- },
- // timezone abbrev. may be between 1 - 5 chars
- Z: {
- g: 1,
- c: "zz = results[{0}] * 1;\n" + // -43200 <= UTC offset <= 50400
- "zz = (-43200 <= zz && zz <= 50400)? zz : null;\n",
- s: "([+-]?\\d{1,5})"
- },
- // leading '+' sign is optional for UTC offset
- c: function() {
- var calc = [],
- arr = [
- utilDate.formatCodeToRegex("Y", 1),
- // year
- utilDate.formatCodeToRegex("m", 2),
- // month
- utilDate.formatCodeToRegex("d", 3),
- // day
- utilDate.formatCodeToRegex("H", 4),
- // hour
- utilDate.formatCodeToRegex("i", 5),
- // minute
- utilDate.formatCodeToRegex("s", 6),
- // second
- {
- c: "ms = results[7] || '0'; ms = parseInt(ms, 10)/Math.pow(10, ms.length - 3);\n"
- },
- // decimal fraction of a second (minimum = 1 digit, maximum = unlimited)
- {
- c: [
- // allow either "Z" (i.e. UTC) or "-0530" or "+08:00" (i.e. UTC offset) timezone delimiters. assumes local timezone if no timezone is specified
- "if (results[8]) {",
- // timezone specified
- "if (results[8] == 'Z') {",
- "zz = 0;",
- // UTC
- "}",
- "else if (results[8].indexOf(':') > -1) {",
- utilDate.formatCodeToRegex("P", 8).c,
- // timezone offset with colon separator
- "}",
- "else {",
- utilDate.formatCodeToRegex("O", 8).c,
- // timezone offset without colon separator
- "}",
- "}"
- ].join('\n')
- }
- ],
- i, l;
- for (i = 0 , l = arr.length; i < l; ++i) {
- calc.push(arr[i].c);
- }
- return {
- g: 1,
- c: calc.join(""),
- s: [
- arr[0].s,
- // year (required)
- "(?:",
- "-",
- arr[1].s,
- // month (optional)
- "(?:",
- "-",
- arr[2].s,
- // day (optional)
- "(?:",
- "(?:T| )?",
- // time delimiter -- either a "T" or a single blank space
- arr[3].s,
- ":",
- arr[4].s,
- // hour AND minute, delimited by a single colon (optional). MUST be preceded by either a "T" or a single blank space
- "(?::",
- arr[5].s,
- ")?",
- // seconds (optional)
- "(?:(?:\\.|,)(\\d+))?",
- // decimal fraction of a second (e.g. ",12345" or ".98765") (optional)
- "(Z|(?:[-+]\\d{2}(?::)?\\d{2}))?",
- // "Z" (UTC) or "-0530" (UTC offset without colon delimiter) or "+08:00" (UTC offset with colon delimiter) (optional)
- ")?",
- ")?",
- ")?"
- ].join("")
- };
- },
- U: {
- g: 1,
- c: "u = parseInt(results[{0}], 10);\n",
- s: "(-?\\d+)"
- }
- },
- // leading minus sign indicates seconds before UNIX epoch
- /* eslint-enable indent, max-len */
- compare: function(d1, d2, includeTime) {
- var s1, s2;
- if (typeof d1 === 'string') {
- d1 = Ext.Date.parse(d1);
- }
- if (typeof d2 === 'string') {
- d2 = Ext.Date.parse(d2);
- }
- s1 = Ext.Date.format(d1, 'C');
- s2 = Ext.Date.format(d2, 'C');
- if (!includeTime) {
- s1 = s1.substr(0, 10);
- // "YYYY-MM-DD".length === 10
- s2 = s2.substr(0, 10);
- }
- return (s1 < s2) ? -1 : ((s2 < s1) ? 1 : 0);
- },
- // Old Ext.Date prototype methods.
- /**
- * @private
- */
- dateFormat: function(date, format) {
- return utilDate.format(date, format);
- },
- /**
- * Compares if two dates are equal by comparing their values.
- * @param {Date} date1
- * @param {Date} date2
- * @return {Boolean} `true` if the date values are equal
- */
- isEqual: function(date1, date2) {
- // check we have 2 date objects
- if (date1 && date2) {
- return +date1 === +date2;
- }
- // one or both isn't a date, only equal if both are falsy
- return !(date1 || date2);
- },
- /**
- * Formats a date given the supplied format string.
- * @param {Date} date The date to format
- * @param {String} format The format string
- * @return {String} The formatted date or an empty string if date parameter is not
- * a JavaScript Date object
- */
- format: function(date, format) {
- var formatFunctions = utilDate.formatFunctions;
- if (!Ext.isDate(date)) {
- return '';
- }
- if (formatFunctions[format] == null) {
- utilDate.createFormat(format);
- }
- return formatFunctions[format].call(date) + '';
- },
- /**
- * Get the timezone abbreviation of the current date (equivalent to the format specifier 'T').
- *
- * __Note:__ The date string returned by the JavaScript Date object's `toString()` method varies
- * between browsers (e.g. FF vs IE) and system region settings (e.g. IE in Asia vs IE in
- * America). For a given date string e.g. "Thu Oct 25 2007 22:55:35 GMT+0800 (Malay Peninsula
- * Standard Time)", `getTimezone()` first tries to get the timezone abbreviation from between
- * a pair of parentheses (which may or may not be present), failing which it proceeds to get
- * the timezone abbreviation from the GMT offset portion of the date string.
- *
- * var dt = new Date('9/17/2011');
- * console.log(Ext.Date.getTimezone(dt));
- *
- * @param {Date} date The date
- * @return {String} The abbreviated timezone name (e.g. 'CST', 'PDT', 'EDT', 'MPST' ...).
- */
- getTimezone: function(date) {
- /* eslint-disable max-len, no-useless-escape, newline-per-chained-call */
- // the following list shows the differences between date strings from different browsers on a WinXP SP2 machine from an Asian locale:
- //
- // Opera : "Thu, 25 Oct 2007 22:53:45 GMT+0800" -- shortest (weirdest) date string of the lot
- // Safari : "Thu Oct 25 2007 22:55:35 GMT+0800 (Malay Peninsula Standard Time)" -- value in parentheses always gives the correct timezone (same as FF)
- // FF : "Thu Oct 25 2007 22:55:35 GMT+0800 (Malay Peninsula Standard Time)" -- value in parentheses always gives the correct timezone
- // IE : "Thu Oct 25 22:54:35 UTC+0800 2007" -- (Asian system setting) look for 3-4 letter timezone abbrev
- // IE : "Thu Oct 25 17:06:37 PDT 2007" -- (American system setting) look for 3-4 letter timezone abbrev
- //
- // this crazy regex attempts to guess the correct timezone abbreviation despite these differences.
- // step 1: (?:\((.*)\) -- find timezone in parentheses
- // step 2: ([A-Z]{1,4})(?:[\-+][0-9]{4})?(?: -?\d+)?) -- if nothing was found in step 1, find timezone from timezone offset portion of date string
- // step 3: remove all non uppercase characters found in step 1 and 2
- return date.toString().replace(/^.* (?:\((.*)\)|([A-Z]{1,5})(?:[\-+][0-9]{4})?(?: -?\d+)?)$/, "$1$2").replace(/[^A-Z]/g, "");
- },
- /* eslint-enable max-len, no-useless-escape, newline-per-chained-call */
- /**
- * Get the offset from GMT of the current date (equivalent to the format specifier 'O').
- *
- * var dt = new Date('9/17/2011');
- * console.log(Ext.Date.getGMTOffset(dt));
- *
- * @param {Date} date The date
- * @param {Boolean} [colon=false] `true` to separate the hours and minutes with a colon.
- * @return {String} The 4-character offset string prefixed with + or - (e.g. '-0600').
- */
- getGMTOffset: function(date, colon) {
- var offset = date.getTimezoneOffset();
- return (offset > 0 ? "-" : "+") + Ext.String.leftPad(Math.floor(Math.abs(offset) / 60), 2, "0") + (colon ? ":" : "") + Ext.String.leftPad(Math.abs(offset % 60), 2, "0");
- },
- /**
- * Get the numeric day number of the year, adjusted for leap year.
- *
- * var dt = new Date('9/17/2011');
- * console.log(Ext.Date.getDayOfYear(dt)); // 259
- *
- * @param {Date} date The date
- * @return {Number} 0 to 364 (365 in leap years).
- */
- getDayOfYear: function(date) {
- var num = 0,
- d = utilDate.clone(date),
- m = date.getMonth(),
- i;
- for (i = 0 , d.setDate(1) , d.setMonth(0); i < m; d.setMonth(++i)) {
- num += utilDate.getDaysInMonth(d);
- }
- return num + date.getDate() - 1;
- },
- /**
- * Get the numeric ISO-8601 week number of the year.
- * (equivalent to the format specifier 'W', but without a leading zero).
- *
- * var dt = new Date('9/17/2011');
- * console.log(Ext.Date.getWeekOfYear(dt)); // 37
- *
- * @param {Date} date The date.
- * @return {Number} 1 to 53.
- * @method
- */
- getWeekOfYear: (function() {
- // adapted from http://www.merlyn.demon.co.uk/weekcalc.htm
- var ms1d = 86400000,
- // milliseconds in a day
- ms7d = 7 * ms1d;
- // milliseconds in a week
- return function(date) {
- // return a closure so constants get calculated only once
- /* eslint-disable-next-line max-len */
- var DC3 = nativeDate.UTC(date.getFullYear(), date.getMonth(), date.getDate() + 3) / ms1d,
- // an Absolute Day Number
- AWN = Math.floor(DC3 / 7),
- // an Absolute Week Number
- Wyr = new nativeDate(AWN * ms7d).getUTCFullYear();
- return AWN - Math.floor(nativeDate.UTC(Wyr, 0, 7) / ms7d) + 1;
- };
- }()),
- /**
- * Checks if the current date falls within a leap year.
- *
- * var dt = new Date('1/10/2011');
- * console.log(Ext.Date.isLeapYear(dt)); // false
- *
- * @param {Date} date The date
- * @return {Boolean} `true` if the current date falls within a leap year, `false` otherwise.
- */
- isLeapYear: function(date) {
- var year = date.getFullYear();
- return !!((year & 3) === 0 && (year % 100 || (year % 400 === 0 && year)));
- },
- /**
- * Get the first day of the current month, adjusted for leap year. The returned value
- * is the numeric day index within the week (0-6) which can be used in conjunction with
- * the {@link #monthNames} array to retrieve the textual day name.
- *
- * var dt = new Date('1/10/2007'),
- * firstDay = Ext.Date.getFirstDayOfMonth(dt);
- *
- * console.log(Ext.Date.dayNames[firstDay]); // output: 'Monday'
- *
- * @param {Date} date The date
- * @return {Number} The day number (0-6).
- */
- getFirstDayOfMonth: function(date) {
- var day = (date.getDay() - (date.getDate() - 1)) % 7;
- return (day < 0) ? (day + 7) : day;
- },
- /**
- * Get the last day of the current month, adjusted for leap year. The returned value
- * is the numeric day index within the week (0-6) which can be used in conjunction with
- * the {@link #monthNames} array to retrieve the textual day name.
- *
- * var dt = new Date('1/10/2007'),
- * lastDay = Ext.Date.getLastDayOfMonth(dt);
- *
- * console.log(Ext.Date.dayNames[lastDay]); // output: 'Wednesday'
- *
- * @param {Date} date The date
- * @return {Number} The day number (0-6).
- */
- getLastDayOfMonth: function(date) {
- return utilDate.getLastDateOfMonth(date).getDay();
- },
- /**
- * Get the date of the first day of the month in which this date resides.
- * @param {Date} date The date
- * @return {Date}
- */
- getFirstDateOfMonth: function(date) {
- return new nativeDate(date.getFullYear(), date.getMonth(), 1);
- },
- /**
- * Get the date of the last day of the month in which this date resides.
- * @param {Date} date The date
- * @return {Date}
- */
- getLastDateOfMonth: function(date) {
- return new nativeDate(date.getFullYear(), date.getMonth(), utilDate.getDaysInMonth(date));
- },
- /**
- * Get the number of days in the current month, adjusted for leap year.
- * @param {Date} date The date
- * @return {Number} The number of days in the month.
- * @method
- */
- getDaysInMonth: (function() {
- var daysInMonth = [
- 31,
- 28,
- 31,
- 30,
- 31,
- 30,
- 31,
- 31,
- 30,
- 31,
- 30,
- 31
- ];
- return function(date) {
- // return a closure for efficiency
- var m = date.getMonth();
- return m === 1 && utilDate.isLeapYear(date) ? 29 : daysInMonth[m];
- };
- }()),
- /**
- * Get the English ordinal suffix of the current day (equivalent to the format specifier 'S').
- * @param {Date} date The date
- * @return {String} 'st, 'nd', 'rd' or 'th'.
- * @locale
- */
- getSuffix: function(date) {
- switch (date.getDate()) {
- case 1:
- case 21:
- case 31:
- return "st";
- case 2:
- case 22:
- return "nd";
- case 3:
- case 23:
- return "rd";
- default:
- return "th";
- }
- },
- /**
- * Creates and returns a new Date instance with the exact same date value as the called
- * instance. Dates are copied and passed by reference, so if a copied date variable is modified
- * later, the original variable will also be changed. When the intention is to create a new
- * variable that will not modify the original instance, you should create a clone.
- *
- * Example of correctly cloning a date:
- *
- * //wrong way:
- * var orig = new Date('10/1/2006');
- * var copy = orig;
- * copy.setDate(5);
- * console.log(orig); // returns 'Thu Oct 05 2006'!
- *
- * //correct way:
- * var orig = new Date('10/1/2006'),
- * copy = Ext.Date.clone(orig);
- * copy.setDate(5);
- * console.log(orig); // returns 'Thu Oct 01 2006'
- *
- * @param {Date} date The date.
- * @return {Date} The new Date instance.
- */
- clone: function(date) {
- return new nativeDate(date.getTime());
- },
- /**
- * Checks if the current date is affected by Daylight Saving Time (DST).
- * @param {Date} date The date
- * @return {Boolean} `true` if the current date is affected by DST.
- */
- isDST: function(date) {
- // adapted from http://sencha.com/forum/showthread.php?p=247172#post247172
- // courtesy of @geoffrey.mcgill
- /* eslint-disable-next-line max-len */
- return new nativeDate(date.getFullYear(), 0, 1).getTimezoneOffset() !== date.getTimezoneOffset();
- },
- /**
- * Attempts to clear all time information from this Date by setting the time to midnight
- * of the same day, automatically adjusting for Daylight Saving Time (DST) where applicable.
- *
- * __Note:__ DST timezone information for the browser's host operating system is assumed to be
- * up-to-date.
- * @param {Date} date The date
- * @param {Boolean} [clone=false] `true` to create a clone of this date, clear the time and
- * return it.
- * @return {Date} this or the clone.
- */
- clearTime: function(date, clone) {
- var d, hr, c;
- // handles invalid dates preventing the browser from crashing.
- if (isNaN(date.getTime())) {
- return date;
- }
- if (clone) {
- return utilDate.clearTime(utilDate.clone(date));
- }
- // get current date before clearing time
- d = date.getDate();
- // clear time
- date.setHours(0);
- date.setMinutes(0);
- date.setSeconds(0);
- date.setMilliseconds(0);
- // account for DST (i.e. day of month changed when setting hour = 0)
- if (date.getDate() !== d) {
- // note: DST adjustments are assumed to occur in multiples of 1 hour
- // (this is almost always the case)
- // refer to http://www.timeanddate.com/time/aboutdst.html for the (rare) exceptions
- // to this rule
- // increment hour until cloned date == current date
- /* eslint-disable-next-line max-len, curly, nonblock-statement-body-position */
- for (hr = 1 , c = utilDate.add(date, utilDate.HOUR, hr); c.getDate() !== d; hr++ , c = utilDate.add(date, utilDate.HOUR, hr)){}
- date.setDate(d);
- date.setHours(c.getHours());
- }
- return date;
- },
- /**
- * Provides a convenient method for performing basic date arithmetic. This method
- * does not modify the Date instance being called - it creates and returns
- * a new Date instance containing the resulting date value.
- *
- * Examples:
- *
- * // Basic usage:
- * var dt = Ext.Date.add(new Date('10/29/2006'), Ext.Date.DAY, 5);
- * console.log(dt); // returns 'Fri Nov 03 2006 00:00:00'
- *
- * // Negative values will be subtracted:
- * var dt2 = Ext.Date.add(new Date('10/1/2006'), Ext.Date.DAY, -5);
- * console.log(dt2); // returns 'Tue Sep 26 2006 00:00:00'
- *
- * // Decimal values can be used:
- * var dt3 = Ext.Date.add(new Date('10/1/2006'), Ext.Date.DAY, 1.25);
- * console.log(dt3); // returns 'Mon Oct 02 2006 06:00:00'
- *
- * @param {Date} date The date to modify
- * @param {String} interval A valid date interval enum value.
- * @param {Number} value The amount to add to the current date.
- * @param {Boolean} [preventDstAdjust=false] `true` to prevent adjustments when crossing
- * daylight savings boundaries.
- * @return {Date} The new Date instance.
- */
- add: function(date, interval, value, preventDstAdjust) {
- var d = utilDate.clone(date),
- base = 0,
- day, decimalValue;
- if (!interval || value === 0) {
- return d;
- }
- decimalValue = value - parseInt(value, 10);
- value = parseInt(value, 10);
- if (value) {
- switch (interval.toLowerCase()) {
- // See EXTJSIV-7418. We use setTime() here to deal with issues related to
- // the switchover that occurs when changing to daylight savings and vice
- // versa. setTime() handles this correctly where setHour/Minute/Second/Millisecond
- // do not. Let's assume the DST change occurs at 2am and we're incrementing using
- // add for 15 minutes at time. When entering DST, we should see:
- // 01:30am
- // 01:45am
- // 03:00am // skip 2am because the hour does not exist
- // ...
- // Similarly, leaving DST, we should see:
- // 01:30am
- // 01:45am
- // 01:00am // repeat 1am because that's the change over
- // 01:30am
- // 01:45am
- // 02:00am
- // ....
- //
- case utilDate.MILLI:
- if (preventDstAdjust) {
- d.setMilliseconds(d.getMilliseconds() + value);
- } else {
- d.setTime(d.getTime() + value);
- };
- break;
- case utilDate.SECOND:
- if (preventDstAdjust) {
- d.setSeconds(d.getSeconds() + value);
- } else {
- d.setTime(d.getTime() + value * 1000);
- };
- break;
- case utilDate.MINUTE:
- if (preventDstAdjust) {
- d.setMinutes(d.getMinutes() + value);
- } else {
- d.setTime(d.getTime() + value * 60 * 1000);
- };
- break;
- case utilDate.HOUR:
- if (preventDstAdjust) {
- d.setHours(d.getHours() + value);
- } else {
- d.setTime(d.getTime() + value * 60 * 60 * 1000);
- };
- break;
- case utilDate.DAY:
- if (preventDstAdjust === false) {
- d.setTime(d.getTime() + value * 24 * 60 * 60 * 1000);
- } else {
- d.setDate(d.getDate() + value);
- };
- break;
- case utilDate.MONTH:
- day = date.getDate();
- if (day > 28) {
- /* eslint-disable-next-line max-len */
- day = Math.min(day, utilDate.getLastDateOfMonth(utilDate.add(utilDate.getFirstDateOfMonth(date), utilDate.MONTH, value)).getDate());
- };
- d.setDate(day);
- d.setMonth(date.getMonth() + value);
- break;
- case utilDate.YEAR:
- day = date.getDate();
- if (day > 28) {
- /* eslint-disable-next-line max-len */
- day = Math.min(day, utilDate.getLastDateOfMonth(utilDate.add(utilDate.getFirstDateOfMonth(date), utilDate.YEAR, value)).getDate());
- };
- d.setDate(day);
- d.setFullYear(date.getFullYear() + value);
- break;
- }
- }
- if (decimalValue) {
- switch (interval.toLowerCase()) {
- /* eslint-disable no-multi-spaces */
- case utilDate.MILLI:
- base = 1;
- break;
- case utilDate.SECOND:
- base = 1000;
- break;
- case utilDate.MINUTE:
- base = 1000 * 60;
- break;
- case utilDate.HOUR:
- base = 1000 * 60 * 60;
- break;
- case utilDate.DAY:
- base = 1000 * 60 * 60 * 24;
- break;
- /* eslint-enable no-multi-spaces */
- case utilDate.MONTH:
- day = utilDate.getDaysInMonth(d);
- base = 1000 * 60 * 60 * 24 * day;
- break;
- case utilDate.YEAR:
- day = (utilDate.isLeapYear(d) ? 366 : 365);
- base = 1000 * 60 * 60 * 24 * day;
- break;
- }
- if (base) {
- d.setTime(d.getTime() + base * decimalValue);
- }
- }
- return d;
- },
- /**
- * Provides a convenient method for performing basic date arithmetic. This method
- * does not modify the Date instance being called - it creates and returns
- * a new Date instance containing the resulting date value.
- *
- * Examples:
- *
- * // Basic usage:
- * var dt = Ext.Date.subtract(new Date('10/29/2006'), Ext.Date.DAY, 5);
- * console.log(dt); // returns 'Tue Oct 24 2006 00:00:00'
- *
- * // Negative values will be added:
- * var dt2 = Ext.Date.subtract(new Date('10/1/2006'), Ext.Date.DAY, -5);
- * console.log(dt2); // returns 'Fri Oct 6 2006 00:00:00'
- *
- * // Decimal values can be used:
- * var dt3 = Ext.Date.subtract(new Date('10/1/2006'), Ext.Date.DAY, 1.25);
- * console.log(dt3); // returns 'Fri Sep 29 2006 06:00:00'
- *
- * @param {Date} date The date to modify
- * @param {String} interval A valid date interval enum value.
- * @param {Number} value The amount to subtract from the current date.
- * @param {Boolean} [preventDstAdjust=false] `true` to prevent adjustments when crossing
- * daylight savings boundaries.
- * @return {Date} The new Date instance.
- */
- subtract: function(date, interval, value, preventDstAdjust) {
- return utilDate.add(date, interval, -value, preventDstAdjust);
- },
- /**
- * Checks if a date falls on or between the given start and end dates.
- * @param {Date} date The date to check
- * @param {Date} start Start date
- * @param {Date} end End date
- * @return {Boolean} `true` if this date falls on or between the given start and end dates.
- */
- between: function(date, start, end) {
- var t = date.getTime();
- return start.getTime() <= t && t <= end.getTime();
- },
- /**
- * Checks if the date is a weekend day. Uses {@link #weekendDays}.
- * @param {Date} date The date.
- * @return {Boolean} `true` if the day falls on a weekend.
- *
- * @since 6.2.0
- */
- isWeekend: function(date) {
- return Ext.Array.indexOf(this.weekendDays, date.getDay()) > -1;
- },
- /**
- * Converts the passed UTC date into a local date.
- * For example, if the passed date is:
- * `Wed Jun 01 2016 00:10:00 GMT+1000 (AUS Eastern Standard Time)`, then
- * the returned date will be `Wed Jun 01 2016 00:00:00 GMT+1000 (AUS Eastern Standard Time)`.
- * @param {Date} d The date to convert.
- * @return {Date} The date as a local. Does not modify the passed date.
- *
- * @since 6.2.0
- */
- utcToLocal: function(d) {
- return new Date(d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate(), d.getUTCHours(), d.getUTCMinutes(), d.getUTCSeconds(), d.getUTCMilliseconds());
- },
- /**
- * Converts the passed local date into a UTC date.
- * For example, if the passed date is:
- * `Wed Jun 01 2016 00:00:00 GMT+1000 (AUS Eastern Standard Time)`, then
- * the returned date will be `Wed Jun 01 2016 10:00:00 GMT+1000 (AUS Eastern Standard Time)`.
- * @param {Date} d The date to convert.
- * @return {Date} The date as UTC. Does not modify the passed date.
- *
- * @since 6.2.0
- */
- localToUtc: function(d) {
- return utilDate.utc(d.getFullYear(), d.getMonth(), d.getDate(), d.getHours(), d.getMinutes(), d.getSeconds(), d.getMilliseconds());
- },
- /**
- * Create a UTC date.
- * @param {Number} year The year.
- * @param {Number} month The month.
- * @param {Number} day The day.
- * @param {Number} [hour=0] The hour.
- * @param {Number} [min=0] The minutes.
- * @param {Number} [s=0] The seconds.
- * @param {Number} [ms=0] The milliseconds.
- * @return {Date} The UTC date.
- *
- * @since 6.2.0
- */
- utc: function(year, month, day, hour, min, s, ms) {
- return new Date(Date.UTC(year, month, day, hour || 0, min || 0, s || 0, ms || 0));
- },
- // Maintains compatibility with old static and prototype window.Date methods.
- compat: function() {
- var p,
- /* eslint-disable max-len */
- statics = [
- 'useStrict',
- 'formatCodeToRegex',
- 'parseFunctions',
- 'parseRegexes',
- 'formatFunctions',
- 'y2kYear',
- 'MILLI',
- 'SECOND',
- 'MINUTE',
- 'HOUR',
- 'DAY',
- 'MONTH',
- 'YEAR',
- 'defaults',
- 'dayNames',
- 'monthNames',
- 'monthNumbers',
- 'getShortMonthName',
- 'getShortDayName',
- 'getMonthNumber',
- 'formatCodes',
- 'isValid',
- 'parseDate',
- 'getFormatCode',
- 'createFormat',
- 'createParser',
- 'parseCodes'
- ],
- proto = [
- 'dateFormat',
- 'format',
- 'getTimezone',
- 'getGMTOffset',
- 'getDayOfYear',
- 'getWeekOfYear',
- 'isLeapYear',
- 'getFirstDayOfMonth',
- 'getLastDayOfMonth',
- 'getDaysInMonth',
- 'getSuffix',
- 'clone',
- 'isDST',
- 'clearTime',
- 'add',
- 'between'
- ],
- /* eslint-enable max-len */
- sLen = statics.length,
- pLen = proto.length,
- stat, prot, s;
- // Append statics
- for (s = 0; s < sLen; s++) {
- stat = statics[s];
- nativeDate[stat] = utilDate[stat];
- }
- // Append to prototype
- for (p = 0; p < pLen; p++) {
- prot = proto[p];
- nativeDate.prototype[prot] = function() {
- var args = Array.prototype.slice.call(arguments);
- args.unshift(this);
- return utilDate[prot].apply(utilDate, args);
- };
- }
- },
- /**
- * Calculate how many units are there between two time.
- * @param {Date} min The first time.
- * @param {Date} max The second time.
- * @param {String} unit The unit. This unit is compatible with the date interval constants.
- * @return {Number} The maximum number n of units that min + n * unit <= max.
- */
- diff: function(min, max, unit) {
- var diff = +max - min,
- est;
- switch (unit) {
- case utilDate.MILLI:
- return diff;
- case utilDate.SECOND:
- return Math.floor(diff / 1000);
- case utilDate.MINUTE:
- return Math.floor(diff / 60000);
- case utilDate.HOUR:
- return Math.floor(diff / 3600000);
- case utilDate.DAY:
- return Math.floor(diff / 86400000);
- case 'w':
- return Math.floor(diff / 604800000);
- case utilDate.MONTH:
- est = (max.getFullYear() * 12 + max.getMonth()) - (min.getFullYear() * 12 + min.getMonth());
- if (utilDate.add(min, unit, est) > max) {
- return est - 1;
- };
- return est;
- case utilDate.YEAR:
- est = max.getFullYear() - min.getFullYear();
- if (utilDate.add(min, unit, est) > max) {
- return est - 1;
- } else {
- return est;
- };
- }
- },
- /**
- * Align the date to `unit`.
- * @param {Date} date The date to be aligned.
- * @param {String} unit The unit. This unit is compatible with the date interval constants.
- * @param {Number} step
- * @return {Date} The aligned date.
- */
- align: function(date, unit, step) {
- var num = new nativeDate(+date);
- switch (unit.toLowerCase()) {
- case utilDate.MILLI:
- return num;
- case utilDate.SECOND:
- num.setUTCSeconds(num.getUTCSeconds() - num.getUTCSeconds() % step);
- num.setUTCMilliseconds(0);
- return num;
- case utilDate.MINUTE:
- num.setUTCMinutes(num.getUTCMinutes() - num.getUTCMinutes() % step);
- num.setUTCSeconds(0);
- num.setUTCMilliseconds(0);
- return num;
- case utilDate.HOUR:
- num.setUTCHours(num.getUTCHours() - num.getUTCHours() % step);
- num.setUTCMinutes(0);
- num.setUTCSeconds(0);
- num.setUTCMilliseconds(0);
- return num;
- case utilDate.DAY:
- if (step === 7 || step === 14) {
- num.setUTCDate(num.getUTCDate() - num.getUTCDay() + 1);
- };
- num.setUTCHours(0);
- num.setUTCMinutes(0);
- num.setUTCSeconds(0);
- num.setUTCMilliseconds(0);
- return num;
- case utilDate.MONTH:
- num.setUTCMonth(num.getUTCMonth() - (num.getUTCMonth() - 1) % step, 1);
- num.setUTCHours(0);
- num.setUTCMinutes(0);
- num.setUTCSeconds(0);
- num.setUTCMilliseconds(0);
- return num;
- case utilDate.YEAR:
- num.setUTCFullYear(num.getUTCFullYear() - num.getUTCFullYear() % step, 1, 1);
- num.setUTCHours(0);
- num.setUTCMinutes(0);
- num.setUTCSeconds(0);
- num.setUTCMilliseconds(0);
- return date;
- }
- },
- flexParse: function(inDate, defaultFormat) {
- var parts = datePartsRe.exec(inDate),
- firstFormatToken, day, month, year, result;
- // Regex couldn't parse; invalid date.
- if (!parts) {
- return Ext.Date.parse(inDate, 'C');
- }
- // handle "YYYY-MM-DDThh:mm:ssZ"
- // Use this format string to work out what is the desired date order, d/m/y|m/d/y|y/m/d
- if (!defaultFormat) {
- defaultFormat = Ext.Date.defaultFormat;
- }
- // Now the parts array will be:
- // [0] - the full string
- // [1] - The first token if numeric
- // [2] - The first token if alphabetic
- // [3] - The second token if numeric
- // [4] - The second token if alphabetic
- // [5] - The third token.
- // If they've used all numeric parts, we have to use locale order
- // to decide what the parts are. We have three valid choices:
- // d/m/y
- // m/d/y
- // y/m/d
- if (!(parts[2] || parts[4])) {
- firstFormatToken = defaultFormat[0];
- // Not in a y/m/d locale and (first character is a day token, or first
- // token is definitely a day) - it's d/m/y
- // eslint-disable-next-line no-undef
- if (!yearInfo[firstFormatToken] && (dayInfo[firstFormatToken] || (parts[1] > 12 && parts[3] < 13))) {
- day = parseInt(parts[1]);
- month = parseInt(parts[3]) - 1;
- year = parseInt(parts[5]);
- } else if (!yearInfo[firstFormatToken] && (monthInfo[firstFormatToken] || (parts[3] > 12 && parts[1] < 13))) {
- // Not in a y/m/d locale and (first charecter is a month token, or
- // first token is definitely a month) - it's m/d/y
- month = parseInt(parts[1]) - 1;
- day = parseInt(parts[3]);
- year = parseInt(parts[5]);
- } else {
- // y/m/d is the only other valid format
- year = parseInt(parts[1]);
- month = parseInt(parts[3]) - 1;
- day = parseInt(parts[5]);
- }
- } else {
- // They've used an alphabetic month
- // Two alphabetic tokens - not valid.
- if (parts[2] && parts[4]) {
- return null;
- }
- // m/d/y
- if (parts[2]) {
- month = utilDate.monthNumbers[Ext.String.capitalize(parts[2].substr(0, 3))];
- day = parseInt(parts[3]);
- year = parseInt(parts[5]);
- } else {
- // d/m/y
- day = parseInt(parts[1]);
- month = utilDate.monthNumbers[Ext.String.capitalize(parts[4].substr(0, 3))];
- year = parseInt(parts[5]);
- }
- }
- // Alphabetic month couldn't be found, or numeric one out of range.
- if (isNaN(month) || (month < 0 || month > 11)) {
- return null;
- }
- // Short years must be upgraded according to the y2kYear setting
- if (year < utilDate.y2kYear) {
- year += 2000;
- }
- // Create the first of the month so that we can check the validity of the day
- result = new Date(year, month, 1, 0, 0, 0);
- // Validate the day of month.
- if (day < 1 || day > Ext.Date.getDaysInMonth(result)) {
- return null;
- }
- result.setDate(day);
- return result;
- }
- };
- utilDate.parseCodes.C = utilDate.parseCodes.c;
- return utilDate;
- }());
- /**
- * @class Ext.Function
- *
- * A collection of useful static methods to deal with function callbacks.
- * @singleton
- */
- /* eslint-disable indent */
- Ext.Function = (function() {
- // @define Ext.lang.Function
- // @define Ext.Function
- // @require Ext
- // @require Ext.lang.Array
- var lastTime = 0,
- animFrameId,
- animFrameHandlers = [],
- animFrameNoArgs = [],
- idSource = 0,
- animFrameMap = {},
- slice = Array.prototype.slice,
- win = window,
- global = Ext.global,
- // We disable setImmediate in unit tests because it derails internal Jasmine queue
- hasImmediate = !Ext.disableImmediate && !!(global.setImmediate && global.clearImmediate),
- requestAnimFrame = win.requestAnimationFrame || win.webkitRequestAnimationFrame || win.mozRequestAnimationFrame || win.oRequestAnimationFrame || function(callback) {
- var currTime = Ext.now(),
- timeToCall = Math.max(0, 16 - (currTime - lastTime)),
- timerFn = function() {
- callback(currTime + timeToCall);
- },
- id;
- timerFn.$origFn = callback.$origFn || callback;
- timerFn.$skipTimerCheck = timerFn.$origFn.$skipTimerCheck;
- id = win.setTimeout(timerFn, timeToCall);
- lastTime = currTime + timeToCall;
- return id;
- },
- fireHandlers = function() {
- var len = animFrameHandlers.length,
- id, i, handler;
- animFrameId = null;
- var timer;
- // eslint-disable-line vars-on-top
- // Fire all animation frame handlers in one go
- for (i = 0; i < len; i++) {
- handler = animFrameHandlers[i];
- id = handler[3];
- // Check if this timer has been canceled; its map entry is going to be removed
- if (animFrameMap[id]) {
- delete animFrameMap[id];
- timer = Ext.Timer.get(id, 'raf');
- if (timer) {
- timer.tick();
- }
- handler[0].apply(handler[1] || global, handler[2] || animFrameNoArgs);
- if (timer) {
- timer.tock();
- }
- }
- }
- // Clear all fired animation frame handlers, don't forget that new handlers
- // could have been created in user handler functions called in the loop above
- animFrameHandlers = animFrameHandlers.slice(len);
- },
- fireElevatedHandlers = function() {
- Ext.elevate(fireHandlers);
- },
- ExtFunction = {
- /**
- * A very commonly used method throughout the framework. It acts as a wrapper around
- * another method which originally accepts 2 arguments for `name` and `value`.
- * The wrapped function then allows "flexible" value setting of either:
- *
- * - `name` and `value` as 2 arguments
- * - one single object argument with multiple key - value pairs
- *
- * For example:
- *
- * var setValue = Ext.Function.flexSetter(function(name, value) {
- * this[name] = value;
- * });
- *
- * // Afterwards
- * // Setting a single name - value
- * setValue('name1', 'value1');
- *
- * // Settings multiple name - value pairs
- * setValue({
- * name1: 'value1',
- * name2: 'value2',
- * name3: 'value3'
- * });
- *
- * @param {Function} setter The single value setter method.
- * @param {String} setter.name The name of the value being set.
- * @param {Object} setter.value The value being set.
- * @return {Function}
- */
- flexSetter: function(setter) {
- return function(name, value) {
- var k, i;
- if (name !== null) {
- if (typeof name !== 'string') {
- for (k in name) {
- if (name.hasOwnProperty(k)) {
- setter.call(this, k, name[k]);
- }
- }
- if (Ext.enumerables) {
- for (i = Ext.enumerables.length; i--; ) {
- k = Ext.enumerables[i];
- if (name.hasOwnProperty(k)) {
- setter.call(this, k, name[k]);
- }
- }
- }
- } else {
- setter.call(this, name, value);
- }
- }
- return this;
- };
- },
- /**
- * Create a new function from the provided `fn`, change `this` to the provided scope,
- * optionally overrides arguments for the call. Defaults to the arguments passed by
- * the caller.
- *
- * {@link Ext#bind Ext.bind} is alias for {@link Ext.Function#bind Ext.Function.bind}
- *
- * **NOTE:** This method is similar to the native `bind()` method. The major difference
- * is in the way the parameters are passed. This method expects an array of parameters,
- * and if supplied, it does not automatically pass forward parameters from the bound
- * function:
- *
- * function foo (a, b, c) {
- * console.log(a, b, c);
- * }
- *
- * var nativeFn = foo.bind(this, 1, 2);
- * var extFn = Ext.Function.bind(foo, this, [1, 2]);
- *
- * nativeFn(3); // 1, 2, 3
- * extFn(3); // 1, 2, undefined
- *
- * This method is unavailable natively on IE8 and IE/Quirks but Ext JS provides a
- * "polyfill" to emulate the important features of the standard `bind` method. In
- * particular, the polyfill only provides binding of "this" and optional arguments.
- *
- * @param {Function} fn The function to delegate.
- * @param {Object} [scope] The scope (`this` reference) in which the function
- * is executed.
- * **If omitted, defaults to the global environment object (usually the browser `window`).**
- * @param {Array} [args] Overrides arguments for the call. (Defaults to
- * the arguments passed by the caller).
- * @param {Boolean/Number} [appendArgs] if `true` the `args` are appended to the
- * arguments passed to the returned wrapper (by default these arguments are ignored).
- * If a number then the `args` are inserted at the specified position.
- * @return {Function} The bound wrapper function.
- */
- bind: function(fn, scope, args, appendArgs) {
- // Function.prototype.bind is polyfilled in IE8, otherwise native
- if (arguments.length <= 2) {
- return fn.bind(scope);
- }
- var method = fn;
- // eslint-disable-line vars-on-top
- return function() {
- var callArgs = args || arguments;
- if (appendArgs === true) {
- callArgs = slice.call(arguments, 0);
- callArgs = callArgs.concat(args);
- } else if (typeof appendArgs === 'number') {
- callArgs = slice.call(arguments, 0);
- // copy arguments first
- Ext.Array.insert(callArgs, appendArgs, args);
- }
- return method.apply(scope || global, callArgs);
- };
- },
- /**
- * Captures the given parameters for a later call to `Ext.callback`. This binding is
- * most useful for resolving scopes for example to an `Ext.app.ViewController`.
- *
- * The arguments match that of `Ext.callback` except for the `args` which, if provided
- * to this method, are prepended to any arguments supplied by the eventual caller of
- * the returned function.
- *
- * @return {Function} A function that, when called, uses `Ext.callback` to call the
- * captured `callback`.
- * @since 5.0.0
- */
- bindCallback: function(callback, scope, args, delay, caller) {
- return function() {
- var a = slice.call(arguments);
- return Ext.callback(callback, scope, args ? args.concat(a) : a, delay, caller);
- };
- },
- /**
- * Create a new function from the provided `fn`, the arguments of which are pre-set
- * to `args`. New arguments passed to the newly created callback when it's invoked
- * are appended after the pre-set ones.
- * This is especially useful when creating callbacks.
- *
- * For example:
- *
- * var originalFunction = function(){
- * alert(Ext.Array.from(arguments).join(' '));
- * };
- *
- * var callback = Ext.Function.pass(originalFunction, ['Hello', 'World']);
- *
- * callback(); // alerts 'Hello World'
- * callback('by Me'); // alerts 'Hello World by Me'
- *
- * {@link Ext#pass Ext.pass} is alias for {@link Ext.Function#pass Ext.Function.pass}
- *
- * @param {Function} fn The original function.
- * @param {Array} args The arguments to pass to new callback.
- * @param {Object} scope (optional) The scope (`this` reference) in which the function
- * is executed.
- * @return {Function} The new callback function.
- */
- pass: function(fn, args, scope) {
- if (!Ext.isArray(args)) {
- if (Ext.isIterable(args)) {
- args = Ext.Array.clone(args);
- } else {
- args = args !== undefined ? [
- args
- ] : [];
- }
- }
- return function() {
- var fnArgs = args.slice();
- fnArgs.push.apply(fnArgs, arguments);
- return fn.apply(scope || this, fnArgs);
- };
- },
- /**
- * Create an alias to the provided method property with name `methodName` of `object`.
- * Note that the execution scope will still be bound to the provided `object` itself.
- *
- * @param {Object/Function} object
- * @param {String} methodName
- * @return {Function} aliasFn
- */
- alias: function(object, methodName) {
- return function() {
- return object[methodName].apply(object, arguments);
- };
- },
- /**
- * Create a "clone" of the provided method. The returned method will call the given
- * method passing along all arguments and the "this" pointer and return its result.
- *
- * @param {Function} method
- * @return {Function} cloneFn
- */
- clone: function(method) {
- var newMethod, prop;
- newMethod = function() {
- return method.apply(this, arguments);
- };
- for (prop in method) {
- if (method.hasOwnProperty(prop)) {
- newMethod[prop] = method[prop];
- }
- }
- return newMethod;
- },
- /**
- * Creates an interceptor function. The passed function is called before the original one.
- * If it returns false, the original one is not called. The resulting function returns
- * the results of the original function. The passed function is called with the parameters
- * of the original function. Example usage:
- *
- * var sayHi = function(name){
- * alert('Hi, ' + name);
- * };
- *
- * sayHi('Fred'); // alerts "Hi, Fred"
- *
- * // create a new function that validates input without
- * // directly modifying the original function:
- * var sayHiToFriend = Ext.Function.createInterceptor(sayHi, function(name){
- * return name === 'Brian';
- * });
- *
- * sayHiToFriend('Fred'); // no alert
- * sayHiToFriend('Brian'); // alerts "Hi, Brian"
- *
- * @param {Function} origFn The original function.
- * @param {Function} newFn The function to call before the original.
- * @param {Object} [scope] The scope (`this` reference) in which the passed function
- * is executed. **If omitted, defaults to the scope in which the original function
- * is called or the browser window.**
- * @param {Object} [returnValue=null] The value to return if the passed function return
- * `false`.
- * @return {Function} The new function.
- */
- createInterceptor: function(origFn, newFn, scope, returnValue) {
- if (!Ext.isFunction(newFn)) {
- return origFn;
- } else {
- returnValue = Ext.isDefined(returnValue) ? returnValue : null;
- return function() {
- var me = this,
- args = arguments;
- return (newFn.apply(scope || me || global, args) !== false) ? origFn.apply(me || global, args) : returnValue;
- };
- }
- },
- /**
- * Creates a delegate (callback) which, when called, executes after a specific delay.
- *
- * @param {Function} fn The function which will be called on a delay when the returned
- * function is called. Optionally, a replacement (or additional) argument list
- * may be specified.
- * @param {Number} delay The number of milliseconds to defer execution by whenever called.
- * @param {Object} scope (optional) The scope (`this` reference) used by the function
- * at execution time.
- * @param {Array} args (optional) Override arguments for the call.
- * (Defaults to the arguments passed by the caller)
- * @param {Boolean/Number} appendArgs (optional) if True args are appended to call args
- * instead of overriding, if a number the args are inserted at the specified position.
- * @return {Function} A function which, when called, executes the original function
- * after the specified delay.
- */
- createDelayed: function(fn, delay, scope, args, appendArgs) {
- var boundFn = fn;
- if (scope || args) {
- boundFn = Ext.Function.bind(fn, scope, args, appendArgs);
- }
- return function() {
- var me = this,
- args = slice.call(arguments),
- timerFn, timerId;
- var timer;
- // eslint-disable-line vars-on-top, one-var
- timerFn = function() {
- Ext.elevate(boundFn, me, args, timer);
- };
- // eslint-disable-line comma-style
- timerId = setTimeout(timerFn, delay);
- timerFn.$origFn = fn.$origFn || fn;
- timerFn.$skipTimerCheck = timerFn.$origFn.$skipTimerCheck;
- timer = Ext.Timer.created('timeout', timerId, {
- type: 'createDelayed',
- fn: fn,
- timerFn: timerFn
- });
- };
- },
- /**
- * Calls function `fn` after the number of milliseconds specified, optionally with
- * a specific `scope` (`this` pointer).
- *
- * Example usage:
- *
- * var sayHi = function(name) {
- * alert('Hi, ' + name);
- * }
- *
- * // executes immediately:
- * sayHi('Fred');
- *
- * // executes after 2 seconds:
- * Ext.defer(sayHi, 2000, this, ['Fred']);
- *
- * The following syntax is useful for scheduling anonymous functions:
- *
- * Ext.defer(function() {
- * alert('Anonymous');
- * }, 100);
- *
- * NOTE: The `Ext.Function.defer()` method is an alias for `Ext.defer()`.
- *
- * @param {Function} fn The function to defer.
- * @param {Number} millis The number of milliseconds for the `setTimeout` call
- * (if less than or equal to 0 the function is executed immediately).
- * @param {Object} scope (optional) The scope (`this` reference) in which the function
- * is executed. **If omitted, defaults to the browser window.**
- * @param {Array} [args] Overrides arguments for the call. Defaults to the arguments passed
- * by the caller.
- * @param {Boolean/Number} [appendArgs=false] If `true` args are appended to call args
- * instead of overriding, or, if a number, then the args are inserted at the specified
- * position.
- * @return {Number} The timeout id that can be used with `Ext.undefer`.
- */
- defer: function(fn, millis, scope, args, appendArgs) {
- var timerId = 0,
- timerFn, boundFn;
- var timer;
- // eslint-disable-line vars-on-top, one-var
- if (!scope && !args && !appendArgs) {
- boundFn = fn;
- } else {
- boundFn = Ext.Function.bind(fn, scope, args, appendArgs);
- }
- if (millis > 0) {
- timerFn = function() {
- Ext.elevate(boundFn, null, null, timer);
- };
- // eslint-disable-line comma-style
- timerId = setTimeout(timerFn, millis);
- timerFn.$origFn = fn.$origFn || fn;
- timerFn.$skipTimerCheck = timerFn.$origFn.$skipTimerCheck;
- timer = Ext.Timer.created('timeout', timerId, {
- type: 'defer',
- fn: fn,
- timerFn: timerFn
- });
- } else {
- boundFn();
- }
- return timerId;
- },
- /**
- * Calls the function `fn` repeatedly at a given interval, optionally with a
- * specific `scope` (`this` pointer).
- *
- * var sayHi = function(name) {
- * console.log('Hi, ' + name);
- * }
- *
- * // executes every 2 seconds:
- * var timerId = Ext.interval(sayHi, 2000, this, ['Fred']);
- *
- * The timer is stopped by:
- *
- * Ext.uninterval(timerId);
- *
- * NOTE: The `Ext.Function.interval()` method is an alias for `Ext.interval()`.
- *
- * @param {Function} fn The function to defer.
- * @param {Number} millis The number of milliseconds for the `setInterval` call
- * @param {Object} scope (optional) The scope (`this` reference) in which the function
- * is executed. **If omitted, defaults to the browser window.**
- * @param {Array} [args] Overrides arguments for the call. Defaults to the arguments
- * passed by the caller.
- * @param {Boolean/Number} [appendArgs=false] If `true` args are appended to call args
- * instead of overriding, or, if a number, then the args are inserted at the specified
- * position.
- * @return {Number} The interval id that can be used with `Ext.uninterval`.
- */
- interval: function(fn, millis, scope, args, appendArgs) {
- var timerFn, timerId, boundFn;
- var timer;
- // eslint-disable-line vars-on-top, one-var
- boundFn = Ext.Function.bind(fn, scope, args, appendArgs);
- timerFn = function() {
- Ext.elevate(boundFn, null, null, timer);
- };
- // eslint-disable-line comma-style
- timerId = setInterval(timerFn, millis);
- timerFn.$origFn = boundFn.$origFn || fn;
- timerFn.$skipTimerCheck = timerFn.$origFn.$skipTimerCheck;
- timer = Ext.Timer.created('interval', timerId, {
- type: 'interval',
- fn: fn,
- timerFn: timerFn
- });
- return timerId;
- },
- /**
- * Create a combined function call sequence of the original function + the passed function.
- * The resulting function returns the results of the original function.
- * The passed function is called with the parameters of the original function.
- * Example usage:
- *
- * var sayHi = function(name){
- * alert('Hi, ' + name);
- * };
- *
- * sayHi('Fred'); // alerts "Hi, Fred"
- *
- * var sayGoodbye = Ext.Function.createSequence(sayHi, function(name){
- * alert('Bye, ' + name);
- * });
- *
- * sayGoodbye('Fred'); // both alerts show
- *
- * @param {Function} originalFn The original function.
- * @param {Function} newFn The function to sequence.
- * @param {Object} [scope] The scope (`this` reference) in which the passed function
- * is executed. If omitted, defaults to the scope in which the original function is called
- * or the default global environment object (usually the browser window).
- * @return {Function} The new function.
- */
- createSequence: function(originalFn, newFn, scope) {
- if (!newFn) {
- return originalFn;
- } else {
- return function() {
- var result = originalFn.apply(this, arguments);
- newFn.apply(scope || this, arguments);
- return result;
- };
- }
- },
- /**
- * Creates a delegate function, optionally with a bound scope which, when called, buffers
- * the execution of the passed function for the configured number of milliseconds.
- * If called again within that period, the impending invocation will be canceled, and the
- * timeout period will begin again.
- *
- * @param {Function} fn The function to invoke on a buffered timer.
- * @param {Number} buffer The number of milliseconds by which to buffer the invocation
- * of the function.
- * @param {Object} [scope] The scope (`this` reference) in which.
- * the passed function is executed. If omitted, defaults to the scope specified
- * by the caller.
- * @param {Array} [args] Override arguments for the call. Defaults to the arguments
- * passed by the caller.
- * @return {Function} A function which invokes the passed function after buffering
- * for the specified time.
- */
- createBuffered: function(fn, buffer, scope, args) {
- var timerId,
- result = function() {
- var callArgs = args || slice.call(arguments, 0),
- me = scope || this,
- timerFn;
- var timer;
- // eslint-disable-line vars-on-top, one-var
- if (timerId) {
- Ext.undefer(timerId);
- }
- timerFn = function() {
- Ext.elevate(fn, me, callArgs, timer);
- };
- // eslint-disable-line comma-style
- result.timer = timerId = setTimeout(timerFn, buffer);
- timerFn.$origFn = fn.$origFn || fn;
- timerFn.$skipTimerCheck = timerFn.$origFn.$skipTimerCheck;
- timer = Ext.Timer.created('timeout', timerId, {
- type: 'createBuffered',
- fn: fn,
- timerFn: timerFn
- });
- };
- return result;
- },
- /**
- * Creates a wrapped function that, when invoked, defers execution until the next
- * animation frame
- * @private
- * @param {Function} fn The function to call.
- * @param {Object} [scope] The scope (`this` reference) in which the function is executed.
- * Defaults to the window object.
- * @param {Array} [args] The argument list to pass to the function.
- * @param {Number} [queueStrategy=3] A bit flag that indicates how multiple calls to
- * the returned function within the same animation frame should be handled.
- *
- * - 1: All calls will be queued - FIFO order
- * - 2: Only the first call will be queued
- * - 3: The last call will replace all previous calls
- *
- * @return {Function}
- */
- createAnimationFrame: function(fn, scope, args, queueStrategy) {
- var boundFn, timerId;
- queueStrategy = queueStrategy || 3;
- boundFn = function() {
- var timerFn,
- callArgs = args || slice.call(arguments, 0);
- scope = scope || this;
- if (queueStrategy === 3 && timerId) {
- ExtFunction.cancelAnimationFrame(timerId);
- }
- if ((queueStrategy & 1) || !timerId) {
- timerFn = function() {
- timerId = boundFn.timerId = null;
- fn.apply(scope, callArgs);
- };
- timerFn.$origFn = fn.$origFn || fn;
- timerFn.$skipTimerCheck = timerFn.$origFn.$skipTimerCheck;
- timerId = boundFn.timerId = ExtFunction.requestAnimationFrame(timerFn);
- }
- };
- return boundFn;
- },
- /**
- * @private
- * Schedules the passed function to be called on the next animation frame.
- * @param {Function} fn The function to call.
- * @param {Object} [scope] The scope (`this` reference) in which the function is executed.
- * Defaults to the window object.
- * @param {Mixed[]} [args] The argument list to pass to the function.
- *
- * @return {Number} Timer id for the new animation frame to use when canceling it.
- */
- requestAnimationFrame: function(fn, scope, args) {
- var id = ++idSource,
- // Ids start at 1
- handler = slice.call(arguments, 0);
- handler[3] = id;
- animFrameMap[id] = 1;
- // A flag to indicate that the timer exists
- Ext.Timer.created('raf', id, {
- type: 'raf',
- fn: fn
- });
- // We might be in fireHandlers at this moment but this new entry will not
- // be executed until the next frame
- animFrameHandlers.push(handler);
- if (!animFrameId) {
- animFrameId = requestAnimFrame(fireElevatedHandlers);
- }
- return id;
- },
- cancelAnimationFrame: function(id) {
- // Don't remove any handlers from animFrameHandlers array, because
- // the might be in use at the moment (when cancelAnimationFrame is called).
- // Just remove the handler id from the map so it will not be executed
- delete animFrameMap[id];
- Ext.Timer.cancel('raf', id);
- },
- /**
- * Creates a throttled version of the passed function which, when called repeatedly and
- * rapidly, invokes the passed function only after a certain interval has elapsed since the
- * previous invocation.
- *
- * This is useful for wrapping functions which may be called repeatedly, such as
- * a handler of a mouse move event when the processing is expensive.
- *
- * @param {Function} fn The function to execute at a regular time interval.
- * @param {Number} interval The interval in milliseconds on which the passed function
- * is executed.
- * @param {Object} [scope] The scope (`this` reference) in which
- * the passed function is executed. If omitted, defaults to the scope specified
- * by the caller.
- * @return {Function} A function which invokes the passed function at the specified
- * interval.
- */
- createThrottled: function(fn, interval, scope) {
- var lastCallTime = 0,
- elapsed, lastArgs, timerId,
- execute = function() {
- fn.apply(scope, lastArgs);
- lastCallTime = Ext.now();
- lastArgs = timerId = null;
- };
- execute.$origFn = fn.$origFn || fn;
- execute.$skipTimerCheck = execute.$origFn.$skipTimerCheck;
- return function() {
- // Use scope of last call unless the creator specified a scope
- if (!scope) {
- scope = this;
- }
- elapsed = Ext.now() - lastCallTime;
- lastArgs = Ext.Array.slice(arguments);
- // If this is the first invocation, or the throttle interval has been reached,
- // clear any pending invocation, and call the target function now.
- if (elapsed >= interval) {
- Ext.undefer(timerId);
- execute();
- }
- // Throttle interval has not yet been reached. Only set the timer to fire
- // if not already set.
- else if (!timerId) {
- timerId = Ext.defer(execute, interval - elapsed);
- }
- };
- },
- /**
- * Wraps the passed function in a barrier function which will call the passed function
- * after the passed number of invocations.
- * @param {Number} count The number of invocations which will result in the calling
- * of the passed function.
- * @param {Function} fn The function to call after the required number of invocations.
- * @param {Object} scope The scope (`this` reference) in which the function will be called.
- */
- createBarrier: function(count, fn, scope) {
- var barrierFn = function() {
- if (!--count) {
- fn.apply(scope, arguments);
- }
- };
- barrierFn.$origFn = fn.$origFn || fn;
- barrierFn.$skipTimerCheck = barrierFn.$origFn.$skipTimerCheck;
- return barrierFn;
- },
- /**
- * Adds behavior to an existing method that is executed before the
- * original behavior of the function. For example:
- *
- * var soup = {
- * contents: [],
- * add: function(ingredient) {
- * this.contents.push(ingredient);
- * }
- * };
- * Ext.Function.interceptBefore(soup, "add", function(ingredient){
- * if (!this.contents.length && ingredient !== "water") {
- * // Always add water to start with
- * this.contents.push("water");
- * }
- * });
- * soup.add("onions");
- * soup.add("salt");
- * soup.contents; // will contain: water, onions, salt
- *
- * @param {Object} object The target object
- * @param {String} methodName Name of the method to override
- * @param {Function} fn Function with the new behavior. It will
- * be called with the same arguments as the original method. The
- * return value of this function will be the return value of the
- * new method.
- * @param {Object} [scope] The scope to execute the interceptor function.
- * Defaults to the object.
- * @return {Function} The new function just created.
- */
- interceptBefore: function(object, methodName, fn, scope) {
- var method = object[methodName] || Ext.emptyFn;
- return (object[methodName] = function() {
- var ret = fn.apply(scope || this, arguments);
- method.apply(this, arguments);
- return ret;
- });
- },
- /**
- * Adds behavior to an existing method that is executed after the
- * original behavior of the function. For example:
- *
- * var soup = {
- * contents: [],
- * add: function(ingredient) {
- * this.contents.push(ingredient);
- * }
- * };
- * Ext.Function.interceptAfter(soup, "add", function(ingredient){
- * // Always add a bit of extra salt
- * this.contents.push("salt");
- * });
- * soup.add("water");
- * soup.add("onions");
- * soup.contents; // will contain: water, salt, onions, salt
- *
- * @param {Object} object The target object
- * @param {String} methodName Name of the method to override
- * @param {Function} fn Function with the new behavior. It will
- * be called with the same arguments as the original method. The
- * return value of this function will be the return value of the
- * new method.
- * @param {Object} [scope] The scope to execute the interceptor function.
- * Defaults to the object.
- * @return {Function} The new function just created.
- */
- interceptAfter: function(object, methodName, fn, scope) {
- var method = object[methodName] || Ext.emptyFn;
- return (object[methodName] = function() {
- method.apply(this, arguments);
- return fn.apply(scope || this, arguments);
- });
- },
- interceptAfterOnce: function(object, methodName, fn, scope) {
- var origMethod = object[methodName],
- newMethod;
- newMethod = function() {
- var ret;
- if (origMethod) {
- origMethod.apply(this, arguments);
- }
- ret = fn.apply(scope || this, arguments);
- object[methodName] = origMethod;
- object = methodName = fn = scope = origMethod = newMethod = null;
- return ret;
- };
- object[methodName] = newMethod;
- return newMethod;
- },
- makeCallback: function(callback, scope) {
- if (!scope[callback]) {
- if (scope.$className) {
- Ext.raise('No method "' + callback + '" on ' + scope.$className);
- }
- Ext.raise('No method "' + callback + '"');
- }
- return function() {
- return scope[callback].apply(scope, arguments);
- };
- },
- /**
- * Returns a wrapper function that caches the return value for previously
- * processed function argument(s).
- *
- * For example:
- *
- * function factorial (value) {
- * var ret = value;
- *
- * while (--value > 1) {
- * ret *= value;
- * }
- *
- * return ret;
- * }
- *
- * Each call to `factorial` will loop and multiply to produce the answer. Using
- * this function we can wrap the above and cache its answers:
- *
- * factorial = Ext.Function.memoize(factorial);
- *
- * The returned function operates in the same manner as before, but results are
- * stored in a cache to avoid calling the wrapped function when given the same
- * arguments.
- *
- * var x = factorial(20); // first time; call real factorial()
- * var y = factorial(20); // second time; return value from first call
- *
- * To support multi-argument methods, you will need to provide a `hashFn`.
- *
- * function permutation (n, k) {
- * return factorial(n) / factorial(n - k);
- * }
- *
- * permutation = Ext.Function.memoize(permutation, null, function(n, k) {
- * n + '-' + k;
- * });
- *
- * In this case, the `memoize` of `factorial` is sufficient optimization, but the
- * example is simply to illustrate how to generate a unique key for an expensive,
- * multi-argument method.
- *
- * **IMPORTANT**: This cache is unbounded so be cautious of memory leaks if the
- * `memoize`d function is kept indefinitely or is given an unbounded set of
- * possible arguments.
- *
- * @param {Function} fn Function to wrap.
- * @param {Object} scope Optional scope in which to execute the wrapped function.
- * @param {Function} hashFn Optional function used to compute a hash key for
- * storing the result, based on the arguments to the original function.
- * @return {Function} The caching wrapper function.
- * @since 6.0.0
- */
- memoize: function(fn, scope, hashFn) {
- var memo = {},
- isFunc = hashFn && Ext.isFunction(hashFn);
- return function(value) {
- var key = isFunc ? hashFn.apply(scope, arguments) : value;
- if (!(key in memo)) {
- memo[key] = fn.apply(scope, arguments);
- }
- return memo[key];
- };
- },
- _stripCommentRe: /(\/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*+\/)|(\/\/.*)/g,
- toCode: function(fn) {
- var s = fn ? fn.toString() : '';
- s = s.replace(ExtFunction._stripCommentRe, '');
- return s;
- },
- // This is useful for unit testing so we can force handlers which have been deferred
- // to the next animation frame to run immediately
- fireElevatedHandlers: function() {
- // eslint-disable-line comma-style
- fireElevatedHandlers();
- }
- };
- // ExtFunction
- /**
- * @member Ext
- * @method asap
- * Schedules the specified callback function to be executed on the next turn of the
- * event loop. Where available, this method uses the browser's `setImmediate` API. If
- * not available, this method substitutes `setTimeout(0)`. Though not a perfect
- * replacement for `setImmediate` it is sufficient for many use cases.
- *
- * For more details see [MDN](https://developer.mozilla.org/en-US/docs/Web/API/Window/setImmediate).
- *
- * @param {Function} fn Callback function.
- * @param {Object} [scope] The scope for the callback (`this` pointer).
- * @param {Mixed[]} [parameters] Additional parameters to pass to `fn`.
- * @return {Number} A cancellation id for `{@link Ext#unasap}`.
- */
- Ext.asap = hasImmediate ? function(fn, scope, parameters) {
- var boundFn = fn,
- timerFn, timerId;
- var timer;
- // eslint-disable-line vars-on-top, one-var
- if (scope != null || parameters != null) {
- boundFn = ExtFunction.bind(fn, scope, parameters);
- }
- timerFn = function() {
- Ext.elevate(boundFn, null, null, timer);
- };
- // eslint-disable-line comma-style
- timerId = setImmediate(timerFn);
- timerFn.$origFn = fn.$origFn || fn;
- timerFn.$skipTimerCheck = timerFn.$origFn.$skipTimerCheck;
- timer = Ext.Timer.created('asap', timerId, {
- type: 'asap',
- fn: fn,
- timerFn: timerFn
- });
- return timerId;
- } : function(fn, scope, parameters) {
- var boundFn = fn,
- timerFn, timerId;
- var timer;
- // eslint-disable-line vars-on-top, one-var
- if (scope != null || parameters != null) {
- boundFn = ExtFunction.bind(fn, scope, parameters);
- }
- timerFn = function() {
- Ext.elevate(boundFn, null, null, timer);
- };
- // eslint-disable-line comma-style
- timerId = setTimeout(timerFn, 0, true);
- timerFn.$origFn = fn.$origFn || fn;
- timerFn.$skipTimerCheck = timerFn.$origFn.$skipTimerCheck;
- timer = Ext.Timer.created('timeout', timerId, {
- type: 'asap',
- fn: fn,
- timerFn: timerFn
- });
- return timerId;
- };
- /**
- * @member Ext
- * @method unasap
- * Cancels a previously scheduled call to `{@link Ext#asap}`.
- *
- * var timerId = Ext.asap(me.method, me);
- * ...
- *
- * if (nevermind) {
- * Ext.unasap(timerId);
- * }
- *
- * This method always returns `null` to enable simple cleanup:
- *
- * timerId = Ext.unasap(timerId); // safe even if !timerId
- *
- * @param {Number} id The id returned by `{@link Ext#asap}`.
- * @return {Object} Always returns `null`.
- */
- Ext.unasap = hasImmediate ? function(id) {
- if (id) {
- clearImmediate(id);
- Ext.Timer.cancel('asap', id);
- }
- return null;
- } : function(id) {
- return Ext.undefer(id);
- };
- /**
- * @member Ext
- * @method asapCancel
- * Cancels a previously scheduled call to `{@link Ext#asap}`.
- * @param {Number} id The id returned by `{@link Ext#asap}`.
- * @deprecated 6.5.1 Use `Ext.unasap` instead.
- */
- Ext.asapCancel = function(id) {
- return Ext.unasap(id);
- };
- /**
- * @method defer
- * @member Ext
- * @inheritdoc Ext.Function#defer
- */
- Ext.defer = ExtFunction.defer;
- /**
- * @member Ext
- * @method undefer
- * Cancels a previously scheduled call to `{@link Ext#defer}`.
- *
- * var timerId = Ext.defer(me.method, me);
- * ...
- *
- * if (nevermind) {
- * Ext.undefer(timerId);
- * }
- *
- * This method always returns `null` to enable simple cleanup:
- *
- * timerId = Ext.undefer(timerId); // safe even if !timerId
- *
- * @param {Number} id The id returned by `{@link Ext#defer}`.
- */
- Ext.undefer = function(id) {
- if (id) {
- clearTimeout(id);
- Ext.Timer.cancel('timeout', id);
- }
- return null;
- };
- /**
- * @method interval
- * @member Ext
- * @inheritdoc Ext.Function#interval
- */
- Ext.interval = ExtFunction.interval;
- /**
- * @member Ext
- * @method uninterval
- * Cancels a previously scheduled call to `{@link Ext#interval}`.
- *
- * var timerId = Ext.interval(me.method, me);
- * ...
- *
- * if (nevermind) {
- * Ext.uninterval(timerId);
- * }
- *
- * This method always returns `null` to enable simple cleanup:
- *
- * timerId = Ext.uninterval(timerId); // safe even if !timerId
- *
- * @param {Number} id The id returned by `{@link Ext#interval}`.
- */
- Ext.uninterval = function(id) {
- if (id) {
- clearInterval(id);
- Ext.Timer.cancel('interval', id);
- }
- return null;
- };
- /**
- * @method pass
- * @member Ext
- * @inheritdoc Ext.Function#pass
- */
- Ext.pass = ExtFunction.pass;
- /**
- * @method bind
- * @member Ext
- * @inheritdoc Ext.Function#bind
- */
- Ext.bind = ExtFunction.bind;
- Ext.raf = function() {
- return ExtFunction.requestAnimationFrame.apply(ExtFunction, arguments);
- };
- Ext.unraf = function(id) {
- ExtFunction.cancelAnimationFrame(id);
- };
- return ExtFunction;
- })();
- /**
- * @class Ext.Number
- *
- * A collection of useful static methods to deal with numbers
- * @singleton
- */
- Ext.Number = (new function() {
- // jshint ignore:line
- // @define Ext.lang.Number
- // @define Ext.Number
- // @require Ext
- var ExtNumber = this,
- isToFixedBroken = (0.9).toFixed() !== '1',
- math = Math,
- ClipDefault = {
- count: false,
- inclusive: false,
- wrap: true
- };
- // polyfill
- Number.MIN_SAFE_INTEGER = Number.MIN_SAFE_INTEGER || -(math.pow(2, 53) - 1);
- Number.MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER || math.pow(2, 53) - 1;
- Ext.apply(ExtNumber, {
- MIN_SAFE_INTEGER: Number.MIN_SAFE_INTEGER,
- MAX_SAFE_INTEGER: Number.MAX_SAFE_INTEGER,
- MAX_32BIT_INTEGER: math.pow(2, 31) - 1,
- // No good way to allow "9." w/o allowing "." alone but we use isNaN to reject that
- floatRe: /^[-+]?(?:\d+|\d*\.\d*)(?:[Ee][+-]?\d+)?$/,
- intRe: /^[-+]?\d+(?:[Ee]\+?\d+)?$/,
- Clip: {
- DEFAULT: ClipDefault,
- COUNT: Ext.applyIf({
- count: true
- }, ClipDefault),
- INCLUSIVE: Ext.applyIf({
- inclusive: true
- }, ClipDefault),
- NOWRAP: Ext.applyIf({
- wrap: false
- }, ClipDefault)
- },
- /**
- * Strictly parses the given value and returns the value as a number or `null` if
- * the value is not a number or contains non-numeric pieces.
- * @param {String} value
- * @return {Number}
- * @since 6.5.1
- */
- parseFloat: function(value) {
- if (value === undefined) {
- value = null;
- }
- if (value !== null && typeof value !== 'number') {
- value = String(value);
- value = ExtNumber.floatRe.test(value) ? +value : null;
- if (isNaN(value)) {
- value = null;
- }
- }
- return value;
- },
- /**
- * Strictly parses the given value and returns the value as a number or `null` if
- * the value is not an integer number or contains non-integer pieces.
- * @param {String} value
- * @return {Number}
- * @since 6.5.1
- */
- parseInt: function(value) {
- if (value === undefined) {
- value = null;
- }
- if (typeof value === 'number') {
- value = Math.floor(value);
- } else if (value !== null) {
- value = String(value);
- value = ExtNumber.intRe.test(value) ? +value : null;
- }
- return value;
- },
- binarySearch: function(array, value, begin, end) {
- var middle, midVal;
- if (begin === undefined) {
- begin = 0;
- }
- if (end === undefined) {
- end = array.length;
- }
- --end;
- while (begin <= end) {
- middle = (begin + end) >>> 1;
- // unsigned right shift = Math.floor(x/2)
- midVal = array[middle];
- if (value === midVal) {
- return middle;
- }
- if (midVal < value) {
- begin = middle + 1;
- } else {
- end = middle - 1;
- }
- }
- return begin;
- },
- bisectTuples: function(array, value, index, begin, end) {
- var middle, midVal;
- if (begin === undefined) {
- begin = 0;
- }
- if (end === undefined) {
- end = array.length;
- }
- --end;
- while (begin <= end) {
- middle = (begin + end) >>> 1;
- // unsigned right shift = Math.floor(x/2)
- midVal = array[middle][index];
- if (value === midVal) {
- return middle;
- }
- if (midVal < value) {
- begin = middle + 1;
- } else {
- end = middle - 1;
- }
- }
- return begin;
- },
- /**
- * Coerces a given index into a valid index given a `length`.
- *
- * Negative indexes are interpreted starting at the end of the collection. That is,
- * a value of -1 indicates the last item, or equivalent to `length - 1`.
- *
- * When handling methods that take "begin" and "end" arguments like most array or
- * string methods, this method can be used like so:
- *
- * function foo (array, begin, end) {
- * var range = Ext.Number.clipIndices(array.length, [begin, end]);
- *
- * begin = range[0];
- * end = range[1];
- *
- * // 0 <= begin <= end <= array.length
- *
- * var length = end - begin;
- * }
- *
- * For example:
- *
- * +---+---+---+---+---+---+---+---+
- * | | | | | | | | | length = 8
- * +---+---+---+---+---+---+---+---+
- * 0 1 2 3 4 5 6 7
- * -8 -7 -6 -5 -4 -3 -2 -1
- *
- * console.log(Ext.Number.clipIndices(8, [3, 10])); // logs "[3, 8]"
- * console.log(Ext.Number.clipIndices(8, [-5])); // logs "[3, 8]"
- * console.log(Ext.Number.clipIndices(8, []));
- * console.log(Ext.Number.clipIndices(8, []));
- *
- * @param {Number} length
- * @param {Number[]} indices
- * @param {Object} [options] An object with different option flags.
- * @param {Boolean} [options.count=false] The second number in `indices` is the
- * count not and an index.
- * @param {Boolean} [options.inclusive=false] The second number in `indices` is
- * "inclusive" meaning that the item should be considered in the range. Normally,
- * the second number is considered the first item outside the range or as an
- * "exclusive" bound.
- * @param {Boolean} [options.wrap=true] Wraps negative numbers backwards from the
- * end of the array. Passing `false` simply clips negative index values at 0.
- * @return {Number[]} The normalized `[begin, end]` array where `end` is now
- * exclusive such that `length = end - begin`. Both values are between 0 and the
- * given `length` and `end` will not be less-than `begin`.
- */
- clipIndices: function(length, indices, options) {
- var defaultValue = 0,
- // default value for "begin"
- wrap, begin, end, i;
- options = options || ClipDefault;
- wrap = options.wrap;
- indices = indices || [];
- for (i = 0; i < 2; ++i) {
- // names are off on first pass but used this way so things make sense
- // following the loop..
- begin = end;
- // pick up and keep the result from the first loop
- end = indices[i];
- if (end == null) {
- end = defaultValue;
- } else if (i && options.count) {
- end += begin;
- // this is the length not "end" so convert to "end"
- end = (end > length) ? length : end;
- } else {
- if (wrap) {
- end = (end < 0) ? (length + end) : end;
- }
- if (i && options.inclusive) {
- ++end;
- }
- end = (end < 0) ? 0 : ((end > length) ? length : end);
- }
- defaultValue = length;
- }
- // default value for "end"
- // after loop:
- // 0 <= begin <= length (calculated from indices[0])
- // 0 <= end <= length (calculated from indices[1])
- indices[0] = begin;
- indices[1] = (end < begin) ? begin : end;
- return indices;
- },
- /**
- * Checks whether or not the passed number is within a desired range. If the number is
- * already within the range it is returned, otherwise the min or max value is returned
- * depending on which side of the range is exceeded. Note that this method returns the
- * constrained value but does not change the current number.
- * @param {Number} number The number to check
- * @param {Number} min The minimum number in the range
- * @param {Number} max The maximum number in the range
- * @return {Number} The constrained value if outside the range, otherwise the current value
- */
- constrain: function(number, min, max) {
- var x = parseFloat(number);
- // (x < Nan) || (x < undefined) == false
- // same for (x > NaN) || (x > undefined)
- // sadly this is not true of null - (1 > null)
- if (min === null) {
- min = number;
- }
- if (max === null) {
- max = number;
- }
- // Watch out for NaN in Chrome 18
- // V8bug: http://code.google.com/p/v8/issues/detail?id=2056
- // Operators are faster than Math.min/max. See http://jsperf.com/number-constrain
- return (x < min) ? min : ((x > max) ? max : x);
- },
- /**
- * Snaps the passed number between stopping points based upon a passed increment value.
- *
- * The difference between this and {@link #snapInRange} is that {@link #snapInRange} uses
- * the minValue when calculating snap points:
- *
- * // Returns 56 - snap points are zero based
- * r = Ext.Number.snap(56, 2, 55, 65);
- *
- * // Returns 57 - snap points are based from minValue
- * r = Ext.Number.snapInRange(56, 2, 55, 65);
- *
- * @param {Number} value The unsnapped value.
- * @param {Number} increment The increment by which the value must move.
- * @param {Number} minValue The minimum value to which the returned value must be
- * constrained. Overrides the increment.
- * @param {Number} maxValue The maximum value to which the returned value must be
- * constrained. Overrides the increment.
- * @return {Number} The value of the nearest snap target.
- */
- snap: function(value, increment, minValue, maxValue) {
- var m;
- // If no value passed, or minValue was passed and value is less than minValue
- // (anything < undefined is false)
- // Then use the minValue (or zero if the value was undefined)
- if (value === undefined || value < minValue) {
- return minValue || 0;
- }
- if (increment) {
- m = value % increment;
- if (m !== 0) {
- value -= m;
- if (m * 2 >= increment) {
- value += increment;
- } else if (m * 2 < -increment) {
- value -= increment;
- }
- }
- }
- return ExtNumber.constrain(value, minValue, maxValue);
- },
- /**
- * Snaps the passed number between stopping points based upon a passed increment value.
- *
- * The difference between this and {@link #snap} is that {@link #snap} does not use
- * the minValue when calculating snap points:
- *
- * // Returns 56 - snap points are zero based
- * r = Ext.Number.snap(56, 2, 55, 65);
- *
- * // Returns 57 - snap points are based from minValue
- * r = Ext.Number.snapInRange(56, 2, 55, 65);
- *
- * @param {Number} value The unsnapped value.
- * @param {Number} increment The increment by which the value must move.
- * @param {Number} [minValue=0] The minimum value to which the returned value must be
- * constrained.
- * @param {Number} [maxValue=Infinity] The maximum value to which the returned value
- * must be constrained.
- * @return {Number} The value of the nearest snap target.
- */
- snapInRange: function(value, increment, minValue, maxValue) {
- var tween;
- // default minValue to zero
- minValue = (minValue || 0);
- // If value is undefined, or less than minValue, use minValue
- if (value === undefined || value < minValue) {
- return minValue;
- }
- // Calculate how many snap points from the minValue the passed value is.
- if (increment && (tween = ((value - minValue) % increment))) {
- value -= tween;
- tween *= 2;
- if (tween >= increment) {
- value += increment;
- }
- }
- // If constraining within a maximum, ensure the maximum is on a snap point
- if (maxValue !== undefined) {
- if (value > (maxValue = ExtNumber.snapInRange(maxValue, increment, minValue))) {
- value = maxValue;
- }
- }
- return value;
- },
- /**
- * Round a number to the nearest interval.
- * @param {Number} value The value to round.
- * @param {Number} interval The interval to round to.
- * @return {Number} The rounded value.
- *
- * @since 6.2.0
- */
- roundToNearest: function(value, interval) {
- interval = interval || 1;
- return interval * math.round(value / interval);
- },
- /**
- * Rounds a number to the specified precision.
- * @param value
- * @param precision
- * @return {number}
- */
- roundToPrecision: function(value, precision) {
- var factor = math.pow(10, precision || 1);
- return math.round(value * factor) / factor;
- },
- /**
- * Truncates a number to the specified precision,
- * without rounding.
- * @param value
- * @param precision
- * @return {number}
- * @since 6.5.1
- */
- truncateToPrecision: function(value, precision) {
- var factor = math.pow(10, precision || 1);
- return parseInt(value * factor, 10) / factor;
- },
- /**
- * Returns the sign of the given number. See also MDN for Math.sign documentation
- * for the standard method this method emulates.
- * @param {Number} x The number.
- * @return {Number} The sign of the number `x`, indicating whether the number is
- * positive (1), negative (-1) or zero (0).
- * @method sign
- */
- sign: math.sign || function(x) {
- x = +x;
- // force to a Number
- if (x === 0 || isNaN(x)) {
- return x;
- }
- return (x > 0) ? 1 : -1;
- },
- /**
- * Returns the base 10 logarithm of a number.
- * This will use Math.log10, if available (ES6).
- * @param {Number} x The number.
- * @return {Number} Base 10 logarithm of the number 'x'.
- * @method log10
- */
- log10: math.log10 || function(x) {
- return math.log(x) * math.LOG10E;
- },
- /**
- * Determines if two numbers `n1` and `n2` are equal within a given
- * margin of precision `epsilon`.
- * @param {Number} n1 First number.
- * @param {Number} n2 Second number.
- * @param {Number} epsilon Margin of precision.
- * @return {Boolean} `true`, if numbers are equal. `false` otherwise.
- */
- isEqual: function(n1, n2, epsilon) {
- /* eslint-disable-next-line max-len */
- if (!(typeof n1 === 'number' && typeof n2 === 'number' && typeof epsilon === 'number')) {
- Ext.raise("All parameters should be valid numbers.");
- }
- return math.abs(n1 - n2) < epsilon;
- },
- /**
- * Determines if the value passed is a number and also finite.
- * This a Polyfill version of Number.isFinite(),differently than
- * the isFinite() function, this method doesn't convert the parameter to a number.
- * @param {Number} value Number to be tested.
- * @return {Boolean} `true`, if the parameter is a number and finite, `false` otherwise.
- * @since 6.2
- */
- isFinite: Number.isFinite || function(value) {
- return typeof value === 'number' && isFinite(value);
- },
- isInteger: Number.isInteger || function(value) {
- // Add zero get a valid result in a special case where the value is a number string.
- // E.g. '10' + 0 is '100'.
- return ~~(value + 0) === value;
- },
- /**
- * @method
- * Formats a number using fixed-point notation
- * @param {Number} value The number to format
- * @param {Number} precision The number of digits to show after the decimal point
- */
- toFixed: isToFixedBroken ? function(value, precision) {
- var pow;
- precision = precision || 0;
- pow = math.pow(10, precision);
- return (math.round(value * pow) / pow).toFixed(precision);
- } : function(value, precision) {
- return value.toFixed(precision);
- },
- /**
- * Validate that a value is numeric and convert it to a number if necessary.
- * Returns the specified default value if it is not.
- *
- * Ext.Number.from('1.23', 1); // returns 1.23
- * Ext.Number.from('abc', 1); // returns 1
- *
- * @param {Object} value
- * @param {Number} defaultValue The value to return if the original value is non-numeric
- * @return {Number} value, if numeric, defaultValue otherwise
- */
- from: function(value, defaultValue) {
- if (isFinite(value)) {
- value = parseFloat(value);
- }
- return !isNaN(value) ? value : defaultValue;
- },
- /**
- * Returns a random integer between the specified range (inclusive)
- * @param {Number} from Lowest value to return.
- * @param {Number} to Highest value to return.
- * @return {Number} A random integer within the specified range.
- */
- randomInt: function(from, to) {
- return math.floor(math.random() * (to - from + 1) + from);
- },
- /**
- * Corrects floating point numbers that overflow to a non-precise
- * value because of their floating nature, for example `0.1 + 0.2`
- * @param {Number} n The number
- * @return {Number} The correctly rounded number
- */
- correctFloat: function(n) {
- // This is to correct the type of errors where 2 floats end with
- // a long string of decimals, eg 0.1 + 0.2. When they overflow in this
- // manner, they usually go to 15-16 decimals, so we cut it off at 14.
- return parseFloat(n.toPrecision(14));
- }
- });
- /**
- * @deprecated 4.0.0 Please use {@link Ext.Number#from} instead.
- * @member Ext
- * @method num
- * @inheritdoc Ext.Number#from
- */
- Ext.num = function() {
- return ExtNumber.from.apply(this, arguments);
- };
- }());
- /**
- * @class Ext.Object
- *
- * A collection of useful static methods to deal with objects.
- *
- * @singleton
- */
- (function() {
- // The "constructor" for chain:
- var TemplateClass = function() {},
- queryRe = /^\?/,
- keyRe = /(\[):?([^\]]*)\]/g,
- nameRe = /^([^\[]+)/,
- // eslint-disable-line no-useless-escape
- plusRe = /\+/g,
- ExtObject;
- // @define Ext.lang.Object
- // @define Ext.Object
- // @require Ext
- // @require Ext.lang.Date
- ExtObject = Ext.Object = {
- /**
- * @method
- * Returns a new object with the given object as the prototype chain. This method is
- * designed to mimic the ECMA standard `Object.create` method and is assigned to that
- * function when it is available.
- *
- * **NOTE** This method does not support the property definitions capability of the
- * `Object.create` method. Only the first argument is supported.
- *
- * @param {Object} object The prototype chain for the new object.
- */
- chain: Object.create || function(object) {
- var result;
- TemplateClass.prototype = object;
- result = new TemplateClass();
- TemplateClass.prototype = null;
- return result;
- },
- /**
- * This method removes all keys from the given object.
- * @param {Object} object The object from which to remove all keys.
- * @return {Object} The given object.
- */
- clear: function(object) {
- var key;
- // Safe to delete during iteration
- for (key in object) {
- delete object[key];
- }
- return object;
- },
- /**
- * Freezes the given object making it immutable. This operation is by default shallow
- * and does not effect objects referenced by the given object.
- *
- * @method
- * @param {Object} obj The object to freeze.
- * @param {Boolean} [deep=false] Pass `true` to freeze sub-objects recursively.
- * @return {Object} The given object `obj`.
- */
- freeze: Object.freeze ? function(obj, deep) {
- var name;
- if (obj && typeof obj === 'object' && !Object.isFrozen(obj)) {
- Object.freeze(obj);
- if (deep) {
- for (name in obj) {
- ExtObject.freeze(obj[name], deep);
- }
- }
- }
- return obj;
- } : Ext.identityFn,
- /**
- * Converts a `name` - `value` pair to an array of objects with support for nested structures.
- * Useful to construct query strings. For example:
- *
- * var objects = Ext.Object.toQueryObjects('hobbies', ['reading', 'cooking', 'swimming']);
- *
- * // objects then equals:
- * [
- * { name: 'hobbies', value: 'reading' },
- * { name: 'hobbies', value: 'cooking' },
- * { name: 'hobbies', value: 'swimming' },
- * ];
- *
- * var objects = Ext.Object.toQueryObjects('dateOfBirth', {
- * day: 3,
- * month: 8,
- * year: 1987,
- * extra: {
- * hour: 4
- * minute: 30
- * }
- * }, true); // Recursive
- *
- * // objects then equals:
- * [
- * { name: 'dateOfBirth[day]', value: 3 },
- * { name: 'dateOfBirth[month]', value: 8 },
- * { name: 'dateOfBirth[year]', value: 1987 },
- * { name: 'dateOfBirth[extra][hour]', value: 4 },
- * { name: 'dateOfBirth[extra][minute]', value: 30 },
- * ];
- *
- * @param {String} name
- * @param {Object/Array} value
- * @param {Boolean} [recursive=false] True to traverse object recursively
- * @return {Object[]}
- */
- toQueryObjects: function(name, value, recursive) {
- var self = ExtObject.toQueryObjects,
- objects = [],
- i, ln;
- if (Ext.isArray(value)) {
- for (i = 0 , ln = value.length; i < ln; i++) {
- if (recursive) {
- objects = objects.concat(self(name + '[' + i + ']', value[i], true));
- } else {
- objects.push({
- name: name,
- value: value[i]
- });
- }
- }
- } else if (Ext.isObject(value)) {
- for (i in value) {
- if (value.hasOwnProperty(i)) {
- if (recursive) {
- objects = objects.concat(self(name + '[' + i + ']', value[i], true));
- } else {
- objects.push({
- name: name,
- value: value[i]
- });
- }
- }
- }
- } else {
- objects.push({
- name: name,
- value: value
- });
- }
- return objects;
- },
- /* eslint-disable max-len */
- /**
- * Takes an object and converts it to an encoded query string.
- *
- * Non-recursive:
- *
- * Ext.Object.toQueryString({foo: 1, bar: 2}); // returns "foo=1&bar=2"
- * Ext.Object.toQueryString({foo: null, bar: 2}); // returns "foo=&bar=2"
- * Ext.Object.toQueryString({'some price': '$300'}); // returns "some%20price=%24300"
- * Ext.Object.toQueryString({date: new Date(2011, 0, 1)}); // returns "date=%222011-01-01T00%3A00%3A00%22"
- * Ext.Object.toQueryString({colors: ['red', 'green', 'blue']}); // returns "colors=red&colors=green&colors=blue"
- *
- * Recursive:
- *
- * Ext.Object.toQueryString({
- * username: 'Jacky',
- * dateOfBirth: {
- * day: 1,
- * month: 2,
- * year: 1911
- * },
- * hobbies: ['coding', 'eating', 'sleeping', ['nested', 'stuff']]
- * }, true); // returns the following string (broken down and url-decoded for ease of reading purpose):
- * // username=Jacky
- * // &dateOfBirth[day]=1&dateOfBirth[month]=2&dateOfBirth[year]=1911
- * // &hobbies[0]=coding&hobbies[1]=eating&hobbies[2]=sleeping&hobbies[3][0]=nested&hobbies[3][1]=stuff
- *
- * @param {Object} object The object to encode
- * @param {Boolean} [recursive=false] Whether or not to interpret the object in recursive format.
- * (PHP / Ruby on Rails servers and similar).
- * @return {String} queryString
- */
- toQueryString: function(object, recursive) {
- var paramObjects = [],
- params = [],
- i, j, ln, paramObject, value;
- for (i in object) {
- if (object.hasOwnProperty(i)) {
- paramObjects = paramObjects.concat(ExtObject.toQueryObjects(i, object[i], recursive));
- }
- }
- for (j = 0 , ln = paramObjects.length; j < ln; j++) {
- paramObject = paramObjects[j];
- value = paramObject.value;
- if (Ext.isEmpty(value)) {
- value = '';
- } else if (Ext.isDate(value)) {
- value = Ext.Date.toString(value);
- }
- params.push(encodeURIComponent(paramObject.name) + '=' + encodeURIComponent(String(value)));
- }
- return params.join('&');
- },
- /**
- * Converts a query string back into an object.
- *
- * Non-recursive:
- *
- * Ext.Object.fromQueryString("foo=1&bar=2"); // returns {foo: '1', bar: '2'}
- * Ext.Object.fromQueryString("foo=&bar=2"); // returns {foo: '', bar: '2'}
- * Ext.Object.fromQueryString("some%20price=%24300"); // returns {'some price': '$300'}
- * Ext.Object.fromQueryString("colors=red&colors=green&colors=blue"); // returns {colors: ['red', 'green', 'blue']}
- *
- * Recursive:
- *
- * Ext.Object.fromQueryString(
- * "username=Jacky&"+
- * "dateOfBirth[day]=1&dateOfBirth[month]=2&dateOfBirth[year]=1911&"+
- * "hobbies[0]=coding&hobbies[1]=eating&hobbies[2]=sleeping&"+
- * "hobbies[3][0]=nested&hobbies[3][1]=stuff", true);
- *
- * // returns
- * {
- * username: 'Jacky',
- * dateOfBirth: {
- * day: '1',
- * month: '2',
- * year: '1911'
- * },
- * hobbies: ['coding', 'eating', 'sleeping', ['nested', 'stuff']]
- * }
- *
- * @param {String} queryString The query string to decode
- * @param {Boolean} [recursive=false] Whether or not to recursively decode the string. This format is supported by
- * PHP / Ruby on Rails servers and similar.
- * @return {Object}
- */
- fromQueryString: function(queryString, recursive) {
- var parts = queryString.replace(queryRe, '').split('&'),
- object = {},
- temp, components, name, value, i, ln, part, j, subLn, matchedKeys, matchedName, keys, key, nextKey;
- for (i = 0 , ln = parts.length; i < ln; i++) {
- part = parts[i];
- if (part.length > 0) {
- components = part.split('=');
- name = components[0];
- name = name.replace(plusRe, '%20');
- name = decodeURIComponent(name);
- value = components[1];
- if (value !== undefined) {
- value = value.replace(plusRe, '%20');
- value = decodeURIComponent(value);
- } else {
- value = '';
- }
- if (!recursive) {
- if (object.hasOwnProperty(name)) {
- if (!Ext.isArray(object[name])) {
- object[name] = [
- object[name]
- ];
- }
- object[name].push(value);
- } else {
- object[name] = value;
- }
- } else {
- matchedKeys = name.match(keyRe);
- matchedName = name.match(nameRe);
- if (!matchedName) {
- throw new Error('[Ext.Object.fromQueryString] Malformed query string given, failed parsing name from "' + part + '"');
- }
- name = matchedName[0];
- keys = [];
- if (matchedKeys === null) {
- object[name] = value;
-
- continue;
- }
- for (j = 0 , subLn = matchedKeys.length; j < subLn; j++) {
- key = matchedKeys[j];
- key = (key.length === 2) ? '' : key.substring(1, key.length - 1);
- keys.push(key);
- }
- keys.unshift(name);
- temp = object;
- for (j = 0 , subLn = keys.length; j < subLn; j++) {
- key = keys[j];
- if (j === subLn - 1) {
- if (Ext.isArray(temp) && key === '') {
- temp.push(value);
- } else {
- temp[key] = value;
- }
- } else {
- if (temp[key] === undefined || typeof temp[key] === 'string') {
- nextKey = keys[j + 1];
- temp[key] = (Ext.isNumeric(nextKey) || nextKey === '') ? [] : {};
- }
- temp = temp[key];
- }
- }
- }
- }
- }
- return object;
- },
- /* eslint-enable max-len */
- /**
- * Iterates through an object and invokes the given callback function for each iteration.
- * The iteration can be stopped by returning `false` in the callback function. For example:
- *
- * var person = {
- * name: 'Jacky'
- * hairColor: 'black'
- * loves: ['food', 'sleeping', 'wife']
- * };
- *
- * Ext.Object.each(person, function(key, value, myself) {
- * console.log(key + ":" + value);
- *
- * if (key === 'hairColor') {
- * return false; // stop the iteration
- * }
- * });
- *
- * @param {Object} object The object to iterate
- * @param {Function} fn The callback function.
- * @param {String} fn.key
- * @param {Object} fn.value
- * @param {Object} fn.object The object itself
- * @param {Object} [scope] The execution scope (`this`) of the callback function
- */
- each: function(object, fn, scope) {
- var enumerables = Ext.enumerables,
- i, property;
- if (object) {
- scope = scope || object;
- for (property in object) {
- if (object.hasOwnProperty(property)) {
- if (fn.call(scope, property, object[property], object) === false) {
- return;
- }
- }
- }
- if (enumerables) {
- for (i = enumerables.length; i--; ) {
- if (object.hasOwnProperty(property = enumerables[i])) {
- if (fn.call(scope, property, object[property], object) === false) {
- return;
- }
- }
- }
- }
- }
- },
- /**
- * Iterates through an object and invokes the given callback function for each iteration.
- * The iteration can be stopped by returning `false` in the callback function. For example:
- *
- * var items = {
- * 1: 'Hello',
- * 2: 'World'
- * };
- *
- * Ext.Object.eachValue(items, function(value) {
- * console.log("Value: " + value);
- * });
- *
- * This will log 'Hello' and 'World' in no particular order. This method is useful
- * in cases where the keys are not important to the processing, just the values.
- *
- * @param {Object} object The object to iterate
- * @param {Function} fn The callback function.
- * @param {Object} fn.value The value of
- * @param {Object} [scope] The execution scope (`this`) of the callback function
- */
- eachValue: function(object, fn, scope) {
- var enumerables = Ext.enumerables,
- i, property;
- scope = scope || object;
- for (property in object) {
- if (object.hasOwnProperty(property)) {
- if (fn.call(scope, object[property]) === false) {
- return;
- }
- }
- }
- if (enumerables) {
- for (i = enumerables.length; i--; ) {
- if (object.hasOwnProperty(property = enumerables[i])) {
- if (fn.call(scope, object[property]) === false) {
- return;
- }
- }
- }
- }
- },
- /**
- * Merges any number of objects recursively without referencing them or their children.
- * Note: It will reference arrays if they are only present in one of the objects being merged.
- *
- * var extjs = {
- * companyName: 'Ext JS',
- * products: ['Ext JS', 'Ext GWT', 'Ext Designer'],
- * isSuperCool: true,
- * office: {
- * size: 2000,
- * location: 'Palo Alto',
- * isFun: true
- * }
- * };
- *
- * var newStuff = {
- * companyName: 'Sencha Inc.',
- * products: ['Ext JS', 'Ext GWT', 'Ext Designer', 'Sencha Touch', 'Sencha Animator'],
- * office: {
- * size: 40000,
- * location: 'Redwood City'
- * }
- * };
- *
- * var sencha = Ext.Object.merge(extjs, newStuff);
- *
- * // extjs and sencha then equals to
- * {
- * companyName: 'Sencha Inc.',
- * products: ['Ext JS', 'Ext GWT', 'Ext Designer', 'Sencha Touch', 'Sencha Animator'],
- * isSuperCool: true,
- * office: {
- * size: 40000,
- * location: 'Redwood City',
- * isFun: true
- * }
- * }
- *
- * @param {Object} destination The object into which all subsequent objects are merged.
- * @param {Object...} object Any number of objects to merge into the destination.
- * @return {Object} merged The destination object with all passed objects merged in.
- */
- merge: function(destination) {
- var i = 1,
- args = arguments,
- ln = args.length,
- mergeFn = ExtObject.merge,
- cloneFn = Ext.clone,
- object, key, value, sourceKey;
- for (; i < ln; i++) {
- object = args[i];
- for (key in object) {
- value = object[key];
- if (value && value.constructor === Object) {
- sourceKey = destination[key];
- if (sourceKey && sourceKey.constructor === Object) {
- mergeFn(sourceKey, value);
- } else {
- destination[key] = cloneFn(value);
- }
- } else {
- destination[key] = value;
- }
- }
- }
- return destination;
- },
- /**
- * @private
- * @param destination
- */
- mergeIf: function(destination) {
- var i = 1,
- ln = arguments.length,
- cloneFn = Ext.clone,
- object, key, value;
- for (; i < ln; i++) {
- object = arguments[i];
- for (key in object) {
- if (!(key in destination)) {
- value = object[key];
- if (value && value.constructor === Object) {
- destination[key] = cloneFn(value);
- } else {
- destination[key] = value;
- }
- }
- }
- }
- return destination;
- },
- /**
- * Returns all keys of the given object as an array.
- *
- * @param {Object} object
- * @return {String[]} An array of keys from the object or any of its prototypes.
- * @method
- */
- getAllKeys: function(object) {
- var keys = [],
- property;
- for (property in object) {
- keys.push(property);
- }
- return keys;
- },
- /**
- * Returns the first matching key corresponding to the given value.
- * If no matching value is found, null is returned.
- *
- * var person = {
- * name: 'Jacky',
- * loves: 'food'
- * };
- *
- * alert(Ext.Object.getKey(person, 'food')); // alerts 'loves'
- *
- * @param {Object} object
- * @param {Object} value The value to find
- */
- getKey: function(object, value) {
- var property;
- for (property in object) {
- if (object.hasOwnProperty(property) && object[property] === value) {
- return property;
- }
- }
- return null;
- },
- /**
- * Gets all values of the given object as an array.
- *
- * var values = Ext.Object.getValues({
- * name: 'Jacky',
- * loves: 'food'
- * }); // ['Jacky', 'food']
- *
- * @param {Object} object
- * @return {Array} An array of values from the object
- */
- getValues: function(object) {
- var values = [],
- property;
- for (property in object) {
- if (object.hasOwnProperty(property)) {
- values.push(object[property]);
- }
- }
- return values;
- },
- /**
- * Returns the `hasOwnProperty` keys of the given object as an array.
- *
- * var values = Ext.Object.getKeys({
- * name: 'Jacky',
- * loves: 'food'
- * }); // ['name', 'loves']
- *
- * @param {Object} object
- * @return {String[]} An array of keys from the object
- * @method
- */
- getKeys: (typeof Object.keys === 'function') ? function(object) {
- if (!object) {
- return [];
- }
- return Object.keys(object);
- } : function(object) {
- var keys = [],
- property;
- for (property in object) {
- if (object.hasOwnProperty(property)) {
- keys.push(property);
- }
- }
- return keys;
- },
- /**
- * Gets the total number of this object's own properties
- *
- * var size = Ext.Object.getSize({
- * name: 'Jacky',
- * loves: 'food'
- * }); // size equals 2
- *
- * @param {Object} object
- * @return {Number} size
- */
- getSize: function(object) {
- var size = 0,
- property;
- for (property in object) {
- if (object.hasOwnProperty(property)) {
- size++;
- }
- }
- return size;
- },
- /**
- * Checks if there are any properties on this object.
- * @param {Object} object
- * @return {Boolean} `true` if there no properties on the object.
- */
- isEmpty: function(object) {
- var key;
- for (key in object) {
- if (object.hasOwnProperty(key)) {
- return false;
- }
- }
- return true;
- },
- /**
- * @method
- * Shallow compares the contents of 2 objects using strict equality. Objects are
- * considered equal if they both have the same set of properties and the
- * value for those properties equals the other in the corresponding object.
- *
- * // Returns true
- * Ext.Object.equals({
- * foo: 1,
- * bar: 2
- * }, {
- * foo: 1,
- * bar: 2
- * });
- *
- * @param {Object} object1
- * @param {Object} object2
- * @return {Boolean} `true` if the objects are equal.
- */
- equals: (function() {
- var check = function(o1, o2) {
- var key;
- for (key in o1) {
- if (o1.hasOwnProperty(key)) {
- if (o1[key] !== o2[key]) {
- return false;
- }
- }
- }
- return true;
- };
- return function(object1, object2) {
- // Short circuit if the same object is passed twice
- if (object1 === object2) {
- return true;
- }
- if (object1 && object2) {
- // Do the second check because we could have extra keys in
- // object2 that don't exist in object1.
- return check(object1, object2) && check(object2, object1);
- } else if (!object1 && !object2) {
- return object1 === object2;
- } else {
- return false;
- }
- };
- })(),
- /**
- * @private
- */
- fork: function(obj) {
- var ret, key, value;
- if (obj && obj.constructor === Object) {
- ret = ExtObject.chain(obj);
- for (key in obj) {
- value = obj[key];
- if (value) {
- if (value.constructor === Object) {
- ret[key] = ExtObject.fork(value);
- } else if (value instanceof Array) {
- ret[key] = Ext.Array.clone(value);
- }
- }
- }
- } else {
- ret = obj;
- }
- return ret;
- },
- defineProperty: ('defineProperty' in Object) ? Object.defineProperty : function(object, name, descriptor) {
- if (!Object.prototype.__defineGetter__) {
- return;
- }
- if (descriptor.get) {
- object.__defineGetter__(name, descriptor.get);
- }
- if (descriptor.set) {
- object.__defineSetter__(name, descriptor.set);
- }
- },
- /**
- * @private
- */
- classify: function(object) {
- var prototype = object,
- objectProperties = [],
- propertyClassesMap = {},
- objectClass, key, value;
- objectClass = function() {
- var property, i, ln;
- for (i = 0 , ln = objectProperties.length; i < ln; i++) {
- property = objectProperties[i];
- this[property] = new propertyClassesMap[property]();
- }
- };
- for (key in object) {
- if (object.hasOwnProperty(key)) {
- value = object[key];
- if (value && value.constructor === Object) {
- objectProperties.push(key);
- propertyClassesMap[key] = ExtObject.classify(value);
- }
- }
- }
- objectClass.prototype = prototype;
- return objectClass;
- }
- };
- /**
- * A convenient alias method for {@link Ext.Object#merge}.
- *
- * @member Ext
- * @method merge
- * @inheritdoc Ext.Object#merge
- */
- Ext.merge = Ext.Object.merge;
- /**
- * @private
- * @member Ext
- */
- Ext.mergeIf = Ext.Object.mergeIf;
- }());
- /*
- * This file contains miscellaneous utility methods that depends on various helper classes
- * like `Ext.Array` and `Ext.Date`. Historically these methods were defined in Ext.js or
- * Ext-more.js but that creates circular dependencies so they were consolidated here.
- */
- Ext.apply(Ext, {
- // @define Ext.Util
- // @require Ext
- // @require Ext.lang.*
- // shortcut for the special named scopes for listener scope resolution
- _namedScopes: {
- 'this': {
- isThis: 1
- },
- controller: {
- isController: 1
- },
- owner: {
- isOwner: 1
- },
- // Uses helper Ext.lookUpFn to find the scope where fn is defined (skips the
- // component at which things originate):
- up: {
- isUp: 1
- },
- // These two are private, used to indicate that listeners were declared on the
- // class body with either an unspecified scope, or scope:'controller'
- self: {
- isSelf: 1
- },
- 'self.controller': {
- isSelf: 1,
- isController: 1
- }
- },
- scrollbar: {
- _size: null,
- /**
- * @member Ext.scrollbar
- * Returns the size of the browser scrollbars. This can differ depending on
- * operating system settings, such as the theme or font size.
- * @param {Boolean} [force] Pass `true` to force a recalculation of scrollbar size.
- * @return {Object} An object containing scrollbar sizes.
- * @return {Number} return.width The width of the vertical scrollbar.
- * @return {Number} return.height The height of the horizontal scrollbar.
- */
- size: function(force) {
- var scrollbar = Ext.scrollbar,
- size = scrollbar._size;
- if (!Ext.isDomReady) {
- Ext.raise("Ext.scrollbar.size() called before DomReady");
- }
- if (force || !size) {
- /* eslint-disable-next-line vars-on-top */
- var db = document.body,
- div = document.createElement('div'),
- h, w;
- div.style.width = div.style.height = '100px';
- div.style.overflow = 'scroll';
- div.style.position = 'absolute';
- db.appendChild(div);
- // now we can measure the div...
- // at least in iE9 the div is not 100px - the scrollbar size is removed!
- scrollbar._size = size = {
- width: w = div.offsetWidth - div.clientWidth,
- height: h = div.offsetHeight - div.clientHeight
- };
- size.reservedWidth = w ? 'calc(100% - ' + w + 'px)' : '';
- size.reservedHeight = h ? 'calc(100% - ' + h + 'px)' : '';
- db.removeChild(div);
- }
- return size;
- },
- height: function(force) {
- return Ext.scrollbar.size(force).height;
- },
- width: function(force) {
- return Ext.scrollbar.size(force).width;
- }
- },
- escapeId: (function() {
- /* eslint-disable-next-line no-useless-escape */
- var validIdRe = /^[a-zA-Z_][a-zA-Z0-9_\-]*$/i,
- escapeRx = /([\W]{1})/g,
- leadingNumRx = /^(\d)/g,
- escapeFn = function(match, capture) {
- return "\\" + capture;
- },
- numEscapeFn = function(match, capture) {
- return '\\00' + capture.charCodeAt(0).toString(16) + ' ';
- };
- return function(id) {
- return validIdRe.test(id) ? id : // replace the number portion last to keep the trailing ' '
- // from being escaped
- id.replace(escapeRx, escapeFn).replace(leadingNumRx, numEscapeFn);
- };
- }()),
- lookUpFn: function(from, fn) {
- if (!from || !Ext.isFunction(from.up)) {
- Ext.raise('Callback "up" syntax requires a caller with "up" method');
- }
- // eslint-disable-next-line vars-on-top
- var controller, scope;
- for (scope = from.up(); scope && !scope[fn]; scope = scope.up()) {
- controller = scope.controller;
- if (controller && controller[fn]) {
- scope = controller;
- break;
- }
- }
- if (!scope || !Ext.isFunction(scope[fn])) {
- Ext.raise('No such method "' + fn + '" found up() from ' + (from.getId ? from.getId() : from.id));
- }
- return scope;
- },
- /**
- * @method callback
- * @member Ext
- * Execute a callback function in a particular scope. If `callback` argument is a
- * function reference, that is called. If it is a string, the string is assumed to
- * be the name of a method on the given `scope`. If no function is passed the call
- * is ignored.
- *
- * For example, these calls are equivalent:
- *
- * var myFunc = this.myFunc;
- *
- * Ext.callback('myFunc', this, [arg1, arg2]);
- * Ext.callback(myFunc, this, [arg1, arg2]);
- *
- * Ext.isFunction(myFunc) && this.myFunc(arg1, arg2);
- *
- * @param {Function/String} callback The callback function to execute or the name of
- * the callback method on the provided `scope`.
- * @param {Object} [scope] The scope in which `callback` should be invoked. If `callback`
- * is a string this object provides the method by that name. If this is `null` then
- * the `caller` is used to resolve the scope to a `ViewController` or the proper
- * `defaultListenerScope`.
- * @param {Array} [args] The arguments to pass to the function.
- * @param {Number} [delay] Pass a number to delay the call by a number of milliseconds.
- * @param {Object} [caller] The object calling the callback. This is used to resolve
- * named methods when no explicit `scope` is provided.
- * @param {Object} [defaultScope=caller] The default scope to return if none is found.
- * @return The value returned by the callback or `undefined` (if there is a `delay`
- * or if the `callback` is not a function).
- */
- callback: function(callback, scope, args, delay, caller, defaultScope) {
- if (!callback) {
- return;
- }
- /* eslint-disable-next-line vars-on-top */
- var namedScope = (scope in Ext._namedScopes),
- ret;
- if (callback.charAt) {
- // if (isString(fn))
- // Custom components cannot often use declarative method resolution when
- // they need to allow the user to supply declarative method names that can
- // reach the user's controller. The "up" callback syntax can help with that:
- //
- // xtype: 'button',
- // handler: 'up.onFoo',
- //
- // When Ext.callback('up.onFoo',..., button) is called, we can perform a
- // "button.up('[onFoo]')" search for the handler. Thus we have a declarative
- // way to dispatch such handlers that will work even if the user can supply
- // such handlers.
- //
- if (callback[2] === '.') {
- // callback = 'up.foo'
- if (callback.substr(0, 2) !== 'up') {
- Ext.raise('Invalid callback method name "' + callback + '"');
- }
- if (scope) {
- Ext.raise('Callback "up" syntax is incompatible with scopes');
- }
- scope = Ext.lookUpFn(caller, callback = callback.substr(3));
- } else if (caller) {
- if (namedScope && namedScope.isUp) {
- scope = Ext.lookUpFn(caller, callback);
- } else if (!scope || namedScope) {
- scope = caller.resolveListenerScope(namedScope ? scope : defaultScope);
- }
- }
- if (!scope || !Ext.isObject(scope)) {
- Ext.raise('Named method "' + callback + '" requires a scope object');
- }
- if (!Ext.isFunction(scope[callback])) {
- Ext.raise('No method named "' + callback + '" on ' + (scope.$className || 'scope object'));
- }
- callback = scope[callback];
- } else if (namedScope) {
- scope = defaultScope || caller;
- } else if (!scope) {
- scope = caller;
- }
- if (callback && Ext.isFunction(callback)) {
- scope = scope || Ext.global;
- if (delay) {
- Ext.defer(callback, delay, scope, args);
- } else {
- ret = args ? callback.apply(scope, args) : callback.call(scope);
- }
- }
- return ret;
- },
- /**
- * @method coerce
- * @member Ext
- * Coerces the first value if possible so that it is comparable to the second value.
- *
- * Coercion only works between the basic atomic data types String, Boolean, Number, Date, null
- * and undefined. Numbers and numeric strings are coerced to Dates using the value
- * as the millisecond era value.
- *
- * Strings are coerced to Dates by parsing using the
- * {@link Ext.Date#defaultFormat defaultFormat}.
- *
- * For example
- *
- * Ext.coerce('false', true);
- *
- * returns the boolean value `false` because the second parameter is of type `Boolean`.
- *
- * @param {Mixed} from The value to coerce
- * @param {Mixed} to The value it must be compared against
- * @return The coerced value.
- */
- coerce: function(from, to) {
- var fromType = Ext.typeOf(from),
- toType = Ext.typeOf(to),
- isString = typeof from === 'string';
- if (fromType !== toType) {
- switch (toType) {
- case 'string':
- return String(from);
- case 'number':
- return Number(from);
- case 'boolean':
- // See http://ecma262-5.com/ELS5_HTML.htm#Section_11.9.3 as to why '0'.
- // TL;DR => ('0' == 0), so if given string '0', we must return boolean false.
- return isString && (!from || from === 'false' || from === '0') ? false : Boolean(from);
- case 'null':
- return isString && (!from || from === 'null') ? null : false;
- case 'undefined':
- return isString && (!from || from === 'undefined') ? undefined : false;
- case 'date':
- return isString && isNaN(from) ? Ext.Date.parse(from, Ext.Date.defaultFormat) : Date(Number(from));
- }
- }
- return from;
- },
- /**
- * @method copyTo
- * @member Ext
- * Copies a set of named properties fom the source object to the destination object.
- *
- * Example:
- *
- * var foo = { a: 1, b: 2, c: 3 };
- *
- * var bar = Ext.copyTo({}, foo, 'a,c');
- * // bar = { a: 1, c: 3 };
- *
- * Important note: To borrow class prototype methods, use {@link Ext.Base#borrow} instead.
- *
- * @param {Object} dest The destination object.
- * @param {Object} source The source object.
- * @param {String/String[]} names Either an Array of property names, or a comma-delimited list
- * of property names to copy.
- * @param {Boolean} [usePrototypeKeys=false] Pass `true` to copy keys off of the
- * prototype as well as the instance.
- * @return {Object} The `dest` object.
- * @deprecated 6.0.1 Use {@link Ext#copy Ext.copy} instead. This old method
- * would copy the named properties even if they did not exist in the source which
- * could produce `undefined` values in the destination.
- */
- copyTo: function(dest, source, names, usePrototypeKeys) {
- var name, i, n;
- if (typeof names === 'string') {
- names = names.split(Ext.propertyNameSplitRe);
- }
- for (i = 0 , n = names ? names.length : 0; i < n; i++) {
- name = names[i];
- if (usePrototypeKeys || source.hasOwnProperty(name)) {
- dest[name] = source[name];
- }
- }
- return dest;
- },
- /**
- * @method copy
- * @member Ext
- * Copies a set of named properties fom the source object to the destination object.
- *
- * Example:
- *
- * var foo = { a: 1, b: 2, c: 3 };
- *
- * var bar = Ext.copy({}, foo, 'a,c');
- * // bar = { a: 1, c: 3 };
- *
- * Important note: To borrow class prototype methods, use {@link Ext.Base#borrow} instead.
- *
- * @param {Object} dest The destination object.
- * @param {Object} source The source object.
- * @param {String/String[]} names Either an Array of property names, or a comma-delimited list
- * of property names to copy.
- * @param {Boolean} [usePrototypeKeys=false] Pass `true` to copy keys off of the
- * prototype as well as the instance.
- * @return {Object} The `dest` object.
- */
- copy: function(dest, source, names, usePrototypeKeys) {
- var name, i, n;
- if (typeof names === 'string') {
- names = names.split(Ext.propertyNameSplitRe);
- }
- for (i = 0 , n = names ? names.length : 0; i < n; i++) {
- name = names[i];
- // Only copy a property if the source actually *has* that property.
- // If we are including prototype properties, then ensure that a property of
- // that name can be found *somewhere* in the prototype chain (otherwise we'd be
- // copying undefined in which may break things)
- if (source.hasOwnProperty(name) || (usePrototypeKeys && name in source)) {
- dest[name] = source[name];
- }
- }
- return dest;
- },
- propertyNameSplitRe: /[,;\s]+/,
- /**
- * @method copyToIf
- * @member Ext
- * Copies a set of named properties fom the source object to the destination object
- * if the destination object does not already have them.
- *
- * Example:
- *
- * var foo = { a: 1, b: 2, c: 3 };
- *
- * var bar = Ext.copyToIf({ a:42 }, foo, 'a,c');
- * // bar = { a: 42, c: 3 };
- *
- * @param {Object} destination The destination object.
- * @param {Object} source The source object.
- * @param {String/String[]} names Either an Array of property names, or a single string
- * with a list of property names separated by ",", ";" or spaces.
- * @return {Object} The `dest` object.
- * @deprecated 6.0.1 Use {@link Ext#copyIf Ext.copyIf} instead. This old method
- * would copy the named preoperties even if they did not exist in the source which
- * could produce `undefined` values in the destination.
- */
- copyToIf: function(destination, source, names) {
- var name, i, n;
- if (typeof names === 'string') {
- names = names.split(Ext.propertyNameSplitRe);
- }
- for (i = 0 , n = names ? names.length : 0; i < n; i++) {
- name = names[i];
- if (destination[name] === undefined) {
- destination[name] = source[name];
- }
- }
- return destination;
- },
- /**
- * @method copyIf
- * @member Ext
- * Copies a set of named properties fom the source object to the destination object
- * if the destination object does not already have them.
- *
- * Example:
- *
- * var foo = { a: 1, b: 2, c: 3 };
- *
- * var bar = Ext.copyIf({ a:42 }, foo, 'a,c');
- * // bar = { a: 42, c: 3 };
- *
- * @param {Object} destination The destination object.
- * @param {Object} source The source object.
- * @param {String/String[]} names Either an Array of property names, or a single string
- * with a list of property names separated by ",", ";" or spaces.
- * @return {Object} The `dest` object.
- */
- copyIf: function(destination, source, names) {
- var name, i, n;
- if (typeof names === 'string') {
- names = names.split(Ext.propertyNameSplitRe);
- }
- for (i = 0 , n = names ? names.length : 0; i < n; i++) {
- name = names[i];
- // Only copy a property if the destination has no property by that name
- if (!(name in destination) && (name in source)) {
- destination[name] = source[name];
- }
- }
- return destination;
- },
- /**
- * @method extend
- * @member Ext
- * This method deprecated. Use {@link Ext#define Ext.define} instead.
- * @param {Function} superclass
- * @param {Object} overrides
- * @return {Function} The subclass constructor from the <tt>overrides</tt> parameter,
- * or a generated one if not provided.
- * @deprecated 4.0.0 Use {@link Ext#define Ext.define} instead
- */
- extend: (function() {
- // inline overrides
- var objectConstructor = Object.prototype.constructor,
- inlineOverrides = function(o) {
- var m;
- for (m in o) {
- if (!o.hasOwnProperty(m)) {
-
- continue;
- }
- this[m] = o[m];
- }
- };
- return function(subclass, superclass, overrides) {
- // First we check if the user passed in just the superClass with overrides
- if (Ext.isObject(superclass)) {
- overrides = superclass;
- superclass = subclass;
- subclass = overrides.constructor !== objectConstructor ? overrides.constructor : function() {
- superclass.apply(this, arguments);
- };
- }
- if (!superclass) {
- Ext.raise({
- sourceClass: 'Ext',
- sourceMethod: 'extend',
- msg: 'Attempting to extend from a class which has not been loaded on the page.'
- });
- }
- // We create a new temporary class
- /* eslint-disable-next-line vars-on-top */
- var F = function() {},
- superclassProto = superclass.prototype,
- subclassProto;
- F.prototype = superclassProto;
- subclassProto = subclass.prototype = new F();
- subclassProto.constructor = subclass;
- subclass.superclass = superclassProto;
- if (superclassProto.constructor === objectConstructor) {
- superclassProto.constructor = superclass;
- }
- subclass.override = function(overrides) {
- Ext.override(subclass, overrides);
- };
- subclassProto.override = inlineOverrides;
- subclassProto.proto = subclassProto;
- subclass.override(overrides);
- subclass.extend = function(o) {
- return Ext.extend(subclass, o);
- };
- return subclass;
- };
- }()),
- /**
- * @method isOnline
- * @member Ext
- * Indicates if the page is currently running in online or offline mode, according
- * to the `navigator.onLine` property.
- * @return {Boolean} `true` if the page is currently running in an online mode.
- *
- * @since 6.2.1
- */
- isOnline: function() {
- return Ext.global.navigator.onLine;
- },
- /**
- * @method iterate
- * @member Ext
- * Iterates either an array or an object. This method delegates to
- * {@link Ext.Array#each Ext.Array.each} if the given value is iterable, and
- * {@link Ext.Object#each Ext.Object.each} otherwise.
- *
- * @param {Object/Array} object The object or array to be iterated.
- * @param {Function} fn The function to be called for each iteration. See and
- * {@link Ext.Array#each Ext.Array.each} and {@link Ext.Object#each Ext.Object.each}
- * for detailed lists of arguments passed to this function depending on the given object
- * type that is being iterated.
- * @param {Object} [scope] The scope (`this` reference) in which the specified function
- * is executed. Defaults to the object being iterated itself.
- */
- iterate: function(object, fn, scope) {
- if (Ext.isEmpty(object)) {
- return;
- }
- if (scope === undefined) {
- scope = object;
- }
- if (Ext.isIterable(object)) {
- Ext.Array.each.call(Ext.Array, object, fn, scope);
- } else {
- Ext.Object.each.call(Ext.Object, object, fn, scope);
- }
- },
- _resourcePoolRe: /^[<]([^<>@:]*)(?:[@]([^<>@:]+))?[>](.+)$/,
- /**
- * Resolves a resource URL that may contain a resource pool identifier token at the
- * front. The tokens are formatted as HTML tags "<poolName@packageName>" followed
- * by a normal relative path. This token is only processed if present at the first
- * character of the given string.
- *
- * These tokens are parsed and the pieces are then passed to the
- * {@link Ext#getResourcePath} method.
- *
- * For example:
- *
- * [{
- * xtype: 'image',
- * src: '<shared>images/foo.png'
- * },{
- * xtype: 'image',
- * src: '<@package>images/foo.png'
- * },{
- * xtype: 'image',
- * src: '<shared@package>images/foo.png'
- * }]
- *
- * In the above example, "shared" is the name of a Sencha Cmd resource pool and
- * "package" is the name of a Sencha Cmd package.
- * @member Ext
- * @param {String} url The URL that may contain a resource pool token at the front.
- * @return {String}
- * @since 6.0.1
- */
- resolveResource: function(url) {
- var ret = url,
- m;
- if (url && url.charAt(0) === '<') {
- m = Ext._resourcePoolRe.exec(url);
- if (m) {
- ret = Ext.getResourcePath(m[3], m[1], m[2]);
- }
- }
- return ret;
- },
- /**
- *
- * @member Ext
- * @method urlEncode
- * @inheritdoc Ext.Object#toQueryString
- * @deprecated 4.0.0 Use {@link Ext.Object#toQueryString} instead
- */
- urlEncode: function() {
- var args = Ext.Array.from(arguments),
- prefix = '';
- // Support for the old `pre` argument
- if (Ext.isString(args[1])) {
- prefix = args[1] + '&';
- args[1] = false;
- }
- return prefix + Ext.Object.toQueryString.apply(Ext.Object, args);
- },
- /**
- * Alias for {@link Ext.Object#fromQueryString}.
- *
- * @member Ext
- * @method urlDecode
- * @inheritdoc Ext.Object#fromQueryString
- * @deprecated 4.0.0 Use {@link Ext.Object#fromQueryString} instead
- */
- urlDecode: function() {
- return Ext.Object.fromQueryString.apply(Ext.Object, arguments);
- },
- /**
- * @method getScrollbarSize
- * @member Ext
- * Returns the size of the browser scrollbars. This can differ depending on
- * operating system settings, such as the theme or font size.
- * @param {Boolean} [force] true to force a recalculation of the value.
- * @return {Object} An object containing scrollbar sizes.
- * @return {Number} return.width The width of the vertical scrollbar.
- * @return {Number} return.height The height of the horizontal scrollbar.
- * @deprecated 7.0 Use `Ext.scrollbar.size` instead.
- */
- getScrollbarSize: function(force) {
- return Ext.scrollbar.size(force);
- },
- /**
- * @method typeOf
- * @member Ext
- * Returns the type of the given variable in string format. List of possible values are:
- *
- * - `undefined`: If the given value is `undefined`
- * - `null`: If the given value is `null`
- * - `string`: If the given value is a string
- * - `number`: If the given value is a number
- * - `boolean`: If the given value is a boolean value
- * - `date`: If the given value is a `Date` object
- * - `function`: If the given value is a function reference
- * - `object`: If the given value is an object
- * - `array`: If the given value is an array
- * - `regexp`: If the given value is a regular expression
- * - `element`: If the given value is a DOM Element
- * - `textnode`: If the given value is a DOM text node and contains something other than
- * whitespace
- * - `whitespace`: If the given value is a DOM text node and contains only whitespace
- *
- * @param {Object} value
- * @return {String}
- */
- typeOf: (function() {
- var nonWhitespaceRe = /\S/,
- toString = Object.prototype.toString,
- typeofTypes = {
- number: 1,
- string: 1,
- 'boolean': 1,
- 'undefined': 1
- },
- toStringTypes = {
- '[object Array]': 'array',
- '[object Date]': 'date',
- '[object Boolean]': 'boolean',
- '[object Number]': 'number',
- '[object RegExp]': 'regexp'
- };
- return function(value) {
- if (value === null) {
- return 'null';
- }
- /* eslint-disable-next-line vars-on-top */
- var type = typeof value,
- ret, typeToString;
- if (typeofTypes[type]) {
- return type;
- }
- ret = toStringTypes[typeToString = toString.call(value)];
- if (ret) {
- return ret;
- }
- if (type === 'function') {
- return 'function';
- }
- if (type === 'object') {
- if (value.nodeType !== undefined) {
- if (value.nodeType === 3) {
- return nonWhitespaceRe.test(value.nodeValue) ? 'textnode' : 'whitespace';
- } else {
- return 'element';
- }
- }
- return 'object';
- }
- Ext.raise({
- sourceClass: 'Ext',
- sourceMethod: 'typeOf',
- msg: 'Failed to determine the type of "' + value + '".'
- });
- return typeToString;
- };
- }()),
- /**
- * A global factory method to instantiate a class from a config object. For example,
- * these two calls are equivalent:
- *
- * Ext.factory({ text: 'My Button' }, 'Ext.Button');
- * Ext.create('Ext.Button', { text: 'My Button' });
- *
- * If an existing instance is also specified, it will be updated with the supplied config
- * object. This is useful if you need to either create or update an object, depending on
- * if an instance already exists. For example:
- *
- * var button;
- * button = Ext.factory({ text: 'New Button' }, 'Ext.Button', button); // Button created
- * button = Ext.factory({ text: 'Updated Button' }, 'Ext.Button', button); // Button updated
- *
- * @param {Object} config The config object to instantiate or update an instance with.
- * @param {String} [classReference] The class to instantiate from (if there is a default).
- * @param {Object} [instance] The instance to update.
- * @param [aliasNamespace]
- * @member Ext
- * @deprecated 6.5.0 Use the {@link Ext.Factory#method!update update} method of the
- * associated factory instead.
- */
- factory: function(config, classReference, instance, aliasNamespace) {
- var manager = Ext.ClassManager,
- newInstance;
- // If config is falsy or a valid instance, destroy the current instance
- // (if it exists) and replace with the new one
- if (!config || config.isInstance) {
- if (instance && instance !== config) {
- instance.destroy();
- }
- return config;
- }
- if (aliasNamespace) {
- // If config is a string value, treat it as an alias
- if (typeof config === 'string') {
- return manager.instantiateByAlias(aliasNamespace + '.' + config);
- }
- // Same if 'type' is given in config
- else if (Ext.isObject(config) && 'type' in config) {
- return manager.instantiateByAlias(aliasNamespace + '.' + config.type, config);
- }
- }
- if (config === true) {
- if (!instance && !classReference) {
- Ext.raise('[Ext.factory] Cannot determine type of class to create');
- }
- return instance || Ext.create(classReference);
- }
- if (!Ext.isObject(config)) {
- Ext.raise("Invalid config, must be a valid config object");
- }
- if ('xtype' in config) {
- newInstance = manager.instantiateByAlias('widget.' + config.xtype, config);
- } else if ('xclass' in config) {
- newInstance = Ext.create(config.xclass, config);
- }
- if (newInstance) {
- if (instance) {
- instance.destroy();
- }
- return newInstance;
- }
- if (instance) {
- return instance.setConfig(config);
- }
- return Ext.create(classReference, config);
- },
- /**
- * This method converts an object containing config objects keyed by `itemId` into
- * an array of config objects.
- *
- * @param {Object} items An object containing config objects keyed by `itemId`.
- * @param {String} [defaultProperty="xtype"] The property to set for string items.
- * @param functionProperty
- * @return {Object[]}
- * @member Ext
- * @since 6.5.0
- * @private
- */
- convertKeyedItems: function(items, defaultProperty, functionProperty) {
- if (items && !items.isInstance && Ext.isObject(items)) {
- /* eslint-disable-next-line vars-on-top */
- var obj = items,
- item, itemId, value;
- items = [];
- // See if obj looks like a single thing
- if (obj.xtype || obj.xclass || obj.itemId || obj.id) {
- items.push(obj);
- } else {
- for (itemId in obj) {
- item = obj[itemId];
- if (item) {
- if (item === true) {
- item = {};
- } else if (typeof item === 'function') {
- if (!functionProperty) {
- Ext.raise('Function not expected here');
- }
- value = item;
- item = {};
- item[functionProperty] = value;
- } else if (typeof item === 'string') {
- value = item;
- item = {};
- item[defaultProperty || 'xtype'] = value;
- } else {
- item = Ext.apply({}, item);
- }
- item.itemId = itemId;
- items.push(item);
- }
- }
- }
- }
- return items;
- },
- sortByWeight: function(items) {
- if (items) {
- Ext.Array.sort(items, Ext.weightSortFn);
- }
- },
- /**
- * Comparison function for sorting an array of objects in ascending order of `weight`.
- * @param {Object} lhs
- * @param {Object} rhs
- * @return {Number}
- * @member Ext
- * @private
- * @since 6.5.0
- */
- weightSortFn: function(lhs, rhs) {
- return (lhs.weight || 0) - (rhs.weight || 0);
- },
- /**
- * Concatenate 2 arrays. If either argument is `null` or `undefined` then it's not
- * concatenated.
- *
- * @param {Object/Object[]} a
- * @param {Object/Object[]} b
- * @return {Object[]}
- * @member Ext
- * @private
- * @since 6.5.1
- */
- concat: function(a, b) {
- var noB = b == null,
- E = Ext.emptyArray;
- return (a == null) ? (noB ? a : E.concat(b)) : (noB ? E.concat(a) : E.concat(a, b));
- },
- /**
- * @method log
- * @member Ext
- * Logs a message. If a console is present it will be used. On Opera, the method
- * "opera.postError" is called. In other cases, the message is logged to an array
- * "Ext.log.out". An attached debugger can watch this array and view the log. The
- * log buffer is limited to a maximum of "Ext.log.max" entries (defaults to 250).
- *
- * If additional parameters are passed, they are joined and appended to the message.
- * A technique for tracing entry and exit of a function is this:
- *
- * function foo () {
- * Ext.log({ indent: 1 }, '>> foo');
- *
- * // log statements in here or methods called from here will be indented
- * // by one step
- *
- * Ext.log({ outdent: 1 }, '<< foo');
- * }
- *
- * This method does nothing in a release build.
- *
- * @param {String/Object} [options] The message to log or an options object with any
- * of the following properties:
- *
- * - `msg`: The message to log (required).
- * - `level`: One of: "error", "warn", "info" or "log" (the default is "log").
- * - `dump`: An object to dump to the log as part of the message.
- * - `stack`: True to include a stack trace in the log.
- * - `indent`: Cause subsequent log statements to be indented one step.
- * - `outdent`: Cause this and following statements to be one step less indented.
- *
- * @param {String...} [message] The message to log (required unless specified in
- * options object).
- */
- log: (function() {
- /*
- * Iterate through an object to dump its content into a string.
- * For example:
- * {
- * style: {
- * lineWidth: 1
- * },
- * label: {},
- * marker: {
- * strokeStyle: "#555",
- * radius: 3,
- * size: 3
- * },
- * subStyle: {
- * fillStyle: [
- * 0: "#133987",
- * 1: "#1c55ca",
- * 2: "#4d7fe6"
- * ]
- * },
- * markerSubStyle: {}
- * }
- *
- * @param {Object} object The object to iterate
- * @param {Number} [level] Current level of identation (and recursion). Default is 0.
- * @param {Number} [maxLevel] Maximum level of recursion. Default is 3.
- * @param {Boolean} [withFunctions] Include functions in the output.
- * @return {String} The string with the contents of the object
- */
- var primitiveRe = /string|number|boolean/;
- function dumpObject(object, level, maxLevel, withFunctions) {
- var member, type, value, name, prefix, suffix,
- members = [];
- if (Ext.isArray(object)) {
- prefix = '[';
- suffix = ']';
- } else if (Ext.isObject(object)) {
- prefix = '{';
- suffix = '}';
- }
- if (!maxLevel) {
- maxLevel = 3;
- }
- if (level > maxLevel) {
- return prefix + '...' + suffix;
- }
- level = level || 1;
- /* eslint-disable-next-line vars-on-top */
- var spacer = (new Array(level)).join(' ');
- // Cannot use Ext.encode since it can recurse endlessly
- for (name in object) {
- if (object.hasOwnProperty(name)) {
- value = object[name];
- type = typeof value;
- if (type === 'function') {
- if (!withFunctions) {
-
- continue;
- }
- member = type;
- } else if (type === 'undefined') {
- member = type;
- } else if (value === null || primitiveRe.test(type) || Ext.isDate(value)) {
- member = Ext.encode(value);
- } else if (Ext.isArray(value)) {
- member = dumpObject(value, level + 1, maxLevel, withFunctions);
- } else if (Ext.isObject(value)) {
- member = dumpObject(value, level + 1, maxLevel, withFunctions);
- } else {
- member = type;
- }
- members.push(spacer + name + ': ' + member);
- }
- }
- // or Ext.encode(name)
- if (members.length) {
- return prefix + '\n ' + members.join(',\n ') + '\n' + spacer + suffix;
- }
- return prefix + suffix;
- }
- function log(message) {
- var options, dump,
- con = Ext.global.console,
- level = 'log',
- indent = log.indent || 0,
- prefix, stack, fn, out, max;
- log.indent = indent;
- if (typeof message !== 'string') {
- options = message;
- message = options.msg || '';
- level = options.level || level;
- dump = options.dump;
- stack = options.stack;
- prefix = options.prefix;
- fn = options.fn;
- if (options.indent) {
- ++log.indent;
- } else if (options.outdent) {
- log.indent = indent = Math.max(indent - 1, 0);
- }
- if (dump && !(con && con.dir)) {
- message += dumpObject(dump);
- dump = null;
- }
- }
- if (arguments.length > 1) {
- message += Array.prototype.slice.call(arguments, 1).join('');
- }
- if (prefix) {
- message = prefix + ' - ' + message;
- }
- message = indent ? Ext.String.repeat(' ', log.indentSize * indent) + message : message;
- // w/o console, all messages are equal, so munge the level into the message:
- if (level !== 'log') {
- message = '[' + level.charAt(0).toUpperCase() + '] ' + message;
- }
- if (fn) {
- message += '\nCaller: ' + fn.toString();
- }
- // Not obvious, but 'console' comes and goes when Firebug is turned on/off, so
- // an early test may fail either direction if Firebug is toggled.
- //
- if (con) {
- // if (Firebug-like console)
- if (con[level]) {
- con[level](message);
- } else {
- con.log(message);
- }
- if (dump) {
- con.dir(dump);
- }
- if (stack && con.trace) {
- // Firebug's console.error() includes a trace already...
- if (!con.firebug || level !== 'error') {
- con.trace();
- }
- }
- } else if (Ext.isOpera) {
- /* eslint-disable-next-line no-undef */
- opera.postError(message);
- } else {
- out = log.out;
- max = log.max;
- if (out.length >= max) {
- // this formula allows out.max to change (via debugger), where the
- // more obvious "max/4" would not quite be the same
- // keep newest 75%
- Ext.Array.erase(out, 0, out.length - 3 * Math.floor(max / 4));
- }
- out.push(message);
- }
- // Mostly informational, but the Ext.Error notifier uses them:
- ++log.count;
- ++log.counters[level];
- }
- function logx(level, args) {
- if (typeof args[0] === 'string') {
- args.unshift({});
- }
- args[0].level = level;
- log.apply(this, args);
- }
- log.error = function() {
- logx('error', Array.prototype.slice.call(arguments));
- };
- log.info = function() {
- logx('info', Array.prototype.slice.call(arguments));
- };
- log.warn = function() {
- logx('warn', Array.prototype.slice.call(arguments));
- };
- log.count = 0;
- log.counters = {
- error: 0,
- warn: 0,
- info: 0,
- log: 0
- };
- log.indentSize = 2;
- log.out = [];
- log.max = 750;
- return log;
- }()) || (function() {
- var nullLog = function() {};
- nullLog.info = nullLog.warn = nullLog.error = Ext.emptyFn;
- return nullLog;
- }())
- });
- /**
- * @class Ext.Version
- *
- * A utility class that wraps around a version number string and provides convenient methods
- * to perform comparisons. A version number is expressed in the following general format:
- *
- * major[.minor[.patch[.build[release]]]]
- *
- * The `Version` instance holds various readonly properties that contain the digested form
- * of the version string. The numeric componnets of `major`, `minor`, `patch` and `build`
- * as well as the textual suffix called `release`.
- *
- * Not depicted in the above syntax are three possible prefixes used to control partial
- * matching. These are '^' (the default), '>' and '~'. These are discussed below.
- *
- * Examples:
- *
- * var version = new Ext.Version('1.0.2beta'); // or maybe "1.0" or "1.2.3.4RC"
- * console.log("Version is " + version); // Version is 1.0.2beta
- *
- * console.log(version.getMajor()); // 1
- * console.log(version.getMinor()); // 0
- * console.log(version.getPatch()); // 2
- * console.log(version.getBuild()); // 0
- * console.log(version.getRelease()); // beta
- *
- * The understood values of `release` are assigned numberic equivalents for the sake of
- * comparsion. The order of these from smallest to largest is as follows:
- *
- * * `"dev"`
- * * `"alpha"` or `"a"`
- * * `"beta"` or `"b"`
- * * `"RC"` or `"rc"`
- * * `"#"`
- * * `"pl"` or `"p"`
- *
- * Any other (unrecognized) suffix is consider greater than any of these.
- *
- * ## Comparisons
- * There are two forms of comparison that are commonly needed: full and partial. Full
- * comparison is simpler and is also the default.
- *
- * Example:
- *
- * var version = new Ext.Version('1.0.2beta');
- *
- * console.log(version.isGreaterThan('1.0.1')); // True
- * console.log(version.isGreaterThan('1.0.2alpha')); // True
- * console.log(version.isGreaterThan('1.0.2RC')); // False
- * console.log(version.isGreaterThan('1.0.2')); // False
- * console.log(version.isLessThan('1.0.2')); // True
- *
- * console.log(version.match(1.0)); // True (using a Number)
- * console.log(version.match('1.0.2')); // True (using a String)
- *
- * These comparisons are ultimately implemented by {@link Ext.Version#compareTo compareTo}
- * which returns -1, 0 or 1 depending on whether the `Version' instance is less than, equal
- * to, or greater than the given "other" version.
- *
- * For example:
- *
- * var n = version.compareTo('1.0.1'); // == 1 (because 1.0.2beta > 1.0.1)
- *
- * n = version.compareTo('1.1'); // == -1
- * n = version.compareTo(version); // == 0
- *
- * ### Partial Comparisons
- * By default, unspecified version number fields are filled with 0. In other words, the
- * version number fields are 0-padded on the right or a "lower bound". This produces the
- * most commonly used forms of comparsion:
- *
- * var ver = new Version('4.2');
- *
- * n = ver.compareTo('4.2.1'); // == -1 (4.2 promotes to 4.2.0 and is less than 4.2.1)
- *
- * There are two other ways to interpret comparisons of versions of different length. The
- * first of these is to change the padding on the right to be a large number (scuh as
- * Infinity) instead of 0. This has the effect of making the version an upper bound. For
- * example:
- *
- * var ver = new Version('^4.2'); // NOTE: the '^' prefix used
- *
- * n = ver.compareTo('4.3'); // == -1 (less than 4.3)
- *
- * n = ver.compareTo('4.2'); // == 1 (greater than all 4.2's)
- * n = ver.compareTo('4.2.1'); // == 1
- * n = ver.compareTo('4.2.9'); // == 1
- *
- * The second way to interpret this comparison is to ignore the extra digits, making the
- * match a prefix match. For example:
- *
- * var ver = new Version('~4.2'); // NOTE: the '~' prefix used
- *
- * n = ver.compareTo('4.3'); // == -1
- *
- * n = ver.compareTo('4.2'); // == 0
- * n = ver.compareTo('4.2.1'); // == 0
- *
- * This final form can be useful when version numbers contain more components than are
- * important for certain comparisons. For example, the full version of Ext JS 4.2.1 is
- * "4.2.1.883" where 883 is the `build` number.
- *
- * This is how to create a "partial" `Version` and compare versions to it:
- *
- * var version421ish = new Version('~4.2.1');
- *
- * n = version421ish.compareTo('4.2.1.883'); // == 0
- * n = version421ish.compareTo('4.2.1.2'); // == 0
- * n = version421ish.compareTo('4.2.1'); // == 0
- *
- * n = version421ish.compareTo('4.2'); // == 1
- *
- * In the above example, '4.2.1.2' compares as equal to '4.2.1' because digits beyond the
- * given "4.2.1" are ignored. However, '4.2' is less than the '4.2.1' prefix; its missing
- * digit is filled with 0.
- */
- /* eslint-disable indent */
- (function() {
- // @define Ext.Version
- // @require Ext.String
- var // used by checkVersion to avoid temp arrays:
- checkVerTemp = [
- ''
- ],
- endOfVersionRe = /([^\d.])/,
- notDigitsRe = /[^\d]/g,
- plusMinusRe = /[-+]/g,
- stripRe = /\s/g,
- underscoreRe = /_/g,
- toolkitNames = {
- classic: 1,
- modern: 1
- },
- Version;
- Ext.Version = Version = function(version, defaultMode) {
- var me = this,
- padModes = me.padModes,
- ch, i, pad, parts, release, releaseStartIndex, ver;
- if (version.isVersion) {
- version = version.version;
- }
- me.version = ver = String(version).toLowerCase().replace(underscoreRe, '.').replace(plusMinusRe, '');
- ch = ver.charAt(0);
- if (ch in padModes) {
- ver = ver.substring(1);
- pad = padModes[ch];
- } else {
- pad = defaultMode ? padModes[defaultMode] : 0;
- }
- // careful - NaN is falsey!
- me.pad = pad;
- releaseStartIndex = ver.search(endOfVersionRe);
- me.shortVersion = ver;
- if (releaseStartIndex !== -1) {
- me.release = release = ver.substr(releaseStartIndex, version.length);
- me.shortVersion = ver.substr(0, releaseStartIndex);
- release = Version.releaseValueMap[release] || release;
- }
- me.releaseValue = release || pad;
- me.shortVersion = me.shortVersion.replace(notDigitsRe, '');
- /**
- * @property {Number[]} parts
- * The split array of version number components found in the version string.
- * For example, for "1.2.3", this would be `[1, 2, 3]`.
- * @readonly
- * @private
- */
- me.parts = parts = ver.split('.');
- for (i = parts.length; i--; ) {
- parts[i] = parseInt(parts[i], 10);
- }
- if (pad === Infinity) {
- // have to add this to the end to create an upper bound:
- parts.push(pad);
- }
- /**
- * @property {Number} major
- * The first numeric part of the version number string.
- * @readonly
- */
- me.major = parts[0] || pad;
- /**
- * @property {Number} [minor]
- * The second numeric part of the version number string.
- * @readonly
- */
- me.minor = parts[1] || pad;
- /**
- * @property {Number} [patch]
- * The third numeric part of the version number string.
- * @readonly
- */
- me.patch = parts[2] || pad;
- /**
- * @property {Number} [build]
- * The fourth numeric part of the version number string.
- * @readonly
- */
- me.build = parts[3] || pad;
- return me;
- };
- Version.prototype = {
- isVersion: true,
- padModes: {
- '~': NaN,
- '^': Infinity
- },
- /**
- * @property {String} [release=""]
- * The release level. The following values are understood:
- *
- * * `"dev"`
- * * `"alpha"` or `"a"`
- * * `"beta"` or `"b"`
- * * `"RC"` or `"rc"`
- * * `"#"`
- * * `"pl"` or `"p"`
- * @readonly
- */
- release: '',
- /**
- * Compares this version instance to the specified `other` version.
- *
- * @param {String/Number/Ext.Version} other The other version to which to compare.
- * @return {Number} -1 if this version is less than the target version, 1 if this
- * version is greater, and 0 if they are equal.
- */
- compareTo: function(other) {
- // "lhs" == "left-hand-side"
- // "rhs" == "right-hand-side"
- var me = this,
- lhsPad = me.pad,
- lhsParts = me.parts,
- lhsLength = lhsParts.length,
- rhsVersion = other.isVersion ? other : new Version(other),
- rhsPad = rhsVersion.pad,
- rhsParts = rhsVersion.parts,
- rhsLength = rhsParts.length,
- length = Math.max(lhsLength, rhsLength),
- i, lhs, rhs;
- for (i = 0; i < length; i++) {
- lhs = (i < lhsLength) ? lhsParts[i] : lhsPad;
- rhs = (i < rhsLength) ? rhsParts[i] : rhsPad;
- // When one or both of the values are NaN these tests produce false
- // and we end up treating NaN as equal to anything.
- if (lhs < rhs) {
- return -1;
- }
- if (lhs > rhs) {
- return 1;
- }
- }
- // same comments about NaN apply here...
- lhs = me.releaseValue;
- rhs = rhsVersion.releaseValue;
- if (lhs < rhs) {
- return -1;
- }
- if (lhs > rhs) {
- return 1;
- }
- return 0;
- },
- /**
- * Override the native `toString` method
- * @private
- * @return {String} version
- */
- toString: function() {
- return this.version;
- },
- /**
- * Override the native `valueOf` method
- * @private
- * @return {String} version
- */
- valueOf: function() {
- return this.version;
- },
- /**
- * Returns the major component value.
- * @return {Number}
- */
- getMajor: function() {
- return this.major;
- },
- /**
- * Returns the minor component value.
- * @return {Number}
- */
- getMinor: function() {
- return this.minor;
- },
- /**
- * Returns the patch component value.
- * @return {Number}
- */
- getPatch: function() {
- return this.patch;
- },
- /**
- * Returns the build component value.
- * @return {Number}
- */
- getBuild: function() {
- return this.build;
- },
- /**
- * Returns the release component text (e.g., "beta").
- * @return {String}
- */
- getRelease: function() {
- return this.release;
- },
- /**
- * Returns the release component value for comparison purposes.
- * @return {Number/String}
- */
- getReleaseValue: function() {
- return this.releaseValue;
- },
- /**
- * Returns whether this version if greater than the supplied argument
- * @param {String/Number} target The version to compare with
- * @return {Boolean} `true` if this version if greater than the target, `false` otherwise
- */
- isGreaterThan: function(target) {
- return this.compareTo(target) > 0;
- },
- /**
- * Returns whether this version if greater than or equal to the supplied argument
- * @param {String/Number} target The version to compare with
- * @return {Boolean} `true` if this version if greater than or equal to the target,
- * `false` otherwise
- */
- isGreaterThanOrEqual: function(target) {
- return this.compareTo(target) >= 0;
- },
- /**
- * Returns whether this version if smaller than the supplied argument
- * @param {String/Number} target The version to compare with
- * @return {Boolean} `true` if this version if smaller than the target, `false` otherwise
- */
- isLessThan: function(target) {
- return this.compareTo(target) < 0;
- },
- /**
- * Returns whether this version if less than or equal to the supplied argument
- * @param {String/Number} target The version to compare with
- * @return {Boolean} `true` if this version if less than or equal to the target,
- * `false` otherwise
- */
- isLessThanOrEqual: function(target) {
- return this.compareTo(target) <= 0;
- },
- /**
- * Returns whether this version equals to the supplied argument
- * @param {String/Number} target The version to compare with
- * @return {Boolean} `true` if this version equals to the target, `false` otherwise
- */
- equals: function(target) {
- return this.compareTo(target) === 0;
- },
- /**
- * Returns whether this version matches the supplied argument. Example:
- *
- * var version = new Ext.Version('1.0.2beta');
- * console.log(version.match(1)); // true
- * console.log(version.match(1.0)); // true
- * console.log(version.match('1.0.2')); // true
- * console.log(version.match('1.0.2RC')); // false
- *
- * @param {String/Number} target The version to compare with
- * @return {Boolean} `true` if this version matches the target, `false` otherwise
- */
- match: function(target) {
- target = String(target);
- return this.version.substr(0, target.length) === target;
- },
- /**
- * Returns this format: [major, minor, patch, build, release]. Useful for comparison.
- * @return {Number[]}
- */
- toArray: function() {
- var me = this;
- return [
- me.getMajor(),
- me.getMinor(),
- me.getPatch(),
- me.getBuild(),
- me.getRelease()
- ];
- },
- /**
- * Returns shortVersion version without dots and release
- * @return {String}
- */
- getShortVersion: function() {
- return this.shortVersion;
- },
- /**
- * Convenient alias to {@link Ext.Version#isGreaterThan isGreaterThan}
- * @param {String/Number/Ext.Version} target
- * @return {Boolean}
- */
- gt: function(target) {
- return this.compareTo(target) > 0;
- },
- /**
- * Convenient alias to {@link Ext.Version#isLessThan isLessThan}
- * @param {String/Number/Ext.Version} target
- * @return {Boolean}
- */
- lt: function(target) {
- return this.compareTo(target) < 0;
- },
- /**
- * Convenient alias to {@link Ext.Version#isGreaterThanOrEqual isGreaterThanOrEqual}
- * @param {String/Number/Ext.Version} target
- * @return {Boolean}
- */
- gtEq: function(target) {
- return this.compareTo(target) >= 0;
- },
- /**
- * Convenient alias to {@link Ext.Version#isLessThanOrEqual isLessThanOrEqual}
- * @param {String/Number/Ext.Version} target
- * @return {Boolean}
- */
- ltEq: function(target) {
- return this.compareTo(target) <= 0;
- }
- };
- Ext.apply(Version, {
- aliases: {
- from: {
- extjs: 'ext',
- core: 'core',
- touch: 'modern'
- },
- to: {
- ext: [
- 'extjs'
- ],
- 'core': [
- 'core'
- ],
- modern: [
- 'touch'
- ]
- }
- },
- /**
- * @private
- */
- releaseValueMap: {
- dev: -6,
- alpha: -5,
- a: -5,
- beta: -4,
- b: -4,
- rc: -3,
- '#': -2,
- p: -1,
- pl: -1
- },
- /**
- * Converts a version component to a comparable value
- *
- * @static
- * @param {Object} value The value to convert
- * @return {Object}
- */
- getComponentValue: function(value) {
- // eslint-disable-next-line max-len
- return !value ? 0 : (isNaN(value) ? this.releaseValueMap[value] || value : parseInt(value, 10));
- },
- /**
- * Compare 2 specified versions by ensuring the first parameter is a `Version`
- * instance and then calling the `compareTo` method.
- *
- * @static
- * @param {String} current The current version to compare to
- * @param {String} target The target version to compare to
- * @return {Number} Returns -1 if the current version is smaller than the target version,
- * 1 if greater, and 0 if they're equivalent
- */
- compare: function(current, target) {
- var ver = current.isVersion ? current : new Version(current);
- return ver.compareTo(target);
- },
- set: function(collection, packageName, version) {
- var aliases = Version.aliases.to[packageName],
- ver = version.isVersion ? version : new Version(version),
- i;
- collection[packageName] = ver;
- if (aliases) {
- for (i = aliases.length; i-- > 0; ) {
- collection[aliases[i]] = ver;
- }
- }
- return ver;
- }
- });
- /**
- * @class Ext
- */
- Ext.apply(Ext, {
- /**
- * @private
- */
- compatVersions: {},
- /**
- * @private
- *
- * Object containing version information for all packages utilized by your
- * application.
- *
- * For a public getter, please see `Ext.getVersion()`.
- */
- versions: {},
- /**
- * @private
- */
- lastRegisteredVersion: null,
- /**
- * Get the compatibility level (a version number) for the given package name. If
- * none has been registered with `Ext.setCompatVersion` then `Ext.getVersion` is
- * used to get the current version.
- *
- * @param {String} packageName The package name, e.g. 'core', 'touch', 'ext'.
- * @since 5.0.0
- * @private
- */
- getCompatVersion: function(packageName) {
- var versions = Ext.compatVersions,
- compat;
- if (!packageName) {
- compat = versions.ext || versions.touch || versions.core;
- } else {
- compat = versions[Version.aliases.from[packageName] || packageName];
- }
- return compat || Ext.getVersion(packageName);
- },
- /**
- * Set the compatibility level (a version number) for the given package name.
- *
- * @param {String} packageName The package name, e.g. 'core', 'touch', 'ext'.
- * @param {String/Ext.Version} version The version, e.g. '4.2'.
- * @since 5.0.0
- * @private
- */
- setCompatVersion: function(packageName, version) {
- Version.set(Ext.compatVersions, packageName, version);
- },
- /**
- * Set version number for the given package name.
- *
- * @param {String} packageName The package name, e.g. 'core', 'touch', 'ext'.
- * @param {String/Ext.Version} version The version, e.g. '1.2.3alpha', '2.4.0-dev'.
- * @return {Ext}
- */
- setVersion: function(packageName, version) {
- if (packageName in toolkitNames) {
- Ext.toolkit = packageName;
- }
- Ext.lastRegisteredVersion = Version.set(Ext.versions, packageName, version);
- return this;
- },
- /**
- * Get the version number of the supplied package name; will return the version of
- * the framework.
- *
- * @param {String} [packageName] The package name, e.g., 'core', 'touch', 'ext'.
- * @return {Ext.Version} The version.
- */
- getVersion: function(packageName) {
- var versions = Ext.versions;
- if (!packageName) {
- return versions.ext || versions.touch || versions.core;
- }
- return versions[Version.aliases.from[packageName] || packageName];
- },
- /**
- * This method checks the registered package versions against the provided version
- * `specs`. A `spec` is either a string or an object indicating a boolean operator.
- * This method accepts either form or an array of these as the first argument. The
- * second argument applies only when the first is an array and indicates whether
- * all `specs` must match or just one.
- *
- * ## Package Version Specifications
- * The string form of a `spec` is used to indicate a version or range of versions
- * for a particular package. This form of `spec` consists of three (3) parts:
- *
- * * Package name followed by "@". If not provided, the framework is assumed.
- * * Minimum version.
- * * Maximum version.
- *
- * At least one version number must be provided. If both minimum and maximum are
- * provided, these must be separated by a "-".
- *
- * Some examples of package version specifications:
- *
- * 4.2.2 (exactly version 4.2.2 of the framework)
- * 4.2.2+ (version 4.2.2 or higher of the framework)
- * 4.2.2- (version 4.2.2 or higher of the framework)
- * 4.2.1 - 4.2.3 (versions from 4.2.1 up to 4.2.3 of the framework)
- * - 4.2.2 (any version up to version 4.2.1 of the framework)
- *
- * foo@1.0 (exactly version 1.0 of package "foo")
- * foo@1.0-1.3 (versions 1.0 up to 1.3 of package "foo")
- *
- * **NOTE:** This syntax is the same as that used in Sencha Cmd's package
- * requirements declarations.
- *
- * ## Boolean Operator Specifications
- * Instead of a string, an object can be used to describe a boolean operation to
- * perform on one or more `specs`. The operator is either **`and`** or **`or`**
- * and can contain an optional **`not`**.
- *
- * For example:
- *
- * {
- * not: true, // negates boolean result
- * and: [
- * '4.2.2',
- * 'foo@1.0.1 - 2.0.1'
- * ]
- * }
- *
- * Each element of the array can in turn be a string or object spec. In other
- * words, the value is passed to this method (recursively) as the first argument
- * so these two calls are equivalent:
- *
- * Ext.checkVersion({
- * not: true, // negates boolean result
- * and: [
- * '4.2.2',
- * 'foo@1.0.1 - 2.0.1'
- * ]
- * });
- *
- * !Ext.checkVersion([
- * '4.2.2',
- * 'foo@1.0.1 - 2.0.1'
- * ], true);
- *
- * ## Examples
- *
- * // A specific framework version
- * Ext.checkVersion('4.2.2');
- *
- * // A range of framework versions:
- * Ext.checkVersion('4.2.1-4.2.3');
- *
- * // A specific version of a package:
- * Ext.checkVersion('foo@1.0.1');
- *
- * // A single spec that requires both a framework version and package
- * // version range to match:
- * Ext.checkVersion({
- * and: [
- * '4.2.2',
- * 'foo@1.0.1-1.0.2'
- * ]
- * });
- *
- * // These checks can be nested:
- * Ext.checkVersion({
- * and: [
- * '4.2.2', // exactly version 4.2.2 of the framework *AND*
- * {
- * // either (or both) of these package specs:
- * or: [
- * 'foo@1.0.1-1.0.2',
- * 'bar@3.0+'
- * ]
- * }
- * ]
- * });
- *
- * ## Version Comparisons
- * Version comparsions are assumed to be "prefix" based. That is to say, `"foo@1.2"`
- * matches any version of "foo" that has a major version 1 and a minor version of 2.
- *
- * This also applies to ranges. For example `"foo@1.2-2.2"` matches all versions
- * of "foo" from 1.2 up to 2.2 regardless of the specific patch and build.
- *
- * ## Use in Overrides
- * This methods primary use is in support of conditional overrides on an
- * `Ext.define` declaration.
- *
- * @param {String/Array/Object} specs A version specification string, an object
- * containing `or` or `and` with a value that is equivalent to `specs` or an array
- * of either of these.
- * @param {Boolean} [matchAll=false] Pass `true` to require all specs to match.
- * @return {Boolean} True if `specs` matches the registered package versions.
- */
- checkVersion: function(specs, matchAll) {
- var isArray = Ext.isArray(specs),
- aliases = Version.aliases.from,
- compat = isArray ? specs : checkVerTemp,
- length = compat.length,
- versions = Ext.versions,
- frameworkVer = versions.ext || versions.touch,
- i, index, matches, minVer, maxVer, packageName, spec, range, ver;
- if (!isArray) {
- checkVerTemp[0] = specs;
- }
- for (i = 0; i < length; ++i) {
- if (!Ext.isString(spec = compat[i])) {
- matches = Ext.checkVersion(spec.and || spec.or, !spec.or);
- if (spec.not) {
- matches = !matches;
- }
- } else {
- if (spec.indexOf(' ') >= 0) {
- spec = spec.replace(stripRe, '');
- }
- // For "name@..." syntax, we need to find the package by the given name
- // as a registered package.
- index = spec.indexOf('@');
- if (index < 0) {
- range = spec;
- ver = frameworkVer;
- } else {
- packageName = spec.substring(0, index);
- if (!(ver = versions[aliases[packageName] || packageName])) {
- // The package is not registered, so if we must matchAll then
- // we are done - FAIL:
- if (matchAll) {
- return false;
- }
- // Otherwise this spec is not a match so we can move on to the
- // next...
-
- continue;
- }
- range = spec.substring(index + 1);
- }
- // Now look for a version, version range or partial range:
- index = range.indexOf('-');
- if (index < 0) {
- // just a version or "1.0+"
- if (range.charAt(index = range.length - 1) === '+') {
- minVer = range.substring(0, index);
- maxVer = null;
- } else {
- minVer = maxVer = range;
- }
- } else if (index > 0) {
- // a range like "1.0-1.5" or "1.0-"
- minVer = range.substring(0, index);
- maxVer = range.substring(index + 1);
- } else // may be empty
- {
- // an upper limit like "-1.5"
- minVer = null;
- maxVer = range.substring(index + 1);
- }
- matches = true;
- if (minVer) {
- minVer = new Version(minVer, '~');
- // prefix matching
- matches = minVer.ltEq(ver);
- }
- if (matches && maxVer) {
- maxVer = new Version(maxVer, '~');
- // prefix matching
- matches = maxVer.gtEq(ver);
- }
- }
- // string spec
- if (matches) {
- // spec matched and we are looking for any match, so we are GO!
- if (!matchAll) {
- return true;
- }
- } else if (matchAll) {
- // spec does not match the registered package version
- return false;
- }
- }
- // In the loop above, for matchAll we return FALSE on mismatch, so getting
- // here with matchAll means we had no mismatches. On the other hand, if we
- // are !matchAll, we return TRUE on match and so we get here only if we found
- // no matches.
- return !!matchAll;
- },
- /**
- * Create a closure for deprecated code.
- *
- * // This means Ext.oldMethod is only supported in 4.0.0beta and older.
- * // If Ext.getVersion('extjs') returns a version that is later than '4.0.0beta',
- * // for example '4.0.0RC', the closure will not be invoked
- * Ext.deprecate('extjs', '4.0.0beta', function() {
- * Ext.oldMethod = Ext.newMethod;
- *
- * ...
- * });
- *
- * @param {String} packageName The package name
- * @param {String} since The last version before it's deprecated
- * @param {Function} closure The callback function to be executed with the specified
- * version is less than the current version
- * @param {Object} scope The execution scope (`this`) if the closure
- * @private
- */
- deprecate: function(packageName, since, closure, scope) {
- if (Version.compare(Ext.getVersion(packageName), since) < 1) {
- closure.call(scope);
- }
- }
- });
- }());
- // End Versioning
- // load the cmd-5 style app manifest metadata now, if available...
- (function(manifest) {
- var packages = (manifest && manifest.packages) || {},
- compat = manifest && manifest.compatibility,
- name, pkg;
- for (name in packages) {
- pkg = packages[name];
- if (pkg && pkg.version) {
- Ext.setVersion(name, pkg.version);
- }
- }
- if (compat) {
- if (Ext.isString(compat)) {
- Ext.setCompatVersion('core', compat);
- } else {
- for (name in compat) {
- Ext.setCompatVersion(name, compat[name]);
- }
- }
- }
- if (!packages.ext && !packages.touch) {
- Ext.setVersion('ext', '7.4.0.42');
- Ext.setVersion('core', '7.4.0.42');
- }
- })(Ext.manifest);
- /**
- * @class Ext.Config
- * This class manages a config property. Instances of this type are created and cached as
- * classes declare their config properties. One instance of this class is created per
- * config property name.
- *
- * Ext.define('MyClass', {
- * config: {
- * foo: 42
- * }
- * });
- *
- * This uses the cached `Ext.Config` instance for the "foo" property.
- *
- * When config properties apply options to config properties a prototype chained object is
- * created from the cached instance. For example:
- *
- * Ext.define('MyClass', {
- * config: {
- * foo: {
- * $value: 42,
- * lazy: true
- * }
- * }
- * });
- *
- * This creates a prototype chain to the cached "foo" instance of `Ext.Config` and applies
- * the `lazy` option to that new instance. This chained instance is then kept by the
- * `Ext.Configurator` for that class.
- * @private
- */
- Ext.Config = function(name) {
- // @define Ext.class.Config
- // @define Ext.Config
- var me = this,
- capitalizedName = name.charAt(0).toUpperCase() + name.substr(1);
- /**
- * @property {String} name
- * The name of this config property.
- * @readonly
- * @private
- * @since 5.0.0
- */
- me.name = name;
- /**
- * @property {Object} names
- * This object holds the cached names used to lookup properties or methods for this
- * config property. The properties of this object are explained in the context of an
- * example property named "foo".
- *
- * @property {String} names.internal The default backing property ("_foo").
- *
- * @property {String} names.initializing The property that is `true` when the config
- * is being initialized ("isFooInitializing").
- *
- * @property {String} names.apply The name of the applier method ("applyFoo").
- *
- * @property {String} names.update The name of the updater method ("updateFoo").
- *
- * @property {String} names.get The name of the getter method ("getFoo").
- *
- * @property {String} names.set The name of the setter method ("setFoo").
- *
- * @property {String} names.initGet The name of the initializing getter ("initGetFoo").
- *
- * @property {String} names.changeEvent The name of the change event ("foochange").
- *
- * @readonly
- * @private
- * @since 5.0.0
- */
- me.names = {
- internal: '_' + name,
- initializing: 'is' + capitalizedName + 'Initializing',
- apply: 'apply' + capitalizedName,
- update: 'update' + capitalizedName,
- get: 'get' + capitalizedName,
- set: 'set' + capitalizedName,
- initGet: 'initGet' + capitalizedName,
- changeEvent: name.toLowerCase() + 'change'
- };
- // This allows folks to prototype chain on top of these objects and yet still cache
- // generated methods at the bottom of the chain.
- me.root = me;
- };
- Ext.Config.map = {};
- Ext.Config.get = function(name) {
- var map = Ext.Config.map,
- ret = map[name] || (map[name] = new Ext.Config(name));
- return ret;
- };
- Ext.Config.prototype = {
- self: Ext.Config,
- isConfig: true,
- /**
- * @cfg {Boolean} [cached=false]
- * When set as `true` the config property will be stored on the class prototype once
- * the first instance has had a chance to process the default value.
- * @private
- * @since 5.0.0
- */
- /**
- * @cfg {Boolean} [lazy=false]
- * When set as `true` the config property will not be immediately initialized during
- * the `initConfig` call.
- * @private
- * @since 5.0.0
- */
- /**
- * @cfg {Boolean} [evented=false]
- * When set as `true` the config property will be treated as a
- * {@link Ext.Evented Evented Config}.
- * @private
- * @since 6.0.0
- */
- /**
- * @cfg {Function} [merge]
- * This function if supplied will be called as classes or instances provide values
- * that need to be combined with inherited values. The function should return the
- * value that will be the config value. Further calls may receive such returned
- * values as `oldValue`.
- *
- * @cfg {Mixed} merge.newValue The new value to merge with the old.
- *
- * @cfg {Mixed} merge.oldValue The current value prior to `newValue` being merged.
- *
- * @cfg {Mixed} merge.target The class or instance to which the merged config value
- * will be applied.
- *
- * @cfg {Ext.Class} merge.mixinClass The mixin providing the `newValue` or `null` if
- * the `newValue` is not being provided by a mixin.
- */
- combine: function(value, baseValue, instance, clone) {
- var cfg = this;
- if (cfg.merge) {
- value = cfg.merge(clone ? Ext.clone(value) : value, baseValue, instance);
- } else if (value && value.constructor === Object && baseValue && baseValue.constructor === Object) {
- value = Ext.merge({}, baseValue, value);
- } else if (clone && value) {
- value = Ext.clone(value);
- }
- return value;
- },
- equals: function(value1, value2) {
- return value1 === value2;
- },
- getGetter: function() {
- return this.getter || (this.root.getter = this.makeGetter());
- },
- getInitGetter: function() {
- return this.initGetter || (this.root.initGetter = this.makeInitGetter());
- },
- getSetter: function() {
- return this.setter || (this.root.setter = this.makeSetter());
- },
- getEventedSetter: function() {
- return this.eventedSetter || (this.root.eventedSetter = this.makeEventedSetter());
- },
- /**
- * Returns the name of the property that stores this config on the given instance or
- * class prototype.
- * @param {Object} target
- * @return {String}
- */
- getInternalName: function(target) {
- return target.$configPrefixed ? this.names.internal : this.name;
- },
- mergeNew: function(newValue, oldValue, target, mixinClass) {
- var ret, key;
- if (!oldValue) {
- ret = newValue;
- } else if (!newValue) {
- ret = oldValue;
- } else {
- ret = Ext.Object.chain(oldValue);
- for (key in newValue) {
- if (!mixinClass || !(key in ret)) {
- ret[key] = newValue[key];
- }
- }
- }
- return ret;
- },
- /**
- * Merges the `newValue` and the `oldValue` assuming that these are basically objects
- * the represent sets. For example something like:
- *
- * {
- * foo: true,
- * bar: true
- * }
- *
- * The merge process converts arrays like the following into the above:
- *
- * [ 'foo', 'bar' ]
- *
- * @param {String/String[]/Object} newValue
- * @param {Object} oldValue
- * @param {Boolean} [preserveExisting=false]
- * @return {Object}
- * @private
- * @since 5.0.0
- */
- mergeSets: function(newValue, oldValue, preserveExisting) {
- var ret = oldValue ? Ext.Object.chain(oldValue) : {},
- i, val;
- if (newValue instanceof Array) {
- for (i = newValue.length; i--; ) {
- val = newValue[i];
- if (!preserveExisting || !(val in ret)) {
- ret[val] = true;
- }
- }
- } else if (newValue) {
- if (newValue.constructor === Object) {
- for (i in newValue) {
- val = newValue[i];
- if (!preserveExisting || !(i in ret)) {
- ret[i] = val;
- }
- }
- } else if (!preserveExisting || !(newValue in ret)) {
- ret[newValue] = true;
- }
- }
- return ret;
- },
- //--------------------------------------------------
- // Factories
- makeGetter: function() {
- var name = this.name,
- prefixedName = this.names.internal;
- return function() {
- var internalName = this.$configPrefixed ? prefixedName : name;
- return this[internalName];
- };
- },
- makeInitGetter: function() {
- var name = this.name,
- names = this.names,
- setName = names.set,
- getName = names.get,
- initializingName = names.initializing;
- return function() {
- var me = this;
- me[initializingName] = true;
- // Remove the initGetter from the instance now that the value has been set.
- delete me[getName];
- me[setName](me.config[name]);
- delete me[initializingName];
- return me[getName].apply(me, arguments);
- };
- },
- makeSetter: function() {
- var name = this.name,
- names = this.names,
- prefixedName = names.internal,
- getName = names.get,
- applyName = names.apply,
- updateName = names.update,
- setter;
- // http://jsperf.com/method-call-apply-or-direct
- // http://jsperf.com/method-detect-invoke
- setter = function(value) {
- var me = this,
- internalName = me.$configPrefixed ? prefixedName : name,
- oldValue = me[internalName],
- watch;
- // Remove the initGetter from the instance now that the value has been set.
- delete me[getName];
- if (!me[applyName] || (value = me[applyName](value, oldValue)) !== undefined) {
- // The old value might have been changed at this point
- // (after the apply call chain) so it should be read again
- if (value !== (oldValue = me[internalName])) {
- me[internalName] = value;
- if (me[updateName]) {
- me[updateName](value, oldValue);
- }
- watch = me.$configWatch;
- if (watch && !me.isConfiguring) {
- // Since the updater could have modified things (tho unlikely), just
- // re-read the stored value:
- watch.fire(name, [
- me,
- name,
- me[internalName],
- oldValue
- ]);
- }
- }
- }
- return me;
- };
- setter.$isDefault = true;
- return setter;
- },
- makeEventedSetter: function() {
- var name = this.name,
- names = this.names,
- prefixedName = names.internal,
- getName = names.get,
- applyName = names.apply,
- updateName = names.update,
- changeEventName = names.changeEvent,
- updateFn = function(me, value, oldValue, internalName) {
- me[internalName] = value;
- if (me[updateName]) {
- me[updateName](value, oldValue);
- }
- // eslint-disable-next-line vars-on-top
- var watch = me.$configWatch;
- if (watch) {
- // !me.isConfiguring is assured
- watch.fire(name, [
- me,
- name,
- value,
- oldValue
- ]);
- }
- },
- setter;
- // http://jsperf.com/method-call-apply-or-direct
- // http://jsperf.com/method-detect-invoke
- setter = function(value) {
- var me = this,
- internalName = me.$configPrefixed ? prefixedName : name,
- oldValue = me[internalName];
- // Remove the initGetter from the instance now that the value has been set.
- delete me[getName];
- if (!me[applyName] || (value = me[applyName](value, oldValue)) !== undefined) {
- // The old value might have been changed at this point
- // (after the apply call chain) so it should be read again
- if (value !== (oldValue = me[internalName])) {
- if (me.isConfiguring) {
- me[internalName] = value;
- if (me[updateName]) {
- me[updateName](value, oldValue);
- }
- } else {
- me.fireEventedAction(changeEventName, [
- me,
- value,
- oldValue
- ], updateFn, me, [
- me,
- value,
- oldValue,
- internalName
- ]);
- }
- }
- }
- return me;
- };
- setter.$isDefault = true;
- return setter;
- }
- };
- /**
- * @class Ext.Configurator
- * This class manages the config properties for a class.
- * @private
- */
- (function() {
- // see end of file (and please don't indent the whole file)
- var ExtConfig = Ext.Config,
- configPropMap = ExtConfig.map,
- ExtObject = Ext.Object;
- Ext.Configurator = function(cls) {
- // @define Ext.class.Configurator
- // @define Ext.Configurator
- // @require Ext.Config
- var me = this,
- prototype = cls.prototype,
- superCfg = cls.superclass ? cls.superclass.self.$config : null;
- /**
- * @property {Ext.Class} cls The class to which this instance is associated.
- * @private
- * @readonly
- */
- me.cls = cls;
- /**
- * The super class `Configurator` instance or `null` if there is no super class.
- *
- * @property {Ext.Configurator} superCfg
- * @private
- * @readonly
- */
- me.superCfg = superCfg;
- if (superCfg) {
- /**
- * This object holds an `Ext.Config` value for each config property keyed by name.
- * This object has as its prototype object the `configs` of its super class.
- *
- * This map is maintained as each property is added via the `add` method.
- *
- * @property {Object} configs
- * @private
- * @readonly
- */
- me.configs = ExtObject.chain(superCfg.configs);
- /**
- * This object holds a bool value for each cachedConfig property keyed by name.
- *
- * This map is maintained as each property is added via the `add` method.
- *
- * @property {Object} cachedConfigs
- * @private
- * @readonly
- */
- me.cachedConfigs = ExtObject.chain(superCfg.cachedConfigs);
- /**
- * This object holds a `Number` for each config property keyed by name. This object has
- * as its prototype object the `initMap` of its super class. The value of each property
- * has the following meaning:
- *
- * * `0` - initial value is `null` and requires no processing.
- * * `1` - initial value must be set on each instance.
- * * `2` - initial value can be cached on the prototype by the first instance.
- *
- * Any `null` values will either never be added to this map or (if added by a base
- * class and set to `null` by a derived class) will cause the entry to be 0.
- *
- * This map is maintained as each property is added via the `add` method.
- *
- * @property {Object} initMap
- * @private
- * @readonly
- */
- me.initMap = ExtObject.chain(superCfg.initMap);
- /**
- * This object holds the default value for each config property keyed by name. This
- * object has as its prototype object the `values` of its super class.
- *
- * This map is maintained as each property is added via the `add` method.
- *
- * @property {Object} values
- * @private
- * @readonly
- */
- me.values = ExtObject.chain(superCfg.values);
- me.needsFork = superCfg.needsFork;
- // The reason this feature is debug only is that we would have to create this
- // map for all classes because deprecations could be added to bases after the
- // derived class had created its Configurator.
- me.deprecations = ExtObject.chain(superCfg.deprecations);
- } else {
- me.configs = {};
- me.cachedConfigs = {};
- me.initMap = {};
- me.values = {};
- me.deprecations = {};
- }
- prototype.config = prototype.defaultConfig = me.values;
- cls.$config = me;
- };
- Ext.Configurator.prototype = {
- self: Ext.Configurator,
- needsFork: false,
- /**
- * This array holds the properties that need to be set on new instances.
- *
- * This array is populated when the first instance is passed to `configure` (basically
- * when the first instance is created). The entries in `initMap` are iterated to find
- * those configs needing per-instance processing.
- *
- * @property {Ext.Config[]} initList
- * @private
- */
- initList: null,
- /**
- * This method adds new config properties. This is called for classes when they are
- * declared, then for any mixins that class may define and finally for any overrides
- * defined that target the class.
- *
- * @param {Object} config The config object containing the new config properties.
- * @param {Ext.Class} [mixinClass] The mixin class if the configs are from a mixin.
- * @private
- */
- add: function(config, mixinClass) {
- var me = this,
- Cls = me.cls,
- configs = me.configs,
- cachedConfigs = me.cachedConfigs,
- initMap = me.initMap,
- prototype = Cls.prototype,
- mixinConfigs = mixinClass && mixinClass.$config.configs,
- values = me.values,
- isObject, meta, isCached, merge, cfg, currentValue, name, names, s, value;
- for (name in config) {
- value = config[name];
- isObject = value && value.constructor === Object;
- meta = isObject && '$value' in value ? value : null;
- isCached = false;
- if (meta) {
- isCached = !!meta.cached;
- value = meta.$value;
- isObject = value && value.constructor === Object;
- }
- merge = meta && meta.merge;
- cfg = configs[name];
- if (cfg) {
- // Only proceed with a mixin if we have a custom merge.
- if (mixinClass) {
- merge = cfg.merge;
- if (!merge) {
-
- continue;
- }
- // Don't want the mixin meta modifying our own
- meta = null;
- } else {
- merge = merge || cfg.merge;
- }
- // This means that we've already declared this as a config in a superclass
- // Let's not allow us to change it here.
- if (!mixinClass && isCached && !cachedConfigs[name]) {
- Ext.raise('Redefining config as cached: ' + name + ' in class: ' + Cls.$className);
- }
- // There is already a value for this config and we are not allowed to
- // modify it. So, if it is an object and the new value is also an object,
- // the result is a merge so we have to merge both on to a new object.
- currentValue = values[name];
- if (merge) {
- value = merge.call(cfg, value, currentValue, Cls, mixinClass);
- } else if (isObject) {
- if (currentValue && currentValue.constructor === Object) {
- // We favor moving the cost of an "extra" copy here because this
- // is likely to be a rare thing two object values for the same
- // property. The alternative would be to clone the initial value
- // to make it safely modifiable even though it is likely to never
- // need to be modified.
- value = Ext.merge({}, currentValue, value);
- }
- }
- } else // else "currentValue" is a primitive so "value" can just replace it
- // else "value" is a primitive and it can just replace currentValue
- {
- // This is a new property value, so add it to the various maps "as is".
- // In the majority of cases this value will not be overridden or need to
- // be forked.
- if (mixinConfigs) {
- // Since this is a config from a mixin, we don't want to apply its
- // meta-ness because it already has. Instead we want to use its cfg
- // instance:
- cfg = mixinConfigs[name];
- meta = null;
- } else {
- cfg = ExtConfig.get(name);
- }
- configs[name] = cfg;
- if (cfg.cached || isCached) {
- cachedConfigs[name] = true;
- }
- // Ensure that the new config has a getter and setter. Because this method
- // is called during class creation as the "config" (or "cachedConfig") is
- // being processed, the user's methods will not be on the prototype yet.
- //
- // This has the following trade-offs:
- //
- // - Custom getters are rare so there is minimal waste generated by them.
- //
- // - Custom setters are more common but, by putting the default setter on
- // the prototype prior to addMembers, when the user methods are added
- // callParent can be used to call the generated setter. This is almost
- // certainly desirable as the setter has some very important semantics
- // that a custom setter would probably want to preserve by just adding
- // logic before and/or after the callParent.
- //
- // - By not adding these to the class body we avoid all the "is function"
- // tests that get applied to each class member thereby streamlining the
- // downstream class creation process.
- //
- // We still check for getter and/or setter but primarily for reasons of
- // backwards compatibility and "just in case" someone relied on inherited
- // getter/setter even though the base did not have the property listed as
- // a "config" (obscure case certainly).
- //
- names = cfg.names;
- if (!prototype[s = names.get]) {
- prototype[s] = cfg.getter || cfg.getGetter();
- }
- if (!prototype[s = names.set]) {
- prototype[s] = (meta && meta.evented) ? (cfg.eventedSetter || cfg.getEventedSetter()) : (cfg.setter || cfg.getSetter());
- }
- }
- if (meta) {
- if (cfg.owner !== Cls) {
- configs[name] = cfg = Ext.Object.chain(cfg);
- cfg.owner = Cls;
- }
- Ext.apply(cfg, meta);
- delete cfg.$value;
- }
- // Fork checks all the default values to see if they are arrays or objects
- // Do this to save us from doing it on each run
- if (!me.needsFork && value && (value.constructor === Object || value instanceof Array)) {
- me.needsFork = true;
- }
- // If the value is non-null, we need to initialize it.
- if (value !== null) {
- initMap[name] = true;
- } else {
- if (prototype.$configPrefixed) {
- prototype[configs[name].names.internal] = null;
- } else {
- prototype[configs[name].name] = null;
- }
- if (name in initMap) {
- // Only set this to false if we already have it in the map, otherwise,
- // just leave it out!
- initMap[name] = false;
- }
- }
- values[name] = value;
- }
- },
- addDeprecations: function(configs) {
- var me = this,
- deprecations = me.deprecations,
- className = (me.cls.$className || '') + '#',
- message, newName, oldName;
- for (oldName in configs) {
- newName = configs[oldName];
- // configs: {
- // dead: null,
- //
- // renamed: 'newName',
- //
- // removed: {
- // message: 'This config was replaced by pixie dust'
- // }
- // }
- if (!newName) {
- message = 'This config has been removed.';
- } else if (!(message = newName.message)) {
- message = 'This config has been renamed to "' + newName + '"';
- }
- deprecations[oldName] = className + oldName + ': ' + message;
- }
- },
- /**
- * This method configures the given `instance` using the specified `instanceConfig`.
- * The given `instance` should have been created by this object's `cls`.
- *
- * @param {Object} instance The instance to configure.
- * @param {Object} instanceConfig The configuration properties to apply to `instance`.
- * @private
- */
- configure: function(instance, instanceConfig) {
- var me = this,
- configs = me.configs,
- deprecations = me.deprecations,
- initMap = me.initMap,
- initListMap = me.initListMap,
- initList = me.initList,
- prototype = me.cls.prototype,
- values = me.values,
- remaining = 0,
- firstInstance = !initList,
- cachedInitList, cfg, getter, i, internalName, ln, names, name, value, isCached, valuesKey, field, transforms;
- values = me.needsFork ? ExtObject.fork(values) : ExtObject.chain(values);
- // Let apply/update methods know that the initConfig is currently running.
- instance.isConfiguring = true;
- if (firstInstance) {
- // When called to configure the first instance of the class to which we are
- // bound we take a bit to plan for instance 2+.
- me.initList = initList = [];
- me.initListMap = initListMap = {};
- instance.isFirstInstance = true;
- for (name in initMap) {
- cfg = configs[name];
- isCached = cfg.cached;
- if (initMap[name]) {
- names = cfg.names;
- value = values[name];
- if (!prototype[names.set].$isDefault || prototype[names.apply] || prototype[names.update] || typeof value === 'object') {
- if (isCached) {
- // This is a cachedConfig, so it needs to be initialized with
- // the default value and placed on the prototype... but the
- // instanceConfig may have a different value so the value may
- // need resetting. We have to defer the call to the setter so
- // that all of the initGetters are set up first.
- (cachedInitList || (cachedInitList = [])).push(cfg);
- } else {
- // Remember this config so that all instances (including this
- // one) can invoke the setter to properly initialize it.
- initList.push(cfg);
- initListMap[name] = true;
- }
- // Point all getters to the initGetters. By doing this here we
- // avoid creating initGetters for configs that don't need them
- // and we can easily pick up the cached fn to save the call.
- instance[names.get] = cfg.initGetter || cfg.getInitGetter();
- } else {
- // Non-object configs w/o custom setter, applier or updater can
- // be simply stored on the prototype.
- prototype[cfg.getInternalName(prototype)] = value;
- }
- } else if (isCached) {
- prototype[cfg.getInternalName(prototype)] = undefined;
- }
- }
- }
- // TODO - we need to combine the cached loop with the instanceConfig loop to
- // avoid duplication of init getter setups (for correctness if a cached cfg
- // calls on a non-cached cfg)
- ln = cachedInitList && cachedInitList.length;
- if (ln) {
- // This is only ever done on the first instance we configure. Any config in
- // cachedInitList has to be set to the default value to allow any side-effects
- // or transformations to occur. The resulting values can then be elevated to
- // the prototype and this property need not be initialized on each instance.
- for (i = 0; i < ln; ++i) {
- internalName = cachedInitList[i].getInternalName(prototype);
- // Since these are cached configs the base class will potentially have put
- // its cached values on the prototype so we need to hide these while we
- // run the inits for our cached configs.
- instance[internalName] = null;
- }
- for (i = 0; i < ln; ++i) {
- names = (cfg = cachedInitList[i]).names;
- getter = names.get;
- if (instance.hasOwnProperty(getter)) {
- instance[names.set](values[cfg.name]);
- delete instance[getter];
- }
- }
- for (i = 0; i < ln; ++i) {
- internalName = cachedInitList[i].getInternalName(prototype);
- prototype[internalName] = instance[internalName];
- delete instance[internalName];
- }
- }
- // The cachedConfigs have all been set to the default values including any of
- // those that may have been triggered by their getter.
- // If the instanceConfig has a platformConfig in it, we need to merge the active
- // rules of that object to make the actual instanceConfig.
- if (instanceConfig && instanceConfig.platformConfig) {
- instanceConfig = me.resolvePlatformConfig(instance, instanceConfig);
- }
- if (firstInstance) {
- // Allow the class to do things once the cachedConfig has been processed.
- // We need to call this method always when the first instance is configured
- // whether or not it actually has cached configs
- if (instance.afterCachedConfig && !instance.afterCachedConfig.$nullFn) {
- instance.afterCachedConfig(instanceConfig);
- }
- }
- // Now that the cachedConfigs have been processed we can apply the instanceConfig
- // and hide the "configs" on the prototype. This will serve as the source for any
- // configs that need to initialize from their initial getter call.
- // IMPORTANT: "this.hasOwnProperty('config')" is how a config applier/updater can
- // tell it is processing the cached config value vs an instance config value.
- instance.config = values;
- // There are 2 possibilities here:
- // 1) If it's the first time in this function, we may have had cachedConfigs running.
- // these configs may have called the getters for any of the normal getters, which
- // means the initial getters have been clobbered on the instance and won't be able
- // to be called below when we iterate over the initList. As such, we need to
- // reinitialize them here, even though we've done it up above.
- //
- // 2) If this the second time in this function, the cachedConfigs won't be processed,
- // so we don't need to worry about them clobbering config values. However, since
- // we've already done all our setup, we won't enter into the block that sets the
- // initGetter, so we need to do it here anyway.
- //
- // Also note, that lazy configs will appear in the initList because we need
- // to spin up the initGetter.
- for (i = 0 , ln = initList.length; i < ln; ++i) {
- cfg = initList[i];
- instance[cfg.names.get] = cfg.initGetter || cfg.getInitGetter();
- }
- // Give the class a chance to transform the configs. These are stored on the class
- // as a sorted array after the first instance is created. Prior to that, these are
- // stored as a prototype chained object on the class prototype. This allows the
- // transforms to be registered at any time during class load so long as they are
- // all loaded before instances are created.
- if (!(transforms = instance.self.$configTransforms)) {
- instance.self.$configTransforms = transforms = [];
- ln = instance.$configTransforms;
- for (name in ln) {
- transforms.push([
- name,
- ln[name]
- ]);
- }
- ln = transforms.length;
- if (ln > 1) {
- transforms.sort(me.transformSorter);
- for (i = 0; i < ln; ++i) {
- transforms[i] = transforms[i][0];
- }
- } else if (ln) {
- transforms[0] = transforms[0][0];
- }
- }
- for (i = 0; i < transforms.length; ++i) {
- name = transforms[i];
- if (instance[name]) {
- instanceConfig = instance[name](instanceConfig, me);
- }
- }
- // Important: We are looping here twice on purpose. This first loop serves 2 purposes:
- //
- // 1) Ensure the values collection is fully populated before we call any setters. Since
- // a setter may have an updater/applier, it could potentially call another getter() to grab
- // the value for some other property, so this ensures they are all set on the config object.
- //
- // 2) Ensure that the initGetter is set as the getter for any config that doesn't appear in
- // the initList. We need to ensure that the initGetter is pushed on for everything that
- // we will be setting during init time.
- //
- // The merging in this loop cannot be completed by Ext.merge(), since we do NOT want
- // to merge non-strict values, they should always just be assigned across without
- // modification.
- if (instanceConfig) {
- for (name in instanceConfig) {
- value = instanceConfig[name];
- cfg = configs[name];
- if (deprecations[name]) {
- Ext.log.warn(deprecations[name]);
- if (!cfg) {
- // If there is a Config for this, perhaps the class is emulating
- // the old config... If there is not a Config we don't want to
- // proceed and put the property on the instance. That will likely
- // hide the bug during development.
-
- continue;
- }
- }
- if (!cfg) {
- field = instance.self.prototype[name];
- if (instance.$configStrict && (typeof field === 'function') && !field.$nullFn) {
- // In strict mode you cannot override functions
- Ext.raise('Cannot override method ' + name + ' on ' + instance.$className + ' instance.');
- }
- // Not all "configs" use the config system so in this case simply put
- // the value on the instance:
- instance[name] = value;
- } else {
- // However we still need to create the initial value that needs
- // to be used. We also need to spin up the initGetter.
- if (!cfg.lazy) {
- ++remaining;
- }
- if (!initListMap[name]) {
- instance[cfg.names.get] = cfg.initGetter || cfg.getInitGetter();
- }
- valuesKey = values[name];
- if (cfg.merge) {
- value = cfg.merge(value, valuesKey, instance);
- } else if (value && value.constructor === Object) {
- if (valuesKey && valuesKey.constructor === Object) {
- value = Ext.merge(values[name], value);
- } else {
- value = Ext.clone(value, false);
- }
- }
- }
- values[name] = value;
- }
- }
- // Give the class a chance to hook in prior to initializing the configs.
- if (instance.beforeInitConfig && !instance.beforeInitConfig.$nullFn) {
- if (instance.beforeInitConfig(instanceConfig) === false) {
- return;
- }
- }
- if (instanceConfig) {
- for (name in instanceConfig) {
- if (!remaining) {
- // For classes that have few proper Config properties, this saves us
- // from making the full 2 passes over the instanceConfig.
- break;
- }
- // We can ignore deprecated configs here because we warned about them
- // above. Further, since we only process proper Config's here we would
- // not be skipping them anyway.
- cfg = configs[name];
- if (cfg && !cfg.lazy) {
- --remaining;
- // A proper "config" property so call the setter to set the value.
- names = cfg.names;
- getter = names.get;
- // At this point the initGetter may have already been called and
- // cleared if the getter was called from the applier or updater of a
- // previously processed instance config. checking if the instance has
- // its own getter ensures the setter does not get called twice.
- if (instance.hasOwnProperty(getter)) {
- instance[names.set](values[name]);
- // The generated setter will remove the initGetter from the instance
- // but the user may have provided their own setter so we have to do
- // this here as well:
- delete instance[names.get];
- }
- }
- }
- }
- // Process configs declared on the class that need per-instance initialization.
- for (i = 0 , ln = initList.length; i < ln; ++i) {
- cfg = initList[i];
- names = cfg.names;
- getter = names.get;
- if (!cfg.lazy && instance.hasOwnProperty(getter)) {
- // Since the instance still hasOwn the getter, that means we've set an initGetter
- // and it hasn't been cleared by calling any setter. Since we've never set the value
- // because it wasn't passed in the instance, we go and set it here, taking the value
- // from our definition config and passing it through finally clear off the getter.
- instance[names.set](values[cfg.name]);
- delete instance[getter];
- }
- }
- // Expose the value from the prototype chain (false):
- delete instance.isConfiguring;
- },
- getCurrentConfig: function(instance) {
- var defaultConfig = instance.defaultConfig,
- config = {},
- name;
- for (name in defaultConfig) {
- config[name] = instance[configPropMap[name].names.get]();
- }
- return config;
- },
- /**
- * This method is called to update the internal state of a given config when that
- * config is needed in a config transform (such as responsive or stateful mixins).
- *
- * @param {Ext.Base} instance The instance to configure.
- * @param {Object} instanceConfig The config for the instance.
- * @param {String[]} names The name(s) of the config(s) to process.
- * @private
- * @since 6.7.0
- */
- hoistConfigs: function(instance, instanceConfig, names) {
- var config = instance.config,
- configs = this.configs,
- initListMap = this.initListMap,
- ret = false,
- cfg, i, name;
- for (i = 0; i < names.length; ++i) {
- name = names[i];
- if (instanceConfig && name in instanceConfig) {
- cfg = configs[name];
- // the Ext.Config instance
- config[name] = cfg.combine(instanceConfig[name], config[name], instance);
- if (!initListMap[name]) {
- instance[cfg.names.get] = cfg.initGetter || cfg.getInitGetter();
- }
- }
- // The config could be defined on the class, so may be present even if
- // not in instance config.
- if (config[name] != null) {
- ret = true;
- }
- }
- return ret;
- },
- /**
- * Merges the values of a config object onto a base config.
- * @param {Ext.Base} instance
- * @param {Object} baseConfig
- * @param {Object} config
- * @param {Boolean} [clone=false]
- * @return {Object} the merged config
- * @private
- */
- merge: function(instance, baseConfig, config, clone) {
- // Although this is a "private" method. It is used by Sencha Architect and so
- // its api should remain stable.
- var configs = this.configs,
- name, value, baseValue, cfg;
- if (clone) {
- baseConfig = Ext.clone(baseConfig, /* cloneDom= */
- false);
- }
- for (name in config) {
- value = config[name];
- cfg = configs[name];
- if (cfg) {
- baseValue = baseConfig[name];
- if (cfg.merge) {
- value = cfg.merge(value, baseValue, instance);
- } else if (value && value.constructor === Object) {
- if (baseValue && baseValue.constructor === Object) {
- value = Ext.merge(baseValue, value);
- } else {
- value = Ext.clone(value, false);
- }
- }
- }
- baseConfig[name] = value;
- }
- return baseConfig;
- },
- /**
- * @private
- */
- reconfigure: function(instance, instanceConfig, options) {
- var currentConfig = instance.config,
- configList = [],
- strict = instance.$configStrict && !(options && options.strict === false),
- configs = this.configs,
- defaults = options && options.defaults,
- cfg, getter, i, len, name, names, prop;
- for (name in instanceConfig) {
- cfg = configs[name];
- /* eslint-disable-next-line max-len */
- if (defaults && instance.hasOwnProperty(cfg && instance.$configPrefixed ? cfg.names.internal : name)) {
-
- continue;
- }
- currentConfig[name] = instanceConfig[name];
- if (this.deprecations[name]) {
- // See similar logic doc in configure() method.
- Ext.log.warn(this.deprecations[name]);
- if (!cfg) {
-
- continue;
- }
- }
- if (cfg) {
- // To ensure that configs being set here get processed in the proper order
- // we must give them init getters just in case they depend upon each other
- instance[cfg.names.get] = cfg.initGetter || cfg.getInitGetter();
- } else {
- // Check for existence of the property on the prototype before proceeding.
- // If present on the prototype, and if the property is a function we
- // do not allow it to be overridden by a property in the config object
- // in strict mode (unless the function on the prototype is a emptyFn or
- // identityFn). Note that we always check the prototype, not the instance
- // because calling setConfig a second time should have the same results -
- // the first call may have set a function on the instance.
- prop = instance.self.prototype[name];
- if (strict) {
- if ((typeof prop === 'function') && !prop.$nullFn) {
- Ext.Error.raise("Cannot override method " + name + " on " + instance.$className + " instance.");
-
- continue;
- } else {
- if (name !== 'type') {
- Ext.log.warn('No such config "' + name + '" for class ' + instance.$className);
- }
- }
- }
- }
- configList.push(name);
- }
- for (i = 0 , len = configList.length; i < len; i++) {
- name = configList[i];
- cfg = configs[name];
- if (cfg) {
- names = cfg.names;
- getter = names.get;
- if (instance.hasOwnProperty(getter)) {
- // Since the instance still hasOwn the getter, that means we've set
- // an initGetter and it hasn't been cleared by calling any setter.
- // Since we've never set the value because it wasn't passed in the instance,
- // we go and set it here, taking the value from our definition config
- // and passing it through finally clear off the getter.
- instance[names.set](instanceConfig[name]);
- delete instance[getter];
- }
- } else {
- cfg = configPropMap[name] || Ext.Config.get(name);
- names = cfg.names;
- if (instance[names.set]) {
- instance[names.set](instanceConfig[name]);
- } else {
- // apply non-config props directly to the instance
- instance[name] = instanceConfig[name];
- }
- }
- }
- },
- /**
- * This method accepts an instance config object containing a `platformConfig`
- * property and merges the appropriate rules from that sub-object with the root object
- * to create the final config object that should be used. This is method called by
- * `{@link #configure}` when it receives an `instanceConfig` containing a
- * `platformConfig` property.
- *
- * @param {Ext.Base} instance
- * @param {Object} instanceConfig The instance config parameter.
- * @return {Object} The new instance config object with platformConfig results applied.
- * @private
- * @since 5.1.0
- */
- resolvePlatformConfig: function(instance, instanceConfig) {
- var platformConfig = instanceConfig && instanceConfig.platformConfig,
- ret = instanceConfig,
- i, keys, n;
- if (platformConfig) {
- keys = Ext.getPlatformConfigKeys(platformConfig);
- n = keys.length;
- if (n) {
- ret = Ext.merge({}, ret);
- // this deep copies sub-objects
- for (i = 0 , n = keys.length; i < n; ++i) {
- this.merge(instance, ret, platformConfig[keys[i]]);
- }
- }
- }
- return ret;
- },
- transformSorter: function(a, b) {
- return a[1] - b[1];
- }
- };
- }());
- // prototype
- // closure on whole file
- // @tag class
- /**
- * @class Ext.Base
- *
- * The root of all classes created with {@link Ext#define}.
- *
- * Ext.Base is the building block of all Ext classes. All classes in Ext inherit from Ext.Base.
- * All prototype and static members of this class are inherited by all other classes.
- */
- Ext.Base = (function(flexSetter) {
- // @define Ext.Base
- // @require Ext.Util
- // @require Ext.Version
- // @require Ext.Configurator
- // @uses Ext.ClassManager
- // @uses Ext.mixin.Watchable
- /* eslint-disable indent */
- var noArgs = [],
- baseStaticMember,
- baseStaticMembers = [],
- makeDeprecatedMethod = function(oldName, newName, msg) {
- var message = '"' + oldName + '" is deprecated.';
- if (msg) {
- message += ' ' + msg;
- } else if (newName) {
- message += ' Please use "' + newName + '" instead.';
- }
- return function() {
- Ext.raise(message);
- };
- },
- addDeprecatedProperty = function(object, oldName, newName, message) {
- if (!message) {
- message = '"' + oldName + '" is deprecated.';
- }
- if (newName) {
- message += ' Please use "' + newName + '" instead.';
- }
- if (message) {
- Ext.Object.defineProperty(object, oldName, {
- get: function() {
- // eslint-disable-line getter-return
- Ext.raise(message);
- },
- set: function(value) {
- Ext.raise(message);
- },
- configurable: true
- });
- }
- },
- getOwnObject = function(proto, name) {
- if (!proto.hasOwnProperty(name)) {
- proto[name] = Ext.Object.chain(getOwnObject(proto.superclass, name));
- }
- return proto[name];
- },
- makeAliasFn = function(name) {
- return function() {
- return this[name].apply(this, arguments);
- };
- },
- Version = Ext.Version,
- leadingDigitRe = /^\d/,
- oneMember = {},
- aliasOneMember = {},
- Base = function() {},
- BasePrototype = Base.prototype,
- Reaper;
- Ext.Reaper = Reaper = {
- delay: 100,
- queue: [],
- timer: null,
- add: function(obj) {
- if (!Reaper.timer) {
- Reaper.timer = Ext.defer(Reaper.tick, Reaper.delay);
- }
- Reaper.queue.push(obj);
- },
- flush: function() {
- if (Reaper.timer) {
- Ext.undefer(Reaper.timer);
- Reaper.timer = null;
- }
- /* eslint-disable-next-line vars-on-top */
- var queue = Reaper.queue,
- n = queue.length,
- i, obj;
- Reaper.queue = [];
- for (i = 0; i < n; ++i) {
- obj = queue[i];
- if (obj && obj.$reap) {
- obj.$reap();
- }
- }
- },
- tick: function() {
- Reaper.timer = null;
- Reaper.flush();
- }
- };
- // These static properties will be copied to every newly created class with {@link Ext#define}
- Ext.apply(Base, {
- $className: 'Ext.Base',
- $isClass: true,
- /**
- * Create a new instance of this Class.
- *
- * Ext.define('My.cool.Class', {
- * ...
- * });
- *
- * My.cool.Class.create({
- * someConfig: true
- * });
- *
- * All parameters are passed to the constructor of the class.
- *
- * @return {Object} the created instance.
- * @static
- * @inheritable
- */
- create: function() {
- return Ext.create.apply(Ext, [
- this
- ].concat(Array.prototype.slice.call(arguments, 0)));
- },
- addConfigTransform: function(methodName, priority) {
- var transforms = getOwnObject(this.prototype, '$configTransforms');
- if (this.$configTransforms) {
- Ext.raise('Config transforms cannot be added after instances are created');
- }
- transforms[methodName] = priority;
- },
- /**
- * This method applies a versioned, deprecation declaration to this class. This
- * is typically called by the `deprecated` config.
- * @private
- */
- addDeprecations: function(deprecations) {
- var me = this,
- all = [],
- compatVersion = Ext.getCompatVersion(deprecations.name),
- configurator = me.getConfigurator(),
- displayName = (me.$className || '') + '#',
- deprecate, versionSpec, index, message, target, enabled, existing, fn, names, oldName, newName, member, statics, version;
- for (versionSpec in deprecations) {
- if (leadingDigitRe.test(versionSpec)) {
- version = new Ext.Version(versionSpec);
- version.deprecations = deprecations[versionSpec];
- all.push(version);
- }
- }
- all.sort(Version.compare);
- for (index = all.length; index--; ) {
- deprecate = (version = all[index]).deprecations;
- target = me.prototype;
- statics = deprecate.statics;
- // If user specifies, say 4.2 compatibility and we have a 5.0 deprecation
- // then that block needs to be "enabled" to "revert" to behaviors prior
- // to 5.0. By default, compatVersion === currentVersion, so there are no
- // enabled blocks. In dev mode we still want to visit all the blocks and
- // possibly add shims to detect use of deprecated methods, but in a build
- // (if the deprecated block remains somehow) we just break the loop.
- enabled = compatVersion && compatVersion.lt(version);
- if (!enabled) {}
- // eslint-disable-line no-empty, brace-style
- else if (!enabled) {
- // we won't get here in dev mode when !enabled
- break;
- }
- while (deprecate) {
- names = deprecate.methods;
- if (names) {
- for (oldName in names) {
- member = names[oldName];
- fn = null;
- if (!member) {
- /*
- * Something like:
- *
- * '5.1': {
- * methods: {
- * removedMethod: null
- * }
- * }
- *
- * Since there is no recovering the method, we always put
- * on a shim to catch abuse.
- */
- // The class should not already have a method by the oldName
- Ext.Assert.isNotDefinedProp(target, oldName);
- fn = makeDeprecatedMethod(displayName + oldName);
- } else if (Ext.isString(member)) {
- /*
- * Something like:
- *
- * '5.1': {
- * methods: {
- * oldName: 'newName'
- * }
- * }
- *
- * If this block is enabled, we just put an alias in place.
- * Otherwise we need to inject a
- */
- // The class should not already have a method by the oldName
- Ext.Assert.isNotDefinedProp(target, oldName);
- Ext.Assert.isDefinedProp(target, member);
- if (enabled) {
- // This call to the real method name must be late
- // bound if it is to pick up overrides and such.
- fn = makeAliasFn(member);
- } else {
- fn = makeDeprecatedMethod(displayName + oldName, member);
- }
- } else {
- /*
- * Something like:
- *
- * '5.1': {
- * methods: {
- * foo: function() { ... }
- * }
- * }
- *
- * Or this:
- *
- * '5.1': {
- * methods: {
- * foo: {
- * fn: function() { ... },
- * message: 'Please use "bar" instead.'
- * }
- * }
- * }
- *
- * Or just this:
- *
- * '5.1': {
- * methods: {
- * foo: {
- * message: 'Use something else instead.'
- * }
- * }
- * }
- *
- * If this block is enabled, and "foo" is an existing
- * method, than we apply the given method as an override.
- * If "foo" is not existing, we simply add the method.
- *
- * If the block is not enabled and there is no existing
- * method by that name, than we add a shim to prevent
- * abuse.
- */
- message = '';
- if (member.message || member.fn) {
- message = member.message;
- member = member.fn;
- }
- existing = target.hasOwnProperty(oldName) && target[oldName];
- if (enabled && member) {
- member.$owner = me;
- member.$name = oldName;
- member.name = displayName + oldName;
- if (existing) {
- member.$previous = existing;
- }
- fn = member;
- } else if (!existing) {
- fn = makeDeprecatedMethod(displayName + oldName, null, message);
- }
- }
- if (fn) {
- target[oldName] = fn;
- }
- }
- }
- // for oldName
- //-------------------------------------
- // Debug only
- names = deprecate.configs;
- if (names) {
- //
- // '6.0': {
- // configs: {
- // dead: null,
- //
- // renamed: 'newName',
- //
- // removed: {
- // message: 'This config was replaced by pixie dust'
- // }
- // }
- // }
- //
- configurator.addDeprecations(names);
- }
- names = deprecate.properties;
- if (names && !enabled) {
- // For properties about the only thing we can do is (on Good
- // Browsers), add warning shims for accessing them. So if the
- // block is enabled, we don't want those.
- for (oldName in names) {
- newName = names[oldName];
- if (Ext.isString(newName)) {
- addDeprecatedProperty(target, displayName + oldName, newName);
- } else if (newName && newName.message) {
- addDeprecatedProperty(target, displayName + oldName, null, newName.message);
- } else {
- addDeprecatedProperty(target, displayName + oldName);
- }
- }
- }
- //-------------------------------------
- // reset to handle statics and apply them to the class
- deprecate = statics;
- statics = null;
- target = me;
- }
- }
- },
- /**
- * @private
- * @static
- * @inheritable
- * @param parentClass
- */
- extend: function(parentClass) {
- var me = this,
- parentPrototype = parentClass.prototype,
- prototype, name, statics;
- prototype = me.prototype = Ext.Object.chain(parentPrototype);
- prototype.self = me;
- me.superclass = prototype.superclass = parentPrototype;
- if (!parentClass.$isClass) {
- for (name in BasePrototype) {
- if (name in prototype) {
- prototype[name] = BasePrototype[name];
- }
- }
- }
- // Statics inheritance
- statics = parentPrototype.$inheritableStatics;
- if (statics) {
- for (name in statics) {
- if (!me.hasOwnProperty(name)) {
- me[name] = parentClass[name];
- }
- }
- }
- if (parentClass.$onExtended) {
- me.$onExtended = parentClass.$onExtended.slice();
- }
- me.getConfigurator();
- },
- /**
- * @private
- * @static
- * @inheritable
- */
- $onExtended: [],
- /**
- * @private
- * @static
- * @inheritable
- */
- triggerExtended: function() {
- if (Ext.classSystemMonitor) {
- Ext.classSystemMonitor(this, 'Ext.Base#triggerExtended', arguments);
- }
- /* eslint-disable-next-line vars-on-top */
- var callbacks = this.$onExtended,
- ln = callbacks.length,
- i, callback;
- if (ln > 0) {
- for (i = 0; i < ln; i++) {
- callback = callbacks[i];
- callback.fn.apply(callback.scope || this, arguments);
- }
- }
- },
- /**
- * @private
- * @static
- * @inheritable
- */
- onExtended: function(fn, scope) {
- this.$onExtended.push({
- fn: fn,
- scope: scope
- });
- return this;
- },
- /**
- * Add / override static properties of this class.
- *
- * Ext.define('My.cool.Class', {
- * ...
- * });
- *
- * My.cool.Class.addStatics({
- * someProperty: 'someValue', // My.cool.Class.someProperty = 'someValue'
- * method1: function() { ... }, // My.cool.Class.method1 = function() { ... };
- * method2: function() { ... } // My.cool.Class.method2 = function() { ... };
- * });
- *
- * @param {Object} members
- * @return {Ext.Base} this
- * @static
- * @inheritable
- */
- addStatics: function(members) {
- this.addMembers(members, true);
- return this;
- },
- /**
- * @private
- * @static
- * @inheritable
- * @param {Object} members
- */
- addInheritableStatics: function(members) {
- var me = this,
- proto = me.prototype,
- inheritableStatics = me.$inheritableStatics,
- name, member, current;
- if (!inheritableStatics) {
- inheritableStatics = Ext.apply({}, proto.$inheritableStatics);
- me.$inheritableStatics = proto.$inheritableStatics = inheritableStatics;
- }
- /* eslint-disable-next-line vars-on-top */
- var className = Ext.getClassName(me) + '.';
- for (name in members) {
- if (members.hasOwnProperty(name)) {
- member = members[name];
- current = me[name];
- if (typeof member === 'function') {
- member.name = className + name;
- }
- if (typeof current === 'function' && !current.$isClass && !current.$nullFn) {
- member.$previous = current;
- }
- me[name] = member;
- inheritableStatics[name] = true;
- }
- }
- return me;
- },
- /**
- * Add methods / properties to the prototype of this class.
- *
- * Ext.define('My.awesome.Cat', {
- * constructor: function() {
- * ...
- * }
- * });
- *
- * My.awesome.Cat.addMembers({
- * meow: function() {
- * alert('Meowww...');
- * }
- * });
- *
- * var kitty = new My.awesome.Cat();
- * kitty.meow();
- *
- * @param {Object} members The members to add to this class.
- * @param {Boolean} [isStatic=false] Pass `true` if the members are static.
- * @param {Boolean} [privacy=false] Pass `true` if the members are private. This
- * only has meaning in debug mode and only for methods.
- * @static
- * @inheritable
- */
- addMembers: function(members, isStatic, privacy) {
- var me = this,
- // this class
- cloneFunction = Ext.Function.clone,
- target = isStatic ? me : me.prototype,
- defaultConfig = !isStatic && target.defaultConfig,
- enumerables = Ext.enumerables,
- privates = members.privates,
- configs, i, ln, member, name, subPrivacy, privateStatics;
- /* eslint-disable-next-line vars-on-top, one-var */
- var displayName = (me.$className || '') + '#';
- if (privates) {
- // This won't run for normal class private members but will pick up all
- // others (statics, overrides, etc).
- delete members.privates;
- if (!isStatic) {
- privateStatics = privates.statics;
- delete privates.statics;
- }
- subPrivacy = privates.privacy || privacy || 'framework';
- me.addMembers(privates, isStatic, subPrivacy);
- if (privateStatics) {
- me.addMembers(privateStatics, true, subPrivacy);
- }
- }
- for (name in members) {
- if (members.hasOwnProperty(name)) {
- member = members[name];
- if (privacy === true) {
- privacy = 'framework';
- }
- if (member && member.$nullFn && privacy !== member.$privacy) {
- Ext.raise('Cannot use stock function for private method ' + (me.$className ? me.$className + '#' : '') + name);
- }
- if (typeof member === 'function' && !member.$isClass && !member.$nullFn) {
- if (member.$owner) {
- member = cloneFunction(member);
- }
- if (target.hasOwnProperty(name)) {
- member.$previous = target[name];
- }
- // This information is needed by callParent() and callSuper() as
- // well as statics() and even Ext.fly().
- member.$owner = me;
- member.$name = name;
- member.name = displayName + name;
- /* eslint-disable-next-line vars-on-top */
- var existing = target[name];
- if (privacy) {
- member.$privacy = privacy;
- // The general idea here is that an existing, non-private
- // method can be marked private. This is because the other
- // way is strictly forbidden (private method going public)
- // so if a method is in that gray area it can only be made
- // private in doc form which allows a derived class to make
- // it public.
- if (existing && existing.$privacy && existing.$privacy !== privacy) {
- Ext.privacyViolation(me, existing, member, isStatic);
- }
- } else if (existing && existing.$privacy) {
- Ext.privacyViolation(me, existing, member, isStatic);
- }
- }
- // The last part of the check here resolves a conflict if we have the same
- // property declared as both a config and a member on the class so that
- // the config wins.
- else if (defaultConfig && (name in defaultConfig) && !target.config.hasOwnProperty(name)) {
- // This is a config property so it must be added to the configs
- // collection not just smashed on the prototype...
- (configs || (configs = {}))[name] = member;
-
- continue;
- }
- target[name] = member;
- }
- }
- if (configs) {
- // Add any configs found in the normal members arena:
- me.addConfig(configs);
- }
- if (enumerables) {
- for (i = 0 , ln = enumerables.length; i < ln; ++i) {
- if (members.hasOwnProperty(name = enumerables[i])) {
- member = members[name];
- // The enumerables are all functions...
- if (member && !member.$nullFn) {
- if (member.$owner) {
- member = cloneFunction(member);
- }
- member.$owner = me;
- member.$name = name;
- member.name = displayName + name;
- if (target.hasOwnProperty(name)) {
- member.$previous = target[name];
- }
- }
- target[name] = member;
- }
- }
- }
- return this;
- },
- /**
- * @private
- * @static
- * @inheritable
- * @param name
- * @param member
- * @param privacy
- */
- addMember: function(name, member, privacy) {
- oneMember[name] = member;
- this.addMembers(oneMember, false, privacy);
- delete oneMember[name];
- return this;
- },
- hookMember: function(name, member) {
- var existing = this.prototype[name];
- return this.addMember(name, member, existing && existing.$privacy);
- },
- /**
- * Borrow another class' members to the prototype of this class.
- *
- * Ext.define('Bank', {
- * money: '$$$',
- * printMoney: function() {
- * alert('$$$$$$$');
- * }
- * });
- *
- * Ext.define('Thief', {
- * ...
- * });
- *
- * Thief.borrow(Bank, ['money', 'printMoney']);
- *
- * var steve = new Thief();
- *
- * alert(steve.money); // alerts '$$$'
- * steve.printMoney(); // alerts '$$$$$$$'
- *
- * @param {Ext.Base} fromClass The class to borrow members from
- * @param {Array/String} members The names of the members to borrow
- * @return {Ext.Base} this
- * @static
- * @inheritable
- * @private
- */
- borrow: function(fromClass, members) {
- if (Ext.classSystemMonitor) {
- Ext.classSystemMonitor(this, 'Ext.Base#borrow', arguments);
- }
- /* eslint-disable-next-line vars-on-top */
- var prototype = fromClass.prototype,
- membersObj = {},
- i, ln, name;
- members = Ext.Array.from(members);
- for (i = 0 , ln = members.length; i < ln; i++) {
- name = members[i];
- membersObj[name] = prototype[name];
- }
- return this.addMembers(membersObj);
- },
- /**
- * Override members of this class. Overridden methods can be invoked via
- * {@link Ext.Base#method!callParent}.
- *
- * Ext.define('My.Cat', {
- * constructor: function() {
- * alert("I'm a cat!");
- * }
- * });
- *
- * My.Cat.override({
- * constructor: function() {
- * alert("I'm going to be a cat!");
- *
- * this.callParent(arguments);
- *
- * alert("Meeeeoooowwww");
- * }
- * });
- *
- * var kitty = new My.Cat(); // alerts "I'm going to be a cat!"
- * // alerts "I'm a cat!"
- * // alerts "Meeeeoooowwww"
- *
- * Direct use of this method should be rare. Use {@link Ext#define Ext.define}
- * instead:
- *
- * Ext.define('My.CatOverride', {
- * override: 'My.Cat',
- * constructor: function() {
- * alert("I'm going to be a cat!");
- *
- * this.callParent(arguments);
- *
- * alert("Meeeeoooowwww");
- * }
- * });
- *
- * The above accomplishes the same result but can be managed by the {@link Ext.Loader}
- * which can properly order the override and its target class and the build process
- * can determine whether the override is needed based on the required state of the
- * target class (My.Cat).
- *
- * @param {Object} members The properties to add to this class. This should be
- * specified as an object literal containing one or more properties.
- * @return {Ext.Base} this class
- * @static
- * @inheritable
- */
- override: function(members) {
- var me = this,
- statics = members.statics,
- inheritableStatics = members.inheritableStatics,
- config = members.config,
- mixins = members.mixins,
- cachedConfig = members.cachedConfig;
- if (statics || inheritableStatics || config) {
- members = Ext.apply({}, members);
- }
- if (statics) {
- me.addMembers(statics, true);
- delete members.statics;
- }
- if (inheritableStatics) {
- me.addInheritableStatics(inheritableStatics);
- delete members.inheritableStatics;
- }
- if (members.platformConfig) {
- me.addPlatformConfig(members);
- }
- if (config) {
- me.addConfig(config);
- delete members.config;
- }
- if (cachedConfig) {
- me.addCachedConfig(cachedConfig);
- delete members.cachedConfig;
- }
- delete members.mixins;
- me.addMembers(members);
- if (mixins) {
- me.mixin(mixins);
- }
- return me;
- },
- addPlatformConfig: function(data) {
- var me = this,
- prototype = me.prototype,
- platformConfigs = data.platformConfig,
- added, classConfigs, configs, configurator, keys, name, value, i, ln;
- delete prototype.platformConfig;
- if (platformConfigs instanceof Array) {
- throw new Error('platformConfigs must be specified as an object.');
- }
- configurator = me.getConfigurator();
- classConfigs = configurator.configs;
- // Get the keys shortest to longest (ish).
- keys = Ext.getPlatformConfigKeys(platformConfigs);
- // To leverage the Configurator#add method, we want to generate potentially
- // two objects to pass in: "added" and "hoisted". For any properties in an
- // active platformConfig rule that set proper Configs in the base class, we
- // need to put them in "added". If instead of the proper Config coming from
- // a base class, it comes from this class's config block, we still need to
- // put that config in "added" but we also need move the class-level config
- // out of "config" and into "hoisted".
- //
- // This will ensure that the config defined at the class level is added to
- // the Configurator first.
- for (i = 0 , ln = keys.length; i < ln; ++i) {
- configs = platformConfigs[keys[i]];
- added = null;
- for (name in configs) {
- value = configs[name];
- // We have a few possibilities for each config name:
- if (name in classConfigs) {
- // It is a proper Config defined by a base class.
- (added || (added = {}))[name] = value;
- } else {
- // It is just a property to put on the prototype.
- prototype[name] = value;
- }
- }
- if (added) {
- configurator.add(added);
- }
- }
- },
- /**
- * @protected
- * @static
- * @inheritable
- */
- callParent: function(args) {
- var method;
- // This code is intentionally inlined for the least amount of debugger stepping
- return (method = this.callParent.caller) && (method.$previous || ((method = method.$owner ? method : method.caller) && method.$owner.superclass.self[method.$name])).apply(this, args || noArgs);
- },
- /**
- * @protected
- * @static
- * @inheritable
- */
- callSuper: function(args) {
- var method;
- // This code is intentionally inlined for the least amount of debugger stepping
- return (method = this.callSuper.caller) && ((method = method.$owner ? method : method.caller) && method.$owner.superclass.self[method.$name]).apply(this, args || noArgs);
- },
- /**
- * Used internally by the mixins pre-processor
- * @private
- * @static
- * @inheritable
- */
- mixin: function(name, mixinClass) {
- var me = this,
- mixin, prototype, key, statics, i, ln, mixinName, mixinValue, mixins, mixinStatics, staticName;
- if (typeof name !== 'string') {
- mixins = name;
- if (mixins instanceof Array) {
- for (i = 0 , ln = mixins.length; i < ln; i++) {
- mixin = mixins[i];
- me.mixin(mixin.prototype.mixinId || mixin.$className, mixin);
- }
- } else {
- // Not a string or array - process the object form:
- // mixins: {
- // foo: ...
- // }
- for (mixinName in mixins) {
- me.mixin(mixinName, mixins[mixinName]);
- }
- }
- return;
- }
- mixin = mixinClass.prototype;
- prototype = me.prototype;
- if (mixin.onClassMixedIn) {
- mixin.onClassMixedIn.call(mixinClass, me);
- }
- if (!prototype.hasOwnProperty('mixins')) {
- if ('mixins' in prototype) {
- prototype.mixins = Ext.Object.chain(prototype.mixins);
- } else {
- prototype.mixins = {};
- }
- }
- for (key in mixin) {
- mixinValue = mixin[key];
- if (key === 'mixins') {
- // if 2 superclasses (e.g. a base class and a mixin) of this class both
- // have a mixin with the same id, the first one wins, that is to say,
- // the first mixin's methods to be applied to the prototype will not
- // be overwritten by the second one. Since this is the case we also
- // want to make sure we use the first mixin's prototype as the mixin
- // reference, hence the "applyIf" below. A real world example of this
- // is Ext.Widget which mixes in Ext.mixin.Observable. Ext.Widget can
- // be mixed into subclasses of Ext.Component, which mixes in
- // Ext.util.Observable. In this example, since the first "observable"
- // mixin's methods win, we also want its reference to be preserved.
- Ext.applyIf(prototype.mixins, mixinValue);
- }
- /* eslint-disable-next-line max-len */
- else if (!(key === 'mixinId' || key === 'config' || key === '$inheritableStatics') && (prototype[key] === undefined)) {
- prototype[key] = mixinValue;
- }
- }
- // Mixin statics inheritance
- statics = mixin.$inheritableStatics;
- if (statics) {
- mixinStatics = {};
- for (staticName in statics) {
- if (!me.hasOwnProperty(staticName)) {
- mixinStatics[staticName] = mixinClass[staticName];
- }
- }
- me.addInheritableStatics(mixinStatics);
- }
- if ('config' in mixin) {
- me.addConfig(mixin.config, mixinClass);
- }
- prototype.mixins[name] = mixin;
- if (mixin.afterClassMixedIn) {
- mixin.afterClassMixedIn.call(mixinClass, me);
- }
- return me;
- },
- /**
- * Adds new config properties to this class. This is called for classes when they
- * are declared, then for any mixins that class may define and finally for any
- * overrides defined that target the class.
- *
- * @param {Object} config
- * @param {Ext.Class} [mixinClass] The mixin class if the configs are from a mixin.
- * @private
- * @static
- * @inheritable
- */
- addConfig: function(config, mixinClass) {
- var cfg = this.$config || this.getConfigurator();
- cfg.add(config, mixinClass);
- },
- addCachedConfig: function(config, isMixin) {
- var cached = {},
- key;
- for (key in config) {
- cached[key] = {
- cached: true,
- $value: config[key]
- };
- }
- this.addConfig(cached, isMixin);
- },
- /**
- * Returns the `Ext.Configurator` for this class.
- *
- * @return {Ext.Configurator}
- * @private
- * @static
- * @inheritable
- */
- getConfigurator: function() {
- // the Ext.Configurator ctor will set $config so micro-opt out fn call:
- return this.$config || new Ext.Configurator(this);
- },
- /**
- * Get the current class' name in string format.
- *
- * Ext.define('My.cool.Class', {
- * constructor: function() {
- * alert(this.self.getName()); // alerts 'My.cool.Class'
- * }
- * });
- *
- * My.cool.Class.getName(); // 'My.cool.Class'
- *
- * @return {String} className
- * @static
- * @inheritable
- */
- getName: function() {
- return Ext.getClassName(this);
- },
- /**
- * Create aliases for existing prototype methods. Example:
- *
- * Ext.define('My.cool.Class', {
- * method1: function() { ... },
- * method2: function() { ... }
- * });
- *
- * var test = new My.cool.Class();
- *
- * My.cool.Class.createAlias({
- * method3: 'method1',
- * method4: 'method2'
- * });
- *
- * test.method3(); // test.method1()
- *
- * My.cool.Class.createAlias('method5', 'method3');
- *
- * test.method5(); // test.method3() -> test.method1()
- *
- * @param {String/Object} alias The new method name, or an object to set multiple aliases.
- * See {@link Ext.Function#flexSetter flexSetter}
- * @param {String/Object} origin The original method name
- * @static
- * @inheritable
- * @method
- */
- createAlias: flexSetter(function(alias, origin) {
- aliasOneMember[alias] = function() {
- return this[origin].apply(this, arguments);
- };
- this.override(aliasOneMember);
- delete aliasOneMember[alias];
- })
- });
- // Capture the set of static members on Ext.Base that we want to copy to all
- // derived classes. This array is used by Ext.Class as well as the optimizer.
- for (baseStaticMember in Base) {
- if (Base.hasOwnProperty(baseStaticMember)) {
- baseStaticMembers.push(baseStaticMember);
- }
- }
- Base.$staticMembers = baseStaticMembers;
- Base.getConfigurator();
- // lazily create now so as not capture in $staticMembers
- Base.addMembers({
- /** @private */
- $className: 'Ext.Base',
- /**
- * @property {Object/Array} $configTransforms
- * A prototype-chained object storing transform method names and priorities stored
- * on the class prototype. On first instantiation, this object is converted into
- * an array that is sorted by priority and stored on the constructor.
- * @private
- */
- $configTransforms: {},
- /**
- * @property {Boolean} isInstance
- * This value is `true` and is used to identify plain objects from instances of
- * a defined class.
- * @protected
- * @readonly
- */
- isInstance: true,
- /**
- * @property {Boolean} $configPrefixed
- * The value `true` causes `config` values to be stored on instances using a
- * property name prefixed with an underscore ("_") character. A value of `false`
- * stores `config` values as properties using their exact name (no prefix).
- * @private
- * @since 5.0.0
- */
- $configPrefixed: true,
- /**
- * @property {Boolean} $configStrict
- * The value `true` instructs the `initConfig` method to only honor values for
- * properties declared in the `config` block of a class. When `false`, properties
- * that are not declared in a `config` block will be placed on the instance.
- * @private
- * @since 5.0.0
- */
- $configStrict: true,
- /**
- * @property {Boolean} isConfiguring
- * This property is set to `true` during the call to `initConfig`.
- * @protected
- * @readonly
- * @since 5.0.0
- */
- isConfiguring: false,
- /**
- * @property {Boolean} isFirstInstance
- * This property is set to `true` if this instance is the first of its class.
- * @protected
- * @readonly
- * @since 5.0.0
- */
- isFirstInstance: false,
- /**
- * @property {Boolean} destroyed
- * This property is set to `true` after the `destroy` method is called.
- */
- destroyed: false,
- /**
- * @property {Boolean/"async"} [clearPropertiesOnDestroy=true]
- * Setting this property to `false` will prevent nulling object references
- * on a Class instance after destruction. Setting this to `"async"` will delay
- * the clearing for approx 50ms.
- * @protected
- * @since 6.2.0
- */
- clearPropertiesOnDestroy: true,
- /**
- * @property {Boolean} [clearPrototypeOnDestroy=false]
- * Setting this property to `true` will result in setting the object's
- * prototype to `null` after the destruction sequence is fully completed.
- * After that, most attempts at calling methods on the object instance
- * will result in "method not defined" exception. This can be very helpful
- * with tracking down otherwise hard to find bugs like runaway Ajax requests,
- * timed functions not cleared on destruction, etc.
- *
- * Note that this option can only work in browsers that support `Object.setPrototypeOf`
- * method, and is only available in debugging mode.
- * @private
- * @since 6.2.0
- */
- clearPrototypeOnDestroy: false,
- /**
- * Get the reference to the class from which this object was instantiated. Note that unlike
- * {@link Ext.Base#self}, `this.statics()` is scope-independent and it always returns
- * the class from which it was called, regardless of what `this` points to during run-time
- *
- * Ext.define('My.Cat', {
- * statics: {
- * totalCreated: 0,
- * speciesName: 'Cat' // My.Cat.speciesName = 'Cat'
- * },
- *
- * constructor: function() {
- * var statics = this.statics();
- *
- * // always equals to 'Cat' no matter what 'this' refers to
- * // equivalent to: My.Cat.speciesName
- * alert(statics.speciesName);
- *
- *
- * alert(this.self.speciesName); // dependent on 'this'
- *
- * statics.totalCreated++;
- * },
- *
- * clone: function() {
- * var cloned = new this.self(); // dependent on 'this'
- *
- * // equivalent to: My.Cat.speciesName
- * cloned.groupName = this.statics().speciesName;
- *
- * return cloned;
- * }
- * });
- *
- *
- * Ext.define('My.SnowLeopard', {
- * extend: 'My.Cat',
- *
- * statics: {
- * speciesName: 'Snow Leopard' // My.SnowLeopard.speciesName = 'Snow Leopard'
- * },
- *
- * constructor: function() {
- * this.callParent();
- * }
- * });
- *
- * var cat = new My.Cat(); // alerts 'Cat', then alerts 'Cat'
- *
- * var snowLeopard = new My.SnowLeopard(); // alerts 'Cat', then alerts 'Snow Leopard'
- *
- * var clone = snowLeopard.clone();
- * alert(Ext.getClassName(clone)); // alerts 'My.SnowLeopard'
- * alert(clone.groupName); // alerts 'Cat'
- *
- * alert(My.Cat.totalCreated); // alerts 3
- *
- * @protected
- * @return {Ext.Class}
- */
- statics: function() {
- var method = this.statics.caller,
- self = this.self;
- if (!method) {
- return self;
- }
- return method.$owner;
- },
- /**
- * Call the "parent" method of the current method. That is the method previously
- * overridden by derivation or by an override (see {@link Ext#define}).
- *
- * Ext.define('My.Base', {
- * constructor: function(x) {
- * this.x = x;
- * },
- *
- * statics: {
- * method: function(x) {
- * return x;
- * }
- * }
- * });
- *
- * Ext.define('My.Derived', {
- * extend: 'My.Base',
- *
- * constructor: function() {
- * this.callParent([21]);
- * }
- * });
- *
- * var obj = new My.Derived();
- *
- * alert(obj.x); // alerts 21
- *
- * This can be used with an override as follows:
- *
- * Ext.define('My.DerivedOverride', {
- * override: 'My.Derived',
- *
- * constructor: function(x) {
- * this.callParent([x*2]); // calls original My.Derived constructor
- * }
- * });
- *
- * var obj = new My.Derived();
- *
- * alert(obj.x); // now alerts 42
- *
- * This also works with static and private methods.
- *
- * Ext.define('My.Derived2', {
- * extend: 'My.Base',
- *
- * // privates: {
- * statics: {
- * method: function(x) {
- * return this.callParent([x*2]); // calls My.Base.method
- * }
- * }
- * });
- *
- * alert(My.Base.method(10)); // alerts 10
- * alert(My.Derived2.method(10)); // alerts 20
- *
- * Lastly, it also works with overridden static methods.
- *
- * Ext.define('My.Derived2Override', {
- * override: 'My.Derived2',
- *
- * // privates: {
- * statics: {
- * method: function(x) {
- * return this.callParent([x*2]); // calls My.Derived2.method
- * }
- * }
- * });
- *
- * alert(My.Derived2.method(10); // now alerts 40
- *
- * To override a method and replace it and also call the superclass method, use
- * {@link #method-callSuper}. This is often done to patch a method to fix a bug.
- *
- * @protected
- * @param {Array/Arguments} args The arguments, either an array or the `arguments` object
- * from the current method, for example: `this.callParent(arguments)`
- * @return {Object} Returns the result of calling the parent method
- */
- callParent: function(args) {
- // NOTE: this code is deliberately as few expressions (and no function calls)
- // as possible so that a debugger can skip over this noise with the minimum number
- // of steps. Basically, just hit Step Into until you are where you really wanted
- // to be.
- var method,
- superMethod = (method = this.callParent.caller) && (method.$previous || ((method = method.$owner ? method : method.caller) && method.$owner.superclass[method.$name]));
- if (!superMethod) {
- method = this.callParent.caller;
- /* eslint-disable-next-line vars-on-top */
- var parentClass, methodName;
- if (!method.$owner) {
- if (!method.caller) {
- throw new Error("Attempting to call a protected method from the " + "public scope, which is not allowed");
- }
- method = method.caller;
- }
- parentClass = method.$owner.superclass;
- methodName = method.$name;
- if (!(methodName in parentClass)) {
- throw new Error("this.callParent() was called but there's no such method (" + methodName + ") found in the parent class (" + (Ext.getClassName(parentClass) || 'Object') + ")");
- }
- }
- return superMethod.apply(this, args || noArgs);
- },
- /**
- * This method is used by an **override** to call the superclass method but
- * bypass any overridden method. This is often done to "patch" a method that
- * contains a bug but for whatever reason cannot be fixed directly.
- *
- * Consider:
- *
- * Ext.define('Ext.some.Class', {
- * method: function() {
- * console.log('Good');
- * }
- * });
- *
- * Ext.define('Ext.some.DerivedClass', {
- * extend: 'Ext.some.Class',
- *
- * method: function() {
- * console.log('Bad');
- *
- * // ... logic but with a bug ...
- *
- * this.callParent();
- * }
- * });
- *
- * To patch the bug in `Ext.some.DerivedClass.method`, the typical solution is to create an
- * override:
- *
- * Ext.define('App.patches.DerivedClass', {
- * override: 'Ext.some.DerivedClass',
- *
- * method: function() {
- * console.log('Fixed');
- *
- * // ... logic but with bug fixed ...
- *
- * this.callSuper();
- * }
- * });
- *
- * The patch method cannot use {@link #method-callParent} to call the superclass
- * `method` since that would call the overridden method containing the bug. In
- * other words, the above patch would only produce "Fixed" then "Good" in the
- * console log, whereas, using `callParent` would produce "Fixed" then "Bad"
- * then "Good".
- *
- * @protected
- * @param {Array/Arguments} args The arguments, either an array or the `arguments` object
- * from the current method, for example: `this.callSuper(arguments)`
- * @return {Object} Returns the result of calling the superclass method
- */
- callSuper: function(args) {
- // NOTE: this code is deliberately as few expressions (and no function calls)
- // as possible so that a debugger can skip over this noise with the minimum number
- // of steps. Basically, just hit Step Into until you are where you really wanted
- // to be.
- var method,
- superMethod = (method = this.callSuper.caller) && ((method = method.$owner ? method : method.caller) && method.$owner.superclass[method.$name]);
- if (!superMethod) {
- method = this.callSuper.caller;
- /* eslint-disable-next-line vars-on-top */
- var parentClass, methodName;
- if (!method.$owner) {
- if (!method.caller) {
- throw new Error("Attempting to call a protected method from the " + "public scope, which is not allowed");
- }
- method = method.caller;
- }
- parentClass = method.$owner.superclass;
- methodName = method.$name;
- if (!(methodName in parentClass)) {
- throw new Error("this.callSuper() was called but there's no such method (" + methodName + ") found in the parent class (" + (Ext.getClassName(parentClass) || 'Object') + ")");
- }
- }
- return superMethod.apply(this, args || noArgs);
- },
- /**
- * @property {Ext.Class} self
- *
- * Get the reference to the current class from which this object was instantiated. Unlike
- * {@link Ext.Base#statics}, `this.self` is scope-dependent and it's meant to be used
- * for dynamic inheritance. See {@link Ext.Base#statics} for a detailed comparison
- *
- * Ext.define('My.Cat', {
- * statics: {
- * speciesName: 'Cat' // My.Cat.speciesName = 'Cat'
- * },
- *
- * constructor: function() {
- * alert(this.self.speciesName); // dependent on 'this'
- * },
- *
- * clone: function() {
- * return new this.self();
- * }
- * });
- *
- *
- * Ext.define('My.SnowLeopard', {
- * extend: 'My.Cat',
- * statics: {
- * speciesName: 'Snow Leopard' // My.SnowLeopard.speciesName = 'Snow Leopard'
- * }
- * });
- *
- * var cat = new My.Cat(); // alerts 'Cat'
- * var snowLeopard = new My.SnowLeopard(); // alerts 'Snow Leopard'
- *
- * var clone = snowLeopard.clone();
- * alert(Ext.getClassName(clone)); // alerts 'My.SnowLeopard'
- *
- * @protected
- */
- self: Base,
- // Default constructor, simply returns `this`
- constructor: function() {
- return this;
- },
- /**
- * Initialize configuration for this class. a typical example:
- *
- * Ext.define('My.awesome.Class', {
- * // The default config
- * config: {
- * name: 'Awesome',
- * isAwesome: true
- * },
- *
- * constructor: function(config) {
- * this.initConfig(config);
- * }
- * });
- *
- * var awesome = new My.awesome.Class({
- * name: 'Super Awesome'
- * });
- *
- * alert(awesome.getName()); // 'Super Awesome'
- *
- * @protected
- * @param {Object} instanceConfig
- * @return {Ext.Base} this
- * @chainable
- */
- initConfig: function(instanceConfig) {
- var me = this,
- cfg = me.self.getConfigurator();
- me.initConfig = Ext.emptyFn;
- // ignore subsequent calls to initConfig
- me.initialConfig = instanceConfig || {};
- cfg.configure(me, instanceConfig);
- return me;
- },
- beforeInitConfig: Ext.emptyFn,
- /**
- * Returns a specified config property value. If the name parameter is not passed,
- * all current configuration options will be returned as key value pairs.
- * @param {String} [name] The name of the config property to get.
- * @param {Boolean} [peek=false] `true` to peek at the raw value without calling the getter.
- * @param {Boolean} [ifInitialized=false] `true` to only return the initialized property
- * value, not the raw config value, and *not* to trigger initialization. Returns
- * `undefined` if the property has not yet been initialized.
- * @return {Object} The config property value.
- */
- getConfig: function(name, peek, ifInitialized) {
- var me = this,
- ret, cfg, propName;
- if (name) {
- cfg = me.self.$config.configs[name];
- if (cfg) {
- propName = me.$configPrefixed ? cfg.names.internal : name;
- // They only want the fully initialized value, not the initial config,
- // but only if it's already present on this instance.
- // They don't want to trigger the initGetter.
- // This form is used by Bindable#updatePublishes to initially publish
- // the properties it's being asked make publishable.
- if (ifInitialized) {
- ret = me.hasOwnProperty(propName) ? me[propName] : null;
- } else if (peek) {
- // Attempt to return the instantiated property on this instance first.
- // Only return the config object if it has not yet been pulled through
- // the applier into the instance.
- ret = me.hasOwnProperty(propName) ? me[propName] : me.config[name];
- } else {
- ret = me[cfg.names.get]();
- }
- } else {
- ret = me[name];
- }
- } else {
- ret = me.getCurrentConfig();
- }
- return ret;
- },
- /**
- * Destroys member properties by name.
- *
- * If a property name is the name of a *config*, the getter is *not* invoked, so
- * if the config has not been initialized, nothing will be done.
- *
- * The property will be destroyed, and the corrected name (if the property is a *config*
- * and config names are prefixed) will set to `null` in this object's dictionary.
- *
- * @param {String...} args One or more names of the properties to destroy and remove from
- * the object.
- */
- destroyMembers: function() {
- var me = this,
- configs = me.self.$config.configs,
- len = arguments.length,
- cfg, name, value, i;
- for (i = 0; i < len; i++) {
- name = arguments[i];
- cfg = configs[name];
- name = cfg && me.$configPrefixed ? cfg.names.internal : name;
- value = me.hasOwnProperty(name) && me[name];
- if (value) {
- Ext.destroy(value);
- me[name] = null;
- }
- }
- },
- freezeConfig: function(name) {
- var me = this,
- config = Ext.Config.get(name),
- names = config.names,
- value = me[names.get]();
- me[names.set] = function(v) {
- if (v !== value) {
- Ext.raise('Cannot change frozen config "' + name + '"');
- }
- return me;
- };
- if (!Ext.isIE8) {
- Object.defineProperty(me, me.$configPrefixed ? names.internal : name, {
- get: function() {
- return value;
- },
- set: function(v) {
- if (v !== value) {
- Ext.raise('Cannot change frozen config "' + name + '"');
- }
- }
- });
- }
- },
- /**
- * Sets a single/multiple configuration options.
- * @param {String/Object} name The name of the property to set, or a set of key value
- * pairs to set.
- * @param {Object} [value] The value to set for the name parameter.
- * @param {Object} [options] (private)
- * @return {Ext.Base} this
- */
- setConfig: function(name, value, options) {
- // options can have the following properties:
- // - defaults `true` to only set the config(s) that have not been already set on
- // this instance.
- // - strict `false` to apply properties to the instance that are not configs,
- // and do not have setters.
- var me = this,
- configurator, config, prop;
- if (name) {
- configurator = me.self.getConfigurator();
- if (typeof name === 'string') {
- config = configurator.configs[name];
- if (!config) {
- if (me.$configStrict) {
- prop = me.self.prototype[name];
- if ((typeof prop === 'function') && !prop.$nullFn) {
- Ext.Error.raise("Cannot override method " + name + " on " + me.$className + " instance.");
- return me;
- } else {
- if (name !== 'type') {
- Ext.log.warn('No such config "' + name + '" for class ' + me.$className);
- }
- }
- }
- config = Ext.Config.map[name] || Ext.Config.get(name);
- }
- if (me[config.names.set]) {
- me[config.names.set](value);
- } else {
- // apply non-config props directly to the instance
- me[name] = value;
- }
- } else {
- // This should not have "options ||" except that it shipped in that
- // broken state, so we use it if present for compat.
- configurator.reconfigure(me, name, options || value);
- }
- }
- return me;
- },
- getConfigWatcher: function() {
- return this.$configWatch || (this.$configWatch = new Ext.mixin.Watchable());
- },
- /**
- * Watches config properties.
- *
- * instance.watchConfig({
- * title: 'onTitleChange',
- * scope: me
- * });
- *
- * @private
- * @since 6.7.0
- */
- watchConfig: function(name, fn, scope) {
- var watcher = this.getConfigWatcher();
- return watcher.on.apply(watcher, arguments);
- },
- $configWatch: null,
- /**
- * @private
- */
- getCurrentConfig: function() {
- var cfg = this.self.getConfigurator();
- return cfg.getCurrentConfig(this);
- },
- /**
- * @param {String} name
- * @private
- */
- hasConfig: function(name) {
- return name in this.defaultConfig;
- },
- /**
- * Returns the initial configuration passed to the constructor when
- * instantiating this class.
- *
- * Given this example Ext.button.Button definition and instance:
- *
- * Ext.define('MyApp.view.Button', {
- * extend: 'Ext.button.Button',
- * xtype: 'mybutton',
- *
- * scale: 'large',
- * enableToggle: true
- * });
- *
- * var btn = Ext.create({
- * xtype: 'mybutton',
- * renderTo: Ext.getBody(),
- * text: 'Test Button'
- * });
- *
- * Calling `btn.getInitialConfig()` would return an object including the config
- * options passed to the `create` method:
- *
- * xtype: 'mybutton',
- * renderTo: // The document body itself
- * text: 'Test Button'
- *
- * Calling `btn.getInitialConfig('text')`returns **'Test Button'**.
- *
- * @param {String} [name] Name of the config option to return.
- * @return {Object/Mixed} The full config object or a single config value
- * when `name` parameter specified.
- */
- getInitialConfig: function(name) {
- var config = this.config;
- if (!name) {
- return config;
- }
- return config[name];
- },
- $links: null,
- /**
- * Adds a "destroyable" object to an internal list of objects that will be destroyed
- * when this instance is destroyed (via `{@link #method!destroy}`).
- * @param {String} name
- * @param {Object} value
- * @return {Object} The `value` passed.
- * @private
- */
- link: function(name, value) {
- var me = this,
- links = me.$links || (me.$links = {});
- links[name] = true;
- me[name] = value;
- return value;
- },
- /**
- * Destroys a given set of `{@link #link linked}` objects. This is only needed if
- * the linked object is being destroyed before this instance.
- * @param {String[]} names The names of the linked objects to destroy.
- * @return {Ext.Base} this
- * @private
- */
- unlink: function(names) {
- var me = this,
- i, ln, link, value;
- if (!Ext.isArray(names)) {
- Ext.raise('Invalid argument - expected array of strings');
- }
- for (i = 0 , ln = names.length; i < ln; i++) {
- link = names[i];
- value = me[link];
- if (value) {
- if (value.isInstance && !value.destroyed) {
- value.destroy();
- } else if (value.parentNode && 'nodeType' in value) {
- value.parentNode.removeChild(value);
- }
- }
- me[link] = null;
- }
- return me;
- },
- $reap: function() {
- var me = this,
- keepers = me.$noClearOnDestroy,
- props, prop, val, t, i, len;
- // This only returns own keys which is *much* faster than iterating
- // over the whole prototype chain and calling hasOwnProperty()
- props = Ext.Object.getKeys(me);
- for (i = 0 , len = props.length; i < len; i++) {
- prop = props[i];
- val = me[prop];
- // typeof null === 'object' :(
- if (val && !(keepers && keepers[prop])) {
- t = typeof val;
- // Object may retain references to other objects. Functions can do too
- // if they are closures, and most of the *own* function properties
- // are closures indeed. We skip Ext.emptyFn and the like though,
- // they're mostly harmless.
- if (t === 'object' || (t === 'function' && !val.$noClearOnDestroy)) {
- me[prop] = null;
- }
- }
- }
- me.$nulled = true;
- // We also want to make sure no methods are called on the destroyed object,
- // because that may lead to accessing nulled properties and resulting exceptions.
- if (Object.setPrototypeOf) {
- if (me.clearPrototypeOnDestroy && !me.$vetoClearingPrototypeOnDestroy) {
- props = me.$preservePrototypeProperties;
- if (props) {
- for (i = 0 , len = props.length; i < len; i++) {
- prop = props[i];
- if (!me.hasOwnProperty(prop)) {
- /* eslint-disable-next-line no-self-assign */
- me[prop] = me[prop];
- }
- }
- }
- Object.setPrototypeOf(me, null);
- }
- }
- },
- /**
- * This method is called to cleanup an object and its resources. After calling
- * this method, the object should not be used any further in any way, including
- * access to its methods and properties.
- *
- * To prevent potential memory leaks, all object references will be nulled
- * at the end of destruction sequence, unless {@link #clearPropertiesOnDestroy}
- * is set to `false`.
- */
- destroy: function() {
- var me = this,
- links = me.$links,
- clearPropertiesOnDestroy = me.clearPropertiesOnDestroy;
- if (links) {
- me.$links = null;
- me.unlink(Ext.Object.getKeys(links));
- }
- me.destroy = Ext.emptyFn;
- // isDestroyed added for compat reasons
- me.isDestroyed = me.destroyed = true;
- // By this time the destruction is complete. Now we can make sure
- // no objects are retained by the husk of this ex-Instance.
- if (clearPropertiesOnDestroy === true) {
- // Observable mixin will call destroyObservable that will reap the properties.
- if (!me.isObservable) {
- me.$reap();
- }
- } else if (clearPropertiesOnDestroy) {
- if (clearPropertiesOnDestroy !== 'async') {
- Ext.raise('Invalid value for clearPropertiesOnDestroy');
- }
- Reaper.add(me);
- }
- }
- });
- /**
- * @method callOverridden
- * Call the original method that was previously overridden with {@link Ext.Base#override}
- *
- * Ext.define('My.Cat', {
- * constructor: function() {
- * alert("I'm a cat!");
- * }
- * });
- *
- * My.Cat.override({
- * constructor: function() {
- * alert("I'm going to be a cat!");
- *
- * this.callOverridden();
- *
- * alert("Meeeeoooowwww");
- * }
- * });
- *
- * var kitty = new My.Cat(); // alerts "I'm going to be a cat!"
- * // alerts "I'm a cat!"
- * // alerts "Meeeeoooowwww"
- *
- * @param {Array/Arguments} args The arguments, either an array or the `arguments` object
- * from the current method, for example: `this.callOverridden(arguments)`
- * @return {Object} Returns the result of calling the overridden method
- * @deprecated 4.1.0 Use {@link #method-callParent} instead.
- * @protected
- */
- BasePrototype.callOverridden = BasePrototype.callParent;
- Ext.privacyViolation = function(cls, existing, member, isStatic) {
- var name = member.$name,
- conflictCls = existing.$owner && existing.$owner.$className,
- s = isStatic ? 'static ' : '',
- msg = member.$privacy ? 'Private ' + s + member.$privacy + ' method "' + name + '"' : 'Public ' + s + 'method "' + name + '"';
- if (cls.$className) {
- msg = cls.$className + ': ' + msg;
- }
- if (!existing.$privacy) {
- msg += conflictCls ? ' hides public method inherited from ' + conflictCls : ' hides inherited public method.';
- } else {
- msg += conflictCls ? ' conflicts with private ' + existing.$privacy + ' method declared by ' + conflictCls : ' conflicts with inherited private ' + existing.$privacy + ' method.';
- }
- /* eslint-disable-next-line vars-on-top */
- var compat = Ext.getCompatVersion(),
- ver = Ext.getVersion();
- // When compatibility is enabled, log problems instead of throwing errors.
- if (ver && compat && compat.lt(ver)) {
- Ext.log.error(msg);
- } else {
- Ext.raise(msg);
- }
- };
- Ext.Reaper.tick.$skipTimerCheck = true;
- return Base;
- }(Ext.Function.flexSetter));
- /**
- * This class manages a double-linked list. It provides an absolutely minimal container
- * interface.
- *
- * @class Ext.util.LRU
- * @private
- * @since 6.5.0
- */
- /* eslint-disable indent */
- (function(LRU, prototype) {
- // @define Ext.util.LRU
- // NOTE: We have to implement this class old-school because it is used by the
- // platformConfig class processor (so Ext.define is not yet ready for action).
- (Ext.util || (Ext.util = {})).LRU = LRU = function(config) {
- var me = this,
- head;
- if (config) {
- Ext.apply(me, config);
- }
- // Give all entries the same object shape.
- me.head = head = {
- id: (me.seed = 0),
- key: null,
- value: null
- };
- /**
- * @property {Object} map
- * The items in the list indexed by their `key`.
- * @readonly
- */
- me.map = {};
- head.next = head.prev = head;
- };
- LRU.prototype = prototype = {
- /**
- * @property {Number} count
- * The number of items in this list.
- * @readonly
- */
- count: 0,
- /**
- * Adds an item to the list with the specified `key`. Items are added at the
- * front (MRU) of the list.
- * @param {String} key
- * @param {Object} value
- */
- add: function(key, value) {
- var me = this,
- map = me.map,
- entry = map[key];
- if (entry) {
- me.unlink(entry);
- --me.count;
- }
- map[key] = entry = {
- id: ++me.seed,
- key: key,
- value: value
- };
- me.link(entry);
- ++me.count;
- return entry;
- },
- /**
- * Removes all items from this list optionally calling a function for each
- * remove item.
- * @param {Function} [fn] A function to call for each removed item.
- * @param {Object} fn.key The key of the removed item.
- * @param {Object} fn.value The removed item.
- * @param {Object} [scope] The `this` pointer for `fn`.
- */
- clear: function(fn, scope) {
- var me = this,
- head = me.head,
- entry = head.next;
- head.next = head.prev = head;
- me.count = 0;
- if (fn && !fn.$nullFn) {
- for (; entry !== head; entry = entry.next) {
- fn.call(scope || me, entry.key, entry.value);
- }
- }
- },
- /**
- * Calls the given function `fn` for each item in the list. The items will be
- * passed to `fn` from most-to-least recently added or touched.
- * @param {Function} fn The function to call for each cache item.
- * @param {String} fn.key The key for the item.
- * @param {Object} fn.value The item.
- * @param {Object} [scope] The `this` pointer to use for `fn`.
- */
- each: function(fn, scope) {
- var head, ent;
- scope = scope || this;
- for (head = this.head , ent = head.next; ent !== head; ent = ent.next) {
- if (fn.call(scope, ent.key, ent.value)) {
- break;
- }
- }
- },
- /**
- * Removes the item at the end (LRU) of the list. Optionally the item can be passed
- * to a callback function. If the list is empty, no callback is made and this
- * method will return `undefined`.
- * @param {Function} fn The function to call for the removed item.
- * @param {Object} fn.key The key of the removed item.
- * @param {Object} fn.value The removed item.
- * @param {Object} [scope] The `this` pointer to use for `fn`.
- * @return {Object} The removed item.
- */
- prune: function(fn, scope) {
- var me = this,
- entry = me.head.prev,
- ret;
- if (me.count) {
- ret = entry.value;
- me.unlink(entry);
- --me.count;
- if (fn) {
- fn.call(scope || me, entry.key, ret);
- }
- }
- return ret;
- },
- /**
- * Removes an item from the list given its key.
- * @param {String} key The key of the item to remove.
- * @return {Object} The removed item or `undefined` if the key was not found.
- */
- remove: function(key) {
- var me = this,
- map = me.map,
- entry = map[key],
- value;
- if (entry) {
- me.unlink(entry);
- value = entry.value;
- delete map[key];
- --me.count;
- }
- return value;
- },
- /**
- * Moves the item with the given key to the front (MRU) of the list.
- * @param {String} key The key of the item to move to the front.
- */
- touch: function(key) {
- var me = this,
- head = me.head,
- entry = me.map[key];
- if (entry && entry.prev !== head) {
- // The entry is not at the front, so remove it and insert it at the front
- // (to make it the MRU - Most Recently Used).
- me.unlink(entry);
- me.link(entry);
- }
- },
- /**
- * Reduces the length of the list to be no more than the specified `size`, removing
- * items from the end of the list as necessary. Optionally each removed item can
- * be passed to a callback `fn`.
- * @param {Number} size The number of items in the list
- * @param {Function} [fn] A function to call for each removed item.
- * @param {Object} fn.key The key of the removed item.
- * @param {Object} fn.value The removed item.
- * @param {Object} [scope] The `this` pointer for `fn`.
- */
- trim: function(size, fn, scope) {
- while (this.count > size) {
- this.prune(fn, scope);
- }
- },
- //-------------------------------------------------------------------------
- // Internals
- /**
- * Inserts the given entry at the front (MRU) end of the entry list.
- * @param {Object} entry The cache item entry.
- * @private
- */
- link: function(entry) {
- var head = this.head,
- first = head.next;
- entry.next = first;
- entry.prev = head;
- head.next = entry;
- first.prev = entry;
- },
- /**
- * Removes the given entry from the entry list.
- * @param {Object} entry The cache item entry.
- * @private
- */
- unlink: function(entry) {
- var next = entry.next,
- prev = entry.prev;
- prev.next = next;
- next.prev = prev;
- }
- };
- prototype.destroy = function() {
- this.clear.apply(this, arguments);
- };
- }());
- /**
- * This class is used to manage simple, LRU caches. It provides an absolutely minimal
- * container interface. It is created like this:
- *
- * this.itemCache = new Ext.util.Cache({
- * miss: function (key) {
- * return new CacheItem(key);
- * }
- * });
- *
- * The `{@link #miss}` abstract method must be implemented by either a derived class or
- * at the instance level as shown above.
- *
- * Once the cache exists and it can handle cache misses, the cache is used like so:
- *
- * var item = this.itemCache.get(key);
- *
- * The `key` is some value that uniquely identifies the cached item.
- *
- * In some cases, creating the cache item may require more than just the lookup key. In
- * that case, any extra arguments passed to `get` will be passed to `miss`.
- *
- * this.otherCache = new Ext.util.Cache({
- * miss: function (key, extra) {
- * return new CacheItem(key, extra);
- * }
- * });
- *
- * var item = this.otherCache.get(key, extra);
- *
- * To process items as they are removed, you can provide an `{@link #evict}` method. The
- * stock method is `Ext.emptyFn` and so does nothing.
- *
- * For example:
- *
- * this.itemCache = new Ext.util.Cache({
- * miss: function (key) {
- * return new CacheItem(key);
- * },
- *
- * evict: function (key, cacheItem) {
- * cacheItem.destroy();
- * }
- * });
- *
- * @class Ext.util.Cache
- * @private
- * @since 5.1.0
- */
- /* eslint-disable indent */
- (function(LRU, fn, Cache) {
- // @require Ext.util.LRU
- // @define Ext.util.Cache
- // NOTE: We have to implement this class old-school because it is used by the
- // platformConfig class processor (so Ext.define is not yet ready for action).
- Ext.util.Cache = Cache = function(config) {
- LRU.call(this, config);
- };
- fn.prototype = LRU.prototype;
- Cache.prototype = Ext.apply(new fn(), {
- /**
- * @cfg {Number} maxSize The maximum size the cache is allowed to grow to before
- * further additions cause removal of the least recently used entry.
- */
- maxSize: 100,
- /**
- * This method is called by `{@link #get}` when the key is not found in the cache.
- * The implementation of this method should create the (expensive) value and return
- * it. Whatever arguments were passed to `{@link #get}` will be passed on to this
- * method.
- *
- * @param {String} key The cache lookup key for the item.
- * @param {Object...} args Any other arguments originally passed to `{@link #get}`.
- * @method miss
- * @abstract
- * @protected
- */
- /**
- * Removes all items from this cache.
- */
- clear: function() {
- LRU.prototype.clear.call(this, this.evict);
- },
- /**
- * Finds an item in this cache and returns its value. If the item is present, it is
- * shuffled into the MRU (most-recently-used) position as necessary. If the item is
- * missing, the `{@link #miss}` method is called to create the item.
- *
- * @param {String} key The cache key of the item.
- * @param {Object...} args Arguments for the `miss` method should it be needed.
- * @return {Object} The cached object.
- */
- get: function(key) {
- var me = this,
- entry = me.map[key],
- value;
- if (entry) {
- value = entry.value;
- me.touch(key);
- } else {
- value = me.miss.apply(me, arguments);
- me.add(key, value);
- me.trim(me.maxSize, me.evict);
- }
- return value;
- },
- //-------------------------------------------------------------------------
- // Internals
- /**
- * This method is called internally from `{@link #get}` when the cache is full and
- * the least-recently-used (LRU) item has been removed.
- *
- * @param {String} key The cache lookup key for the item being removed.
- * @param {Object} value The cache value (returned by `{@link #miss}`) for the item
- * being removed.
- * @method evict
- * @template
- * @protected
- */
- evict: Ext.emptyFn
- });
- }(Ext.util.LRU, function() {}));
- /**
- * @class Ext.Class
- *
- * This is a low level factory that is used by {@link Ext#define Ext.define} and should not be used
- * directly in application code.
- *
- * The configs of this class are intended to be used in `Ext.define` calls to describe the class you
- * are declaring. For example:
- *
- * Ext.define('App.util.Thing', {
- * extend: 'App.util.Other',
- *
- * alias: 'util.thing',
- *
- * config: {
- * foo: 42
- * }
- * });
- *
- * Ext.Class is the factory and **not** the superclass of everything. For the base class
- * that **all** classes inherit from, see {@link Ext.Base}.
- */
- /* eslint-disable indent */
- (function() {
- // @tag class
- // @define Ext.Class
- // @require Ext.Base
- // @require Ext.Util
- // @require Ext.util.Cache
- var ExtClass,
- Base = Ext.Base,
- baseStaticMembers = Base.$staticMembers,
- ruleKeySortFn = function(a, b) {
- // longest to shortest, by text if names are equal
- return (a.length - b.length) || ((a < b) ? -1 : ((a > b) ? 1 : 0));
- };
- // Creates a constructor that has nothing extra in its scope chain.
- function makeCtor(className) {
- function constructor() {
- // Opera has some problems returning from a constructor when Dragonfly isn't running.
- // The || null seems to be sufficient to stop it misbehaving. Known to be required
- // against 10.53, 11.51 and 11.61.
- return this.constructor.apply(this, arguments) || null;
- }
- if (className) {
- constructor.name = className;
- }
- return constructor;
- }
- /**
- * @method constructor
- * Create a new anonymous class.
- *
- * @param Class
- * @param {Object} data An object represent the properties of this class
- * @param {Function} onCreated Optional, the callback function to be executed when this class
- * is fully created. Note that the creation process can be asynchronous depending
- * on the pre-processors used.
- *
- * @return {Ext.Base} The newly created class
- */
- Ext.Class = ExtClass = function(Class, data, onCreated) {
- if (typeof Class !== 'function') {
- onCreated = data;
- data = Class;
- Class = null;
- }
- if (!data) {
- data = {};
- }
- Class = ExtClass.create(Class, data);
- ExtClass.process(Class, data, onCreated);
- return Class;
- };
- Ext.apply(ExtClass, {
- makeCtor: makeCtor,
- /**
- * @private
- */
- onBeforeCreated: function(Class, data, hooks) {
- if (Ext.classSystemMonitor) {
- Ext.classSystemMonitor(Class, '>> Ext.Class#onBeforeCreated', arguments);
- }
- Class.addMembers(data);
- hooks.onCreated.call(Class, Class);
- if (Ext.classSystemMonitor) {
- Ext.classSystemMonitor(Class, '<< Ext.Class#onBeforeCreated', arguments);
- }
- },
- /**
- * @private
- */
- create: function(Class, data) {
- var i = baseStaticMembers.length,
- name;
- if (!Class) {
- Class = makeCtor(data.$className);
- }
- while (i--) {
- name = baseStaticMembers[i];
- Class[name] = Base[name];
- }
- return Class;
- },
- /**
- * @private
- */
- process: function(Class, data, onCreated) {
- var preprocessorStack = data.preprocessors || ExtClass.defaultPreprocessors,
- registeredPreprocessors = this.preprocessors,
- hooks = {
- onBeforeCreated: this.onBeforeCreated
- },
- preprocessors = [],
- preprocessor, preprocessorsProperties, i, ln, j, subLn, preprocessorProperty;
- delete data.preprocessors;
- Class._classHooks = hooks;
- for (i = 0 , ln = preprocessorStack.length; i < ln; i++) {
- preprocessor = preprocessorStack[i];
- if (typeof preprocessor === 'string') {
- preprocessor = registeredPreprocessors[preprocessor];
- preprocessorsProperties = preprocessor.properties;
- if (preprocessorsProperties === true) {
- preprocessors.push(preprocessor.fn);
- } else if (preprocessorsProperties) {
- for (j = 0 , subLn = preprocessorsProperties.length; j < subLn; j++) {
- preprocessorProperty = preprocessorsProperties[j];
- if (data.hasOwnProperty(preprocessorProperty)) {
- preprocessors.push(preprocessor.fn);
- break;
- }
- }
- }
- } else {
- preprocessors.push(preprocessor);
- }
- }
- hooks.onCreated = onCreated ? onCreated : Ext.emptyFn;
- hooks.preprocessors = preprocessors;
- this.doProcess(Class, data, hooks);
- },
- doProcess: function(Class, data, hooks) {
- var me = this,
- preprocessors = hooks.preprocessors,
- preprocessor = preprocessors.shift(),
- doProcess = me.doProcess;
- for (; preprocessor; preprocessor = preprocessors.shift()) {
- // Returning false signifies an asynchronous preprocessor - it will call doProcess
- // when we can continue
- if (preprocessor.call(me, Class, data, hooks, doProcess) === false) {
- return;
- }
- }
- hooks.onBeforeCreated.apply(me, arguments);
- },
- /**
- * @private
- * */
- preprocessors: {},
- /**
- * Register a new pre-processor to be used during the class creation process
- *
- * @param {String} name The pre-processor's name
- * @param {Function} fn The callback function to be executed. Typical format:
- *
- * function(cls, data, fn) {
- * // Your code here
- *
- * // Execute this when the processing is finished.
- * // Asynchronous processing is perfectly ok
- * if (fn) {
- * fn.call(this, cls, data);
- * }
- * });
- *
- * @param {Function} fn.cls The created class
- * @param {Object} fn.data The set of properties passed in {@link Ext.Class} constructor
- * @param {Function} fn.fn The callback function that **must** to be executed when this
- * pre-processor finishes, regardless of whether the processing is synchronous or
- * asynchronous.
- * @param properties
- * @param position
- * @param relativeTo
- * @return {Ext.Class} this
- * @private
- * @static
- */
- registerPreprocessor: function(name, fn, properties, position, relativeTo) {
- if (!position) {
- position = 'last';
- }
- if (!properties) {
- properties = [
- name
- ];
- }
- this.preprocessors[name] = {
- name: name,
- properties: properties || false,
- fn: fn
- };
- this.setDefaultPreprocessorPosition(name, position, relativeTo);
- return this;
- },
- /**
- * Retrieve a pre-processor callback function by its name, which has been registered before
- *
- * @param {String} name
- * @return {Function} preprocessor
- * @private
- * @static
- */
- getPreprocessor: function(name) {
- return this.preprocessors[name];
- },
- /**
- * @private
- */
- getPreprocessors: function() {
- return this.preprocessors;
- },
- /**
- * @private
- */
- defaultPreprocessors: [],
- /**
- * Retrieve the array stack of default pre-processors
- * @return {Function[]} defaultPreprocessors
- * @private
- * @static
- */
- getDefaultPreprocessors: function() {
- return this.defaultPreprocessors;
- },
- /**
- * Set the default array stack of default pre-processors
- *
- * @private
- * @param {Array} preprocessors
- * @return {Ext.Class} this
- * @static
- */
- setDefaultPreprocessors: function(preprocessors) {
- this.defaultPreprocessors = Ext.Array.from(preprocessors);
- return this;
- },
- /**
- * Insert this pre-processor at a specific position in the stack, optionally relative to
- * any existing pre-processor. For example:
- *
- * Ext.Class.registerPreprocessor('debug', function(cls, data, fn) {
- * // Your code here
- *
- * if (fn) {
- * fn.call(this, cls, data);
- * }
- * }).setDefaultPreprocessorPosition('debug', 'last');
- *
- * @private
- * @param {String} name The pre-processor name. Note that it needs to be registered with
- * {@link Ext.Class#registerPreprocessor registerPreprocessor} before this
- * @param {String} offset The insertion position. Four possible values are:
- * 'first', 'last', or: 'before', 'after' (relative to the name provided in the third
- * argument)
- * @param {String} relativeName
- * @return {Ext.Class} this
- * @static
- */
- setDefaultPreprocessorPosition: function(name, offset, relativeName) {
- var defaultPreprocessors = this.defaultPreprocessors,
- index;
- if (typeof offset === 'string') {
- if (offset === 'first') {
- defaultPreprocessors.unshift(name);
- return this;
- } else if (offset === 'last') {
- defaultPreprocessors.push(name);
- return this;
- }
- offset = (offset === 'after') ? 1 : -1;
- }
- index = Ext.Array.indexOf(defaultPreprocessors, relativeName);
- if (index !== -1) {
- Ext.Array.splice(defaultPreprocessors, Math.max(0, index + offset), 0, name);
- }
- return this;
- }
- });
- /**
- * @cfg {String} extend
- * The parent class that this class extends. For example:
- *
- * Ext.define('Person', {
- * say: function(text) { alert(text); }
- * });
- *
- * Ext.define('Developer', {
- * extend: 'Person',
- * say: function(text) { this.callParent(["print "+text]); }
- * });
- */
- ExtClass.registerPreprocessor('extend', function(Class, data, hooks) {
- var Base = Ext.Base,
- basePrototype = Base.prototype,
- extend = data.extend,
- Parent, parentPrototype, i;
- if (Ext.classSystemMonitor) {
- Ext.classSystemMonitor(Class, 'Ext.Class#extendPreProcessor', arguments);
- }
- delete data.extend;
- if (extend && extend !== Object) {
- Parent = extend;
- } else {
- Parent = Base;
- }
- parentPrototype = Parent.prototype;
- if (!Parent.$isClass) {
- for (i in basePrototype) {
- if (!parentPrototype[i]) {
- parentPrototype[i] = basePrototype[i];
- }
- }
- }
- Class.extend(Parent);
- Class.triggerExtended.apply(Class, arguments);
- /**
- * @cfg {Object} eventedConfig
- * Config options defined within `eventedConfig` will auto-generate the setter /
- * getter methods (see {@link #cfg-config config} for more information on
- * auto-generated getter / setter methods). Additionally, when an
- * `eventedConfig` is set it will also fire a before{cfg}change and {cfg}change
- * event when the value of the eventedConfig is changed from its originally
- * defined value.
- *
- * **Note:** When creating a custom class you'll need to extend Ext.Evented
- *
- * Example custom class:
- *
- * Ext.define('MyApp.util.Test', {
- * extend: 'Ext.Evented',
- *
- * eventedConfig: {
- * foo: null
- * }
- * });
- *
- * In this example, the `foo` config will initially be null. Changing it via
- * `setFoo` will fire the `beforefoochange` event. The call to the setter can be
- * halted by returning `false` from a listener on the **before** event.
- *
- * var test = Ext.create('MyApp.util.Test', {
- * listeners: {
- * beforefoochange: function (instance, newValue, oldValue) {
- * return newValue !== 'bar';
- * },
- * foochange: function (instance, newValue, oldValue) {
- * console.log('foo changed to:', newValue);
- * }
- * }
- * });
- *
- * test.setFoo('bar');
- *
- * The `before` event handler can be used to validate changes to `foo`.
- * Returning `false` will prevent the setter from changing the value of the
- * config. In the previous example the `beforefoochange` handler returns false
- * so `foo` will not be updated and `foochange` will not be fired.
- *
- * test.setFoo('baz');
- *
- * Setting `foo` to 'baz' will not be prevented by the `before` handler. Foo
- * will be set to the value: 'baz' and the `foochange` event will be fired.
- */
- if (data.onClassExtended) {
- Class.onExtended(data.onClassExtended, Class);
- delete data.onClassExtended;
- }
- }, true);
- // true to always run this preprocessor even w/o "extend" keyword
- /**
- * @cfg {Object} privates
- * The `privates` config is a list of methods intended to be used internally by the
- * framework. Methods are placed in a `privates` block to prevent developers from
- * accidentally overriding framework methods in custom classes.
- *
- * Ext.define('Computer', {
- * privates: {
- * runFactory: function(brand) {
- * // internal only processing of brand passed to factory
- * this.factory(brand);
- * }
- * },
- *
- * factory: function (brand) {}
- * });
- *
- * In order to override a method from a `privates` block, the overridden method must
- * also be placed in a `privates` block within the override class.
- *
- * Ext.define('Override.Computer', {
- * override: 'Computer',
- * privates: {
- * runFactory: function() {
- * // overriding logic
- * }
- * }
- * });
- */
- ExtClass.registerPreprocessor('privates', function(Class, data) {
- var privates = data.privates,
- statics = privates.statics,
- privacy = privates.privacy || true;
- if (Ext.classSystemMonitor) {
- Ext.classSystemMonitor(Class, 'Ext.Class#privatePreprocessor', arguments);
- }
- delete data.privates;
- delete privates.statics;
- // We have to add this preprocessor so that private getters/setters are picked up
- // by the config system. This also catches duplication in the public part of the
- // class since it is an error to override a private method with a public one.
- Class.addMembers(privates, false, privacy);
- if (statics) {
- Class.addMembers(statics, true, privacy);
- }
- });
- /**
- * @cfg {Object} statics
- * List of static methods for this class. For example:
- *
- * Ext.define('Computer', {
- * statics: {
- * factory: function(brand) {
- * // 'this' in static methods refer to the class itself
- * return new this(brand);
- * }
- * },
- *
- * constructor: function() { ... }
- * });
- *
- * var dellComputer = Computer.factory('Dell');
- */
- ExtClass.registerPreprocessor('statics', function(Class, data) {
- if (Ext.classSystemMonitor) {
- Ext.classSystemMonitor(Class, 'Ext.Class#staticsPreprocessor', arguments);
- }
- Class.addStatics(data.statics);
- delete data.statics;
- });
- /**
- * @cfg {Object} inheritableStatics
- * List of inheritable static methods for this class.
- * Otherwise just like {@link #statics} but subclasses inherit these methods.
- */
- ExtClass.registerPreprocessor('inheritableStatics', function(Class, data) {
- if (Ext.classSystemMonitor) {
- Ext.classSystemMonitor(Class, 'Ext.Class#inheritableStaticsPreprocessor', arguments);
- }
- Class.addInheritableStatics(data.inheritableStatics);
- delete data.inheritableStatics;
- });
- Ext.createRuleFn = function(code) {
- return new Function('$c', 'with($c) { try { return (' + code + '); } catch(e) { return false;}}');
- };
- Ext.expressionCache = new Ext.util.Cache({
- miss: Ext.createRuleFn
- });
- Ext.ruleKeySortFn = ruleKeySortFn;
- Ext.getPlatformConfigKeys = function(platformConfig) {
- var ret = [],
- platform, rule;
- for (platform in platformConfig) {
- rule = Ext.expressionCache.get(platform);
- if (rule(Ext.platformTags)) {
- ret.push(platform);
- }
- }
- ret.sort(ruleKeySortFn);
- return ret;
- };
- /**
- * @cfg {Object} config
- *
- * List of configuration options with their default values.
- *
- * __Note:__ You need to make sure {@link Ext.Base#initConfig} is called from your constructor
- * if you are defining your own class or singleton, unless you are extending a Component.
- * Otherwise the generated getter and setter methods will not be initialized.
- *
- * Each config item will have its own setter and getter method automatically generated inside
- * the class prototype during class creation time, if the class does not have those methods
- * explicitly defined.
- *
- * As an example, let's convert the name property of a Person class to be a config item, then
- * add extra age and gender items.
- *
- * Ext.define('My.sample.Person', {
- * config: {
- * name: 'Mr. Unknown',
- * age: 0,
- * gender: 'Male'
- * },
- *
- * constructor: function(config) {
- * this.initConfig(config);
- *
- * return this;
- * }
- *
- * // ...
- * });
- *
- * Within the class, this.name still has the default value of "Mr. Unknown". However, it's now
- * publicly accessible without sacrificing encapsulation, via setter and getter methods.
- *
- * var jacky = new My.sample.Person({
- * name: "Jacky",
- * age: 35
- * });
- *
- * alert(jacky.getAge()); // alerts 35
- * alert(jacky.getGender()); // alerts "Male"
- *
- * jacky.setName("Mr. Nguyen");
- * alert(jacky.getName()); // alerts "Mr. Nguyen"
- *
- * Notice that we changed the class constructor to invoke this.initConfig() and pass in the
- * provided config object. Two key things happened:
- *
- * - The provided config object when the class is instantiated is recursively merged with
- * the default config object.
- * - All corresponding setter methods are called with the merged values.
- *
- * Beside storing the given values, throughout the frameworks, setters generally have two key
- * responsibilities:
- *
- * - Filtering / validation / transformation of the given value before it's actually stored
- * within the instance.
- * - Notification (such as firing events) / post-processing after the value has been set,
- * or changed from a previous value.
- *
- * By standardize this common pattern, the default generated setters provide two extra template
- * methods that you can put your own custom logic into, i.e: an "applyFoo" and "updateFoo"
- * method for a "foo" config item, which are executed before and after the value is actually
- * set, respectively. Back to the example class, let's validate that age must be a valid
- * positive number, and fire an 'agechange' if the value is modified.
- *
- * Ext.define('My.sample.Person', {
- * config: {
- * // ...
- * },
- *
- * constructor: {
- * // ...
- * },
- *
- * applyAge: function(age) {
- * if (typeof age !== 'number' || age < 0) {
- * console.warn("Invalid age, must be a positive number");
- * return;
- * }
- *
- * return age;
- * },
- *
- * updateAge: function(newAge, oldAge) {
- * // age has changed from "oldAge" to "newAge"
- * this.fireEvent('agechange', this, newAge, oldAge);
- * }
- *
- * // ...
- * });
- *
- * var jacky = new My.sample.Person({
- * name: "Jacky",
- * age: 'invalid'
- * });
- *
- * alert(jacky.getAge()); // alerts 0
- *
- * alert(jacky.setAge(-100)); // alerts 0
- * alert(jacky.getAge()); // alerts 0
- *
- * alert(jacky.setAge(35)); // alerts 0
- * alert(jacky.getAge()); // alerts 35
- *
- * In other words, when leveraging the config feature, you mostly never need to define setter
- * and getter methods explicitly. Instead, "apply*" and "update*" methods should be implemented
- * where necessary. Your code will be consistent throughout and only contain the minimal logic
- * that you actually care about.
- *
- * When it comes to inheritance, the default config of the parent class is automatically,
- * recursively merged with the child's default config. The same applies for mixins.
- */
- ExtClass.registerPreprocessor('config', function(Class, data) {
- // Need to copy to the prototype here because that happens after preprocessors
- if (data.hasOwnProperty('$configPrefixed')) {
- Class.prototype.$configPrefixed = data.$configPrefixed;
- }
- Class.addConfig(data.config);
- // We need to remove this or it will be applied by addMembers and smash the
- // "config" placed on the prototype by Configurator (which includes *all* configs
- // such as cachedConfigs).
- delete data.config;
- });
- /**
- * @cfg {Object} cachedConfig
- *
- * This configuration works in a very similar manner to the {@link #config} option.
- * The difference is that the configurations are only ever processed when the first instance
- * of that class is created. The processed value is then stored on the class prototype and
- * will not be processed on subsequent instances of the class. Getters/setters will be generated
- * in exactly the same way as {@link #config}.
- *
- * This option is useful for expensive objects that can be shared across class instances.
- * The class itself ensures that the creation only occurs once.
- */
- ExtClass.registerPreprocessor('cachedConfig', function(Class, data) {
- // Need to copy to the prototype here because that happens after preprocessors
- if (data.hasOwnProperty('$configPrefixed')) {
- Class.prototype.$configPrefixed = data.$configPrefixed;
- }
- Class.addCachedConfig(data.cachedConfig);
- // Remove this so it won't be placed on the prototype.
- delete data.cachedConfig;
- });
- /**
- * @cfg {String[]/Object} mixins
- * List of classes to mix into this class. For example:
- *
- * Ext.define('CanSing', {
- * sing: function() {
- * alert("For he's a jolly good fellow...")
- * }
- * });
- *
- * Ext.define('Musician', {
- * mixins: ['CanSing']
- * })
- *
- * In this case the Musician class will get a `sing` method from CanSing mixin.
- *
- * But what if the Musician already has a `sing` method? Or you want to mix
- * in two classes, both of which define `sing`? In such a cases it's good
- * to define mixins as an object, where you assign a name to each mixin:
- *
- * Ext.define('Musician', {
- * mixins: {
- * canSing: 'CanSing'
- * },
- *
- * sing: function() {
- * // delegate singing operation to mixin
- * this.mixins.canSing.sing.call(this);
- * }
- * })
- *
- * In this case the `sing` method of Musician will overwrite the
- * mixed in `sing` method. But you can access the original mixed in method
- * through special `mixins` property.
- */
- ExtClass.registerPreprocessor('mixins', function(Class, data, hooks) {
- var mixins = data.mixins,
- onCreated = hooks.onCreated;
- if (Ext.classSystemMonitor) {
- Ext.classSystemMonitor(Class, 'Ext.Class#mixinsPreprocessor', arguments);
- }
- delete data.mixins;
- hooks.onCreated = function() {
- /* eslint-disable-next-line max-len */
- if (Ext.classSystemMonitor) {
- Ext.classSystemMonitor(Class, 'Ext.Class#mixinsPreprocessor#beforeCreated', arguments);
- }
- // Put back the original onCreated before processing mixins. This allows a
- // mixin to hook onCreated by access Class._classHooks.
- hooks.onCreated = onCreated;
- Class.mixin(mixins);
- // We must go back to hooks.onCreated here because it may have changed during
- // calls to onClassMixedIn.
- return hooks.onCreated.apply(this, arguments);
- };
- });
- // Backwards compatible
- Ext.extend = function(Class, Parent, members) {
- var cls, m;
- if (Ext.classSystemMonitor) {
- Ext.classSystemMonitor(Class, 'Ext.Class#extend-backwards-compatible', arguments);
- }
- if (arguments.length === 2 && Ext.isObject(Parent)) {
- members = Parent;
- Parent = Class;
- Class = null;
- }
- if (!Parent) {
- throw new Error("[Ext.extend] Attempting to extend from a class which has not " + "been loaded on the page.");
- }
- members.extend = Parent;
- /* eslint-disable comma-style */
- members.preprocessors = [
- 'extend',
- 'statics',
- 'inheritableStatics',
- 'mixins',
- 'config'
- ];
- /* eslint-enable comma-style */
- if (Class) {
- cls = new ExtClass(Class, members);
- // The 'constructor' is given as 'Class' but also needs to be on prototype
- cls.prototype.constructor = Class;
- } else {
- cls = new ExtClass(members);
- }
- cls.prototype.override = function(o) {
- for (m in o) {
- if (o.hasOwnProperty(m)) {
- this[m] = o[m];
- }
- }
- };
- return cls;
- };
- }());
- /**
- * This object contains properties that describe the current device or platform. These
- * values can be used in `{@link Ext.Class#platformConfig platformConfig}` as well as
- * `{@link Ext.mixin.Responsive#responsiveConfig responsiveConfig}` statements.
- *
- * This object can be modified to include tags that are useful for the application. To
- * add custom properties, it is advisable to use a sub-object. For example:
- *
- * Ext.platformTags.app = {
- * mobile: true
- * };
- *
- * @property {Object} platformTags
- * @property {Boolean} platformTags.phone
- * @property {Boolean} platformTags.tablet
- * @property {Boolean} platformTags.desktop
- * @property {Boolean} platformTags.touch Indicates touch inputs are available.
- * @property {Boolean} platformTags.safari
- * @property {Boolean} platformTags.chrome
- * @property {Boolean} platformTags.windows
- * @property {Boolean} platformTags.firefox
- * @property {Boolean} platformTags.ios True for iPad, iPhone and iPod.
- * @property {Boolean} platformTags.android
- * @property {Boolean} platformTags.blackberry
- * @property {Boolean} platformTags.tizen
- * @member Ext
- */
- // @tag class
- /**
- * @class Ext.Inventory
- * @private
- */
- Ext.Inventory = function() {
- // @define Ext.Script
- // @define Ext.Inventory
- // @require Ext.Function
- var me = this;
- me.names = [];
- me.paths = {};
- me.alternateToName = {};
- me.aliasToName = {};
- me.nameToAliases = {};
- me.nameToAlternates = {};
- me.nameToPrefix = {};
- };
- Ext.Inventory.prototype = {
- _array1: [
- 0
- ],
- prefixes: null,
- dotRe: /\./g,
- wildcardRe: /\*/g,
- addAlias: function(className, alias, update) {
- return this.addMapping(className, alias, this.aliasToName, this.nameToAliases, update);
- },
- addAlternate: function(className, alternate) {
- return this.addMapping(className, alternate, this.alternateToName, this.nameToAlternates);
- },
- addMapping: function(className, alternate, toName, nameTo, update) {
- var name = className.$className || className,
- mappings = name,
- array = this._array1,
- a, aliases, cls, i, length, nameMapping;
- if (Ext.isString(name)) {
- mappings = {};
- mappings[name] = alternate;
- }
- for (cls in mappings) {
- aliases = mappings[cls];
- if (Ext.isString(aliases)) {
- array[0] = aliases;
- aliases = array;
- }
- length = aliases.length;
- nameMapping = nameTo[cls] || (nameTo[cls] = []);
- for (i = 0; i < length; ++i) {
- if (!(a = aliases[i])) {
-
- continue;
- }
- if (toName[a] !== cls) {
- if (!update && toName[a] && ('Ext.Gadget' !== a)) {
- Ext.log.warn("Overriding existing mapping: '" + a + "' From '" + toName[a] + "' to '" + cls + "'. Is this intentional?");
- }
- toName[a] = cls;
- nameMapping.push(a);
- }
- }
- }
- },
- /**
- * Get the aliases of a class by the class name
- *
- * @param {String} name
- * @return {Array} aliases
- */
- getAliasesByName: function(name) {
- return this.nameToAliases[name] || null;
- },
- getAlternatesByName: function(name) {
- return this.nameToAlternates[name] || null;
- },
- /**
- * Get the name of a class by its alias.
- *
- * @param {String} alias
- * @return {String} className
- */
- getNameByAlias: function(alias) {
- return this.aliasToName[alias] || '';
- },
- /**
- * Get the name of a class by its alternate name.
- *
- * @param {String} alternate
- * @return {String} className
- */
- getNameByAlternate: function(alternate) {
- return this.alternateToName[alternate] || '';
- },
- /**
- * Converts a string expression to an array of matching class names. An expression can
- * either refers to class aliases or class names. Expressions support wildcards:
- *
- * // returns ['Ext.window.Window']
- * var window = Ext.ClassManager.getNamesByExpression('widget.window');
- *
- * // returns ['widget.panel', 'widget.window', ...]
- * var allWidgets = Ext.ClassManager.getNamesByExpression('widget.*');
- *
- * // returns ['Ext.data.Store', 'Ext.data.ArrayProxy', ...]
- * var allData = Ext.ClassManager.getNamesByExpression('Ext.data.*');
- *
- * @param {String/String[]} expression
- * @param {Object} [exclude=null] An object keyed by class name containing classes to
- * exclude from the returned classes. This must be provided if `accumulate` is set to
- * `true`.
- * @param {Boolean} [accumulate=false] Pass `true` to add matching classes to the
- * specified `exclude` object.
- * @return {String[]} An array of class names.
- */
- getNamesByExpression: function(expression, exclude, accumulate) {
- var me = this,
- aliasToName = me.aliasToName,
- alternateToName = me.alternateToName,
- nameToAliases = me.nameToAliases,
- nameToAlternates = me.nameToAlternates,
- map = accumulate ? exclude : {},
- names = [],
- expressions = Ext.isString(expression) ? [
- expression
- ] : expression,
- length = expressions.length,
- wildcardRe = me.wildcardRe,
- expr, i, list, match, n, name, regex;
- for (i = 0; i < length; ++i) {
- if ((expr = expressions[i]).indexOf('*') < 0) {
- // No wildcard
- if (!(name = aliasToName[expr])) {
- if (!(name = alternateToName[expr])) {
- name = expr;
- }
- }
- if (!(name in map) && !(exclude && (name in exclude))) {
- map[name] = 1;
- names.push(name);
- }
- } else {
- regex = new RegExp('^' + expr.replace(wildcardRe, '(.*?)') + '$');
- for (name in nameToAliases) {
- if (!(name in map) && !(exclude && (name in exclude))) {
- if (!(match = regex.test(name))) {
- n = (list = nameToAliases[name]).length;
- while (!match && n-- > 0) {
- match = regex.test(list[n]);
- }
- list = nameToAlternates[name];
- if (list && !match) {
- n = list.length;
- while (!match && n-- > 0) {
- match = regex.test(list[n]);
- }
- }
- }
- if (match) {
- map[name] = 1;
- names.push(name);
- }
- }
- }
- }
- }
- return names;
- },
- getPath: function(className) {
- var me = this,
- paths = me.paths,
- ret = '',
- prefix;
- if (className in paths) {
- ret = paths[className];
- } else {
- prefix = me.nameToPrefix[className] || (me.nameToPrefix[className] = me.getPrefix(className));
- if (prefix) {
- className = className.substring(prefix.length + 1);
- ret = paths[prefix];
- if (ret) {
- ret += '/';
- }
- }
- ret += className.replace(me.dotRe, '/') + '.js';
- }
- return ret;
- },
- getPrefix: function(className) {
- if (className in this.paths) {
- return className;
- } else if (className in this.nameToPrefix) {
- return this.nameToPrefix[className];
- }
- /* eslint-disable-next-line vars-on-top */
- var prefixes = this.getPrefixes(),
- length = className.length,
- items, currChar, prefix, j, jlen;
- // Walk the prefixes backwards so we consider the longest ones first.
- // Prefixes are kept in a sparse array grouped by length so we don't have to
- // iterate over all of them, just the ones we need.
- while (length-- > 0) {
- items = prefixes[length];
- if (items) {
- currChar = className.charAt(length);
- if (currChar !== '.') {
-
- continue;
- }
- for (j = 0 , jlen = items.length; j < jlen; j++) {
- prefix = items[j];
- if (prefix === className.substring(0, length)) {
- return prefix;
- }
- }
- }
- }
- return '';
- },
- getPrefixes: function() {
- var me = this,
- prefixes = me.prefixes,
- names, name, nameLength, items, i, len;
- if (!prefixes) {
- names = me.names.slice(0);
- me.prefixes = prefixes = [];
- for (i = 0 , len = names.length; i < len; i++) {
- name = names[i];
- nameLength = name.length;
- items = prefixes[nameLength] || (prefixes[nameLength] = []);
- items.push(name);
- }
- }
- return prefixes;
- },
- removeName: function(name) {
- var me = this,
- aliasToName = me.aliasToName,
- alternateToName = me.alternateToName,
- nameToAliases = me.nameToAliases,
- nameToAlternates = me.nameToAlternates,
- aliases = nameToAliases[name],
- alternates = nameToAlternates[name],
- i, a;
- delete nameToAliases[name];
- delete nameToAlternates[name];
- delete me.nameToPrefix[name];
- if (aliases) {
- for (i = aliases.length; i--; ) {
- // Aliases can be reassigned so if this class is the current mapping of
- // the alias, remove it. Since there is no chain to restore what was
- // removed this is not perfect.
- if (name === aliasToName[a = aliases[i]]) {
- delete aliasToName[a];
- }
- }
- }
- if (alternates) {
- for (i = alternates.length; i--; ) {
- // Like aliases, alternate class names can also be remapped.
- if (name === alternateToName[a = alternates[i]]) {
- delete alternateToName[a];
- }
- }
- }
- },
- resolveName: function(name) {
- var me = this,
- trueName;
- // If the name has a registered alias, it is a true className (not an alternate)
- // so we can stop now.
- if (!(name in me.nameToAliases)) {
- // The name is not a known class name, so check to see if it is a known alias:
- if (!(trueName = me.aliasToName[name])) {
- // The name does not correspond to a known alias, so check if it is a known
- // alternateClassName:
- trueName = me.alternateToName[name];
- }
- }
- return trueName || name;
- },
- /**
- * This method returns a selector object that produces a selection of classes and
- * delivers them to the desired `receiver`.
- *
- * The returned selector object has the same methods as the given `receiver` object
- * but these methods on the selector accept a first argument that expects a pattern
- * or array of patterns. The actual method on the `receiver` will be called with an
- * array of classes that match these patterns but with any patterns passed to an
- * `exclude` call removed.
- *
- * For example:
- *
- * var sel = inventory.select({
- * require: function (classes) {
- * console.log('Classes: ' + classes.join(','));
- * }
- * });
- *
- * sel.exclude('Ext.chart.*').exclude('Ext.draw.*').require('*');
- *
- * // Logs all classes except those in the Ext.chart and Ext.draw namespaces.
- *
- * @param {Object} receiver
- * @param {Object} [scope] Optional scope to use when calling `receiver` methods.
- * @return {Object} An object with the same methods as `receiver` plus `exclude`.
- */
- select: function(receiver, scope) {
- var me = this,
- excludes = {},
- ret = {
- excludes: excludes,
- exclude: function() {
- me.getNamesByExpression(arguments[0], excludes, true);
- return this;
- }
- },
- name;
- for (name in receiver) {
- ret[name] = me.selectMethod(excludes, receiver[name], scope || receiver);
- }
- return ret;
- },
- selectMethod: function(excludes, fn, scope) {
- var me = this;
- return function(include) {
- var args = Ext.Array.slice(arguments, 1);
- args.unshift(me.getNamesByExpression(include, excludes));
- return fn.apply(scope, args);
- };
- },
- /**
- * Sets the path of a namespace.
- * For Example:
- *
- * inventory.setPath('Ext', '.');
- * inventory.setPath({
- * Ext: '.'
- * });
- *
- * @param {String/Object} name The name of a single mapping or an object of mappings.
- * @param {String} [path] If `name` is a String, then this is the path for that name.
- * Otherwise this parameter is ignored.
- * @return {Ext.Inventory} this
- * @method
- */
- setPath: Ext.Function.flexSetter(function(name, path) {
- var me = this;
- me.paths[name] = path;
- me.names.push(name);
- me.prefixes = null;
- me.nameToPrefix = {};
- return me;
- })
- };
- // @tag class
- /**
- * @class Ext.ClassManager
- *
- * Ext.ClassManager manages all classes and handles mapping from string class name to
- * actual class objects throughout the whole framework. It is not generally accessed directly,
- * rather through these convenient shorthands:
- *
- * - {@link Ext#define Ext.define}
- * - {@link Ext#method!create Ext.create}
- * - {@link Ext#widget Ext.widget}
- * - {@link Ext#getClass Ext.getClass}
- * - {@link Ext#getClassName Ext.getClassName}
- *
- * # Basic syntax:
- *
- * Ext.define(className, properties);
- *
- * in which `properties` is an object represent a collection of properties that apply to the class.
- * See {@link Ext.ClassManager#method!create} for more detailed instructions.
- *
- * Ext.define('Person', {
- * name: 'Unknown',
- *
- * constructor: function(name) {
- * if (name) {
- * this.name = name;
- * }
- * },
- *
- * eat: function(foodType) {
- * alert("I'm eating: " + foodType);
- *
- * return this;
- * }
- * });
- *
- * var aaron = new Person("Aaron");
- * aaron.eat("Sandwich"); // alert("I'm eating: Sandwich");
- *
- * Ext.Class has a powerful set of extensible {@link Ext.Class#registerPreprocessor pre-processors}
- * which takes care of everything related to class creation, including but not limited to
- * inheritance, mixins, configuration, statics, etc.
- *
- * # Inheritance:
- *
- * Ext.define('Developer', {
- * extend: 'Person',
- *
- * constructor: function(name, isGeek) {
- * this.isGeek = isGeek;
- *
- * // Apply a method from the parent class' prototype
- * this.callParent([name]);
- * },
- *
- * code: function(language) {
- * alert("I'm coding in: " + language);
- *
- * this.eat("Bugs");
- *
- * return this;
- * }
- * });
- *
- * var jacky = new Developer("Jacky", true);
- * jacky.code("JavaScript"); // alert("I'm coding in: JavaScript");
- * // alert("I'm eating: Bugs");
- *
- * See {@link Ext.Base#method!callParent} for more details on calling superclass' methods
- *
- * # Mixins:
- *
- * Ext.define('CanPlayGuitar', {
- * playGuitar: function() {
- * alert("F#...G...D...A");
- * }
- * });
- *
- * Ext.define('CanComposeSongs', {
- * composeSongs: function() { ... }
- * });
- *
- * Ext.define('CanSing', {
- * sing: function() {
- * alert("For he's a jolly good fellow...")
- * }
- * });
- *
- * Ext.define('Musician', {
- * extend: 'Person',
- *
- * mixins: {
- * canPlayGuitar: 'CanPlayGuitar',
- * canComposeSongs: 'CanComposeSongs',
- * canSing: 'CanSing'
- * }
- * })
- *
- * Ext.define('CoolPerson', {
- * extend: 'Person',
- *
- * mixins: {
- * canPlayGuitar: 'CanPlayGuitar',
- * canSing: 'CanSing'
- * },
- *
- * sing: function() {
- * alert("Ahem....");
- *
- * this.mixins.canSing.sing.call(this);
- *
- * alert("[Playing guitar at the same time...]");
- *
- * this.playGuitar();
- * }
- * });
- *
- * var me = new CoolPerson("Jacky");
- *
- * me.sing(); // alert("Ahem...");
- * // alert("For he's a jolly good fellow...");
- * // alert("[Playing guitar at the same time...]");
- * // alert("F#...G...D...A");
- *
- * # Config:
- *
- * Ext.define('SmartPhone', {
- * config: {
- * hasTouchScreen: false,
- * operatingSystem: 'Other',
- * price: 500
- * },
- *
- * isExpensive: false,
- *
- * constructor: function(config) {
- * this.initConfig(config);
- * },
- *
- * applyPrice: function(price) {
- * this.isExpensive = (price > 500);
- *
- * return price;
- * },
- *
- * applyOperatingSystem: function(operatingSystem) {
- * if (!(/^(iOS|Android|BlackBerry)$/i).test(operatingSystem)) {
- * return 'Other';
- * }
- *
- * return operatingSystem;
- * }
- * });
- *
- * var iPhone = new SmartPhone({
- * hasTouchScreen: true,
- * operatingSystem: 'iOS'
- * });
- *
- * iPhone.getPrice(); // 500;
- * iPhone.getOperatingSystem(); // 'iOS'
- * iPhone.getHasTouchScreen(); // true;
- *
- * iPhone.isExpensive; // false;
- * iPhone.setPrice(600);
- * iPhone.getPrice(); // 600
- * iPhone.isExpensive; // true;
- *
- * iPhone.setOperatingSystem('AlienOS');
- * iPhone.getOperatingSystem(); // 'Other'
- *
- * # Statics:
- *
- * Ext.define('Computer', {
- * statics: {
- * factory: function(brand) {
- * // 'this' in static methods refer to the class itself
- * return new this(brand);
- * }
- * },
- *
- * constructor: function() { ... }
- * });
- *
- * var dellComputer = Computer.factory('Dell');
- *
- * Also see {@link Ext.Base#statics} and {@link Ext.Base#self} for more details on accessing
- * static properties within class methods
- *
- * @singleton
- */
- Ext.ClassManager = (function(Class, alias, arraySlice, arrayFrom, global) {
- // @define Ext.ClassManager
- // @require Ext.Inventory
- // @require Ext.Class
- // @require Ext.Function
- // @require Ext.Array
- var makeCtor = Ext.Class.makeCtor,
- nameLookupStack = [],
- namespaceCache = {
- Ext: {
- name: 'Ext',
- value: Ext
- }
- },
- // specially added for sandbox (Ext === global.Ext6)
- /*
- 'Ext.grid': {
- name: 'grid',
- parent: namespaceCache['Ext']
- },
- 'Ext.grid.Panel': {
- name: 'Panel',
- parent: namespaceCache['Ext.grid']
- },
- ...
- Also,
- 'MyApp': {
- name: 'MyApp',
- value: MyApp
- }
- */
- Manager = Ext.apply(new Ext.Inventory(), {
- /**
- * @property {Object} classes
- * All classes which were defined through the ClassManager. Keys are the
- * name of the classes and the values are references to the classes.
- * @private
- */
- classes: {},
- classCount: 0,
- classState: {},
- /*
- * 'Ext.foo.Bar': <state enum>
- *
- * 10 = Ext.define called
- * 20 = Ext.define/override called
- * 30 = Manager.existCache[<name>] == true for define
- * 40 = Manager.existCache[<name>] == true for define/override
- * 50 = Manager.isCreated(<name>) == true for define
- * 60 = Manager.isCreated(<name>) == true for define/override
- *
- */
- /**
- * @private
- */
- existCache: {},
- /** @private */
- instantiators: [],
- /**
- * Checks if a class has already been created.
- *
- * @param {String} className
- * @return {Boolean} exist
- */
- isCreated: function(className) {
- if (typeof className !== 'string' || className.length < 1) {
- throw new Error("[Ext.ClassManager] Invalid classname, must be a string and " + "must not be empty");
- }
- if (Manager.classes[className] || Manager.existCache[className]) {
- return true;
- }
- if (!Manager.lookupName(className, false)) {
- return false;
- }
- Manager.triggerCreated(className);
- return true;
- },
- /**
- * @private
- */
- createdListeners: [],
- /**
- * @private
- */
- nameCreatedListeners: {},
- /**
- * @private
- */
- existsListeners: [],
- /**
- * @private
- */
- nameExistsListeners: {},
- /**
- * @private
- */
- overrideMap: {},
- /**
- * @private
- */
- triggerCreated: function(className, state) {
- Manager.existCache[className] = state || 1;
- Manager.classState[className] += 40;
- Manager.notify(className, Manager.createdListeners, Manager.nameCreatedListeners);
- },
- /**
- * @private
- */
- onCreated: function(fn, scope, className) {
- Manager.addListener(fn, scope, className, Manager.createdListeners, Manager.nameCreatedListeners);
- },
- /**
- * @private
- */
- notify: function(className, listeners, nameListeners) {
- var alternateNames = Manager.getAlternatesByName(className),
- names = [
- className
- ],
- i, ln, j, subLn, listener, name;
- for (i = 0 , ln = listeners.length; i < ln; i++) {
- listener = listeners[i];
- listener.fn.call(listener.scope, className);
- }
- while (names) {
- for (i = 0 , ln = names.length; i < ln; i++) {
- name = names[i];
- listeners = nameListeners[name];
- if (listeners) {
- for (j = 0 , subLn = listeners.length; j < subLn; j++) {
- listener = listeners[j];
- listener.fn.call(listener.scope, name);
- }
- delete nameListeners[name];
- }
- }
- names = alternateNames;
- // for 2nd pass (if needed)
- alternateNames = null;
- }
- },
- // no 3rd pass
- /**
- * @private
- */
- addListener: function(fn, scope, className, listeners, nameListeners) {
- var i;
- if (Ext.isArray(className)) {
- fn = Ext.Function.createBarrier(className.length, fn, scope);
- for (i = 0; i < className.length; i++) {
- this.addListener(fn, null, className[i], listeners, nameListeners);
- }
- return;
- }
- /* eslint-disable-next-line vars-on-top */
- var listener = {
- fn: fn,
- scope: scope
- };
- if (className) {
- if (this.isCreated(className)) {
- fn.call(scope, className);
- return;
- }
- if (!nameListeners[className]) {
- nameListeners[className] = [];
- }
- nameListeners[className].push(listener);
- } else {
- listeners.push(listener);
- }
- },
- /**
- * Supports namespace rewriting.
- * @private
- */
- $namespaceCache: namespaceCache,
- /**
- * See `{@link Ext#addRootNamespaces Ext.addRootNamespaces}`.
- * @since 6.0.0
- * @private
- */
- addRootNamespaces: function(namespaces) {
- var name;
- for (name in namespaces) {
- namespaceCache[name] = {
- name: name,
- value: namespaces[name]
- };
- }
- },
- /**
- * Clears the namespace lookup cache. After application launch, this cache can
- * often contain several hundred entries that are unlikely to be needed again.
- * These will be rebuilt as needed, so it is harmless to clear this cache even
- * if its results will be used again.
- * @since 6.0.0
- * @private
- */
- clearNamespaceCache: function() {
- var name;
- nameLookupStack.length = 0;
- for (name in namespaceCache) {
- if (!namespaceCache[name].value) {
- delete namespaceCache[name];
- }
- }
- },
- /**
- * Return the namespace cache entry for the given a class name or namespace (e.g.,
- * "Ext.grid.Panel").
- *
- * @param {String} namespace The namespace or class name to lookup.
- * @return {Object} The cache entry.
- * @return {String} return.name The leaf name ("Panel" for "Ext.grid.Panel").
- * @return {Object} return.parent The entry of the parent namespace (i.e., "Ext.grid").
- * @return {Object} return.value The namespace object. This is only set for
- * top-level namespace entries to support renaming them for sandboxing ("Ext6" vs
- * "Ext").
- * @since 6.0.0
- * @private
- */
- getNamespaceEntry: function(namespace) {
- var entry, i;
- if (typeof namespace !== 'string') {
- return namespace;
- }
- // assume we've been given an entry object
- entry = namespaceCache[namespace];
- if (!entry) {
- i = namespace.lastIndexOf('.');
- if (i < 0) {
- entry = {
- name: namespace
- };
- } else {
- entry = {
- name: namespace.substring(i + 1),
- parent: Manager.getNamespaceEntry(namespace.substring(0, i))
- };
- }
- namespaceCache[namespace] = entry;
- }
- return entry;
- },
- /**
- * Return the value of the given "dot path" name. This supports remapping (for use
- * in sandbox builds) as well as auto-creating of namespaces.
- *
- * @param {String} namespace The name of the namespace or class.
- * @param {Boolean} [autoCreate] Pass `true` to create objects for undefined names.
- * @return {Object} The object that is the namespace or class name.
- * @since 6.0.0
- * @private
- */
- lookupName: function(namespace, autoCreate) {
- var entry = Manager.getNamespaceEntry(namespace),
- scope = Ext.global,
- i = 0,
- e, parent;
- // Put entries on the stack in reverse order: [ 'Panel', 'grid', 'Ext' ]
- for (e = entry; e; e = e.parent) {
- // since we process only what we add to the array, and that always
- // starts at index=0, we don't need to clean up the array (that would
- // just encourage the GC to do something pointless).
- nameLookupStack[i++] = e;
- }
- while (scope && i-- > 0) {
- // We'll process entries in top-down order ('Ext', 'grid' then 'Panel').
- e = nameLookupStack[i];
- parent = scope;
- scope = e.value || scope[e.name];
- if (!scope && autoCreate) {
- parent[e.name] = scope = {};
- }
- }
- return scope;
- },
- /**
- * Creates a namespace and assign the `value` to the created object.
- *
- * Ext.ClassManager.setNamespace('MyCompany.pkg.Example', someObject);
- *
- * alert(MyCompany.pkg.Example === someObject); // alerts true
- *
- * @param {String} namespace
- * @param {Object} value
- */
- setNamespace: function(namespace, value) {
- var entry = Manager.getNamespaceEntry(namespace),
- scope = Ext.global;
- if (entry.parent) {
- scope = Manager.lookupName(entry.parent, true);
- }
- scope[entry.name] = value;
- return value;
- },
- /**
- * Changes the mapping of an `xtype` to map to the specified component class.
- * @param {String/Ext.Class} cls The class or class name to which `xtype` is mapped.
- * @param {String} xtype The `xtype` to map or redefine as `cls`.
- * @since 6.0.1
- * @private
- */
- setXType: function(cls, xtype) {
- var className = cls.$className,
- C = className ? cls : Manager.get(className = cls),
- proto = C.prototype,
- xtypes = proto.xtypes,
- xtypesChain = proto.xtypesChain,
- xtypesMap = proto.xtypesMap;
- if (!proto.hasOwnProperty('xtypes')) {
- proto.xtypes = xtypes = [];
- proto.xtypesChain = xtypesChain = xtypesChain ? xtypesChain.slice(0) : [];
- proto.xtypesMap = xtypesMap = Ext.apply({}, xtypesMap);
- }
- Manager.addAlias(className, 'widget.' + xtype, true);
- xtypes.push(xtype);
- xtypesChain.push(xtype);
- xtypesMap[xtype] = true;
- },
- // TODO consider updating derived class xtypesChain / xtypesMap
- /**
- * Sets a name reference to a class.
- *
- * @param {String} name
- * @param {Object} value
- * @return {Ext.ClassManager} this
- */
- set: function(name, value) {
- var targetName = Manager.getName(value);
- Manager.classes[name] = Manager.setNamespace(name, value);
- Manager.classCount++;
- if (targetName && targetName !== name) {
- Manager.addAlternate(targetName, name);
- }
- return Manager;
- },
- /**
- * Retrieve a class by its name.
- *
- * @param {String} name
- * @return {Ext.Class} class
- */
- get: function(name) {
- return Manager.classes[name] || Manager.lookupName(name, false);
- },
- /**
- * Adds a batch of class name to alias mappings.
- * @param {Object} aliases The set of mappings of the form.
- * className : [values...]
- */
- addNameAliasMappings: function(aliases) {
- Manager.addAlias(aliases);
- },
- /**
- *
- * @param {Object} alternates The set of mappings of the form
- * className : [values...]
- */
- addNameAlternateMappings: function(alternates) {
- Manager.addAlternate(alternates);
- },
- /**
- * Get a reference to the class by its alias.
- *
- * @param {String} alias
- * @return {Ext.Class} class
- */
- getByAlias: function(alias) {
- return Manager.get(Manager.getNameByAlias(alias));
- },
- /**
- * Get a component class name from a config object.
- * @param {Object} config The config object.
- * @param {String} [aliasPrefix] A prefix to use when getting
- * a class name by alias.
- * @return {Ext.Class} The class.
- *
- * @private
- */
- getByConfig: function(config, aliasPrefix) {
- var xclass = config.xclass,
- name;
- if (xclass) {
- name = xclass;
- } else {
- name = config.xtype;
- if (name) {
- aliasPrefix = 'widget.';
- } else {
- name = config.type;
- }
- name = Manager.getNameByAlias(aliasPrefix + name);
- }
- return Manager.get(name);
- },
- /**
- * Get the name of the class by its reference or its instance. This is
- * usually invoked by the shorthand {@link Ext#getClassName}.
- *
- * Ext.ClassManager.getName(Ext.Action); // returns "Ext.Action"
- *
- * @param {Ext.Class/Object} object
- * @return {String} className
- */
- getName: function(object) {
- return object && object.$className || '';
- },
- /**
- * Get the class of the provided object; returns null if it's not an instance
- * of any class created with Ext.define. This is usually invoked by the
- * shorthand {@link Ext#getClass}.
- *
- * var component = new Ext.Component();
- *
- * Ext.getClass(component); // returns Ext.Component
- *
- * @param {Object} object
- * @return {Ext.Class} class
- */
- getClass: function(object) {
- return object && object.self || null;
- },
- /**
- * Defines a class.
- * @deprecated 4.1 Use {@link Ext#define} instead.
- * @private
- */
- create: function(className, data, createdFn) {
- var ctor;
- if (className != null && typeof className !== 'string') {
- throw new Error("[Ext.define] Invalid class name '" + className + "' specified, must be a non-empty string");
- }
- ctor = makeCtor(className);
- if (typeof data === 'function') {
- data = data(ctor);
- }
- if (className) {
- if (Manager.classes[className]) {
- Ext.log.warn("[Ext.define] Duplicate class name '" + className + "' specified, must be a non-empty string");
- }
- ctor.name = className;
- }
- data.$className = className;
- return new Class(ctor, data, function() {
- var postprocessorStack = data.postprocessors || Manager.defaultPostprocessors,
- registeredPostprocessors = Manager.postprocessors,
- postprocessors = [],
- postprocessor, i, ln, j, subLn, postprocessorProperties, postprocessorProperty;
- delete data.postprocessors;
- for (i = 0 , ln = postprocessorStack.length; i < ln; i++) {
- postprocessor = postprocessorStack[i];
- if (typeof postprocessor === 'string') {
- postprocessor = registeredPostprocessors[postprocessor];
- postprocessorProperties = postprocessor.properties;
- if (postprocessorProperties === true) {
- postprocessors.push(postprocessor.fn);
- } else if (postprocessorProperties) {
- for (j = 0 , subLn = postprocessorProperties.length; j < subLn; j++) {
- postprocessorProperty = postprocessorProperties[j];
- if (data.hasOwnProperty(postprocessorProperty)) {
- postprocessors.push(postprocessor.fn);
- break;
- }
- }
- }
- } else {
- postprocessors.push(postprocessor);
- }
- }
- data.postprocessors = postprocessors;
- data.createdFn = createdFn;
- Manager.processCreate(className, this, data);
- });
- },
- processCreate: function(className, cls, clsData) {
- var me = this,
- postprocessor = clsData.postprocessors.shift(),
- createdFn = clsData.createdFn;
- if (!postprocessor) {
- if (Ext.classSystemMonitor) {
- Ext.classSystemMonitor(className, 'Ext.ClassManager#classCreated', arguments);
- }
- if (className) {
- me.set(className, cls);
- }
- delete cls._classHooks;
- if (createdFn) {
- createdFn.call(cls, cls);
- }
- if (className) {
- me.triggerCreated(className);
- }
- return;
- }
- if (postprocessor.call(me, className, cls, clsData, me.processCreate) !== false) {
- me.processCreate(className, cls, clsData);
- }
- },
- createOverride: function(className, data, createdFn) {
- var me = this,
- overriddenClassName = data.override,
- requires = data.requires,
- uses = data.uses,
- mixins = data.mixins,
- mixinsIsArray,
- compat = 1,
- // default if 'compatibility' is not specified
- dependenciesLoaded, classReady;
- classReady = function() {
- var cls, dependencies, i, key, temp;
- if (!dependenciesLoaded) {
- dependencies = requires ? requires.slice(0) : [];
- if (mixins) {
- if (!(mixinsIsArray = mixins instanceof Array)) {
- for (key in mixins) {
- if (Ext.isString(cls = mixins[key])) {
- dependencies.push(cls);
- }
- }
- } else {
- for (i = 0 , temp = mixins.length; i < temp; ++i) {
- if (Ext.isString(cls = mixins[i])) {
- dependencies.push(cls);
- }
- }
- }
- }
- dependenciesLoaded = true;
- if (dependencies.length) {
- // Since the override is going to be used (its target class is
- // now created), we need to fetch the required classes for the
- // override and call us back once they are loaded:
- Ext.require(dependencies, classReady);
- return;
- }
- }
- // else we have no dependencies, so proceed
- // transform mixin class names into class references, This
- // loop can handle both the array and object forms of
- // mixin definitions
- if (mixinsIsArray) {
- for (i = 0 , temp = mixins.length; i < temp; ++i) {
- if (Ext.isString(cls = mixins[i])) {
- mixins[i] = Ext.ClassManager.get(cls);
- }
- }
- } else if (mixins) {
- for (key in mixins) {
- if (Ext.isString(cls = mixins[key])) {
- mixins[key] = Ext.ClassManager.get(cls);
- }
- }
- }
- // The target class and the required classes for this override are
- // ready, so we can apply the override now:
- cls = overriddenClassName.$isClass ? overriddenClassName : me.get(overriddenClassName);
- // We don't want to apply these:
- delete data.override;
- delete data.compatibility;
- delete data.requires;
- delete data.uses;
- Ext.override(cls, data);
- // This pushes the overriding file itself into Ext.Loader.history
- // Hence if the target class never exists, the overriding file will
- // never be included in the build.
- Ext.Loader.history.push(className);
- if (uses) {
- // This "hides" from the Cmd auto-dependency scanner since
- // the reference is circular (Loader requires us).
- /* eslint-disable-next-line dot-notation */
- Ext['Loader'].addUsedClasses(uses);
- }
- // get these classes too!
- if (createdFn) {
- createdFn.call(cls, cls);
- }
- };
- // last but not least!
- if (className) {
- Manager.overrideMap[className] = true;
- }
- // If specified, parse strings as versions, but otherwise treat as a
- // boolean (maybe "compatibility: Ext.isIE8" or something).
- //
- if ('compatibility' in data) {
- compat = data.compatibility;
- if (!compat) {
- // Cast '', null, undefined, 0 to false.
- compat = false;
- } else if (typeof compat === 'number') {
- // By virtue of the condition above we must be a nonzero number.
- compat = true;
- } else if (typeof compat !== 'boolean') {
- compat = Ext.checkVersion(compat);
- }
- }
- if (compat) {
- // override the target class right after it's created
- if (overriddenClassName.$isClass) {
- classReady();
- } else {
- me.onCreated(classReady, me, overriddenClassName);
- }
- }
- me.triggerCreated(className, 2);
- return me;
- },
- /**
- * Instantiate a class by its alias. This is usually invoked by the
- * shorthand {@link Ext#createByAlias}.
- *
- * If {@link Ext.Loader} is {@link Ext.Loader#setConfig enabled} and the class
- * has not been defined yet, it will attempt to load the class via synchronous
- * loading.
- *
- * var window = Ext.createByAlias('widget.window', { width: 600, height: 800 });
- *
- * @param {String} alias
- * @param {Object...} args Additional arguments after the alias will be passed to the
- * class constructor.
- * @return {Object} instance
- */
- instantiateByAlias: function() {
- var alias = arguments[0],
- args = arraySlice.call(arguments),
- className = this.getNameByAlias(alias);
- if (!className) {
- throw new Error("[Ext.createByAlias] Unrecognized alias: " + alias);
- }
- args[0] = className;
- return Ext.create.apply(Ext, args);
- },
- /**
- * Instantiate a class by either full name, alias or alternate name
- * @param {String} name
- * @param {Mixed} args Additional arguments after the name will be passed to the class'
- * constructor.
- * @return {Object} instance
- * @deprecated 5.0 Use Ext.create() instead.
- */
- instantiate: function() {
- Ext.log.warn('Ext.ClassManager.instantiate() is deprecated. Use Ext.create() instead.');
- return Ext.create.apply(Ext, arguments);
- },
- /**
- * @private
- * @param name
- * @param args
- */
- dynInstantiate: function(name, args) {
- args = arrayFrom(args, true);
- args.unshift(name);
- return Ext.create.apply(Ext, args);
- },
- /**
- * @private
- * @param length
- */
- getInstantiator: function(length) {
- var instantiators = this.instantiators,
- instantiator, args, i;
- instantiator = instantiators[length];
- if (!instantiator) {
- i = length;
- args = [];
- for (i = 0; i < length; i++) {
- args.push('a[' + i + ']');
- }
- instantiator = instantiators[length] = new Function('c', 'a', 'return new c(' + args.join(',') + ')');
- instantiator.name = "Ext.create" + length;
- }
- return instantiator;
- },
- /**
- * @private
- */
- postprocessors: {},
- /**
- * @private
- */
- defaultPostprocessors: [],
- /**
- * Register a post-processor function.
- *
- * @param {String} name
- * @param {Function} fn
- * @param {String/String[]} properties
- * @param {String} position
- * @param {String} relativeTo
- * @private
- */
- registerPostprocessor: function(name, fn, properties, position, relativeTo) {
- if (!position) {
- position = 'last';
- }
- if (!properties) {
- properties = [
- name
- ];
- }
- this.postprocessors[name] = {
- name: name,
- properties: properties || false,
- fn: fn
- };
- this.setDefaultPostprocessorPosition(name, position, relativeTo);
- return this;
- },
- /**
- * Set the default post processors array stack which are applied to every class.
- *
- * @private
- * @param {String/Array} postprocessors The name of a registered post processor or an array
- * of registered names.
- * @return {Ext.ClassManager} this
- */
- setDefaultPostprocessors: function(postprocessors) {
- this.defaultPostprocessors = arrayFrom(postprocessors);
- return this;
- },
- /**
- * Insert this post-processor at a specific position in the stack, optionally relative to
- * any existing post-processor
- *
- * @private
- * @param {String} name The post-processor name. Note that it needs to be registered with
- * {@link Ext.ClassManager#registerPostprocessor} before this
- * @param {String} offset The insertion position. Four possible values are:
- * 'first', 'last', or: 'before', 'after' (relative to the name provided in the third
- * argument)
- * @param {String} relativeName
- * @return {Ext.ClassManager} this
- */
- setDefaultPostprocessorPosition: function(name, offset, relativeName) {
- var defaultPostprocessors = this.defaultPostprocessors,
- index;
- if (typeof offset === 'string') {
- if (offset === 'first') {
- defaultPostprocessors.unshift(name);
- return this;
- } else if (offset === 'last') {
- defaultPostprocessors.push(name);
- return this;
- }
- offset = (offset === 'after') ? 1 : -1;
- }
- index = Ext.Array.indexOf(defaultPostprocessors, relativeName);
- if (index !== -1) {
- Ext.Array.splice(defaultPostprocessors, Math.max(0, index + offset), 0, name);
- }
- return this;
- }
- });
- /* eslint-disable indent */
- /**
- * @cfg xtype
- * @member Ext.Class
- * @inheritdoc Ext.Component#cfg-xtype
- */
- /**
- * @cfg {String} override
- * @member Ext.Class
- * Overrides members of the specified `target` class.
- *
- * **NOTE:** the overridden class must have been defined using
- * {@link Ext#define Ext.define} in order to use the `override` config.
- *
- * Methods defined on the overriding class will not automatically call the methods of
- * the same name in the ancestor class chain. To call the parent's method of the
- * same name you must call {@link Ext.Base#method!callParent callParent}. To skip the
- * method of the overridden class and call its parent you will instead call
- * {@link Ext.Base#method!callSuper callSuper}.
- *
- * See {@link Ext#define Ext.define} for additional usage examples.
- */
- /**
- * @cfg {Object} platformConfig
- * Allows setting config values for a class based on specific platforms. The value
- * of this config is an object whose properties are "rules" and whose values are
- * objects containing config values.
- *
- * For example:
- *
- * Ext.define('App.view.Foo', {
- * extend: 'Ext.panel.Panel',
- *
- * platformConfig: {
- * desktop: {
- * title: 'Some Rather Descriptive Title'
- * },
- *
- * '!desktop': {
- * title: 'Short Title'
- * }
- * }
- * });
- *
- * In the above, "desktop" and "!desktop" are (mutually exclusive) rules. Whichever
- * evaluates to `true` will have its configs applied to the class. In this case, only
- * the "title" property, but the object can contain any number of config properties.
- * In this case, the `platformConfig` is evaluated as part of the class and there is
- * no cost for each instance created.
- *
- * The rules are evaluated expressions in the context of the platform tags contained
- * in `{@link Ext#platformTags Ext.platformTags}`. Any properties of that object are
- * implicitly usable (as shown above).
- *
- * If a `platformConfig` specifies a config value, it will replace any values declared
- * on the class itself.
- *
- * Use of `platformConfig` on instances is handled by the config system when classes
- * call `{@link Ext.Base#initConfig initConfig}`. For example:
- *
- * Ext.create({
- * xtype: 'panel',
- *
- * platformConfig: {
- * desktop: {
- * title: 'Some Rather Descriptive Title'
- * },
- *
- * '!desktop': {
- * title: 'Short Title'
- * }
- * }
- * });
- *
- * The following is equivalent to the above:
- *
- * if (Ext.platformTags.desktop) {
- * Ext.create({
- * xtype: 'panel',
- * title: 'Some Rather Descriptive Title'
- * });
- * } else {
- * Ext.create({
- * xtype: 'panel',
- * title: 'Short Title'
- * });
- * }
- *
- * To adjust configs based on dynamic conditions, see `{@link Ext.mixin.Responsive}`.
- */
- Manager.registerPostprocessor('platformConfig', function(name, Class, data) {
- Class.addPlatformConfig(data);
- });
- /**
- * @cfg {String/String[]} alias
- * @member Ext.Class
- * List of short aliases for class names. An alias consists of a namespace and a name
- * concatenated by a period as <namespace>.<name>
- *
- * - **namespace** - The namespace describes what kind of alias this is and must be
- * all lowercase.
- * - **name** - The name of the alias which allows the lazy-instantiation via the
- * alias. The name shouldn't contain any periods.
- *
- * A list of namespaces and the usages are:
- *
- * - **feature** - {@link Ext.grid.Panel Grid} features
- * - **plugin** - Plugins
- * - **store** - {@link Ext.data.Store}
- * - **widget** - Components
- *
- * Most useful for defining xtypes for widgets:
- *
- * Ext.define('MyApp.CoolPanel', {
- * extend: 'Ext.panel.Panel',
- * alias: ['widget.coolpanel'],
- * title: 'Yeah!'
- * });
- *
- * // Using Ext.create
- * Ext.create('widget.coolpanel');
- *
- * // Using the shorthand for defining widgets by xtype
- * Ext.widget('panel', {
- * items: [
- * {xtype: 'coolpanel', html: 'Foo'},
- * {xtype: 'coolpanel', html: 'Bar'}
- * ]
- * });
- */
- Manager.registerPostprocessor('alias', function(name, cls, data) {
- if (Ext.classSystemMonitor) {
- Ext.classSystemMonitor(name, 'Ext.ClassManager#aliasPostProcessor', arguments);
- }
- /* eslint-disable-next-line vars-on-top */
- var aliases = Ext.Array.from(data.alias),
- i, ln;
- for (i = 0 , ln = aliases.length; i < ln; i++) {
- alias = aliases[i];
- this.addAlias(cls, alias);
- }
- }, [
- 'xtype',
- 'alias'
- ]);
- /**
- * @cfg {Boolean} singleton
- * @member Ext.Class
- * When set to true, the class will be instantiated as singleton. For example:
- *
- * Ext.define('Logger', {
- * singleton: true,
- * log: function(msg) {
- * console.log(msg);
- * }
- * });
- *
- * Logger.log('Hello');
- */
- Manager.registerPostprocessor('singleton', function(name, cls, data, fn) {
- if (Ext.classSystemMonitor) {
- Ext.classSystemMonitor(name, 'Ext.ClassManager#singletonPostProcessor', arguments);
- }
- if (data.singleton) {
- fn.call(this, name, new cls(), data);
- } else {
- return true;
- }
- return false;
- });
- /**
- * @cfg {String/String[]} alternateClassName
- * @member Ext.Class
- * Defines alternate names for this class. For example:
- *
- * Ext.define('Developer', {
- * alternateClassName: ['Coder', 'Hacker'],
- * code: function(msg) {
- * alert('Typing... ' + msg);
- * }
- * });
- *
- * var joe = Ext.create('Developer');
- * joe.code('stackoverflow');
- *
- * var rms = Ext.create('Hacker');
- * rms.code('hack hack');
- */
- Manager.registerPostprocessor('alternateClassName', function(name, cls, data) {
- var alternates = data.alternateClassName,
- i, ln, alternate;
- if (Ext.classSystemMonitor) {
- Ext.classSystemMonitor(name, 'Ext.ClassManager#alternateClassNamePostprocessor', arguments);
- }
- if (!(alternates instanceof Array)) {
- alternates = [
- alternates
- ];
- }
- for (i = 0 , ln = alternates.length; i < ln; i++) {
- alternate = alternates[i];
- if (typeof alternate !== 'string') {
- throw new Error("[Ext.define] Invalid alternate of: '" + alternate + "' for class: '" + name + "'; must be a valid string");
- }
- this.set(alternate, cls);
- }
- });
- /**
- * @cfg {Object} debugHooks
- * A collection of diagnostic methods to decorate the real methods of the class. These
- * methods are applied as an `override` if this class has debug enabled as defined by
- * `Ext.isDebugEnabled`.
- *
- * These will be automatically removed by the Sencha Cmd compiler for production builds.
- *
- * Example usage:
- *
- * Ext.define('Foo.bar.Class', {
- * foo: function(a, b, c) {
- * ...
- * },
- *
- * bar: function(a, b) {
- * ...
- * return 42;
- * },
- *
- * debugHooks: {
- * foo: function(a, b, c) {
- * // check arguments...
- * return this.callParent(arguments);
- * }
- * }
- * });
- *
- * If you specify a `$enabled` property in the `debugHooks` object that will be used
- * as the default enabled state for the hooks. If the `{@link Ext#manifest}` contains
- * a `debug` object of if `{@link Ext#debugConfig}` is specified, the `$enabled` flag
- * will override its "*" value.
- */
- Manager.registerPostprocessor('debugHooks', function(name, Class, data) {
- var target;
- if (Ext.classSystemMonitor) {
- Ext.classSystemMonitor(Class, 'Ext.Class#debugHooks', arguments);
- }
- if (Ext.isDebugEnabled(Class.$className, data.debugHooks.$enabled)) {
- delete data.debugHooks.$enabled;
- Ext.override(Class, data.debugHooks);
- }
- // may already have an instance here in the case of singleton
- target = Class.isInstance ? Class.self : Class;
- delete target.prototype.debugHooks;
- });
- /**
- * @cfg {Object} deprecated
- * The object given has properties that describe the versions at which the deprecations
- * apply.
- *
- * The purpose of the `deprecated` declaration is to enable development mode to give
- * suitable error messages when deprecated methods or properties are used. Methods can
- * always be injected to provide this feedback, but properties can only be handled on
- * some browsers (those that support `Object.defineProperty`).
- *
- * In some cases, deprecated methods can be restored to their previous behavior or
- * added back if they have been removed.
- *
- * The structure of a `deprecated` declaration is this:
- *
- * Ext.define('Foo.bar.Class', {
- * ...
- *
- * deprecated: {
- * // Optional package name - default is the framework (ext or touch)
- * name: 'foobar',
- *
- * '5.0': {
- * methods: {
- * // Throws: '"removedMethod" is deprecated.'
- * removedMethod: null,
- *
- * // Throws: '"oldMethod" is deprecated. Please use "newMethod" instead.'
- * oldMethod: 'newMethod',
- *
- * // When this block is enabled, this method is applied as an
- * // override. Otherwise you get same as "removeMethod".
- * method: function() {
- * // Do what v5 "method" did. If "method" exists in newer
- * // versions callParent can call it. If 5.1 has "method"
- * // then it would be next in line, otherwise 5.2 and last
- * // would be the current class.
- * },
- *
- * moreHelpful: {
- * message: 'Something helpful to do instead.',
- * fn: function() {
- * // The v5 "moreHelpful" method to use when enabled.
- * }
- * }
- * },
- * properties: {
- * // Throws: '"removedProp" is deprecated.'
- * removedProp: null,
- *
- * // Throws: '"oldProp" is deprecated. Please use "newProp" instead.'
- * oldProp: 'newProp',
- *
- * helpful: {
- * message: 'Something helpful message about what to do.'
- * }
- * ...
- * },
- * statics: {
- * methods: {
- * ...
- * },
- * properties: {
- * ...
- * },
- * }
- * },
- *
- * '5.1': {
- * ...
- * },
- *
- * '5.2': {
- * ...
- * }
- * }
- * });
- *
- * The primary content of `deprecated` are the version number keys. These indicate
- * a version number where methods or properties were deprecated. These versions are
- * compared to the version reported by `Ext.getCompatVersion` to determine the action
- * to take for each "block".
- *
- * When the compatibility version is set to a value less than a version number key,
- * that block is said to be "enabled". For example, if a method was deprecated in
- * version 5.0 but the desired compatibility level is 4.2 then the block is used to
- * patch methods and (to some degree) restore pre-5.0 compatibility.
- *
- * When multiple active blocks have the same method name, each method is applied as
- * an override in reverse order of version. In the above example, if a method appears
- * in the "5.0", "5.1" and "5.2" blocks then the "5.2" method is applied as an override
- * first, followed by the "5.1" method and finally the "5.0" method. This means that
- * the `callParent` from the "5.0" method calls the "5.1" method which calls the
- * "5.2" method which can (if applicable) call the current version.
- */
- Manager.registerPostprocessor('deprecated', function(name, Class, data) {
- var target;
- if (Ext.classSystemMonitor) {
- Ext.classSystemMonitor(Class, 'Ext.Class#deprecated', arguments);
- }
- // may already have an instance here in the case of singleton
- target = Class.isInstance ? Class.self : Class;
- target.addDeprecations(data.deprecated);
- delete target.prototype.deprecated;
- });
- Ext.apply(Ext, {
- /**
- * Instantiate a class by either full name, alias or alternate name.
- *
- * If {@link Ext.Loader} is {@link Ext.Loader#setConfig enabled} and the class has
- * not been defined yet, it will attempt to load the class via synchronous loading.
- *
- * For example, all these three lines return the same result:
- *
- * // xtype
- * var window = Ext.create({
- * xtype: 'window',
- * width: 600,
- * height: 800,
- * ...
- * });
- *
- * // alias
- * var window = Ext.create('widget.window', {
- * width: 600,
- * height: 800,
- * ...
- * });
- *
- * // alternate name
- * var window = Ext.create('Ext.Window', {
- * width: 600,
- * height: 800,
- * ...
- * });
- *
- * // full class name
- * var window = Ext.create('Ext.window.Window', {
- * width: 600,
- * height: 800,
- * ...
- * });
- *
- * // single object with xclass property:
- * var window = Ext.create({
- * xclass: 'Ext.window.Window', // any valid value for 'name' (above)
- * width: 600,
- * height: 800,
- * ...
- * });
- *
- * @param {String} [name] The class name or alias. Can be specified as `xclass`
- * property if only one object parameter is specified.
- * @param {Object...} [args] Additional arguments after the name will be passed to
- * the class' constructor.
- * @return {Object} instance
- * @member Ext
- * @method create
- */
- create: function() {
- var name = arguments[0],
- nameType = typeof name,
- args = arraySlice.call(arguments, 1),
- cls;
- if (nameType === 'function') {
- cls = name;
- } else {
- if (nameType !== 'string' && args.length === 0) {
- args = [
- name
- ];
- if (!(name = name.xclass)) {
- name = args[0].xtype;
- if (name) {
- name = 'widget.' + name;
- }
- }
- }
- if (typeof name !== 'string' || name.length < 1) {
- throw new Error("[Ext.create] Invalid class name or alias '" + name + "' specified, must be a non-empty string");
- }
- name = Manager.resolveName(name);
- cls = Manager.get(name);
- }
- // Still not existing at this point, try to load it via synchronous mode as the last
- // resort
- if (!cls) {
- Ext.syncRequire(name);
- cls = Manager.get(name);
- }
- if (!cls) {
- throw new Error("[Ext.create] Unrecognized class name / alias: " + name);
- }
- if (typeof cls !== 'function') {
- throw new Error("[Ext.create] Singleton '" + name + "' cannot be instantiated.");
- }
- return Manager.getInstantiator(args.length)(cls, args);
- },
- /**
- * Convenient shorthand to create a widget by its xtype or a config object.
- *
- * var button = Ext.widget('button'); // Equivalent to Ext.create('widget.button');
- *
- * var panel = Ext.widget('panel', { // Equivalent to Ext.create('widget.panel')
- * title: 'Panel'
- * });
- *
- * var grid = Ext.widget({
- * xtype: 'grid',
- * ...
- * });
- *
- * If a {@link Ext.Component component} instance is passed, it is simply returned.
- *
- * @member Ext
- * @param {String} [name] The xtype of the widget to create.
- * @param {Object} [config] The configuration object for the widget constructor.
- * @return {Object} The widget instance
- */
- widget: function(name, config) {
- // forms:
- // 1: (xtype)
- // 2: (xtype, config)
- // 3: (config)
- // 4: (xtype, component)
- // 5: (component)
- //
- var xtype = name,
- alias, className, T;
- if (typeof xtype !== 'string') {
- // if (form 3 or 5)
- // first arg is config or component
- config = name;
- // arguments[0]
- xtype = config.xtype;
- className = config.xclass;
- } else {
- config = config || {};
- }
- if (config.isComponent) {
- return config;
- }
- if (!className) {
- alias = 'widget.' + xtype;
- className = Manager.getNameByAlias(alias);
- }
- // this is needed to support demand loading of the class
- if (className) {
- T = Manager.get(className);
- }
- if (!T) {
- return Ext.create(className || alias, config);
- }
- return new T(config);
- },
- /**
- * @method createByAlias
- * @inheritdoc Ext.ClassManager#method-instantiateByAlias
- * @member Ext
- */
- createByAlias: alias(Manager, 'instantiateByAlias'),
- /**
- * Defines a class or override. A basic class is defined like this:
- *
- * Ext.define('My.awesome.Class', {
- * someProperty: 'something',
- *
- * someMethod: function(s) {
- * alert(s + this.someProperty);
- * }
- *
- * ...
- * });
- *
- * var obj = new My.awesome.Class();
- *
- * obj.someMethod('Say '); // alerts 'Say something'
- *
- * To create an anonymous class, pass `null` for the `className`:
- *
- * Ext.define(null, {
- * constructor: function() {
- * // ...
- * }
- * });
- *
- * In some cases, it is helpful to create a nested scope to contain some private
- * properties. The best way to do this is to pass a function instead of an object
- * as the second parameter. This function will be called to produce the class
- * body:
- *
- * Ext.define('MyApp.foo.Bar', function() {
- * var id = 0;
- *
- * return {
- * nextId: function() {
- * return ++id;
- * }
- * };
- * });
- *
- * _Note_ that when using override, the above syntax will not override successfully,
- * because the passed function would need to be executed first to determine whether or not
- * the result is an override or defining a new object. As such, an alternative syntax that
- * immediately invokes the function can be used:
- *
- * Ext.define('MyApp.override.BaseOverride', function() {
- * var counter = 0;
- *
- * return {
- * override: 'Ext.Component',
- * logId: function() {
- * console.log(++counter, this.id);
- * }
- * };
- * }());
- *
- *
- * When using this form of `Ext.define`, the function is passed a reference to its
- * class. This can be used as an efficient way to access any static properties you
- * may have:
- *
- * Ext.define('MyApp.foo.Bar', function(Bar) {
- * return {
- * statics: {
- * staticMethod: function() {
- * // ...
- * }
- * },
- *
- * method: function() {
- * return Bar.staticMethod();
- * }
- * };
- * });
- *
- * To define an override, include the `override` property. The content of an
- * override is aggregated with the specified class in order to extend or modify
- * that class. This can be as simple as setting default property values or it can
- * extend and/or replace methods. This can also extend the statics of the class.
- *
- * One use for an override is to break a large class into manageable pieces.
- *
- * // File: /src/app/Panel.js
- *
- * Ext.define('My.app.Panel', {
- * extend: 'Ext.panel.Panel',
- * requires: [
- * 'My.app.PanelPart2',
- * 'My.app.PanelPart3'
- * ]
- *
- * constructor: function(config) {
- * this.callParent(arguments); // calls Ext.panel.Panel's constructor
- * //...
- * },
- *
- * statics: {
- * method: function() {
- * return 'abc';
- * }
- * }
- * });
- *
- * // File: /src/app/PanelPart2.js
- * Ext.define('My.app.PanelPart2', {
- * override: 'My.app.Panel',
- *
- * constructor: function(config) {
- * this.callParent(arguments); // calls My.app.Panel's constructor
- * //...
- * }
- * });
- *
- * Another use of overrides is to provide optional parts of classes that can be
- * independently required. In this case, the class may even be unaware of the
- * override altogether.
- *
- * Ext.define('My.ux.CoolTip', {
- * override: 'Ext.tip.ToolTip',
- *
- * constructor: function(config) {
- * this.callParent(arguments); // calls Ext.tip.ToolTip's constructor
- * //...
- * }
- * });
- *
- * The above override can now be required as normal.
- *
- * Ext.define('My.app.App', {
- * requires: [
- * 'My.ux.CoolTip'
- * ]
- * });
- *
- * Overrides can also contain statics, inheritableStatics, or privates:
- *
- * Ext.define('My.app.BarMod', {
- * override: 'Ext.foo.Bar',
- *
- * statics: {
- * method: function(x) {
- * return this.callParent([x * 2]); // call Ext.foo.Bar.method
- * }
- * }
- * });
- *
- * Starting in version 4.2.2, overrides can declare their `compatibility` based
- * on the framework version or on versions of other packages. For details on the
- * syntax and options for these checks, see `Ext.checkVersion`.
- *
- * The simplest use case is to test framework version for compatibility:
- *
- * Ext.define('App.overrides.grid.Panel', {
- * override: 'Ext.grid.Panel',
- *
- * compatibility: '4.2.2', // only if framework version is 4.2.2
- *
- * //...
- * });
- *
- * An array is treated as an OR, so if any specs match, the override is
- * compatible.
- *
- * Ext.define('App.overrides.some.Thing', {
- * override: 'Foo.some.Thing',
- *
- * compatibility: [
- * '4.2.2',
- * 'foo@1.0.1-1.0.2'
- * ],
- *
- * //...
- * });
- *
- * To require that all specifications match, an object can be provided:
- *
- * Ext.define('App.overrides.some.Thing', {
- * override: 'Foo.some.Thing',
- *
- * compatibility: {
- * and: [
- * '4.2.2',
- * 'foo@1.0.1-1.0.2'
- * ]
- * },
- *
- * //...
- * });
- *
- * Because the object form is just a recursive check, these can be nested:
- *
- * Ext.define('App.overrides.some.Thing', {
- * override: 'Foo.some.Thing',
- *
- * compatibility: {
- * and: [
- * '4.2.2', // exactly version 4.2.2 of the framework *AND*
- * {
- * // either (or both) of these package specs:
- * or: [
- * 'foo@1.0.1-1.0.2',
- * 'bar@3.0+'
- * ]
- * }
- * ]
- * },
- *
- * //...
- * });
- *
- * IMPORTANT: An override is only included in a build if the class it overrides is
- * required. Otherwise, the override, like the target class, is not included. In
- * Sencha Cmd v4, the `compatibility` declaration can likewise be used to remove
- * incompatible overrides from a build.
- *
- * @param {String} className The class name to create in string dot-namespaced format,
- * for example: 'My.very.awesome.Class', 'FeedViewer.plugin.CoolPager'
- *
- * It is highly recommended to follow this simple convention:
- * - The root and the class name are 'CamelCased'
- * - Everything else is lower-cased
- * Pass `null` to create an anonymous class.
- * @param {Object} data The key - value pairs of properties to apply to this class.
- * Property names can be of any valid strings, except those in the reserved listed below:
- *
- * - {@link Ext.Class#cfg-alias alias}
- * - {@link Ext.Class#cfg-alternateClassName alternateClassName}
- * - {@link Ext.Class#cfg-cachedConfig cachedConfig}
- * - {@link Ext.Class#cfg-config config}
- * - {@link Ext.Class#cfg-extend extend}
- * - {@link Ext.Class#cfg-inheritableStatics inheritableStatics}
- * - {@link Ext.Class#cfg-mixins mixins}
- * - {@link Ext.Class#cfg-override override}
- * - {@link Ext.Class#cfg-platformConfig platformConfig}
- * - {@link Ext.Class#cfg-privates privates}
- * - {@link Ext.Class#cfg-requires requires}
- * - `self`
- * - {@link Ext.Class#cfg-singleton singleton}
- * - {@link Ext.Class#cfg-statics statics}
- * - {@link Ext.Class#cfg-uses uses}
- * - {@link Ext.Class#cfg-xtype xtype} (for {@link Ext.Component Components} only)
- *
- * @param {Function} [createdFn] Callback to execute after the class is created,
- * the execution scope of which (`this`) will be the newly created class itself.
- * @return {Ext.Base}
- * @member Ext
- */
- define: function(className, data, createdFn) {
- if (Ext.classSystemMonitor) {
- Ext.classSystemMonitor(className, 'ClassManager#define', arguments);
- }
- if (data.override) {
- Manager.classState[className] = 20;
- return Manager.createOverride.apply(Manager, arguments);
- }
- Manager.classState[className] = 10;
- return Manager.create.apply(Manager, arguments);
- },
- /**
- * Undefines a class defined using the #define method. Typically used
- * for unit testing where setting up and tearing down a class multiple
- * times is required. For example:
- *
- * // define a class
- * Ext.define('Foo', {
- * ...
- * });
- *
- * // run test
- *
- * // undefine the class
- * Ext.undefine('Foo');
- * @param {String} className The class name to undefine in string dot-namespaced format.
- * @private
- */
- undefine: function(className) {
- var classes = Manager.classes;
- if (Ext.classSystemMonitor) {
- Ext.classSystemMonitor(className, 'Ext.ClassManager#undefine', arguments);
- }
- if (classes[className]) {
- Manager.classCount--;
- }
- delete classes[className];
- delete Manager.existCache[className];
- delete Manager.classState[className];
- Manager.removeName(className);
- // Indiscriminately clear all factory caches here. It might be slightly inefficient
- // however undefine is typically only called during unit testing.
- Ext.Factory.clearCaches();
- /* eslint-disable-next-line vars-on-top */
- var entry = Manager.getNamespaceEntry(className),
- scope = entry.parent ? Manager.lookupName(entry.parent, false) : Ext.global,
- entryName;
- if (scope) {
- entryName = entry.name;
- // Old IE blows up on attempt to delete window property
- try {
- delete scope[entryName];
- } catch (e) {
- scope[entryName] = undefined;
- }
- }
- // We need to know entry name in unit tests
- return entryName;
- },
- /**
- * @method getClassName
- * @inheritdoc Ext.ClassManager#method-getName
- * @member Ext
- */
- getClassName: alias(Manager, 'getName'),
- /**
- * Returns the displayName property or className or object. When all else fails,
- * returns "Anonymous".
- * @param {Object} object
- * @return {String}
- */
- getDisplayName: function(object) {
- if (object) {
- if (object.displayName) {
- return object.displayName;
- }
- if (object.$name && object.$class) {
- return Ext.getClassName(object.$class) + '#' + object.$name;
- }
- if (object.$className) {
- return object.$className;
- }
- }
- return 'Anonymous';
- },
- /**
- * @method getClass
- * @inheritdoc Ext.ClassManager#method-getClass
- * @member Ext
- */
- getClass: alias(Manager, 'getClass'),
- /**
- * Creates namespaces to be used for scoping variables and classes so that they are not
- * global. Specifying the last node of a namespace implicitly creates all other nodes.
- * Usage:
- *
- * Ext.namespace('Company', 'Company.data');
- *
- * // equivalent and preferable to the above syntax
- * Ext.ns('Company.data');
- *
- * Company.Widget = function() { ... };
- *
- * Company.data.CustomStore = function(config) { ... };
- *
- * @param {String...} namespaces
- * @return {Object} The (last) namespace object created.
- * @member Ext
- * @method namespace
- */
- namespace: function() {
- var root = global,
- i;
- for (i = arguments.length; i-- > 0; ) {
- root = Manager.lookupName(arguments[i], true);
- }
- return root;
- }
- });
- /**
- * This function registers top-level (root) namespaces. This is needed for "sandbox"
- * builds.
- *
- * Ext.addRootNamespaces({
- * MyApp: MyApp,
- * Common: Common
- * });
- *
- * In the above example, `MyApp` and `Common` are top-level namespaces that happen
- * to also be included in the sandbox closure. Something like this:
- *
- * (function(Ext) {
- *
- * Ext.sandboxName = 'Ext6';
- * Ext.isSandboxed = true;
- * Ext.buildSettings = { baseCSSPrefix: "x6-", scopeResetCSS: true };
- *
- * var MyApp = MyApp || {};
- * Ext.addRootNamespaces({ MyApp: MyApp );
- *
- * ... normal app.js goes here ...
- *
- * })(this.Ext6 || (this.Ext6 = {}));
- *
- * The sandbox wrapper around the normally built `app.js` content has to take care
- * of introducing top-level namespaces as well as call this method.
- *
- * @param {Object} namespaces
- * @method addRootNamespaces
- * @member Ext
- * @since 6.0.0
- * @private
- */
- Ext.addRootNamespaces = Manager.addRootNamespaces;
- /**
- * Old name for {@link Ext#widget}.
- * @deprecated 5.0 Use {@link Ext#widget} instead.
- * @method createWidget
- * @member Ext
- * @private
- */
- Ext.createWidget = Ext.widget;
- /**
- * @method ns
- * Convenient alias for {@link Ext#namespace Ext.namespace}.
- * @inheritdoc Ext#method-namespace
- * @member Ext
- */
- Ext.ns = Ext.namespace;
- Class.registerPreprocessor('className', function(cls, data) {
- if ('$className' in data) {
- cls.$className = data.$className;
- cls.displayName = cls.$className;
- }
- if (Ext.classSystemMonitor) {
- Ext.classSystemMonitor(cls, 'Ext.ClassManager#classNamePreprocessor', arguments);
- }
- }, true, 'first');
- Class.registerPreprocessor('alias', function(cls, data) {
- if (Ext.classSystemMonitor) {
- Ext.classSystemMonitor(cls, 'Ext.ClassManager#aliasPreprocessor', arguments);
- }
- /* eslint-disable-next-line vars-on-top */
- var prototype = cls.prototype,
- xtypes = arrayFrom(data.xtype),
- aliases = arrayFrom(data.alias),
- widgetPrefix = 'widget.',
- widgetPrefixLength = widgetPrefix.length,
- xtypesChain = Array.prototype.slice.call(prototype.xtypesChain || []),
- xtypesMap = Ext.merge({}, prototype.xtypesMap || {}),
- i, ln, alias, xtype;
- for (i = 0 , ln = aliases.length; i < ln; i++) {
- alias = aliases[i];
- if (typeof alias !== 'string' || alias.length < 1) {
- throw new Error("[Ext.define] Invalid alias of: '" + alias + "' for class: '" + name + "'; must be a valid string");
- }
- if (alias.substring(0, widgetPrefixLength) === widgetPrefix) {
- xtype = alias.substring(widgetPrefixLength);
- Ext.Array.include(xtypes, xtype);
- }
- }
- cls.xtype = data.xtype = xtypes[0];
- data.xtypes = xtypes;
- for (i = 0 , ln = xtypes.length; i < ln; i++) {
- xtype = xtypes[i];
- if (!xtypesMap[xtype]) {
- xtypesMap[xtype] = true;
- xtypesChain.push(xtype);
- }
- }
- data.xtypesChain = xtypesChain;
- data.xtypesMap = xtypesMap;
- // Class is already extended at this point
- Ext.Function.interceptAfterOnce(cls, 'onClassCreated', function() {
- var cls = this,
- prototype = cls.prototype,
- mixins = prototype.mixins,
- key, mixin;
- if (Ext.classSystemMonitor) {
- Ext.classSystemMonitor(cls, 'Ext.ClassManager#aliasPreprocessor#afterClassCreated', arguments);
- }
- for (key in mixins) {
- if (mixins.hasOwnProperty(key)) {
- mixin = mixins[key];
- xtypes = mixin.xtypes;
- if (xtypes) {
- for (i = 0 , ln = xtypes.length; i < ln; i++) {
- xtype = xtypes[i];
- if (!xtypesMap[xtype]) {
- xtypesMap[xtype] = true;
- xtypesChain.push(xtype);
- }
- }
- }
- }
- }
- });
- for (i = 0 , ln = xtypes.length; i < ln; i++) {
- xtype = xtypes[i];
- if (typeof xtype !== 'string' || xtype.length < 1) {
- throw new Error("[Ext.define] Invalid xtype of: '" + xtype + "' for class: '" + name + "'; must be a valid non-empty string");
- }
- Ext.Array.include(aliases, widgetPrefix + xtype);
- }
- data.alias = aliases;
- }, [
- 'xtype',
- 'alias'
- ]);
- // load the cmd-5 style app manifest metadata now, if available...
- if (Ext.manifest) {
- /* eslint-disable-next-line vars-on-top */
- var manifest = Ext.manifest,
- classes = manifest.classes,
- paths = manifest.paths,
- aliases = {},
- alternates = {},
- className, obj, name, path, baseUrl;
- if (paths) {
- // if the manifest paths were calculated as relative to the
- // bootstrap file, then we need to prepend Boot.baseUrl to the
- // paths before processing
- if (manifest.bootRelative) {
- baseUrl = Ext.Boot.baseUrl;
- for (path in paths) {
- if (paths.hasOwnProperty(path)) {
- paths[path] = baseUrl + paths[path];
- }
- }
- }
- Manager.setPath(paths);
- }
- if (classes) {
- for (className in classes) {
- alternates[className] = [];
- aliases[className] = [];
- obj = classes[className];
- if (obj.alias) {
- aliases[className] = obj.alias;
- }
- if (obj.alternates) {
- alternates[className] = obj.alternates;
- }
- }
- }
- Manager.addAlias(aliases);
- Manager.addAlternate(alternates);
- }
- return Manager;
- }(Ext.Class, Ext.Function.alias, Array.prototype.slice, Ext.Array.from, Ext.global));
- // @tag class
- /**
- *
- * @since 6.7.0
- * @private
- */
- Ext.define('Ext.mixin.Watchable', {
- on: function(name, fn, scope) {
- return this._watchUpdate(false, '_watchAdd', name, fn, scope);
- },
- fire: function(event, args) {
- var me = this,
- watching = me.watching,
- watchers = watching && watching[event],
- fn, i, r, scope;
- if (watchers) {
- ++watchers.$firing;
- for (i = 0; i < watchers.length; ++i) {
- scope = watchers[i][0];
- fn = watchers[i][1];
- if (fn.charAt) {
- r = args ? scope[fn].apply(scope, args) : scope[fn]();
- } else {
- r = args ? fn.apply(scope, args) : fn.call(scope);
- }
- if (r === false) {
- return r;
- }
- }
- --watchers.$firing;
- }
- },
- fireEvent: function() {
- var args = Ext.Array.slice(arguments),
- event = args.shift();
- return this.fire(event, args);
- },
- un: function(name, fn, scope) {
- return this._watchUpdate(true, '_watchRemove', name, fn, scope);
- },
- privates: {
- watching: null,
- $watchOptions: {
- destroyable: 1,
- scope: 1
- },
- _watchAdd: function(watching, name, fn, scope, destroyable) {
- if (typeof fn === 'string' && !scope[fn]) {
- Ext.raise('No such method "' + fn + '" on ' + scope.$className);
- }
- // eslint-disable-next-line vars-on-top
- var watchers = watching[name],
- entry = [
- scope,
- fn
- ],
- i, ent;
- if (!watchers) {
- watching[name] = watchers = [];
- watchers.$firing = 0;
- } else {
- // If the scope/fn pair is already registered, don't duplicate it.
- for (i = watchers.length; i-- > 0; ) /* empty */
- {
- ent = watchers[i];
- if (fn === ent[1]) {
- if (scope ? ent[0] === scope : !ent[0]) {
- return;
- }
- }
- }
- if (watchers.$firing) {
- watching[name] = watchers = watchers.slice();
- watchers.$firing = 0;
- }
- }
- watchers.push(entry);
- if (destroyable) {
- entry.push(name);
- destroyable.items.push(entry);
- }
- },
- _watchRemove: function(watching, name, fn, scope) {
- var watchers = watching[name],
- i;
- if (watchers) {
- if (watchers.$firing) {
- watching[name] = watchers = watchers.slice();
- watchers.$firing = 0;
- }
- for (i = watchers.length; i-- > 0; ) /* empty */
- {
- if (watchers[i][0] === scope && watchers[i][1] === fn) {
- watchers.splice(i, 1);
- }
- }
- }
- },
- _watchUpdate: function(remove, process, name, fn, scope) {
- var me = this,
- watch = name,
- watching = me.watching,
- destroyable;
- if (!watching) {
- if (remove) {
- return;
- }
- me.watching = watching = {};
- }
- if (typeof name === 'string') {
- me[process](watching, name, fn, scope);
- } else {
- destroyable = watch.destroyable ? {
- owner: me,
- items: [],
- destroy: me._watcherDestroyer
- } : null;
- scope = watch.scope;
- for (name in watch) {
- if (!me.$watchOptions[name]) {
- me[process](watching, name, watch[name], scope, destroyable);
- }
- }
- }
- return destroyable;
- },
- _watcherDestroyer: function() {
- var me = this.owner,
- watching = me.watching,
- items = this.items,
- entry, i;
- for (i = 0; i < items.length; ++i) {
- entry = items[i];
- me._watchRemove(watching, entry[2], entry[1], entry[0]);
- }
- }
- }
- });
- /**
- * @class Ext.env.Browser
- * Provides information about browser.
- *
- * Should not be manually instantiated unless for unit-testing.
- * Access the global instance stored in {@link Ext.browser} instead.
- * @private
- */
- (Ext.env || (Ext.env = {})).Browser = function(userAgent, publish) {
- // @define Ext.env.Browser
- // @define Ext.browser
- // @require Ext.Object
- // @require Ext.Version
- var me = this,
- browserPrefixes = Ext.Boot.browserPrefixes,
- browserNames = Ext.Boot.browserNames,
- enginePrefixes = me.enginePrefixes,
- engineNames = me.engineNames,
- browserMatch = userAgent.match(new RegExp('((?:' + Ext.Object.getValues(browserPrefixes).join(')|(?:') + '))([\\w\\._]+)')),
- engineMatch = userAgent.match(new RegExp('((?:' + Ext.Object.getValues(enginePrefixes).join(')|(?:') + '))([\\w\\._]+)')),
- browserName = browserNames.other,
- engineName = engineNames.other,
- browserVersion = '',
- engineVersion = '',
- majorVer = '',
- isWebView = false,
- edgeRE = /(Edge\/)([\w.]+)/,
- ripple = '',
- i, prefix, name;
- /**
- * @property {String}
- * Browser User Agent string.
- */
- me.userAgent = userAgent;
- /**
- * A "hybrid" property, can be either accessed as a method call, for example:
- *
- * if (Ext.browser.is('IE')) {
- * // ...
- * }
- *
- * Or as an object with Boolean properties, for example:
- *
- * if (Ext.browser.is.IE) {
- * // ...
- * }
- *
- * Versions can be conveniently checked as well. For example:
- *
- * if (Ext.browser.is.IE10) {
- * // Equivalent to (Ext.browser.is.IE && Ext.browser.version.equals(10))
- * }
- *
- * __Note:__ Only {@link Ext.Version#getMajor major component} and
- * {@link Ext.Version#getShortVersion simplified} value of the version are available via
- * direct property checking.
- *
- * Supported values are:
- *
- * - IE
- * - Firefox
- * - Safari
- * - Chrome
- * - Opera
- * - WebKit
- * - Gecko
- * - Presto
- * - Trident
- * - WebView
- * - Other
- *
- * @param {String} name The OS name to check.
- * @return {Boolean}
- */
- this.is = function(name) {
- // Since this function reference also acts as a map, we do not want it to be
- // shared between instances, so it is defined here, not on the prototype.
- return !!this.is[name];
- };
- // Edge has a userAgent with All browsers so we manage it separately
- // "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)
- // Chrome/42.0.2311.135 Safari/537.36 Edge/12.10240"
- if (/Edge\//.test(userAgent)) {
- browserMatch = userAgent.match(edgeRE);
- engineMatch = userAgent.match(edgeRE);
- }
- if (browserMatch) {
- browserName = browserNames[Ext.Object.getKey(browserPrefixes, browserMatch[1])];
- if (browserName === 'Safari' && /^Opera/.test(userAgent)) {
- // Prevent Opera 12 and earlier from being incorrectly reported as Safari
- browserName = 'Opera';
- }
- browserVersion = new Ext.Version(browserMatch[2]);
- }
- if (engineMatch) {
- engineName = engineNames[Ext.Object.getKey(enginePrefixes, engineMatch[1])];
- engineVersion = new Ext.Version(engineMatch[2]);
- }
- if (engineName === 'Trident' && browserName !== 'IE') {
- browserName = 'IE';
- var version = userAgent.match(/.*rv:(\d+.\d+)/);
- // eslint-disable-line vars-on-top
- if (version && version.length) {
- version = version[1];
- browserVersion = new Ext.Version(version);
- }
- }
- if (browserName && browserVersion) {
- Ext.setVersion(browserName, browserVersion);
- }
- /**
- * @property chromeVersion
- * The current version of Chrome (0 if the browser is not Chrome).
- * @readonly
- * @type Number
- * @member Ext
- */
- /**
- * @property firefoxVersion
- * The current version of Firefox (0 if the browser is not Firefox).
- * @readonly
- * @type Number
- * @member Ext
- */
- /**
- * @property ieVersion
- * The current version of IE (0 if the browser is not IE). This does not account
- * for the documentMode of the current page, which is factored into {@link #isIE8},
- * and {@link #isIE9}. Thus this is not always true:
- *
- * Ext.isIE8 == (Ext.ieVersion == 8)
- *
- * @readonly
- * @type Number
- * @member Ext
- */
- /**
- * @property isChrome
- * True if the detected browser is Chrome.
- * @readonly
- * @type Boolean
- * @member Ext
- */
- /**
- * @property isGecko
- * True if the detected browser uses the Gecko layout engine (e.g. Mozilla, Firefox).
- * @readonly
- * @type Boolean
- * @member Ext
- */
- /**
- * @property isIE
- * True if the detected browser is Internet Explorer.
- * @readonly
- * @type Boolean
- * @member Ext
- */
- /**
- * @property isIE8
- * True if the detected browser is Internet Explorer 8.x.
- * @readonly
- * @type Boolean
- * @member Ext
- */
- /**
- * @property isIE8m
- * True if the detected browser is Internet Explorer 8.x or lower.
- * @readonly
- * @type Boolean
- * @member Ext
- */
- /**
- * @property isIE8p
- * True if the detected browser is Internet Explorer 8.x or higher.
- * @readonly
- * @type Boolean
- * @member Ext
- */
- /**
- * @property isIE9
- * True if the detected browser is Internet Explorer 9.x.
- * @readonly
- * @type Boolean
- * @member Ext
- */
- /**
- * @property isIE9m
- * True if the detected browser is Internet Explorer 9.x or lower.
- * @readonly
- * @type Boolean
- * @member Ext
- */
- /**
- * @property isIE9p
- * True if the detected browser is Internet Explorer 9.x or higher.
- * @readonly
- * @type Boolean
- * @member Ext
- */
- /**
- * @property isIE10
- * True if the detected browser is Internet Explorer 10.x.
- * @readonly
- * @type Boolean
- * @member Ext
- */
- /**
- * @property isIE10m
- * True if the detected browser is Internet Explorer 10.x or lower.
- * @readonly
- * @type Boolean
- * @member Ext
- */
- /**
- * @property isIE10p
- * True if the detected browser is Internet Explorer 10.x or higher.
- * @readonly
- * @type Boolean
- * @member Ext
- */
- /**
- * @property isIE11
- * True if the detected browser is Internet Explorer 11.x.
- * @readonly
- * @type Boolean
- * @member Ext
- */
- /**
- * @property isIE11m
- * True if the detected browser is Internet Explorer 11.x or lower.
- * @readonly
- * @type Boolean
- * @member Ext
- */
- /**
- * @property isIE11p
- * True if the detected browser is Internet Explorer 11.x or higher.
- * @readonly
- * @type Boolean
- * @member Ext
- */
- /**
- * @property isEdge
- * True if the detected browser is Edge.
- * @readonly
- * @type Boolean
- * @member Ext
- */
- /**
- * @property isLinux
- * True if the detected platform is Linux.
- * @readonly
- * @type Boolean
- * @member Ext
- */
- /**
- * @property isMac
- * True if the detected platform is Mac OS.
- * @readonly
- * @type Boolean
- * @member Ext
- */
- /**
- * @property isOpera
- * True if the detected browser is Opera.
- * @readonly
- * @type Boolean
- * @member Ext
- */
- /**
- * @property isSafari
- * True if the detected browser is Safari.
- * @readonly
- * @type Boolean
- * @member Ext
- */
- /**
- * @property isWebKit
- * True if the detected browser uses WebKit.
- * @readonly
- * @type Boolean
- * @member Ext
- */
- /**
- * @property isWindows
- * True if the detected platform is Windows.
- * @readonly
- * @type Boolean
- * @member Ext
- */
- /**
- * @property operaVersion
- * The current version of Opera (0 if the browser is not Opera).
- * @readonly
- * @type Number
- * @member Ext
- */
- /**
- * @property safariVersion
- * The current version of Safari (0 if the browser is not Safari).
- * @readonly
- * @type Number
- * @member Ext
- */
- /**
- * @property webKitVersion
- * The current version of WebKit (0 if the browser does not use WebKit).
- * @readonly
- * @type Number
- * @member Ext
- */
- // Facebook changes the userAgent when you view a website within their iOS app.
- // For some reason, the strip out information about the browser, so we have to detect
- // that and fake it...
- if (userAgent.match(/FB/) && browserName === 'Other') {
- browserName = browserNames.safari;
- engineName = engineNames.webkit;
- }
- // Detect chrome first as Chrome in Android 8.0 introduced OPR in the user agent
- else if (userAgent.match(/Android.*Chrome/g)) {
- browserName = 'ChromeMobile';
- } else {
- browserMatch = userAgent.match(/OPR\/(\d+.\d+)/);
- if (browserMatch) {
- browserName = 'Opera';
- browserVersion = new Ext.Version(browserMatch[1]);
- }
- }
- Ext.apply(this, {
- engineName: engineName,
- engineVersion: engineVersion,
- name: browserName,
- version: browserVersion
- });
- this.setFlag(browserName, true, publish);
- // e.g., Ext.isIE
- if (browserVersion) {
- majorVer = browserVersion.getMajor() || '';
- if (me.is.IE) {
- majorVer = document.documentMode || parseInt(majorVer, 10);
- for (i = 7; i <= 11; ++i) {
- prefix = 'isIE' + i;
- Ext[prefix] = majorVer === i;
- Ext[prefix + 'm'] = majorVer <= i;
- Ext[prefix + 'p'] = majorVer >= i;
- }
- }
- if (me.is.Opera && parseInt(majorVer, 10) <= 12) {
- Ext.isOpera12m = true;
- }
- Ext.chromeVersion = Ext.isChrome ? majorVer : 0;
- Ext.firefoxVersion = Ext.isFirefox ? majorVer : 0;
- Ext.ieVersion = Ext.isIE ? majorVer : 0;
- Ext.operaVersion = Ext.isOpera ? majorVer : 0;
- Ext.safariVersion = Ext.isSafari ? majorVer : 0;
- Ext.webKitVersion = Ext.isWebKit ? majorVer : 0;
- this.setFlag(browserName + majorVer, true, publish);
- // Ext.isIE10
- this.setFlag(browserName + browserVersion.getShortVersion());
- }
- for (i in browserNames) {
- if (browserNames.hasOwnProperty(i)) {
- name = browserNames[i];
- this.setFlag(name, browserName === name);
- }
- }
- this.setFlag(name);
- if (engineVersion) {
- this.setFlag(engineName + (engineVersion.getMajor() || ''));
- this.setFlag(engineName + engineVersion.getShortVersion());
- }
- for (i in engineNames) {
- if (engineNames.hasOwnProperty(i)) {
- name = engineNames[i];
- this.setFlag(name, engineName === name, publish);
- }
- }
- this.setFlag('Standalone', !!navigator.standalone);
- // Cross domain access could throw an error
- try {
- ripple = window.top.ripple;
- } catch (e) {}
- // Do nothing, can't access cross frame so leave it empty
- /* eslint-disable-next-line max-len */
- this.setFlag('Ripple', !!document.getElementById("tinyhippos-injected") && !Ext.isEmpty(ripple));
- this.setFlag('WebWorks', !!window.blackberry);
- if (window.PhoneGap !== undefined || window.Cordova !== undefined || window.cordova !== undefined) {
- isWebView = true;
- this.setFlag('PhoneGap');
- this.setFlag('Cordova');
- }
- // Check if running in UIWebView
- if (/(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)(?!.*FBAN)/i.test(userAgent)) {
- isWebView = true;
- }
- // Flag to check if it we are in the WebView
- this.setFlag('WebView', isWebView);
- /**
- * @property {Boolean}
- * `true` if browser is using strict mode.
- */
- this.isStrict = Ext.isStrict = document.compatMode === "CSS1Compat";
- /**
- * @property {Boolean}
- * `true` if page is running over SSL.
- */
- this.isSecure = Ext.isSecure;
- // IE10Quirks, Chrome26Strict, etc.
- this.identity = browserName + majorVer + (this.isStrict ? 'Strict' : 'Quirks');
- };
- Ext.env.Browser.prototype = {
- constructor: Ext.env.Browser,
- engineNames: {
- edge: 'Edge',
- webkit: 'WebKit',
- gecko: 'Gecko',
- presto: 'Presto',
- trident: 'Trident',
- other: 'Other'
- },
- enginePrefixes: {
- edge: 'Edge/',
- webkit: 'AppleWebKit/',
- gecko: 'Gecko/',
- presto: 'Presto/',
- trident: 'Trident/'
- },
- styleDashPrefixes: {
- WebKit: '-webkit-',
- Gecko: '-moz-',
- Trident: '-ms-',
- Presto: '-o-',
- Other: ''
- },
- stylePrefixes: {
- WebKit: 'Webkit',
- Gecko: 'Moz',
- Trident: 'ms',
- Presto: 'O',
- Other: ''
- },
- propertyPrefixes: {
- WebKit: 'webkit',
- Gecko: 'moz',
- Trident: 'ms',
- Presto: 'o',
- Other: ''
- },
- // scope: Ext.env.Browser.prototype
- /**
- * The full name of the current browser.
- * Possible values are:
- *
- * - IE
- * - Firefox
- * - Safari
- * - Chrome
- * - Opera
- * - Other
- * @type String
- * @readonly
- */
- name: null,
- /**
- * Refer to {@link Ext.Version}.
- * @type Ext.Version
- * @readonly
- */
- version: null,
- /**
- * The full name of the current browser's engine.
- * Possible values are:
- *
- * - WebKit
- * - Gecko
- * - Presto
- * - Trident
- * - Other
- * @type String
- * @readonly
- */
- engineName: null,
- /**
- * Refer to {@link Ext.Version}.
- * @type Ext.Version
- * @readonly
- */
- engineVersion: null,
- setFlag: function(name, value, publish) {
- if (value === undefined) {
- value = true;
- }
- this.is[name] = value;
- this.is[name.toLowerCase()] = value;
- if (publish) {
- Ext['is' + name] = value;
- }
- return this;
- },
- getStyleDashPrefix: function() {
- return this.styleDashPrefixes[this.engineName];
- },
- getStylePrefix: function() {
- return this.stylePrefixes[this.engineName];
- },
- getVendorProperyName: function(name) {
- var prefix = this.propertyPrefixes[this.engineName];
- if (prefix.length > 0) {
- return prefix + Ext.String.capitalize(name);
- }
- return name;
- }
- };
- /**
- * @class Ext.browser
- * @extends Ext.env.Browser
- * @singleton
- * Provides useful information about the current browser.
- *
- * Example:
- *
- * if (Ext.browser.is.IE) {
- * // IE specific code here
- * }
- *
- * if (Ext.browser.is.WebKit) {
- * // WebKit specific code here
- * }
- *
- * console.log("Version " + Ext.browser.version);
- *
- * For a full list of supported values, refer to {@link #is} property/method.
- *
- */
- (function(userAgent) {
- Ext.browser = new Ext.env.Browser(userAgent, true);
- Ext.userAgent = userAgent.toLowerCase();
- /**
- * @property {String} SSL_SECURE_URL
- * URL to a blank file used by Ext when in secure mode for iframe src and onReady src
- * to prevent the IE insecure content warning (`'about:blank'`, except for IE
- * in secure mode, which is `'javascript:""'`).
- * @member Ext
- */
- Ext.SSL_SECURE_URL = Ext.isSecure && Ext.isIE ? 'javascript:\'\'' : 'about:blank';
- }(Ext.global.navigator.userAgent));
- /**
- * @class Ext.env.OS
- *
- * Provides information about operating system environment.
- *
- * Should not be manually instantiated unless for unit-testing.
- * Access the global instance stored in {@link Ext.os} instead.
- * @private
- */
- Ext.env.OS = function(userAgent, platform, browserScope) {
- // @define Ext.env.OS
- // @define Ext.os
- // @require Ext.Version
- // @require Ext.env.Browser
- var me = this,
- names = Ext.Boot.osNames,
- prefixes = Ext.Boot.osPrefixes,
- name,
- version = '',
- is = me.is,
- i, prefix, match, item, match1;
- browserScope = browserScope || Ext.browser;
- for (i in prefixes) {
- if (prefixes.hasOwnProperty(i)) {
- prefix = prefixes[i];
- match = userAgent.match(new RegExp('(?:' + prefix + ')([^\\s;]+)'));
- if (match) {
- name = names[i];
- match1 = match[1];
- // This is here because some HTC android devices show an OSX Snow Leopard
- // userAgent by default.
- // And the Kindle Fire doesn't have any indicator of Android as the OS in its
- // User Agent
- if (match1 && match1 === "HTC_") {
- version = new Ext.Version("2.3");
- } else if (match1 && match1 === "Silk/") {
- version = new Ext.Version("2.3");
- } else {
- version = new Ext.Version(match[match.length - 1]);
- }
- break;
- }
- }
- }
- if (!name) {
- name = names[(userAgent.toLowerCase().match(/mac|win|linux/) || [
- 'other'
- ])[0]];
- version = new Ext.Version('');
- }
- this.name = name;
- this.version = version;
- // This is added as a workaround for Chrome iPad emulation mode
- // it will report the platform of the machine (MacIntel, Win32, etc) instead
- // of an emulated platform
- // iOS versions 12 and lower will include 'iPad' in the user agent string, iPadOS 13+ will
- // not report 'iPad' but 'Mac Intel' so we have to check the touch points.
- if (userAgent.match(/ipad/i) || (!userAgent.match(/iphone/i) && userAgent.match(/Mac/) && navigator.maxTouchPoints > 2)) {
- name = 'iOS';
- platform = 'iPad';
- }
- if (platform) {
- this.setFlag(platform.replace(/ simulator$/i, ''));
- }
- this.setFlag(name);
- if (version) {
- this.setFlag(name + (version.getMajor() || ''));
- this.setFlag(name + version.getShortVersion());
- }
- for (i in names) {
- if (names.hasOwnProperty(i)) {
- item = names[i];
- if (!is.hasOwnProperty(name)) {
- this.setFlag(item, (name === item));
- }
- }
- }
- // Detect if the device is the iPhone 5.
- if (this.name === "iOS" && window.screen.height === 568) {
- this.setFlag('iPhone5');
- }
- if (browserScope.is.Safari || browserScope.is.Silk) {
- // Ext.browser.version.shortVersion == 501 is for debugging off device
- if (this.is.Android2 || this.is.Android3 || browserScope.version.shortVersion === 501) {
- browserScope.setFlag("AndroidStock");
- }
- if (this.is.Android4) {
- browserScope.setFlag("AndroidStock");
- browserScope.setFlag("AndroidStock4");
- }
- }
- };
- Ext.env.OS.prototype = {
- constructor: Ext.env.OS,
- /**
- * A "hybrid" property, can be either accessed as a method call, i.e:
- *
- * if (Ext.os.is('Android')) {
- * // ...
- * }
- *
- * or as an object with boolean properties, i.e:
- *
- * if (Ext.os.is.Android) {
- * // ...
- * }
- *
- * Versions can be conveniently checked as well. For example:
- *
- * if (Ext.os.is.Android2) {
- * // Equivalent to (Ext.os.is.Android && Ext.os.version.equals(2))
- * }
- *
- * if (Ext.os.is.iOS32) {
- * // Equivalent to (Ext.os.is.iOS && Ext.os.version.equals(3.2))
- * }
- *
- * Note that only {@link Ext.Version#getMajor major component} and
- * {@link Ext.Version#getShortVersion simplified} value of the version are available
- * via direct property checking. Supported values are:
- *
- * - iOS
- * - iPad
- * - iPhone
- * - iPhone5 (also true for 4in iPods).
- * - iPod
- * - Android
- * - WebOS
- * - BlackBerry
- * - Bada
- * - MacOS
- * - Windows
- * - Linux
- * - Other
- * @member Ext.os
- * @param {String} name The OS name to check.
- * @return {Boolean}
- */
- is: function(name) {
- return !!this[name];
- },
- /**
- * @property {String} [name=null]
- * @readonly
- * @member Ext.os
- * The full name of the current operating system. Possible values are:
- *
- * - iOS
- * - Android
- * - WebOS
- * - BlackBerry,
- * - MacOS
- * - Windows
- * - Linux
- * - Other
- */
- name: null,
- /**
- * @property {Ext.Version} [version=null]
- * Refer to {@link Ext.Version}
- * @member Ext.os
- * @readonly
- */
- version: null,
- setFlag: function(name, value) {
- if (value === undefined) {
- value = true;
- }
- if (this.flags) {
- this.flags[name] = value;
- }
- this.is[name] = value;
- this.is[name.toLowerCase()] = value;
- return this;
- }
- };
- (function() {
- var navigation = Ext.global.navigator,
- userAgent = navigation.userAgent,
- OS = Ext.env.OS,
- is = (Ext.is || (Ext.is = {})),
- osEnv, osName, deviceType;
- OS.prototype.flags = is;
- /**
- * @class Ext.os
- * @extends Ext.env.OS
- * @singleton
- * Provides useful information about the current operating system environment.
- *
- * Example:
- *
- * if (Ext.os.is.Windows) {
- * // Windows specific code here
- * }
- *
- * if (Ext.os.is.iOS) {
- * // iPad, iPod, iPhone, etc.
- * }
- *
- * console.log("Version " + Ext.os.version);
- *
- * For a full list of supported values, refer to the {@link #is} property/method.
- *
- */
- Ext.os = osEnv = new OS(userAgent, navigation.platform);
- osName = osEnv.name;
- // A couple compatible flavors:
- Ext['is' + osName] = true;
- // e.g., Ext.isWindows
- Ext.isMac = is.Mac = is.MacOS;
- Ext.isApple = Ext.isMac || Ext.isiOS;
- // eslint-disable-next-line vars-on-top
- var search = window.location.search.match(/deviceType=(Tablet|Phone)/),
- nativeDeviceType = window.deviceType;
- // Override deviceType by adding a get variable of deviceType. NEEDED FOR DOCS APP.
- // E.g: example/kitchen-sink.html?deviceType=Phone
- if (search && search[1]) {
- deviceType = search[1];
- } else if (nativeDeviceType === 'iPhone') {
- deviceType = 'Phone';
- } else if (nativeDeviceType === 'iPad') {
- deviceType = 'Tablet';
- } else {
- if (!osEnv.is.Android && !osEnv.is.iOS && !osEnv.is.WindowsPhone && /Windows|Linux|MacOS|ChromeOS/.test(osName)) {
- deviceType = 'Desktop';
- // always set it to false when you are on a desktop not using Ripple Emulation
- Ext.browser.is.WebView = !!Ext.browser.is.Ripple;
- } else if (osEnv.is.iPad || osEnv.is.RIMTablet || osEnv.is.Android3 || Ext.browser.is.Silk || (osEnv.is.Android && userAgent.search(/mobile/i) === -1)) {
- deviceType = 'Tablet';
- } else {
- deviceType = 'Phone';
- }
- }
- // With iPadOS the operating system name is returned as 'MacOS' so let's check if we are
- // using a tablet and if so set it to 'iOS' instead.
- if (deviceType === 'Tablet' && osName === 'MacOS') {
- Ext.isiOS = true;
- Ext.isiPadOS = true;
- }
- /**
- * @property {String} deviceType
- * The generic type of the current device.
- *
- * Possible values:
- *
- * - Phone
- * - Tablet
- * - Desktop
- *
- * For testing purposes the deviceType can be overridden by adding
- * a deviceType parameter to the URL of the page, like so:
- *
- * http://localhost/mypage.html?deviceType=Tablet
- *
- * @member Ext.os
- */
- osEnv.setFlag(deviceType, true);
- osEnv.deviceType = deviceType;
- delete OS.prototype.flags;
- }());
- /**
- * @class Ext.feature
- * @singleton
- *
- * A simple class to verify if a browser feature exists or not on the current device.
- *
- * if (Ext.feature.has.Canvas) {
- * // do some cool things with canvas here
- * }
- *
- * See the {@link #has} property/method for details of the features that can be detected.
- *
- */
- /* eslint-disable vars-on-top */
- Ext.feature = {
- // @define Ext.env.Feature
- // @define Ext.feature
- // @define Ext.supports
- // @require Ext.String
- // @require Ext.env.Browser
- // @require Ext.env.OS
- /**
- * @method has
- * @member Ext.feature
- * Verifies if a browser feature exists or not on the current device.
- *
- * A "hybrid" property, can be either accessed as a method call, i.e:
- *
- * if (Ext.feature.has('Canvas')) {
- * // ...
- * }
- *
- * or as an object with boolean properties, i.e:
- *
- * if (Ext.feature.has.Canvas) {
- * // ...
- * }
- *
- * For possible properties/parameter values see `Ext.supports`.
- *
- * @param {String} name The feature name to check.
- * @return {Boolean}
- */
- has: function(name) {
- return !!this.has[name];
- },
- testElements: {},
- getTestElement: function(tag, createNew) {
- if (tag === undefined) {
- tag = 'div';
- } else if (typeof tag !== 'string') {
- return tag;
- }
- if (createNew) {
- return document.createElement(tag);
- }
- if (!this.testElements[tag]) {
- this.testElements[tag] = document.createElement(tag);
- }
- return this.testElements[tag];
- },
- isStyleSupported: function(name, tag) {
- var elementStyle = this.getTestElement(tag).style,
- cName = Ext.String.capitalize(name);
- if (typeof elementStyle[name] !== 'undefined' || typeof elementStyle[Ext.browser.getStylePrefix(name) + cName] !== 'undefined') {
- return true;
- }
- return false;
- },
- isStyleSupportedWithoutPrefix: function(name, tag) {
- var elementStyle = this.getTestElement(tag).style;
- if (typeof elementStyle[name] !== 'undefined') {
- return true;
- }
- return false;
- },
- isEventSupported: function(name, tag) {
- if (tag === undefined) {
- tag = window;
- }
- var element = this.getTestElement(tag),
- eventName = 'on' + name.toLowerCase(),
- isSupported = (eventName in element);
- if (!isSupported) {
- if (element.setAttribute && element.removeAttribute) {
- element.setAttribute(eventName, '');
- isSupported = typeof element[eventName] === 'function';
- if (typeof element[eventName] !== 'undefined') {
- element[eventName] = undefined;
- }
- element.removeAttribute(eventName);
- }
- }
- return isSupported;
- },
- // This is a local copy of certain logic from Element.getStyle
- // to break a dependancy between the supports mechanism and Element
- // use this instead of element references to check for styling info
- getStyle: function(element, styleName) {
- var view = element.ownerDocument.defaultView,
- style = (view ? view.getComputedStyle(element, null) : element.currentStyle);
- return (style || element.style)[styleName];
- },
- getSupportedPropertyName: function(object, name) {
- var vendorName = Ext.browser.getVendorProperyName(name);
- if (vendorName in object) {
- return vendorName;
- } else if (name in object) {
- return name;
- }
- return null;
- },
- /**
- * Runs feature detection routines and sets the various flags. This is called when
- * the scripts loads (very early) and again at {@link Ext#onReady}. Some detections
- * can be run immediately. Others that require the document body will not run until
- * domready (these have the `ready` flag set).
- *
- * Each test is run only once, so calling this method from an onReady function is safe
- * and ensures that all flags have been set.
- * @private
- */
- detect: function(isReady) {
- var me = this,
- doc = document,
- toRun = me.toRun || me.tests,
- n = toRun.length,
- div = doc.createElement('div'),
- notRun = [],
- supports = Ext.supports,
- has = me.has,
- name, names, test, vector, value;
- // Only the legacy browser tests use this div so clip this out if we don't need
- // to use it.
- div.innerHTML = '<div style="height:30px;width:50px;">' + '<div style="height:20px;width:20px;"></div>' + '</div>' + '<div style="width: 200px; height: 200px; position: relative; padding: 5px;">' + '<div style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;"></div>' + // eslint-disable-line max-len
- '</div>' + '<div style="position: absolute; left: 10%; top: 10%;"></div>' + '<div style="float:left; background-color:transparent;"></div>';
- if (isReady) {
- doc.body.appendChild(div);
- }
- vector = me.preDetected[Ext.browser.identity] || [];
- while (n--) {
- test = toRun[n];
- value = vector[n];
- name = test.name;
- names = test.names;
- if (value === undefined) {
- if (!isReady && test.ready) {
- // test requires domready state
- notRun.push(test);
-
- continue;
- }
- value = test.fn.call(me, doc, div);
- }
- // Store test results on Ext.supports and Ext.feature.has
- if (name) {
- supports[name] = has[name] = value;
- } else if (names) {
- while (names.length) {
- name = names.pop();
- supports[name] = has[name] = value;
- }
- }
- }
- if (isReady) {
- doc.body.removeChild(div);
- }
- me.toRun = notRun;
- },
- //</debug>
- report: function() {
- var values = [],
- len = this.tests.length,
- i;
- for (i = 0; i < len; ++i) {
- values.push(this.has[this.tests[i].name] ? 1 : 0);
- }
- Ext.log(Ext.browser.identity + ': [' + values.join(',') + ']');
- },
- //</debug>
- preDetected: {},
- // TODO
- /**
- * @class Ext.supports
- *
- * Contains information about features supported in the current environment as well
- * as bugs detected.
- *
- * @singleton
- */
- tests: [
- {
- /**
- * @property CloneNodeCopiesExpando `true` if the native DOM cloneNode method copies
- * expando properties to the newly cloned node.
- *
- * This property is available at application boot time, before document ready.
- * @type {Boolean}
- */
- name: 'CloneNodeCopiesExpando',
- fn: function() {
- var el = document.createElement('div');
- el.expandoProp = {};
- return el.cloneNode().expandoProp === el.expandoProp;
- }
- },
- {
- /**
- * @property CSSPointerEvents `true` if document environment supports the CSS3
- * pointer-events style.
- *
- * This property is available at application boot time, before document ready.
- * @type {Boolean}
- */
- name: 'CSSPointerEvents',
- fn: function(doc) {
- return 'pointerEvents' in doc.documentElement.style;
- }
- },
- {
- /**
- * @property CSS3BoxShadow `true` if document environment supports the CSS3
- * box-shadow style.
- *
- * This property is available at application boot time, before document ready.
- * @type {Boolean}
- */
- name: 'CSS3BoxShadow',
- fn: function(doc) {
- return 'boxShadow' in doc.documentElement.style || 'WebkitBoxShadow' in doc.documentElement.style || 'MozBoxShadow' in doc.documentElement.style;
- }
- },
- {
- name: 'CSS3NegationSelector',
- fn: function(doc) {
- try {
- doc.querySelectorAll("foo:not(bar)");
- } catch (e) {
- return false;
- }
- return true;
- }
- },
- {
- /**
- * @property ClassList `true` if document environment supports the HTML5
- * classList API.
- *
- * This property is available at application boot time, before document ready.
- * @type {Boolean}
- */
- name: 'ClassList',
- fn: function(doc) {
- return !!doc.documentElement.classList;
- }
- },
- {
- /**
- * @property Canvas `true` if the device supports Canvas.
- *
- * This property is available at application boot time, before document ready.
- * @type {Boolean}
- */
- name: 'Canvas',
- fn: function() {
- var element = this.getTestElement('canvas');
- return !!(element && element.getContext && element.getContext('2d'));
- }
- },
- {
- /**
- * @property Svg `true` if the device supports SVG.
- *
- * This property is available at application boot time, before document ready.
- * @type {Boolean}
- */
- name: 'Svg',
- fn: function(doc) {
- /* eslint-disable-next-line max-len */
- return !!(doc.createElementNS && !!doc.createElementNS("http:/" + "/www.w3.org/2000/svg", "svg").createSVGRect);
- }
- },
- {
- /**
- * @property Vml `true` if the device supports VML.
- * @type {Boolean}
- *
- * This property is available at application boot time, before document ready.
- */
- name: 'Vml',
- fn: function() {
- var element = this.getTestElement(),
- ret = false;
- element.innerHTML = "<!--[if vml]><br><![endif]-->";
- ret = (element.childNodes.length === 1);
- element.innerHTML = "";
- return ret;
- }
- },
- {
- /**
- * @property {Boolean} Touch `true` if the browser supports touch input.
- *
- * This property is available at application boot time, before document ready.
- */
- name: 'Touch',
- fn: function() {
- // IE10 uses a vendor-prefixed maxTouchPoints property
- var maxTouchPoints = navigator.msMaxTouchPoints || navigator.maxTouchPoints;
- // if the browser has touch events we can be reasonably sure the device has
- // a touch screen
- // browsers that use pointer event have maxTouchPoints > 1 if the
- // device supports touch input
- // Chrome Desktop < 39 reports maxTouchPoints === 1 even if there is no
- // touch support on the device
- // http://www.w3.org/TR/pointerevents/#widl-Navigator-maxTouchPoints
- // Chrome Desktop > 39 properly reports maxTouchPoints === 0 and
- // Chrome Desktop Device Emulation mode reports maxTouchPoints === 1
- if (Ext.browser.is.Chrome && Ext.browser.version.isLessThanOrEqual(39)) {
- return (Ext.supports.TouchEvents && maxTouchPoints !== 1) || maxTouchPoints > 1;
- } else {
- return Ext.supports.TouchEvents || maxTouchPoints > 0;
- }
- }
- },
- {
- /**
- * @property {Boolean} PointerEvents
- * @type {Boolean}
- * @private
- *
- * `true` If the event system should use [pointer events](https://www.w3.org/TR/pointerevents/).
- * Currently only set to true if the browser supports pointer events and does not
- * also support touch events. Touch events are preferred since they allow run-time
- * cancellation of browser default behavior such as scrolling by invoking
- * `e.preventDefault()` whereas pointer events require such intentions to be declared
- * in advance via CSS [touch-action](https://www.w3.org/TR/pointerevents/#h3_the-touch-action-css-property).
- * This means that when pointer events are used, certain interactions are not possible
- * such as long-press to drag within a scrollable element.
- */
- name: 'PointerEvents',
- fn: function() {
- var pointerEvent = window.PointerEvent,
- nav = window.navigator,
- pointerEnabled = !!(pointerEvent && (nav.pointerEnabled || !Ext.isIE));
- return pointerEnabled && !Ext.supports.TouchEvents;
- }
- },
- {
- /**
- * @property {Boolean} MSPointerEvents
- * @private
- */
- name: 'MSPointerEvents',
- fn: function() {
- return Ext.isIE10;
- }
- },
- {
- /**
- * @property {Boolean} TouchEvents
- *
- * `true` if the device supports touch events (`touchstart`, `touchmove`, `touchend`).
- *
- * This property is available at application boot time, before document ready.
- */
- name: 'TouchEvents',
- fn: function() {
- return this.isEventSupported('touchend');
- }
- },
- {
- /**
- * @property {Boolean} TouchAction
- * @private
- *
- * A bit flag representing which property values the browser recognizes as valid
- * values of the CSS `touch-action` property.
- *
- * panX 1 "00000001"
- * panY 2 "00000010"
- * pinchZoom 4 "00000100"
- * doubleTapZoom 8 "00001000"
- */
- name: 'TouchAction',
- ready: true,
- fn: function(doc, div) {
- if (!window.getComputedStyle) {
- return 0;
- }
- var values = [
- 'pan-x',
- 'pan-y',
- 'pinch-zoom',
- 'double-tap-zoom'
- ],
- flags = [
- 1,
- 2,
- 4,
- 8
- ],
- ln = values.length,
- flag = 0,
- i, value;
- for (i = 0; i < ln; i++) {
- value = values[i];
- div.style.touchAction = value;
- if (getComputedStyle(div).touchAction === value) {
- flag |= flags[i];
- }
- }
- return flag;
- }
- },
- {
- /**
- * @property Orientation `true` if the device supports different orientations.
- * @type {Boolean}
- *
- * This property is available at application boot time, before document ready.
- */
- name: 'Orientation',
- fn: function() {
- return ('orientation' in window) && this.isEventSupported('orientationchange');
- }
- },
- {
- /**
- * @property OrientationChange `true` if the device supports the `orientationchange`
- * event.
- *
- * This property is available at application boot time, before document ready.
- * @type {Boolean}
- */
- name: 'OrientationChange',
- fn: function() {
- return this.isEventSupported('orientationchange');
- }
- },
- {
- /**
- * @property DeviceMotion `true` if the device supports device motion (acceleration
- * and rotation rate).
- *
- * This property is available at application boot time, before document ready.
- * @type {Boolean}
- */
- name: 'DeviceMotion',
- fn: function() {
- return this.isEventSupported('devicemotion');
- }
- },
- {
- /**
- * @property Geolocation `true` if the device supports GeoLocation.
- * @type {Boolean}
- *
- * This property is available at application boot time, before document ready.
- */
- /**
- * @property GeoLocation `true` if the device supports Geo-location.
- * @type {Boolean}
- * @deprecated 5.0.0 Use `Geolocation` instead (notice the lower-casing of 'L').
- */
- names: [
- 'Geolocation',
- 'GeoLocation'
- ],
- fn: function() {
- return 'geolocation' in window.navigator;
- }
- },
- {
- name: 'SqlDatabase',
- fn: function() {
- return 'openDatabase' in window;
- }
- },
- {
- name: 'WebSockets',
- fn: function() {
- return 'WebSocket' in window;
- }
- },
- {
- /**
- * @property Range `true` if browser support document.createRange native method.
- * See https://developer.mozilla.org/en/DOM/range.
- *
- * This property is available at application boot time, before document ready.
- * @type {Boolean}
- */
- name: 'Range',
- fn: function() {
- return !!document.createRange;
- }
- },
- {
- /**
- * @property CreateContextualFragment `true` if browser support CreateContextualFragment
- * range native methods.
- * See https://developer.mozilla.org/en/DOM/range.createContextualFragment
- *
- * This property is available at application boot time, before document ready.
- * @type {Boolean}
- */
- name: 'CreateContextualFragment',
- fn: function() {
- var range = !!document.createRange ? document.createRange() : false;
- return range && !!range.createContextualFragment;
- }
- },
- {
- /**
- * @property History `true` if the device supports HTML5 history. See
- * https://developer.mozilla.org/en/DOM/Manipulating_the_browser_history
- *
- * This property is available at application boot time, before document ready.
- * @type {Boolean}
- */
- name: 'History',
- fn: function() {
- return ('history' in window && 'pushState' in window.history);
- }
- },
- {
- /**
- * @property Css3DTransforms `true` if the device supports CSS3DTransform.
- * @type {Boolean}
- *
- * This property is available at application boot time, before document ready.
- */
- name: 'Css3dTransforms',
- fn: function() {
- // See https://sencha.jira.com/browse/TOUCH-1544
- return this.has('CssTransforms') && this.isStyleSupported('perspective');
- }
- },
- // TODO - double check vs Ext JS flavor:
- /* eslint-disable-next-line max-len */
- // return (typeof WebKitCSSMatrix != 'undefined' && new WebKitCSSMatrix().hasOwnProperty('m41'));
- {
- // Important that this goes after Css3dTransforms, since tests are run in reverse order
- name: 'CssTransforms',
- fn: function() {
- return this.isStyleSupported('transform');
- }
- },
- {
- name: 'CssTransformNoPrefix',
- fn: function() {
- return this.isStyleSupportedWithoutPrefix('transform');
- }
- },
- {
- name: 'CssAnimations',
- fn: function() {
- return this.isStyleSupported('animationName');
- }
- },
- {
- /**
- * @property Transitions `true` if the device supports CSS3 Transitions.
- *
- * This property is available at application boot time, before document ready.
- * @type {Boolean}
- */
- names: [
- 'CssTransitions',
- 'Transitions'
- ],
- fn: function() {
- return this.isStyleSupported('transitionProperty');
- }
- },
- {
- /**
- * @property Audio `true` if the device supports the HTML5 `audio` tag.
- *
- * This property is available at application boot time, before document ready.
- * @type {Boolean}
- */
- /**
- * @property AudioTag `true` if the device supports the HTML5 `audio` tag.
- * @type {Boolean}
- * @deprecated 5.0.0 Use `Audio` instead.
- */
- names: [
- 'Audio',
- 'AudioTag'
- ],
- fn: function() {
- return !!this.getTestElement('audio').canPlayType;
- }
- },
- {
- /**
- * @property Video `true` if the device supports the HTML5 `video` tag.
- *
- * This property is available at application boot time, before document ready.
- * @type {Boolean}
- */
- name: 'Video',
- fn: function() {
- return !!this.getTestElement('video').canPlayType;
- }
- },
- {
- /**
- * @property LocalStorage `true` if localStorage is supported.
- *
- * This property is available at application boot time, before document ready.
- * @type {Boolean}
- */
- name: 'LocalStorage',
- fn: function() {
- try {
- // IE10/Win8 throws "Access Denied" accessing window.localStorage, so
- // this test needs to have a try/catch
- /* eslint-disable-next-line dot-notation */
- if ('localStorage' in window && window['localStorage'] !== null) {
- // this should throw an error in private browsing mode in iOS as well
- localStorage.setItem('sencha-localstorage-test', 'test success');
- // clean up if setItem worked
- localStorage.removeItem('sencha-localstorage-test');
- return true;
- }
- } catch (e) {}
- // ignore
- return false;
- }
- },
- {
- /**
- * @property {Boolean} XmlQuerySelector `true` if the browsers supports querySelector
- * and querySelectorAll methods on XML nodes.
- *
- * This property is available at application boot time, before document ready.
- */
- name: 'XmlQuerySelector',
- fn: function() {
- var xmlString = '<?xml version="1.0" encoding="UTF-8" standalone="yes" ?><root></root>',
- xmlDoc;
- // IE10 doesn't create IXMLDOMDocument via DOMParser
- if (window.ActiveXObject) {
- xmlDoc = new ActiveXObject("Microsoft.xmlDOM");
- // eslint-disable-line no-undef
- xmlDoc.async = false;
- // eslint-disable-line id-blacklist
- xmlDoc.loadXML(xmlString);
- } else if (window.DOMParser) {
- var parser = new DOMParser();
- xmlDoc = parser.parseFromString(xmlString, 'text/xml');
- }
- return xmlDoc ? !!xmlDoc.lastChild.querySelector : false;
- }
- },
- {
- /**
- * @property XHR2 `true` if the browser supports XMLHttpRequest
- *
- * This property is available at application boot time, before document ready.
- * @type {Boolean}
- */
- name: 'XHR2',
- fn: function() {
- return window.ProgressEvent && window.FormData && window.XMLHttpRequest && ('withCredentials' in new XMLHttpRequest());
- }
- },
- {
- /**
- * @property XHRUploadProgress `true` if the browser supports XMLHttpRequest
- * upload progress info
- *
- * This property is available at application boot time, before document ready.
- * @type {Boolean}
- */
- name: 'XHRUploadProgress',
- fn: function() {
- var xhr;
- if (window.XMLHttpRequest && !Ext.browser.is.AndroidStock) {
- xhr = new XMLHttpRequest();
- return xhr && ('upload' in xhr) && ('onprogress' in xhr.upload);
- }
- return false;
- }
- },
- {
- /**
- * @property NumericInputPlaceHolder `true` if the browser supports placeholders
- * on numeric input fields
- *
- * This property is available at application boot time, before document ready.
- * @type {Boolean}
- */
- name: 'NumericInputPlaceHolder',
- fn: function() {
- return !(Ext.browser.is.AndroidStock4 && Ext.os.version.getMinor() < 2);
- }
- },
- {
- /**
- * @property {String} matchesSelector
- * The method name which matches an element against a selector if implemented in this
- * environment.
- *
- * This property is available at application boot time, before document ready.
- */
- name: 'matchesSelector',
- fn: function() {
- var el = document.documentElement,
- w3 = 'matches',
- wk = 'webkitMatchesSelector',
- ms = 'msMatchesSelector',
- mz = 'mozMatchesSelector';
- return el[w3] ? w3 : el[wk] ? wk : el[ms] ? ms : el[mz] ? mz : null;
- }
- },
- {
- /**
- * @property RightMargin `true` if the device supports right margin.
- * See https://bugs.webkit.org/show_bug.cgi?id=13343 for why this is needed.
- *
- * This property is *NOT* available at application boot time. Only after the document
- * ready event.
- * @type {Boolean}
- */
- name: 'RightMargin',
- ready: true,
- fn: function(doc, div) {
- var view = doc.defaultView;
- /* eslint-disable-next-line max-len */
- return !(view && view.getComputedStyle(div.firstChild.firstChild, null).marginRight !== '0px');
- }
- },
- {
- /**
- * @property DisplayChangeInputSelectionBug `true` if INPUT elements lose their
- * selection when their display style is changed. Essentially, if a text input
- * has focus and its display style is changed, the I-beam disappears.
- *
- * This bug is encountered due to the work around in place for the {@link #RightMargin}
- * bug. This has been observed in Safari 4.0.4 and older, and appears to be fixed
- * in Safari 5. It's not clear if Safari 4.1 has the bug, but it has the same WebKit
- * version number as Safari 5 (according to http://unixpapa.com/js/gecko.html).
- *
- * This property is available at application boot time, before document ready.
- */
- name: 'DisplayChangeInputSelectionBug',
- fn: function() {
- var webKitVersion = Ext.webKitVersion;
- // WebKit but older than Safari 5 or Chrome 6:
- return 0 < webKitVersion && webKitVersion < 533;
- }
- },
- {
- /**
- * @property DisplayChangeTextAreaSelectionBug `true` if TEXTAREA elements lose their
- * selection when their display style is changed. Essentially, if a text area has
- * focus and its display style is changed, the I-beam disappears.
- *
- * This bug is encountered due to the work around in place for the {@link #RightMargin}
- * bug. This has been observed in Chrome 10 and Safari 5 and older, and appears to
- * be fixed in Chrome 11.
- *
- * This property is available at application boot time, before document ready.
- */
- name: 'DisplayChangeTextAreaSelectionBug',
- fn: function() {
- var webKitVersion = Ext.webKitVersion;
- /*
- Has bug w/textarea:
- (Chrome) Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_7; en-US)
- AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.127
- Safari/534.16
- (Safari) Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_7; en-us)
- AppleWebKit/533.21.1 (KHTML, like Gecko) Version/5.0.5
- Safari/533.21.1
- No bug:
- (Chrome) Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_7)
- AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.57
- Safari/534.24
- */
- return 0 < webKitVersion && webKitVersion < 534.24;
- }
- },
- {
- /**
- * @property TransparentColor `true` if the device supports transparent color.
- * @type {Boolean}
- *
- * This property is *NOT* available at application boot time. Only after the document
- * ready event.
- */
- name: 'TransparentColor',
- ready: true,
- fn: function(doc, div, view) {
- view = doc.defaultView;
- /* eslint-disable-next-line max-len */
- return !(view && view.getComputedStyle(div.lastChild, null).backgroundColor !== 'transparent');
- }
- },
- {
- /**
- * @property ComputedStyle `true` if the browser supports
- * document.defaultView.getComputedStyle().
- * @type {Boolean}
- *
- * This property is *NOT* available at application boot time. Only after the document
- * ready event.
- */
- name: 'ComputedStyle',
- ready: true,
- fn: function(doc, div, view) {
- view = doc.defaultView;
- return !!(view && view.getComputedStyle);
- }
- },
- {
- /**
- * @property Float `true` if the device supports CSS float.
- * @type {Boolean}
- *
- * This property is available at application boot time, before document ready.
- */
- name: 'Float',
- fn: function(doc) {
- return 'cssFloat' in doc.documentElement.style;
- }
- },
- {
- /**
- * @property CSS3BorderRadius `true` if the device supports CSS3 border radius.
- * @type {Boolean}
- *
- * This property is *NOT* available at application boot time. Only after the document
- * ready event.
- */
- name: 'CSS3BorderRadius',
- ready: true,
- fn: function(doc) {
- var domPrefixes = [
- 'borderRadius',
- 'BorderRadius',
- 'MozBorderRadius',
- 'WebkitBorderRadius',
- 'OBorderRadius',
- 'KhtmlBorderRadius'
- ],
- pass = false,
- i;
- for (i = 0; i < domPrefixes.length; i++) {
- if (doc.documentElement.style[domPrefixes[i]] !== undefined) {
- pass = true;
- }
- }
- return pass && !Ext.isIE9;
- }
- },
- {
- /**
- * @property CSS3LinearGradient `true` if the device supports CSS3 linear gradients.
- * @type {Boolean}
- *
- * This property is available at application boot time, before document ready.
- */
- name: 'CSS3LinearGradient',
- fn: function(doc, div) {
- var property = 'background-image:',
- webkit = '-webkit-gradient(linear, left top, right bottom, from(black), to(white))',
- w3c = 'linear-gradient(left top, black, white)',
- moz = '-moz-' + w3c,
- ms = '-ms-' + w3c,
- opera = '-o-' + w3c,
- options = [
- property + webkit,
- property + w3c,
- property + moz,
- property + ms,
- property + opera
- ];
- div.style.cssText = options.join(';');
- return (("" + div.style.backgroundImage).indexOf('gradient') !== -1) && !Ext.isIE9;
- }
- },
- {
- /**
- * @property MouseEnterLeave `true` if the browser supports mouseenter and mouseleave events
- * @type {Boolean}
- *
- * This property is available at application boot time, before document ready.
- */
- name: 'MouseEnterLeave',
- fn: function(doc) {
- return ('onmouseenter' in doc.documentElement && 'onmouseleave' in doc.documentElement);
- }
- },
- {
- /**
- * @property MouseWheel `true` if the browser supports the mousewheel event
- * @type {Boolean}
- *
- * This property is available at application boot time, before document ready.
- */
- name: 'MouseWheel',
- fn: function(doc) {
- return ('onmousewheel' in doc.documentElement);
- }
- },
- {
- /**
- * @property Opacity `true` if the browser supports normal css opacity
- * @type {Boolean}
- *
- * This property is available at application boot time, before document ready.
- */
- name: 'Opacity',
- fn: function(doc, div) {
- // Not a strict equal comparison in case opacity can be converted to a number.
- if (Ext.isIE8) {
- return false;
- }
- div.firstChild.style.cssText = 'opacity:0.73';
- return div.firstChild.style.opacity == '0.73';
- }
- },
- // eslint-disable-line eqeqeq
- {
- /**
- * @property Placeholder `true` if the browser supports the HTML5 placeholder attribute
- * on inputs
- * @type {Boolean}
- *
- * This property is available at application boot time, before document ready.
- */
- name: 'Placeholder',
- fn: function(doc) {
- return 'placeholder' in doc.createElement('input');
- }
- },
- {
- /**
- * @property Direct2DBug `true` if when asking for an element's dimension via offsetWidth
- * or offsetHeight, getBoundingClientRect, etc. the browser returns the subpixel width
- * rounded to the nearest pixel.
- *
- * This property is available at application boot time, before document ready.
- * @type {Boolean}
- */
- name: 'Direct2DBug',
- fn: function(doc) {
- return Ext.isString(doc.documentElement.style.msTransformOrigin) && Ext.isIE9m;
- }
- },
- {
- /**
- * @property BoundingClientRect `true` if the browser supports the getBoundingClientRect
- * method on elements
- * @type {Boolean}
- *
- * This property is available at application boot time, before document ready.
- */
- name: 'BoundingClientRect',
- fn: function(doc) {
- return 'getBoundingClientRect' in doc.documentElement;
- }
- },
- {
- /**
- * @property RotatedBoundingClientRect `true` if the BoundingClientRect is
- * rotated when the element is rotated using a CSS transform.
- * @type {Boolean}
- *
- * This property is *NOT* available at application boot time. Only after the document
- * ready event.
- */
- name: 'RotatedBoundingClientRect',
- ready: true,
- fn: function(doc) {
- var body = doc.body,
- supports = false,
- el = doc.createElement('div'),
- style = el.style;
- if (el.getBoundingClientRect) {
- // If the document body already has child nodes (text nodes etc) we can end
- // up with subpixel rounding errors in IE11 when measuring the height.
- // Absolute positioning prevents this.
- style.position = 'absolute';
- style.top = "0";
- style.WebkitTransform = style.MozTransform = style.msTransform = style.OTransform = style.transform = 'rotate(90deg)';
- style.width = '100px';
- style.height = '30px';
- body.appendChild(el);
- supports = el.getBoundingClientRect().height !== 100;
- body.removeChild(el);
- }
- return supports;
- }
- },
- {
- /**
- * @property ChildContentClearedWhenSettingInnerHTML `true` if created child elements
- * lose their innerHTML when modifying the innerHTML of the parent element.
- * @type {Boolean}
- *
- * This property is *NOT* available at application boot time. Only after the document
- * ready event.
- */
- name: 'ChildContentClearedWhenSettingInnerHTML',
- ready: true,
- fn: function() {
- var el = this.getTestElement(),
- child;
- el.innerHTML = '<div>a</div>';
- child = el.firstChild;
- el.innerHTML = '<div>b</div>';
- return child.innerHTML !== 'a';
- }
- },
- {
- name: 'IncludePaddingInWidthCalculation',
- ready: true,
- fn: function(doc, div) {
- return div.childNodes[1].firstChild.offsetWidth === 210;
- }
- },
- {
- name: 'IncludePaddingInHeightCalculation',
- ready: true,
- fn: function(doc, div) {
- return div.childNodes[1].firstChild.offsetHeight === 210;
- }
- },
- {
- /**
- * @property TextAreaMaxLength `true` if the browser supports maxlength on textareas.
- * @type {Boolean}
- *
- * This property is available at application boot time, before document ready.
- */
- name: 'TextAreaMaxLength',
- fn: function(doc) {
- return ('maxlength' in doc.createElement('textarea'));
- }
- },
- {
- /**
- * @property GetPositionPercentage `true` if the browser will return the
- * left/top/right/bottom position as a percentage when explicitly set as a percentage value.
- *
- * This property is *NOT* available at application boot time. Only after the document
- * ready event.
- * @type {Boolean}
- */
- // Related bug: https://bugzilla.mozilla.org/show_bug.cgi?id=707691#c7
- name: 'GetPositionPercentage',
- ready: true,
- fn: function(doc, div) {
- return Ext.feature.getStyle(div.childNodes[2], 'left') === '10%';
- }
- },
- {
- /**
- * @property {Boolean} PercentageHeightOverflowBug
- * In some browsers (IE quirks, IE6, IE7, IE9, chrome, safari and opera at the time
- * of this writing) a percentage-height element ignores the horizontal scrollbar
- * of its parent element. This method returns true if the browser is affected
- * by this bug.
- *
- * This property is *NOT* available at application boot time. Only after the document
- * ready event.
- * @private
- */
- name: 'PercentageHeightOverflowBug',
- ready: true,
- fn: function(doc) {
- var hasBug = false,
- style, el;
- if (Ext.getScrollbarSize().height) {
- // must have space-consuming scrollbars for bug to be possible
- el = this.getTestElement('div', true);
- style = el.style;
- style.height = '50px';
- style.width = '50px';
- style.overflow = 'auto';
- style.position = 'absolute';
- /* eslint-disable indent */
- el.innerHTML = [
- '<div style="display:table;height:100%;">',
- // The element that causes the horizontal overflow must be
- // a child of the element with the 100% height, otherwise
- // horizontal overflow is not triggered in webkit quirks mode
- '<div style="width:51px;"></div>',
- '</div>'
- ].join('');
- /* eslint-enable indent */
- doc.body.appendChild(el);
- if (el.firstChild.offsetHeight === 50) {
- hasBug = true;
- }
- doc.body.removeChild(el);
- }
- return hasBug;
- }
- },
- {
- /**
- * @property {Boolean} xOriginBug
- * In Chrome 24.0, an RTL element which has vertical overflow positions its right X origin
- * incorrectly. It skips a non-existent scrollbar which has been moved to the left edge
- * due to the RTL setting.
- *
- * http://code.google.com/p/chromium/issues/detail?id=174656
- *
- * This method returns true if the browser is affected by this bug.
- *
- * This property is *NOT* available at application boot time. Only after the document
- * ready event.
- * @private
- */
- name: 'xOriginBug',
- ready: true,
- fn: function(doc, div) {
- /* eslint-disable max-len */
- div.innerHTML = '<div id="b1" style="height:100px;width:100px;direction:rtl;position:relative;overflow:scroll">' + '<div id="b2" style="position:relative;width:100%;height:20px;"></div>' + '<div id="b3" style="position:absolute;width:20px;height:20px;top:0px;right:0px"></div>' + '</div>';
- /* eslint-enable max-len */
- var outerBox = document.getElementById('b1').getBoundingClientRect(),
- b2 = document.getElementById('b2').getBoundingClientRect(),
- b3 = document.getElementById('b3').getBoundingClientRect();
- return (b2.left !== outerBox.left && b3.right !== outerBox.right);
- }
- },
- {
- /**
- * @property {Boolean} ScrollWidthInlinePaddingBug
- * In some browsers the right padding of an overflowing element is not accounted
- * for in its scrollWidth. The result can vary depending on whether or not
- * The element contains block-level children. This method tests the effect
- * of padding on scrollWidth when there are no block-level children inside the
- * overflowing element.
- *
- * This method returns true if the browser is affected by this bug.
- *
- * This property is *NOT* available at application boot time. Only after the document
- * ready event.
- */
- name: 'ScrollWidthInlinePaddingBug',
- ready: true,
- fn: function(doc) {
- var hasBug = false,
- style, el;
- el = doc.createElement('div');
- style = el.style;
- style.height = '50px';
- style.width = '50px';
- style.padding = '10px';
- style.overflow = 'hidden';
- style.position = 'absolute';
- el.innerHTML = '<span style="display:inline-block;zoom:1;height:60px;width:60px;"></span>';
- doc.body.appendChild(el);
- if (el.scrollWidth === 70) {
- hasBug = true;
- }
- doc.body.removeChild(el);
- return hasBug;
- }
- },
- {
- /**
- * @property {Boolean} rtlVertScrollbarOnRight
- * Safari, in RTL mode keeps the scrollbar at the right side.
- * This means that when two elements must keep their left/right positions synched, if one
- * has no vert scrollbar, it must have some extra padding.
- * See https://sencha.jira.com/browse/EXTJSIV-11245
- *
- * This property is *NOT* available at application boot time. Only after the document
- * ready event.
- * @private
- */
- name: 'rtlVertScrollbarOnRight',
- ready: true,
- fn: function(doc, div) {
- div.innerHTML = '<div style="height:100px;width:100px;direction:rtl;overflow:scroll">' + '<div style="width:20px;height:200px;"></div>' + '</div>';
- var outerBox = div.firstChild,
- innerBox = outerBox.firstChild;
- /* eslint-disable-next-line max-len */
- return (innerBox.offsetLeft + innerBox.offsetWidth !== outerBox.offsetLeft + outerBox.offsetWidth);
- }
- },
- {
- /**
- * @property {Boolean} rtlVertScrollbarOverflowBug
- * In Chrome, in RTL mode, horizontal overflow only into the vertical scrollbar does NOT
- * trigger horizontal scrollability.
- * See https://code.google.com/p/chromium/issues/detail?id=179332
- * We need to detect this for when a grid header needs to have exactly the same horizontal
- * scrolling range as its table view. See {@link Ext.grid.ColumnLayout#publishInnerCtSize}
- * TODO: Remove this when all supported Chrome versions are fixed.
- *
- * This property is *NOT* available at application boot time. Only after the document
- * ready event.
- * @private
- */
- name: 'rtlVertScrollbarOverflowBug',
- ready: true,
- fn: function(doc, div) {
- div.innerHTML = '<div style="height:100px;width:100px;direction:rtl;overflow:auto">' + '<div style="width:95px;height:200px;"></div>' + '</div>';
- // If the bug is present, the 95 pixel wide inner div, encroaches into the
- // vertical scrollbar, but does NOT trigger horizontal overflow, so the clientHeight
- // remains equal to the offset height.
- var outerBox = div.firstChild,
- style = div.style,
- pos = style.position;
- // This issue seems to require a repaint to measure correctly
- style.position = 'absolute';
- // eslint-disable-next-line no-unused-expressions
- outerBox.offsetHeight;
- style.position = pos;
- return outerBox.clientHeight === outerBox.offsetHeight;
- }
- },
- {
- identity: 'defineProperty',
- fn: function() {
- if (Ext.isIE8m) {
- Ext.Object.defineProperty = Ext.emptyFn;
- return false;
- }
- return true;
- }
- },
- {
- identify: 'nativeXhr',
- fn: function() {
- if (typeof XMLHttpRequest !== 'undefined') {
- return true;
- }
- // Apply a polyfill:
- XMLHttpRequest = function() {
- // eslint-disable-line no-global-assign
- try {
- // eslint-disable-next-line no-undef
- return new ActiveXObject('MSXML2.XMLHTTP.3.0');
- } catch (ex) {
- return null;
- }
- };
- return false;
- }
- },
- {
- /**
- * @property {Boolean} SpecialKeyDownRepeat
- * True if the browser fires the keydown event on specialkey autorepeat
- *
- * note 1: IE fires ONLY the keydown event on specialkey autorepeat
- * note 2: Safari < 3.1, Gecko (Mac/Linux) & Opera fire only the keypress event on
- * specialkey autorepeat (research done by Jan Wolter at
- * http://unixpapa.com/js/key.html)
- * note 3: Opera 12 behaves like other modern browsers so this workaround does not
- * work anymore
- *
- * This property is available at application boot time, before document ready.
- */
- name: 'SpecialKeyDownRepeat',
- fn: function() {
- return Ext.isWebKit ? parseInt(navigator.userAgent.match(/AppleWebKit\/(\d+)/)[1], 10) >= 525 : !(!(Ext.isGecko || Ext.isIE || Ext.isEdge) || (Ext.isOpera && Ext.operaVersion < 12));
- }
- },
- // eslint-disable-line max-len
- {
- /**
- * @property {Boolean} EmulatedMouseOver
- * True if the browser emulates a mouseover event on tap (mobile safari)
- *
- * This property is available at application boot time, before document ready.
- */
- name: 'EmulatedMouseOver',
- fn: function() {
- // TODO: is it possible to feature detect this?
- return Ext.os.is.iOS;
- }
- },
- {
- /**
- * @property Hashchange True if the user agent supports the hashchange event
- *
- * This property is available at application boot time, before document ready.
- * @type {Boolean}
- */
- // support Vector 12
- name: 'Hashchange',
- fn: function() {
- // Note that IE8 in IE7 compatibility mode reports true for 'onhashchange' in window,
- // so also test documentMode
- var docMode = document.documentMode;
- return 'onhashchange' in window && (docMode === undefined || docMode > 7);
- }
- },
- {
- /**
- * @property FixedTableWidthBug
- * @private
- * @type {Boolean}
- * `true` if the browser has this bug: https://bugs.webkit.org/show_bug.cgi?id=130239
- *
- * This property is *NOT* available at application boot time. Only after the document
- * ready event.
- */
- name: 'FixedTableWidthBug',
- ready: true,
- fn: function() {
- if (Ext.isIE8) {
- // IE8 incorrectly detects that we have this bug.
- return false;
- }
- var outer = document.createElement('div'),
- inner = document.createElement('div'),
- width;
- outer.setAttribute('style', 'display:table;table-layout:fixed;');
- inner.setAttribute('style', 'display:table-cell;min-width:50px;');
- outer.appendChild(inner);
- document.body.appendChild(outer);
- // must poke offsetWidth to trigger a reflow before setting width
- // eslint-disable-next-line no-unused-expressions
- outer.offsetWidth;
- outer.style.width = '25px';
- width = outer.offsetWidth;
- document.body.removeChild(outer);
- return width === 50;
- }
- },
- {
- /**
- * @property FocusinFocusoutEvents
- * @private
- * @type {Boolean}
- * `true` if the browser supports focusin and focusout events:
- * https://developer.mozilla.org/en-US/docs/Web/Events/focusin
- * At this point, only Firefox does not, see this bug:
- * https://bugzilla.mozilla.org/show_bug.cgi?id=687787
- *
- * This property is available at application boot time, before document ready.
- */
- name: 'FocusinFocusoutEvents',
- fn: function() {
- // There is no reliable way to feature detect focusin/focusout event support.
- // window.onfocusin will return undefined both in Chrome (where it is supported)
- // and in Firefox (where it is not supported); adding an element and trying to
- // focus it will fail when the browser window itself is not focused.
- return !(Ext.isGecko && Ext.firefoxVersion < 52);
- }
- },
- {
- /**
- * @property {Boolean} AsyncFocusEvents
- * `true` if the browser fires focus events (focus, blur, focusin, focusout)
- * asynchronously, i.e. in a separate event loop invocation. This is only true
- * for all versions Internet Explorer; Microsoft Edge and other browsers fire
- * focus events synchronously.
- */
- name: 'AsyncFocusEvents',
- fn: function() {
- // The sad part is that we can't feature detect this because the focus
- // event won't be fired when the browser window itself is not focused.
- // Private shortcut for brevity
- return Ext.asyncFocus = !!Ext.isIE;
- }
- },
- {
- /**
- * @property {Object} accessibility Accessibility features.
- *
- * @property {Boolean} accessibility.Images `true` if the browser is configured
- * to display images.
- *
- * @property {Boolean} accessibility.BackgroundImages `true` if the browser
- * is configured to display background images.
- *
- * @property {Boolean} accessibility.BorderColors `true` if the browser
- * is configured to honor CSS styling for border colors.
- *
- * @property {Boolean} accessibility.LightOnDark `true` if the browser
- * is currently using reverse colors in light-on-dark accessibility mode.
- */
- name: 'accessibility',
- ready: true,
- fn: function(doc) {
- var body = doc.body,
- div, img, style, supports, bgImg;
- function getColor(colorTxt) {
- var values = [],
- colorValue = 0,
- regex, match;
- if (colorTxt.indexOf('rgb(') !== -1) {
- values = colorTxt.replace('rgb(', '').replace(')', '').split(', ');
- } else if (colorTxt.indexOf('#') !== -1) {
- regex = colorTxt.length === 7 ? /^#(\S\S)(\S\S)(\S\S)$/ : /^#(\S)(\S)(\S)$/;
- match = colorTxt.match(regex);
- if (match) {
- values = [
- '0x' + match[1],
- '0x' + match[2],
- '0x' + match[3]
- ];
- }
- }
- for (var i = 0; i < values.length; i++) {
- colorValue += parseInt(values[i]);
- }
- return colorValue;
- }
- div = doc.createElement('div');
- img = doc.createElement('img');
- style = div.style;
- Ext.apply(style, {
- width: '2px',
- position: 'absolute',
- clip: 'rect(1px,1px,1px,1px)',
- borderWidth: '1px',
- borderStyle: 'solid',
- borderTopTolor: '#f00',
- borderRightColor: '#ff0',
- backgroundColor: '#fff',
- backgroundImage: 'url(' + Ext.BLANK_IMAGE_URL + ')'
- });
- img.alt = '';
- img.src = Ext.BLANK_IMAGE_URL;
- div.appendChild(img);
- body.appendChild(div);
- // Now check if the styles were indeed honored
- style = div.currentStyle || div.style;
- bgImg = style.backgroundImage;
- supports = {
- // In IE it is possible to untick "Show pictures" option in Advanced
- // settings; this will result in img element reporting its readyState
- // as 'uninitialized'.
- // See http://www.paciellogroup.com/blog/2011/10/detecting-if-images-are-disabled-in-browsers/
- Images: img.offsetWidth === 1 && img.readyState !== 'uninitialized',
- BackgroundImages: !(bgImg !== null && (bgImg === "none" || bgImg === "url(invalid-url:)")),
- BorderColors: style.borderTopColor !== style.borderRightColor,
- LightOnDark: getColor(style.color) - getColor(style.backgroundColor) > 0
- };
- Ext.supports.HighContrastMode = !supports.BackgroundImages;
- body.removeChild(div);
- div = img = null;
- return supports;
- }
- },
- {
- /**
- * @property ViewportUnits `true` if the device supports ViewportUnits.
- * @type {Boolean}
- *
- */
- name: 'ViewportUnits',
- ready: true,
- fn: function(doc) {
- // Even attempting to detect the feature throws a fatal error on IE8
- if (Ext.isIE8) {
- return false;
- }
- var body = doc.body,
- div = document.createElement('div'),
- style = div.currentStyle || div.style,
- width, divWidth;
- body.appendChild(div);
- Ext.apply(style, {
- width: '50vw'
- });
- width = parseInt(window.innerWidth / 2, 10);
- // eslint-disable-next-line max-len
- divWidth = parseInt((window.getComputedStyle ? getComputedStyle(div, null) : div.currentStyle).width, 10);
- body.removeChild(div);
- div = null;
- return width === divWidth;
- }
- },
- {
- name: 'CSSVariables',
- ready: false,
- fn: function() {
- // Legacy browsers do not have this method.
- if (!window.getComputedStyle) {
- return false;
- }
- return window.CSS && window.CSS.supports && window.CSS.supports('--test-var', 0);
- }
- },
- {
- /**
- * @property Selectors2 `true` if the browser supports the CSS selector API level 2.
- * https://dev.w3.org/2006/webapi/selectors-api2/
- * @type {Boolean}
- *
- */
- name: 'Selectors2',
- ready: false,
- fn: function(doc) {
- try {
- return !!doc.querySelectorAll(':scope');
- } catch (e) {
- return false;
- }
- }
- },
- {
- /**
- * @property CSSScrollSnap
- * @private
- * @type {Boolean}
- */
- name: 'CSSScrollSnap',
- ready: false,
- fn: function(doc) {
- var style = doc.documentElement.style;
- return 'scrollSnapType' in style || 'webkitScrollSnapType' in style || 'msScrollSnapType' in style;
- }
- },
- {
- /**
- * @property TranslateYCausesHorizontalScroll
- * @private
- * @type {Boolean}
- *
- * Bug for Edge logged here: https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/9743268/
- */
- name: 'TranslateYCausesHorizontalScroll',
- ready: true,
- fn: function(doc, div) {
- div.innerHTML = '<div style="position: relative; overflow: auto; height: 200px; width: 200px;">' + // eslint-disable-line max-len
- '<div>' + '<div style="transform: translateY(260px); width: 50px;">a</div>' + '</div>' + '</div>';
- return div.firstChild.scrollWidth > div.firstChild.clientWidth;
- }
- },
- {
- /**
- * @property FlexBoxBasisBug
- * @private
- * @type {Boolean}
- * Allows align: stretch to align items to the height of the tallest item
- * in an auto-heighted hbox layout.
- * can't use flex-basis: auto everywhere because it breaks percentage-sized children
- * https://bugs.chromium.org/p/chromium/issues/detail?id=680484
- */
- name: 'FlexBoxBasisBug',
- ready: true,
- fn: function() {
- if (Ext.isIE11 || (Ext.os.is.iOS && Ext.os.version.major <= 10) || (Ext.isSafari && Ext.browser.version.isLessThan(11)) || (Ext.os.is.Android && Ext.os.version.isLessThan(6))) {
- return true;
- }
- return false;
- }
- },
- {
- /**
- * @property PercentageSizeFlexBug
- * @private
- * @type {Boolean}
- *
- * Detects https://bugs.webkit.org/show_bug.cgi?id=137730
- */
- name: 'PercentageSizeFlexBug',
- ready: true,
- fn: function(doc, div) {
- if (Ext.isIE9m) {
- return false;
- }
- var style = div.style;
- style.display = 'flex';
- style.flexDirection = 'column';
- style.height = style.width = '100px';
- div.innerHTML = '<div style="flex: 1 1;"><div style="height:50%"></div></div>';
- return div.firstChild.firstChild.offsetHeight !== 50;
- }
- },
- {
- /**
- * @property CannotScrollExactHeight
- * @type {Boolean}
- *
- * Feature detect the support of browsers that are unable to scroll elements that are
- * the same height as the native scrollbar height.
- */
- name: 'CannotScrollExactHeight',
- fn: function() {
- return Ext.isIE10p;
- }
- },
- {
- /**
- * @property WebKitTextInputMarginBug
- * @private
- * @type {Boolean}
- *
- * Detects the following bug:
- * https://bugs.webkit.org/show_bug.cgi?id=137693
- *
- * Feb 22, 2017: This bug used to affect chrome as well, but appears to be fixed in
- * Chrome 56. The issue still exists in safari 10
- */
- name: 'WebKitInputTableBoxModelBug',
- ready: true,
- fn: function(doc, div) {
- var table = document.createElement('div'),
- cell = document.createElement('div'),
- input = document.createElement('input'),
- tableStyle = table.style,
- cellStyle = cell.style,
- inputStyle = input.style,
- body = doc.body,
- hasBug;
- input.type = 'text';
- tableStyle.display = 'table';
- tableStyle.height = '100px';
- cellStyle.display = 'table-cell';
- inputStyle.border = '0';
- inputStyle.padding = '10px';
- inputStyle.boxSizing = 'border-box';
- inputStyle.height = '100%';
- cell.appendChild(input);
- table.appendChild(cell);
- body.appendChild(table);
- hasBug = input.offsetHeight === 80;
- body.removeChild(table);
- return hasBug;
- }
- },
- {
- /**
- * @property PassiveEventListener
- * @private
- * @type {Boolean}
- *
- * Detects support for the "passive" event listener option
- */
- name: 'PassiveEventListener',
- fn: function(doc, div) {
- var supportsPassive = false,
- options;
- try {
- options = Object.defineProperty({}, 'passive', {
- get: function() {
- // eslint-disable-line getter-return
- supportsPassive = true;
- }
- });
- window.addEventListener('e', null, options);
- window.removeEventListener('e', null, options);
- } catch (e) {}
- // ignore
- return supportsPassive;
- }
- },
- {
- /**
- * @property MinContent
- * @private
- * @type {Boolean}
- *
- * Detects support for CSS "min-content"
- */
- name: 'CSSMinContent',
- ready: true,
- fn: function(doc, div) {
- // As of 3/24/2017 IE/Edge have no min-content support, and firefox has
- // partial/buggy support: https://bugzilla.mozilla.org/show_bug.cgi?id=135015
- // This feature detector is designed to return false if there is not "full" support.
- // eslint-disable-next-line max-len
- div.innerHTML = '<div style="height:4px;width:4px;min-height:-webkit-min-content;min-height:-moz-min-content;min-height:min-content"><div style="height:8px;width:8px"></div></div>';
- return div.firstChild.offsetHeight === 8;
- }
- },
- {
- name: 'ComputedSizeIncludesPadding',
- ready: true,
- fn: function(doc, div) {
- var ret = false,
- bd = document.body,
- el, w;
- if (window.getComputedStyle) {
- el = document.createElement('div');
- el.style.cssText = 'width:10px;padding:2px;' + '-webkit-box-sizing:border-box;box-sizing:border-box;';
- bd.appendChild(el);
- w = window.getComputedStyle(el, null).width;
- ret = w === '10px';
- bd.removeChild(el);
- }
- return ret;
- }
- },
- {
- name: 'inputEventData',
- ready: false,
- fn: function() {
- return !!(window.InputEvent && 'data' in new InputEvent('input'));
- }
- },
- /* eslint-disable indent */
- // placeholder so legacy browser detectors can come/go cleanly
- 0
- ]
- };
- /* eslint-enable indent */
- Ext.feature.tests.pop();
- // remove the placeholder
- Ext.supports = {};
- Ext.feature.detect();
- /**
- * This class manages ready detection and handling. Direct use of this class is not
- * recommended. Instead use `Ext.onReady`:
- *
- * Ext.onReady(function () {
- * // DOM and Framework are ready...
- * });
- *
- * ## DOM Ready
- *
- * The lowest-level of readiness is DOM readiness. This level implies only that the document
- * body exists. Many things require the DOM to be ready for manipulation. If that is all
- * that is required, the `Ext.onDocumentReady` method can be called to register a callback
- * to be called as soon as the DOM is ready:
- *
- * Ext.onDocumentReady(function () {
- * // the document body is ready
- * });
- *
- * ## Framework Ready
- *
- * In production builds of applications it is common to have all of the code loaded before
- * DOM ready, so the need to wait for "onReady" is often confused with only that concern.
- * This is easy to understand, at least in part because historically `Ext.onReady` only
- * waited for DOM ready.
- *
- * With the introduction of `Ext.Loader`, however, it became common for DOM ready to occur
- * in the middle of dynamically loading code. If application code were executed at that
- * time, any use of the yet-to-be-loaded classes would throw errors. As a consequence of
- * this, the `Ext.onReady` mechanism was extended to wait for both DOM ready *and* all of
- * the required classes to be loaded.
- *
- * When the framework enters or leaves a state where it is not ready (for example, the
- * first dynamic load is requested or last load completes), `Ext.env.Ready` is informed.
- * For example:
- *
- * Ext.env.Ready.block();
- *
- * //...
- *
- * Ext.env.Ready.unblock();
- *
- * When there are no blocks and the DOM is ready, the Framework is ready and the "onReady"
- * callbacks are called.
- *
- * Priority can be used to control the ordering of onReady listeners, for example:
- *
- * Ext.onReady(function() {
- *
- * }, null, {
- * priority: 100
- * });
- *
- * Ready listeners with higher priorities will run sooner than those with lower priorities,
- * the default priority being `0`. Internally the framework reserves priorities of 1000
- * or greater, and -1000 or lesser for onReady handlers that must run before or after
- * any application code. Applications should stick to using priorities in the -999 - 999
- * range. The following priorities are currently in use by the framework:
- *
- * - Element_scroll rtl override: `1001`
- * - Event system initialization: `2000`
- * - Ext.dom.Element: `1500`
- *
- * @class Ext.env.Ready
- * @singleton
- * @private
- * @since 5.0.0
- */
- Ext.env.Ready = {
- // @define Ext.env.Ready
- // @require Ext.env.Browser
- // @require Ext.env.OS
- // @require Ext.env.Feature
- /**
- * @property {Number} blocks The number of Framework readiness blocks.
- * @private
- */
- blocks: (location.search || '').indexOf('ext-pauseReadyFire') > 0 ? 1 : 0,
- /**
- * @property {Number} bound This property stores the state of event listeners bound
- * to the document or window to detect ready state.
- * @private
- */
- bound: 0,
- /**
- * @property {Number} [delay=1]
- * This allows the DOM listener thread to complete (usually desirable with mobWebkit,
- * Gecko) before firing the entire onReady chain (high stack load on Loader). For mobile
- * devices when running from Home Screen, the splash screen will not disappear until
- * all external resource requests finish. This delay clears the splash screen.
- * @private
- */
- delay: 1,
- /**
- * @property {Event[]} events An array of events that have triggered ready state. This
- * is for diagnostic purposes only and is only available in debug builds.
- * An array
- * @private
- */
- events: [],
- /**
- * @property {Boolean} firing This property is `true` when we currently calling the
- * listeners.
- * @private
- */
- firing: false,
- /**
- * @property {Number} generation A counter of the number of mutations of `listeners`.
- * @private
- */
- generation: 0,
- /**
- * @property {Object[]} listeners The set of listeners waiting for ready.
- * @private
- */
- listeners: [],
- /**
- * @property {Number} nextId A counter so we can assign listeners an `id` to keep
- * them in FIFO order.
- * @private
- */
- nextId: 0,
- /**
- * @property {Number} sortGeneration A captured value of `generation` that indicates
- * when the `listeners` were last sorted.
- * @private
- */
- sortGeneration: 0,
- /**
- * @property {Number} state
- * Holds the current ready state as managed by this class. The values possible are:
- *
- * * 0 - Not ready.
- * * 1 - Ready detected but listeners are not yet notified.
- * * 2 - Ready detected and listeners are notified. See also `firing`.
- *
- * @private
- */
- state: 0,
- /**
- * @property {Object} timer The handle from `setTimeout` for the delayed notification
- * of ready.
- * @private
- */
- timer: null,
- /**
- * Binds the appropriate browser event for checking if the DOM has loaded.
- * @private
- */
- bind: function() {
- var me = Ext.env.Ready,
- doc = document;
- if (!me.bound) {
- // Test scenario where load is dynamic AFTER window.load
- if (doc.readyState === 'complete') {
- // Firefox4+ got support for this state, others already do.
- me.onReadyEvent({
- type: doc.readyState || 'body'
- });
- } else {
- me.bound = 1;
- if (Ext.browser.is.PhoneGap && !Ext.os.is.Desktop) {
- me.bound = 2;
- doc.addEventListener('deviceready', me.onReadyEvent, false);
- }
- doc.addEventListener('DOMContentLoaded', me.onReadyEvent, false);
- window.addEventListener('load', me.onReadyEvent, false);
- }
- }
- },
- block: function() {
- ++this.blocks;
- Ext.isReady = false;
- },
- /**
- * This method starts the process of firing the ready event. This may be delayed based
- * on the `delay` property.
- * @private
- */
- fireReady: function() {
- var me = Ext.env.Ready;
- if (!me.state) {
- Ext._readyTime = Ext.ticks();
- Ext.isDomReady = true;
- me.state = 1;
- // As soon as we transition to domready, complete the feature detection:
- Ext.feature.detect(true);
- if (!me.delay) {
- me.handleReady();
- } else if (navigator.standalone) {
- // When running from Home Screen, the splash screen will not disappear
- // until all external resource requests finish.
- // The first timeout clears the splash screen
- // The second timeout allows inital HTML content to be displayed
- me.timer = Ext.defer(function() {
- me.timer = null;
- me.handleReadySoon();
- }, 1);
- } else {
- me.handleReadySoon();
- }
- }
- },
- /**
- * This method iterates over the `listeners` and invokes them. This advances the
- * `state` from 1 to 2 and ensure the proper subset of `listeners` are invoked.
- * @private
- */
- handleReady: function() {
- var me = this;
- if (me.state === 1) {
- me.state = 2;
- Ext._beforeReadyTime = Ext.ticks();
- me.invokeAll();
- Ext._afterReadyTime = Ext.ticks();
- }
- },
- /**
- * This method is called to schedule a call to `handleReady` using a `setTimeout`. It
- * ensures that only one timer is pending.
- * @param {Number} [delay] If passed, this overrides the `delay` property.
- * @private
- */
- handleReadySoon: function(delay) {
- var me = this;
- if (!me.timer) {
- me.timer = Ext.defer(function() {
- me.timer = null;
- me.handleReady();
- }, delay || me.delay);
- }
- },
- /**
- * This method invokes the given `listener` instance based on its options.
- * @param {Object} listener
- */
- invoke: function(listener) {
- var delay = listener.delay;
- if (delay) {
- Ext.defer(listener.fn, delay, listener.scope);
- } else {
- if (Ext.elevateFunction) {
- Ext.elevateFunction(listener.fn, listener.scope);
- } else {
- listener.fn.call(listener.scope);
- }
- }
- },
- /**
- * Invokes as many listeners as are appropriate given the current state. This should
- * only be called when DOM ready is achieved. The remaining business of `blocks` is
- * handled here.
- */
- invokeAll: function() {
- if (Ext.elevateFunction) {
- Ext.elevateFunction(this.doInvokeAll, this);
- } else {
- this.doInvokeAll();
- }
- },
- doInvokeAll: function() {
- var me = this,
- listeners = me.listeners,
- listener;
- if (!me.blocks) {
- // Since DOM is ready and we have no blocks, we mark the framework as ready.
- Ext.isReady = true;
- }
- me.firing = true;
- // NOTE: We cannot cache this length because each time through the loop a callback
- // may have added new callbacks.
- while (listeners.length) {
- if (me.sortGeneration !== me.generation) {
- me.sortGeneration = me.generation;
- // This will happen just once on the first pass... if nothing is being
- // added as we call the callbacks. This sorts the listeners such that the
- // highest priority listener is at the *end* of the array ... so we can
- // use pop (as opposed to shift) to extract it.
- listeners.sort(me.sortFn);
- }
- listener = listeners.pop();
- if (me.blocks && !listener.dom) {
- // If we are blocked (i.e., only DOM ready) and this listener is not a
- // DOM-ready listener we have reached the end of the line. The remaining
- // listeners are Framework ready listeners.
- listeners.push(listener);
- break;
- }
- me.invoke(listener);
- }
- me.firing = false;
- },
- /**
- * This method wraps the given listener pieces in a proper object for the `listeners`
- * array and `invoke` methods.
- * @param {Function} fn The method to call.
- * @param {Object} [scope] The scope (`this` reference) in which the `fn` executes.
- * Defaults to the browser window.
- * @param {Object} [options] An object with extra options.
- * @param {Number} [options.delay=0] A number of milliseconds to delay.
- * @param {Number} [options.priority=0] Relative priority of this callback. A larger
- * number will result in the callback being sorted before the others. Priorities
- * 1000 or greater and -1000 or lesser are reserved for internal framework use only.
- * @param {Boolean} [options.dom=false] Pass `true` to only wait for DOM ready, `false`
- * means full Framework and DOM readiness.
- * @return {Object} The listener instance.
- * @private
- */
- makeListener: function(fn, scope, options) {
- var ret = {
- fn: fn,
- id: ++this.nextId,
- // so sortFn can respect FIFO
- scope: scope,
- dom: false,
- priority: 0
- };
- if (options) {
- Ext.apply(ret, options);
- }
- ret.phase = ret.dom ? 0 : 1;
- // to simplify the sortFn
- return ret;
- },
- /**
- * Adds a listener to be notified when the document is ready (before onload and before
- * images are loaded).
- *
- * @param {Function} fn The method to call.
- * @param {Object} [scope] The scope (`this` reference) in which the `fn` executes.
- * Defaults to the browser window.
- * @param {Object} [options] An object with extra options.
- * @param {Number} [options.delay=0] A number of milliseconds to delay.
- * @param {Number} [options.priority=0] Relative priority of this callback. A larger
- * number will result in the callback being sorted before the others. Priorities
- * 1000 or greater and -1000 or lesser are reserved for internal framework use only.
- * @param {Boolean} [options.dom=false] Pass `true` to only wait for DOM ready, `false`
- * means full Framework and DOM readiness.
- * @private
- */
- on: function(fn, scope, options) {
- var me = Ext.env.Ready,
- listener = me.makeListener(fn, scope, options);
- if (me.state === 2 && !me.firing && (listener.dom || !me.blocks)) {
- // If we are DOM ready (state === 2) and not currently in invokeAll (!firing)
- // and this listener is ready to call (either a DOM ready listener or there
- // are no blocks), then we need to invoke the listener now.
- //
- // Otherwise we can fall to the else block and push the listener. The eventual
- // (or currently executing) call to handleReady or unblock will trigger its
- // delivery in proper priority order.
- me.invoke(listener);
- } else {
- me.listeners.push(listener);
- ++me.generation;
- if (!me.bound) {
- // If we have never bound then bind the ready event now. If we have unbound
- // the event then me.bound == -1 and we don't want to rebind it as the DOM
- // is ready.
- me.bind();
- }
- }
- },
- /**
- * This is a generic event handler method attached to all of the various events that
- * may indicate ready state. The first call to this method indicates ready state has
- * been achieved.
- * @param {Event} [ev] The event instance.
- * @private
- */
- onReadyEvent: function(ev) {
- var me = Ext.env.Ready;
- if (Ext.elevateFunction) {
- Ext.elevateFunction(me.doReadyEvent, me, arguments);
- } else {
- me.doReadyEvent(ev);
- }
- },
- doReadyEvent: function(ev) {
- var me = this;
- if (ev && ev.type) {
- me.events.push(ev);
- }
- if (me.bound > 0) {
- me.unbind();
- me.bound = -1;
- }
- // NOTE: *not* 0 or false - we never want to rebind!
- if (!me.state) {
- me.fireReady();
- }
- },
- /**
- * Sorts the `listeners` array by `phase` and `priority` such that the first listener
- * to fire can be determined using `pop` on the `listeners` array.
- * @private
- */
- sortFn: function(a, b) {
- return -((a.phase - b.phase) || (b.priority - a.priority) || (a.id - b.id));
- },
- unblock: function() {
- var me = this;
- if (me.blocks) {
- if (!--me.blocks) {
- if (me.state === 2 && !me.firing) {
- // We have already finished handleReady (the DOM ready handler) so
- // this trigger just needs to dispatch all the remaining listeners.
- me.invokeAll();
- }
- }
- }
- },
- // if we are currently firing then invokeAll will pick up the Framework
- // ready listeners automatically.
- //
- // If me.state < 2 then we are waiting for DOM ready so it will eventually
- // call handleReady and invokeAll when everything is ready.
- /**
- * This method is called to remove all event listeners that may have been set up to
- * detect ready state.
- * @private
- */
- unbind: function() {
- var me = this,
- doc = document;
- if (me.bound > 1) {
- doc.removeEventListener('deviceready', me.onReadyEvent, false);
- }
- doc.removeEventListener('DOMContentLoaded', me.onReadyEvent, false);
- window.removeEventListener('load', me.onReadyEvent, false);
- }
- };
- (function() {
- var Ready = Ext.env.Ready;
- /*
- * EXTJS-13522
- * Although IE 9 has the DOMContentLoaded event available, usage of that causes
- * timing issues when attempting to access document.namespaces (VmlCanvas.js).
- * Consequently, even in IE 9 we need to use the legacy bind override for ready
- * detection. This defers ready firing enough to allow access to the
- * document.namespaces property.
- *
- * NOTE: this issue is very timing sensitive, and typically only displays itself
- * when there is a large amount of latency between the browser and the server, and
- * when testing against a built page (ext-all.js) and not a dev mode page.
- */
- if (Ext.isIE9m) {
- /* Customized implementation for Legacy IE. The default implementation is
- * configured for use with all other 'standards compliant' agents.
- * References: http://javascript.nwbox.com/IEContentLoaded/
- * licensed courtesy of http://developer.yahoo.com/yui/license.html
- */
- Ext.apply(Ready, {
- /**
- * Timer for doScroll polling
- * @private
- */
- scrollTimer: null,
- /**
- * @private
- */
- readyStatesRe: /complete/i,
- /**
- * This strategy has minimal benefits for Sencha solutions that build
- * themselves (ie. minimal initial page markup). However, progressively-enhanced
- * pages (with image content and/or embedded frames) will benefit the most
- * from it. Browser timer resolution is too poor to ensure a doScroll check
- * more than once on a page loaded with minimal assets (the readystatechange
- * event 'complete' usually beats the doScroll timer on a 'lightly-loaded'
- * initial document).
- * @private
- */
- pollScroll: function() {
- var scrollable = true;
- try {
- document.documentElement.doScroll('left');
- } catch (e) {
- scrollable = false;
- }
- // on IE8, when running within an iFrame, document.body is not immediately
- // available
- if (scrollable && document.body) {
- Ready.onReadyEvent({
- type: 'doScroll'
- });
- } else {
- // Minimize thrashing --
- // adjusted for setTimeout's close-to-minimums (not too low),
- // as this method SHOULD always be called once initially
- Ready.scrollTimer = Ext.defer(Ready.pollScroll, 20);
- }
- return scrollable;
- },
- bind: function() {
- var doc = document,
- topContext;
- if (Ready.bound) {
- return;
- }
- // See if we are in an IFRAME? (doScroll ineffective here)
- try {
- topContext = window.frameElement === undefined;
- } catch (e) {}
- // If we throw an exception, it means we're probably getting access
- // denied, which means we're in an iframe cross domain.
- if (!topContext || !doc.documentElement.doScroll) {
- Ready.pollScroll = Ext.emptyFn;
- }
- // then noop this test altogether
- else if (Ready.pollScroll()) {
- // starts scroll polling if necessary
- return;
- }
- if (doc.readyState === 'complete') {
- // Loaded AFTER initial document write/load...
- Ready.onReadyEvent({
- type: 'already ' + (doc.readyState || 'body')
- });
- } else {
- doc.attachEvent('onreadystatechange', Ready.onReadyStateChange);
- window.attachEvent('onload', Ready.onReadyEvent);
- Ready.bound = 1;
- }
- },
- unbind: function() {
- document.detachEvent('onreadystatechange', Ready.onReadyStateChange);
- window.detachEvent('onload', Ready.onReadyEvent);
- if (Ext.isNumber(Ready.scrollTimer)) {
- Ext.undefer(Ready.scrollTimer);
- Ready.scrollTimer = null;
- }
- },
- /**
- * This event handler is called when the readyState changes.
- * @private
- */
- onReadyStateChange: function() {
- var state = document.readyState;
- if (Ready.readyStatesRe.test(state)) {
- Ready.onReadyEvent({
- type: state
- });
- }
- }
- });
- }
- /**
- * @property {Boolean} isDomReady
- * `true` when the document body is ready for use.
- * @member Ext
- * @readonly
- */
- /**
- * @property {Boolean} isReady
- * `true` when `isDomReady` is true and the Framework is ready for use.
- * @member Ext
- * @readonly
- */
- /**
- * @method onDocumentReady
- * @member Ext
- * Adds a listener to be notified when the document is ready (before onload and before
- * images are loaded).
- *
- * @param {Function} fn The method to call.
- * @param {Object} [scope] The scope (`this` reference) in which the handler function
- * executes. Defaults to the browser window.
- * @param {Object} [options] An object with extra options.
- * @param {Number} [options.delay=0] A number of milliseconds to delay.
- * @param {Number} [options.priority=0] Relative priority of this callback. A larger
- * number will result in the callback being sorted before the others. Priorities
- * 1000 or greater and -1000 or lesser are reserved for internal framework use only.
- * @private
- */
- Ext.onDocumentReady = function(fn, scope, options) {
- var opt = {
- dom: true
- };
- if (options) {
- Ext.apply(opt, options);
- }
- Ready.on(fn, scope, opt);
- };
- /**
- * @method onReady
- * @member Ext
- * Adds a listener to be notified when the document is ready (before onload and before
- * images are loaded).
- *
- * @param {Function} fn The method to call.
- * @param {Object} [scope] The scope (`this` reference) in which the handler function
- * executes. Defaults to the browser window.
- * @param {Object} [options] An object with extra options.
- * @param {Number} [options.delay=0] A number of milliseconds to delay.
- * @param {Number} [options.priority=0] Relative priority of this callback. A larger
- * number will result in the callback being sorted before the others. Priorities
- * 1000 or greater and -1000 or lesser are reserved for internal framework use only.
- * @param {Boolean} [options.dom=false] Pass `true` to only wait for DOM ready, `false`
- * means full Framework and DOM readiness.
- * numbers are reserved.
- */
- Ext.onReady = function(fn, scope, options) {
- Ready.on(fn, scope, options);
- };
- // A shortcut method for onReady with a high priority
- Ext.onInternalReady = function(fn, scope, options) {
- Ready.on(fn, scope, Ext.apply({
- priority: 1000
- }, options));
- };
- Ready.bind();
- }());
- // @tag class
- /**
- * This class provides dynamic loading support for JavaScript classes. Application code
- * does not typically need to call `Ext.Loader` except perhaps to configure path mappings
- * when not using [Sencha Cmd](http://www.sencha.com/products/sencha-cmd/).
- *
- * Ext.Loader.setPath('MyApp', 'app');
- *
- * When using Sencha Cmd, this is handled by the "bootstrap" provided by the application
- * build script and such configuration is not necessary.
- *
- * # Typical Usage
- *
- * The `Ext.Loader` is most often used behind the scenes to satisfy class references in
- * class declarations. Like so:
- *
- * Ext.define('MyApp.view.Main', {
- * extend: 'Ext.panel.Panel',
- *
- * mixins: [
- * 'MyApp.util.Mixin'
- * ],
- *
- * requires: [
- * 'Ext.grid.Panel'
- * ],
- *
- * uses: [
- * 'MyApp.util.Stuff'
- * ]
- * });
- *
- * In all of these cases, `Ext.Loader` is used internally to resolve these class names
- * and ensure that the necessary class files are loaded.
- *
- * During development, these files are loaded individually for optimal debugging. For a
- * production use, [Sencha Cmd](http://www.sencha.com/products/sencha-cmd/) will replace
- * all of these strings with the actual resolved class references because it ensures that
- * the classes are all contained in the build in the correct order. In development, these
- * files will not be loaded until the `MyApp.view.Main` class indicates they are needed
- * as shown above.
- *
- * # Loading Classes
- *
- * You can also use `Ext.Loader` directly to load classes or files. The simplest form of
- * use is `{@link Ext#require}`.
- *
- * For example:
- *
- * Ext.require('MyApp.view.Main', function () {
- * // On callback, the MyApp.view.Main class is now loaded
- *
- * var view = new MyApp.view.Main();
- * });
- *
- * You can alternatively require classes by alias or wildcard.
- *
- * Ext.require('widget.window');
- *
- * Ext.require(['widget.window', 'layout.border', 'Ext.data.Connection']);
- *
- * Ext.require(['widget.*', 'layout.*', 'Ext.data.*']);
- *
- * The callback function is optional.
- *
- * **Note** Using `Ext.require` at global scope will cause `{@link Ext#onReady}` and
- * `{@link Ext.app.Application#launch}` methods to be deferred until the required classes
- * are loaded. It is these cases where the callback function is most often unnecessary.
- *
- * ## Using Excludes
- *
- * Alternatively, you can exclude what you don't need:
- *
- * // Include everything except Ext.tree.*
- * Ext.exclude('Ext.tree.*').require('*');
- *
- * // Include all widgets except widget.checkbox* (this will exclude
- * // widget.checkbox, widget.checkboxfield, widget.checkboxgroup, etc.)
- * Ext.exclude('widget.checkbox*').require('widget.*');
- *
- * # Dynamic Instantiation
- *
- * Another feature enabled by `Ext.Loader` is instantiation using class names or aliases.
- *
- * For example:
- *
- * var win = Ext.create({
- * xtype: 'window',
- *
- * // or
- * // xclass: 'Ext.window.Window'
- *
- * title: 'Hello'
- * });
- *
- * This form of creation can be useful if the type to create (`window` in the above) is
- * not known statically. Internally, `{@link Ext#method!create}` may need to *synchronously*
- * load the desired class and its requirements. Doing this will generate a warning in
- * the console:
- *
- * [Ext.Loader] Synchronously loading 'Ext.window.Window'...
- *
- * If you see these in your debug console, you should add the indicated class(es) to the
- * appropriate `requires` array (as above) or make an `{@link Ext#require}` call.
- *
- *
- * **Note** Using `{@link Ext#method!create}` has some performance overhead and is best reserved
- * for cases where the target class is not known until run-time.
- *
- * @class Ext.Loader
- * @singleton
- */
- Ext.Loader = (new function() {
- // @define Ext.Loader
- // @require Ext.Base
- // @require Ext.Class
- // @require Ext.ClassManager
- // @require Ext.mixin.Watchable
- // @require Ext.Function
- // @require Ext.Array
- // @require Ext.env.Ready
- var Loader = this,
- Manager = Ext.ClassManager,
- // this is an instance of Ext.Inventory
- Boot = Ext.Boot,
- Class = Ext.Class,
- Ready = Ext.env.Ready,
- alias = Ext.Function.alias,
- dependencyProperties = [
- 'extend',
- 'mixins',
- 'requires'
- ],
- isInHistory = {},
- history = [],
- readyListeners = [],
- usedClasses = [],
- _requiresMap = {},
- _config = {
- /**
- * @cfg {Boolean} [enabled=true]
- * Whether or not to enable the dynamic dependency loading feature.
- */
- enabled: true,
- /**
- * @cfg {Boolean} [scriptChainDelay=false]
- * millisecond delay between asynchronous script injection (prevents stack
- * overflow on some user agents) 'false' disables delay but potentially
- * increases stack load.
- */
- scriptChainDelay: false,
- /**
- * @cfg {Boolean} [disableCaching=true]
- * Appends current timestamp to script files to prevent caching.
- */
- disableCaching: true,
- /**
- * @cfg {String} [disableCachingParam="_dc"]
- * The get parameter name for the cache buster's timestamp.
- */
- disableCachingParam: '_dc',
- /**
- * @cfg {Object} paths
- * The mapping from namespaces to file paths
- *
- * {
- * 'Ext': '.', // This is set by default, Ext.layout.container.Container will be
- * // loaded from ./layout/Container.js
- *
- * 'My': './src/my_own_folder' // My.layout.Container will be loaded from
- * // ./src/my_own_folder/layout/Container.js
- * }
- *
- * Note that all relative paths are relative to the current HTML document.
- * If not being specified, for example, `Other.awesome.Class` will simply be
- * loaded from `"./Other/awesome/Class.js"`.
- */
- paths: Manager.paths,
- /**
- * @cfg {Boolean} preserveScripts
- * `false` to remove asynchronously loaded scripts, `true` to retain script
- * element for browser debugger compatibility and improved load performance.
- */
- preserveScripts: true,
- /**
- * @cfg {String} scriptCharset
- * Optional charset to specify encoding of dynamic script content.
- */
- scriptCharset: undefined
- },
- // These configs are delegated to Ext.Script and may need different names:
- delegatedConfigs = {
- disableCaching: true,
- disableCachingParam: true,
- preserveScripts: true,
- scriptChainDelay: 'loadDelay'
- };
- Ext.apply(Loader, {
- /**
- * @private
- */
- isInHistory: isInHistory,
- /**
- * Flag indicating whether there are still files being loaded
- * @private
- */
- isLoading: false,
- /**
- * An array of class names to keep track of the dependency loading order.
- * This is not guaranteed to be the same everytime due to the asynchronous
- * nature of the Loader.
- *
- * @property {Array} history
- */
- history: history,
- /**
- * Configuration
- * @private
- */
- config: _config,
- /**
- * Maintain the list of listeners to execute when all required scripts are fully loaded
- * @private
- */
- readyListeners: readyListeners,
- /**
- * Contains classes referenced in `uses` properties.
- * @private
- */
- optionalRequires: usedClasses,
- /**
- * Map of fully qualified class names to an array of dependent classes.
- * @private
- */
- requiresMap: _requiresMap,
- /** @private */
- hasFileLoadError: false,
- /**
- * The number of scripts loading via loadScript.
- * @private
- */
- scriptsLoading: 0,
- /**
- * @private
- */
- classesLoading: {},
- missingCount: 0,
- missingQueue: {},
- /**
- * @private
- */
- syncModeEnabled: false,
- init: function() {
- // initalize the default path of the framework
- var scripts = document.getElementsByTagName('script'),
- src = scripts[scripts.length - 1].src,
- path = src.substring(0, src.lastIndexOf('/') + 1),
- meta = Ext._classPathMetadata,
- microloader = Ext.Microloader,
- manifest = Ext.manifest,
- loadOrder, baseUrl, loadlen, l, loadItem;
- if (src.indexOf("packages/core/src/") !== -1) {
- path = path + "../../";
- } else if (src.indexOf("/core/src/class/") !== -1) {
- path = path + "../../../";
- }
- if (!Manager.getPath("Ext")) {
- Manager.setPath('Ext', path + 'src');
- }
- // Pull in Cmd generated metadata if available.
- if (meta) {
- Ext._classPathMetadata = null;
- Loader.addClassPathMappings(meta);
- }
- if (manifest) {
- loadOrder = manifest.loadOrder;
- // if the manifest paths were calculated as relative to the
- // bootstrap file, then we need to prepend Boot.baseUrl to the
- // paths before processing
- baseUrl = Ext.Boot.baseUrl;
- if (loadOrder && manifest.bootRelative) {
- for (loadlen = loadOrder.length , l = 0; l < loadlen; l++) {
- loadItem = loadOrder[l];
- loadItem.path = baseUrl + loadItem.path;
- loadItem.canonicalPath = true;
- }
- }
- }
- if (microloader) {
- Ready.block();
- microloader.onMicroloaderReady(function() {
- Ready.unblock();
- });
- }
- },
- /**
- * @method setConfig
- * Set the configuration for the loader. This should be called right after ext-(debug).js
- * is included in the page, and before Ext.onReady. i.e:
- *
- * <script type="text/javascript" src="ext-core-debug.js"></script>
- * <script type="text/javascript">
- * Ext.Loader.setConfig({
- * enabled: true,
- * paths: {
- * 'My': 'my_own_path'
- * }
- * });
- * </script>
- * <script type="text/javascript">
- * Ext.require(...);
- *
- * Ext.onReady(function() {
- * // application code here
- * });
- * </script>
- *
- * Refer to config options of {@link Ext.Loader} for the list of possible properties
- *
- * @param {Object} config The config object to override the default values
- * @return {Ext.Loader} this
- */
- setConfig: Ext.Function.flexSetter(function(name, value) {
- var delegated = delegatedConfigs[name];
- if (name === 'paths') {
- Loader.setPath(value);
- } else {
- _config[name] = value;
- if (delegated) {
- Boot.setConfig((delegated === true) ? name : delegated, value);
- }
- }
- return Loader;
- }),
- /**
- * Get the config value corresponding to the specified name. If no name is given,
- * will return the config object
- *
- * @param {String} name The config property name
- * @return {Object}
- */
- getConfig: function(name) {
- return name ? _config[name] : _config;
- },
- /**
- * Sets the path of a namespace.
- * For Example:
- *
- * Ext.Loader.setPath('Ext', '.');
- *
- * @param {String/Object} name See {@link Ext.Function#flexSetter flexSetter}
- * @param {String} [path] See {@link Ext.Function#flexSetter flexSetter}
- * @return {Ext.Loader} this
- * @method
- */
- setPath: function() {
- // Paths are an Ext.Inventory thing and ClassManager is an instance of that:
- Manager.setPath.apply(Manager, arguments);
- return Loader;
- },
- /**
- * Sets a batch of path entries
- *
- * @param {Object} paths a set of className: path mappings
- * @return {Ext.Loader} this
- */
- addClassPathMappings: function(paths) {
- // Paths are an Ext.Inventory thing and ClassManager is an instance of that:
- Manager.setPath(paths);
- return Loader;
- },
- /**
- * fixes up loader path configs by prepending Ext.Boot#baseUrl to the beginning
- * of the path, then delegates to Ext.Loader#addClassPathMappings
- * @param pathConfig
- */
- addBaseUrlClassPathMappings: function(pathConfig) {
- var name;
- for (name in pathConfig) {
- pathConfig[name] = Boot.baseUrl + pathConfig[name];
- }
- Ext.Loader.addClassPathMappings(pathConfig);
- },
- /**
- * Translates a className to a file path by adding the
- * the proper prefix and converting the .'s to /'s. For example:
- *
- * Ext.Loader.setPath('My', '/path/to/My');
- *
- * // alerts '/path/to/My/awesome/Class.js'
- * alert(Ext.Loader.getPath('My.awesome.Class'));
- *
- * Note that the deeper namespace levels, if explicitly set, are always resolved first.
- * For example:
- *
- * Ext.Loader.setPath({
- * 'My': '/path/to/lib',
- * 'My.awesome': '/other/path/for/awesome/stuff',
- * 'My.awesome.more': '/more/awesome/path'
- * });
- *
- * // alerts '/other/path/for/awesome/stuff/Class.js'
- * alert(Ext.Loader.getPath('My.awesome.Class'));
- *
- * // alerts '/more/awesome/path/Class.js'
- * alert(Ext.Loader.getPath('My.awesome.more.Class'));
- *
- * // alerts '/path/to/lib/cool/Class.js'
- * alert(Ext.Loader.getPath('My.cool.Class'));
- *
- * // alerts 'Unknown/strange/Stuff.js'
- * alert(Ext.Loader.getPath('Unknown.strange.Stuff'));
- *
- * @param {String} className
- * @return {String} path
- */
- getPath: function(className) {
- // Paths are an Ext.Inventory thing and ClassManager is an instance of that:
- return Manager.getPath(className);
- },
- require: function(expressions, fn, scope, excludes) {
- var classNames;
- if (excludes) {
- return Loader.exclude(excludes).require(expressions, fn, scope);
- }
- classNames = Manager.getNamesByExpression(expressions);
- return Loader.load(classNames, fn, scope);
- },
- syncRequire: function() {
- var wasEnabled = Loader.syncModeEnabled,
- ret;
- Loader.syncModeEnabled = true;
- ret = Loader.require.apply(Loader, arguments);
- Loader.syncModeEnabled = wasEnabled;
- return ret;
- },
- exclude: function(excludes) {
- var selector = Manager.select({
- require: function(classNames, fn, scope) {
- return Loader.load(classNames, fn, scope);
- },
- syncRequire: function(classNames, fn, scope) {
- var wasEnabled = Loader.syncModeEnabled,
- ret;
- Loader.syncModeEnabled = true;
- ret = Loader.load(classNames, fn, scope);
- Loader.syncModeEnabled = wasEnabled;
- return ret;
- }
- });
- selector.exclude(excludes);
- return selector;
- },
- load: function(classNames, callback, scope) {
- if (callback) {
- if (callback.length) {
- // If callback expects arguments, shim it with a function that will map
- // the requires class(es) from the names we are given.
- callback = Loader.makeLoadCallback(classNames, callback);
- }
- callback = callback.bind(scope || Ext.global);
- }
- /* eslint-disable-next-line vars-on-top */
- var state = Manager.classState,
- missingClassNames = [],
- urls = [],
- urlByClass = {},
- numClasses = classNames.length,
- className, i, numMissing;
- for (i = 0; i < numClasses; ++i) {
- className = Manager.resolveName(classNames[i]);
- if (!Manager.isCreated(className)) {
- missingClassNames.push(className);
- if (!state[className]) {
- urlByClass[className] = Loader.getPath(className);
- urls.push(urlByClass[className]);
- }
- }
- }
- // If the dynamic dependency feature is not being used, throw an error
- // if the dependencies are not defined
- numMissing = missingClassNames.length;
- if (numMissing) {
- Loader.missingCount += numMissing;
- Manager.onCreated(function() {
- if (callback) {
- Ext.callback(callback, scope, arguments);
- }
- Loader.checkReady();
- }, Loader, missingClassNames);
- if (!_config.enabled) {
- Ext.raise("Ext.Loader is not enabled, so dependencies cannot be resolved " + "dynamically. Missing required class" + ((missingClassNames.length > 1) ? "es" : "") + ": " + missingClassNames.join(', '));
- }
- if (urls.length) {
- Loader.loadScripts({
- url: urls,
- // scope will be this options object so we can pass these along:
- _classNames: missingClassNames,
- _urlByClass: urlByClass
- });
- } else {
- // need to call checkReady here, as the _missingCoun
- // may have transitioned from 0 to > 0, meaning we
- // need to block ready
- Loader.checkReady();
- }
- } else {
- if (callback) {
- callback.call(scope);
- }
- // need to call checkReady here, as the _missingCoun
- // may have transitioned from 0 to > 0, meaning we
- // need to block ready
- Loader.checkReady();
- }
- if (Loader.syncModeEnabled) {
- // Class may have been just loaded or was already loaded
- if (numClasses === 1) {
- return Manager.get(classNames[0]);
- }
- }
- return Loader;
- },
- makeLoadCallback: function(classNames, callback) {
- return function() {
- var classes = [],
- i = classNames.length;
- while (i-- > 0) {
- classes[i] = Manager.get(classNames[i]);
- }
- return callback.apply(this, classes);
- };
- },
- onLoadFailure: function(request) {
- var options = this,
- entries = request.entries || [],
- onError = options.onError,
- error, entry, i;
- Loader.hasFileLoadError = true;
- --Loader.scriptsLoading;
- if (onError) {
- for (i = 0; i < entries.length; i++) {
- entry = entries[i];
- if (entry.error) {
- error = new Error('Failed to load: ' + entry.url);
- break;
- }
- }
- error = error || new Error('Failed to load');
- onError.call(options.userScope, options, error, request);
- } else {
- Ext.log.error("[Ext.Loader] Some requested files failed to load.");
- }
- Loader.checkReady();
- },
- onLoadSuccess: function() {
- var options = this,
- onLoad = options.onLoad,
- classNames = options._classNames,
- urlByClass = options._urlByClass,
- state = Manager.classState,
- missingQueue = Loader.missingQueue,
- className, i, len;
- --Loader.scriptsLoading;
- if (onLoad) {
- // TODO: need an adapter to convert to v4 onLoad signatures
- onLoad.call(options.userScope, options);
- }
- // onLoad can cause more loads to start, so it must run first
- // classNames is the array of *all* classes that load() was asked to load,
- // including those that might have been already loaded but not yet created.
- // urlByClass is a map of only those classes that we asked Boot to load.
- for (i = 0 , len = classNames.length; i < len; i++) {
- className = classNames[i];
- // When a script is loaded and executed, we should have Ext.define() called
- // for at least one of the classes in the list, which will set the state
- // for that class. That by itself does not mean that the class is available
- // *now* but it means that ClassManager is tracking it and will fire the
- // onCreated callback that we set back in load().
- // However if there is no state for the class, that may mean two things:
- // either it is not a Ext class, or it is truly missing. In any case we need
- // to watch for that thing ourselves, which we will do every checkReady().
- if (!state[className]) {
- missingQueue[className] = urlByClass[className];
- }
- }
- Loader.checkReady();
- },
- // TODO: this timing of this needs to be deferred until all classes have had
- // a chance to be created
- reportMissingClasses: function() {
- var missingQueue = Loader.missingQueue,
- missingClasses = [],
- missingPaths = [],
- missingClassName;
- if (!Loader.syncModeEnabled && !Loader.scriptsLoading && Loader.isLoading && !Loader.hasFileLoadError) {
- for (missingClassName in missingQueue) {
- missingClasses.push(missingClassName);
- missingPaths.push(missingQueue[missingClassName]);
- }
- if (missingClasses.length) {
- throw new Error("The following classes are not declared even if their files " + "have been loaded: '" + missingClasses.join("', '") + "'. Please check the source code of their " + "corresponding files for possible typos: '" + missingPaths.join("', '"));
- }
- }
- },
- /**
- * Add a new listener to be executed when all required scripts are fully loaded
- *
- * @param {Function} fn The function callback to be executed
- * @param {Object} scope The execution scope (`this`) of the callback function.
- * @param {Boolean} [withDomReady=true] Pass `false` to not also wait for document
- * dom ready.
- * @param {Object} [options] Additional callback options.
- * @param {Number} [options.delay=0] A number of milliseconds to delay.
- * @param {Number} [options.priority=0] Relative priority of this callback. Negative
- * numbers are reserved.
- */
- onReady: function(fn, scope, withDomReady, options) {
- var listener;
- if (withDomReady) {
- Ready.on(fn, scope, options);
- } else {
- listener = Ready.makeListener(fn, scope, options);
- if (Loader.isLoading) {
- readyListeners.push(listener);
- } else {
- Ready.invoke(listener);
- }
- }
- },
- /**
- * @private
- * Ensure that any classes referenced in the `uses` property are loaded.
- */
- addUsedClasses: function(classes) {
- var cls, i, ln;
- if (classes) {
- classes = (typeof classes === 'string') ? [
- classes
- ] : classes;
- for (i = 0 , ln = classes.length; i < ln; i++) {
- cls = classes[i];
- if (typeof cls === 'string' && !Ext.Array.contains(usedClasses, cls)) {
- usedClasses.push(cls);
- }
- }
- }
- return Loader;
- },
- /**
- * @private
- */
- triggerReady: function() {
- var listener,
- refClasses = usedClasses;
- if (Loader.isLoading && refClasses.length) {
- // Empty the array to eliminate potential recursive loop issue
- usedClasses = [];
- // this may immediately call us back if all 'uses' classes
- // have been loaded
- Loader.require(refClasses);
- } else {
- // Must clear this before calling callbacks. This will cause any new loads
- // to call Ready.block() again. See below for more on this.
- Loader.isLoading = false;
- // These listeners are just those attached directly to Loader to wait for
- // class loading only.
- readyListeners.sort(Ready.sortFn);
- // this method can be called with Loader.isLoading either true or false
- // (can be called with false when all 'uses' classes are already loaded)
- // this may bypass the above if condition
- while (readyListeners.length && !Loader.isLoading) {
- // we may re-enter triggerReady so we cannot necessarily iterate the
- // readyListeners array
- listener = readyListeners.pop();
- Ready.invoke(listener);
- }
- // If the DOM is also ready, this will fire the normal onReady listeners.
- // An astute observer would note that we may now be back to isLoading and
- // so ask "Why you call unblock?". The reason is that we must match the
- // calls to block and since we transitioned from isLoading to !isLoading
- // here we must call unblock. If we have transitioned back to isLoading in
- // the above loop it will have called block again so the counter will be
- // increased and this call will not reduce the block count to 0. This is
- // done by loadScripts.
- Ready.unblock();
- }
- },
- /**
- * @private
- * @param {String} className
- */
- historyPush: function(className) {
- if (className && !isInHistory[className] && !Manager.overrideMap[className]) {
- isInHistory[className] = true;
- history.push(className);
- }
- return Loader;
- },
- /**
- * This is an internal method that delegate content loading to the
- * bootstrap layer.
- * @private
- * @param params
- */
- loadScripts: function(params) {
- var manifest = Ext.manifest,
- loadOrder = manifest && manifest.loadOrder,
- loadOrderMap = manifest && manifest.loadOrderMap,
- options;
- ++Loader.scriptsLoading;
- // if the load order map hasn't been created, create it now
- // and cache on the manifest
- if (loadOrder && !loadOrderMap) {
- manifest.loadOrderMap = loadOrderMap = Boot.createLoadOrderMap(loadOrder);
- }
- // verify the loading state, as this may have transitioned us from
- // not loading to loading
- Loader.checkReady();
- options = Ext.apply({
- loadOrder: loadOrder,
- loadOrderMap: loadOrderMap,
- charset: _config.scriptCharset,
- success: Loader.onLoadSuccess,
- failure: Loader.onLoadFailure,
- sync: Loader.syncModeEnabled,
- _classNames: []
- }, params);
- options.userScope = options.scope;
- options.scope = options;
- Boot.load(options);
- },
- /**
- * This method is provide for use by the bootstrap layer.
- * @private
- * @param {String[]} urls
- */
- loadScriptsSync: function(urls) {
- var syncwas = Loader.syncModeEnabled;
- Loader.syncModeEnabled = true;
- Loader.loadScripts({
- url: urls
- });
- Loader.syncModeEnabled = syncwas;
- },
- /**
- * This method is provide for use by the bootstrap layer.
- * @private
- * @param {String[]} urls
- */
- loadScriptsSyncBasePrefix: function(urls) {
- var syncwas = Loader.syncModeEnabled;
- Loader.syncModeEnabled = true;
- Loader.loadScripts({
- url: urls,
- prependBaseUrl: true
- });
- Loader.syncModeEnabled = syncwas;
- },
- /**
- * Loads the specified script URL and calls the supplied callbacks. If this method
- * is called before {@link Ext#isReady}, the script's load will delay the transition
- * to ready. This can be used to load arbitrary scripts that may contain further
- * {@link Ext#require Ext.require} calls.
- *
- * @param {Object/String/String[]} options The options object or simply the URL(s) to load.
- * @param {String} options.url The URL from which to load the script.
- * @param {Function} [options.onLoad] The callback to call on successful load.
- * @param {Function} [options.onError] The callback to call on failure to load.
- * @param {Object} [options.scope] The scope (`this`) for the supplied callbacks.
- */
- loadScript: function(options) {
- var isString = typeof options === 'string',
- isArray = options instanceof Array,
- isObject = !isArray && !isString,
- url = isObject ? options.url : options,
- onError = isObject && options.onError,
- onLoad = isObject && options.onLoad,
- scope = isObject && options.scope,
- request = {
- url: url,
- scope: scope,
- onLoad: onLoad,
- onError: onError,
- _classNames: []
- };
- Loader.loadScripts(request);
- },
- /**
- * @private
- */
- checkMissingQueue: function() {
- var missingQueue = Loader.missingQueue,
- newQueue = {},
- missing = 0,
- name;
- for (name in missingQueue) {
- // If class state is available for the name, that means ClassManager
- // is tracking it and will fire callback when it is created.
- // We only need to track non-class things in the Loader.
- if (!(Manager.classState[name] || Manager.isCreated(name))) {
- newQueue[name] = missingQueue[name];
- missing++;
- }
- }
- Loader.missingCount = missing;
- Loader.missingQueue = newQueue;
- },
- /**
- * @private
- */
- checkReady: function() {
- var wasLoading = Loader.isLoading,
- isLoading;
- Loader.checkMissingQueue();
- isLoading = Loader.missingCount + Loader.scriptsLoading;
- if (isLoading && !wasLoading) {
- Ready.block();
- Loader.isLoading = !!isLoading;
- } else if (!isLoading && wasLoading) {
- Loader.triggerReady();
- }
- if (!Loader.scriptsLoading && Loader.missingCount) {
- // Things look bad, but since load requests may come later, defer this
- // for a bit then check if things are still stuck.
- Ext.defer(function() {
- var name;
- if (!Loader.scriptsLoading && Loader.missingCount) {
- Ext.log.error('[Loader] The following classes failed to load:');
- for (name in Loader.missingQueue) {
- Ext.log.error('[Loader] ' + name + ' from ' + Loader.missingQueue[name]);
- }
- }
- }, 1000);
- }
- }
- });
- /**
- * Loads all classes by the given names and all their direct dependencies; optionally
- * executes the given callback function when finishes, within the optional scope.
- *
- * @param {String/String[]} expressions The class, classes or wildcards to load.
- * @param {Function} [fn] The callback function.
- * @param {Object} [scope] The execution scope (`this`) of the callback function.
- * @member Ext
- * @method require
- */
- Ext.require = alias(Loader, 'require');
- /**
- * Synchronously loads all classes by the given names and all their direct dependencies;
- * optionally executes the given callback function when finishes, within the optional scope.
- *
- * @param {String/String[]} expressions The class, classes or wildcards to load.
- * @param {Function} [fn] The callback function.
- * @param {Object} [scope] The execution scope (`this`) of the callback function.
- * @member Ext
- * @method syncRequire
- */
- Ext.syncRequire = alias(Loader, 'syncRequire');
- /**
- * Explicitly exclude files from being loaded. Useful when used in conjunction with a
- * broad include expression. Can be chained with more `require` and `exclude` methods,
- * for example:
- *
- * Ext.exclude('Ext.data.*').require('*');
- *
- * Ext.exclude('widget.button*').require('widget.*');
- *
- * @param {String/String[]} excludes
- * @return {Object} Contains `exclude`, `require` and `syncRequire` methods for chaining.
- * @member Ext
- * @method exclude
- */
- Ext.exclude = alias(Loader, 'exclude');
- /**
- * @cfg {String[]} requires
- * @member Ext.Class
- * List of classes that have to be loaded before instantiating this class.
- * For example:
- *
- * Ext.define('Mother', {
- * requires: ['Child'],
- * giveBirth: function() {
- * // we can be sure that child class is available.
- * return new Child();
- * }
- * });
- */
- Class.registerPreprocessor('loader', function(cls, data, hooks, continueFn) {
- if (Ext.classSystemMonitor) {
- Ext.classSystemMonitor(cls, 'Ext.Loader#loaderPreprocessor', arguments);
- }
- /* eslint-disable-next-line vars-on-top */
- var me = this,
- dependencies = [],
- dependency,
- className = Manager.getName(cls),
- i, j, ln, subLn, value, propertyName, propertyValue, requiredMap;
- /*
- Loop through the dependencyProperties, look for string class names and push
- them into a stack, regardless of whether the property's value is a string, array or object.
- For example:
- {
- extend: 'Ext.MyClass',
- requires: ['Ext.some.OtherClass'],
- mixins: {
- thing: 'Foo.bar.Thing';
- }
- }
- which will later be transformed into:
- {
- extend: Ext.MyClass,
- requires: [Ext.some.OtherClass],
- mixins: {
- thing: Foo.bar.Thing;
- }
- }
- */
- for (i = 0 , ln = dependencyProperties.length; i < ln; i++) {
- propertyName = dependencyProperties[i];
- if (data.hasOwnProperty(propertyName)) {
- propertyValue = data[propertyName];
- if (typeof propertyValue === 'string') {
- dependencies.push(propertyValue);
- } else if (propertyValue instanceof Array) {
- for (j = 0 , subLn = propertyValue.length; j < subLn; j++) {
- value = propertyValue[j];
- if (typeof value === 'string') {
- dependencies.push(value);
- }
- }
- } else if (typeof propertyValue !== 'function') {
- for (j in propertyValue) {
- if (propertyValue.hasOwnProperty(j)) {
- value = propertyValue[j];
- if (typeof value === 'string') {
- dependencies.push(value);
- }
- }
- }
- }
- }
- }
- if (dependencies.length === 0) {
- return;
- }
- if (className) {
- _requiresMap[className] = dependencies;
- }
- /* eslint-disable-next-line vars-on-top */
- var manifestClasses = Ext.manifest && Ext.manifest.classes,
- deadlockPath = [],
- detectDeadlock;
- /*
- * Automatically detect deadlocks before-hand,
- * will throw an error with detailed path for ease of debugging. Examples
- * of deadlock cases:
- *
- * - A extends B, then B extends A
- * - A requires B, B requires C, then C requires A
- *
- * The detectDeadlock function will recursively transverse till the leaf, hence
- * it can detect deadlocks no matter how deep the path is. However we don't need
- * to run this check if the class name is in the manifest: that means Cmd has
- * already resolved all dependencies for this class with no deadlocks.
- */
- if (className && (!manifestClasses || !manifestClasses[className])) {
- requiredMap = Loader.requiredByMap || (Loader.requiredByMap = {});
- for (i = 0 , ln = dependencies.length; i < ln; i++) {
- dependency = dependencies[i];
- (requiredMap[dependency] || (requiredMap[dependency] = [])).push(className);
- }
- detectDeadlock = function(cls) {
- var requires = _requiresMap[cls],
- dep, i, ln;
- deadlockPath.push(cls);
- if (requires) {
- if (Ext.Array.contains(requires, className)) {
- Ext.Error.raise("Circular requirement detected! '" + className + "' and '" + deadlockPath[1] + "' mutually require each other. " + "Path: " + deadlockPath.join(' -> ') + " -> " + deadlockPath[0]);
- }
- for (i = 0 , ln = requires.length; i < ln; i++) {
- dep = requires[i];
- if (!isInHistory[dep]) {
- detectDeadlock(requires[i]);
- }
- }
- }
- };
- detectDeadlock(className);
- }
- (className ? Loader.exclude(className) : Loader).require(dependencies, function() {
- var i, ln, j, subLn, k;
- for (i = 0 , ln = dependencyProperties.length; i < ln; i++) {
- propertyName = dependencyProperties[i];
- if (data.hasOwnProperty(propertyName)) {
- propertyValue = data[propertyName];
- if (typeof propertyValue === 'string') {
- data[propertyName] = Manager.get(propertyValue);
- } else if (propertyValue instanceof Array) {
- for (j = 0 , subLn = propertyValue.length; j < subLn; j++) {
- value = propertyValue[j];
- if (typeof value === 'string') {
- data[propertyName][j] = Manager.get(value);
- }
- }
- } else if (typeof propertyValue !== 'function') {
- for (k in propertyValue) {
- if (propertyValue.hasOwnProperty(k)) {
- value = propertyValue[k];
- if (typeof value === 'string') {
- data[propertyName][k] = Manager.get(value);
- }
- }
- }
- }
- }
- }
- continueFn.call(me, cls, data, hooks);
- });
- return false;
- }, true, 'after', 'className');
- /**
- * @cfg {String[]} uses
- * @member Ext.Class
- * List of optional classes to load together with this class. These aren't neccessarily loaded
- * before this class is created, but are guaranteed to be available before Ext.onReady
- * listeners are invoked. For example:
- *
- * Ext.define('Mother', {
- * uses: ['Child'],
- * giveBirth: function() {
- * // This code might, or might not work:
- * // return new Child();
- *
- * // Instead use Ext.create() to load the class at the spot if not loaded already:
- * return Ext.create('Child');
- * }
- * });
- */
- Manager.registerPostprocessor('uses', function(name, cls, data) {
- var uses = data.uses,
- classNames;
- if (Ext.classSystemMonitor) {
- Ext.classSystemMonitor(cls, 'Ext.Loader#usesPostprocessor', arguments);
- }
- if (uses) {
- classNames = Manager.getNamesByExpression(data.uses);
- Loader.addUsedClasses(classNames);
- }
- });
- Manager.onCreated(Loader.historyPush);
- Loader.init();
- }());
- //-----------------------------------------------------------------------------
- // Use performance.now when available to keep timestamps consistent.
- Ext._endTime = Ext.ticks();
- // This hook is to allow tools like DynaTrace to deterministically detect the availability
- // of Ext.onReady. Since Loader takes over Ext.onReady this must be done here and not in
- // Ext.env.Ready.
- if (Ext._beforereadyhandler) {
- Ext._beforereadyhandler();
- }
- /**
- * @class Ext.util.Positionable
- */
- Ext.define('Ext.overrides.util.Positionable', {
- override: 'Ext.util.Positionable',
- /**
- * @method alignTo
- * @param {Ext.util.Positionable/HTMLElement/String} anchorToEl The Positionable,
- * HTMLElement, or id of the element to align to.
- * @param {String} [alignment="tl-bl?"] The position to align to
- * @param {Number[]} [offsets] Offset the positioning by [x, y]
- * @param {Boolean/Object} [animate] true for the default animation or a standard
- * Element animation config object
- * @return {Ext.util.Positionable} this
- */
- /**
- * @method anchorTo
- * Anchors an element to another element and realigns it when the window is resized.
- * @param {Ext.util.Positionable/HTMLElement/String} anchorToEl The Positionable,
- * HTMLElement, or id of the element to align to.
- * @param {String} [alignment="tl-bl?"] The position to align to
- * @param {Number[]} [offsets] Offset the positioning by [x, y]
- * @param {Boolean/Object} [animate] true for the default animation or a standard
- * Element animation config object
- * @param {Boolean/Number} [monitorScroll=50] True to monitor body scroll and
- * reposition. If this parameter is a number, it is used as the buffer delay in
- * milliseconds.
- * @param {Function} [callback] The function to call after the animation finishes
- * @return {Ext.util.Positionable} this
- */
- anchorTo: function(anchorToEl, alignment, offsets, animate, monitorScroll, callback) {
- var me = this,
- scroll = !Ext.isEmpty(monitorScroll),
- action = function() {
- me.mixins.positionable.alignTo.call(me, anchorToEl, alignment, offsets, animate);
- Ext.callback(callback, me);
- },
- anchor = me.getAnchor();
- // previous listener anchor, remove it
- me.removeAnchor();
- Ext.apply(anchor, {
- fn: action,
- scroll: scroll
- });
- Ext.on('resize', action, null);
- if (scroll) {
- Ext.getWin().on('scroll', action, null, {
- buffer: !isNaN(monitorScroll) ? monitorScroll : 50
- });
- }
- action();
- // align immediately
- return me;
- },
- getAnchor: function() {
- var el = this.el,
- data, anchor;
- if (!el || !el.dom) {
- return;
- }
- data = el.getData();
- anchor = data._anchor;
- if (!anchor) {
- anchor = data._anchor = {};
- }
- return anchor;
- },
- alignTo: function(element, position, offsets, /* private (documented in ext) */
- animate) {
- var me = this,
- el = me.el,
- newMaxHeight, newRegion;
- // Release any height constraint prior to aligning if we are shrinkwrap height.
- if (me.isComponent && me.getSizeModel().height.shrinkWrap) {
- if (me.maxHeight) {
- me.setMaxHeight(null);
- }
- newMaxHeight = true;
- }
- newRegion = me.getAlignToRegion(element, position, offsets, me.minHeight || 150);
- me.setXY([
- newRegion.x,
- newRegion.y
- ], el.anim && !!animate ? el.anim(animate) : false);
- // Impose calculated height constraint.
- if (newMaxHeight && (newMaxHeight = newRegion.getHeight()) !== me.getHeight()) {
- me.setMaxHeight(newMaxHeight);
- }
- return me;
- },
- /**
- * @method move
- * Move the element relative to its current position.
- * @param {String} direction Possible values are:
- *
- * - `"l"` (or `"left"`)
- * - `"r"` (or `"right"`)
- * - `"t"` (or `"top"`, or `"up"`)
- * - `"b"` (or `"bottom"`, or `"down"`)
- *
- * @param {Number} distance How far to move the element in pixels
- * @param {Boolean/Object} [animate] true for the default animation or a standard
- * Element animation config object
- */
- /**
- * Remove any anchor to this element. See {@link #anchorTo}.
- * @return {Ext.util.Positionable} this
- */
- removeAnchor: function() {
- var anchor = this.getAnchor();
- if (anchor && anchor.fn) {
- Ext.un('resize', anchor.fn);
- if (anchor.scroll) {
- Ext.getWin().on('scroll', anchor.fn);
- }
- delete anchor.fn;
- }
- return this;
- },
- /**
- * @method setBox
- * Sets the element's box. If animate is true then x, y, width, and height will be
- * animated concurrently.
- * @param {Object} box The box to fill {x, y, width, height}
- * @param {Boolean/Object} [animate] true for the default animation or a standard
- * Element animation config object
- * @return {Ext.util.Positionable} this
- */
- setBox: function(box, animate) {
- var me = this;
- if (box.isRegion) {
- box = {
- x: box.left,
- y: box.top,
- width: box.right - box.left,
- height: box.bottom - box.top
- };
- }
- if (animate) {
- me.constrainBox(box);
- me.animate(Ext.applyIf({
- to: box,
- listeners: {
- afteranimate: Ext.Function.bind(me.afterSetPosition, me, [
- box.x,
- box.y
- ])
- }
- }, animate));
- } else {
- me.callParent([
- box
- ]);
- }
- return me;
- }
- });
- /**
- * @method setX
- * Sets the X position of the DOM element based on page coordinates.
- * @param {Number} x The X position
- * @param {Boolean/Object} [animate] True for the default animation, or a standard
- * Element animation config object
- * @return {Ext.util.Positionable} this
- */
- /**
- * @method setXY
- * Sets the position of the DOM element in page coordinates.
- * @param {Number[]} pos Contains X & Y [x, y] values for new position (coordinates
- * are page-based)
- * @param {Boolean/Object} [animate] True for the default animation, or a standard
- * Element animation config object
- * @return {Ext.util.Positionable} this
- */
- /**
- * @method setY
- * Sets the Y position of the DOM element based on page coordinates.
- * @param {Number} y The Y position
- * @param {Boolean/Object} [animate] True for the default animation, or a standard
- * Element animation config object
- * @return {Ext.util.Positionable} this
- */
- /**
- * @class Ext.event.Event
- */
- Ext.define('Ext.overrides.event.Event', {
- override: 'Ext.event.Event',
- /**
- * @method injectEvent
- * @member Ext.event.Event
- * Injects a DOM event using the data in this object and (optionally) a new target.
- * This is a low-level technique and not likely to be used by application code. The
- * currently supported event types are:
- * <p><b>HTMLEvents</b></p>
- * <ul>
- * <li>load</li>
- * <li>unload</li>
- * <li>select</li>
- * <li>change</li>
- * <li>submit</li>
- * <li>reset</li>
- * <li>resize</li>
- * <li>scroll</li>
- * </ul>
- * <p><b>MouseEvents</b></p>
- * <ul>
- * <li>click</li>
- * <li>dblclick</li>
- * <li>mousedown</li>
- * <li>mouseup</li>
- * <li>mouseover</li>
- * <li>mousemove</li>
- * <li>mouseout</li>
- * </ul>
- * <p><b>UIEvents</b></p>
- * <ul>
- * <li>focusin</li>
- * <li>focusout</li>
- * <li>activate</li>
- * <li>focus</li>
- * <li>blur</li>
- * </ul>
- * @param {Ext.Element/HTMLElement} target (optional) If specified, the target for the event.
- * This is likely to be used when relaying a DOM event. If not specified, {@link #getTarget}
- * is used to determine the target.
- */
- injectEvent: (function() {
- var API,
- dispatchers = {},
- // keyed by event type (e.g., 'mousedown')
- crazyIEButtons;
- // Good reference: http://developer.yahoo.com/yui/docs/UserAction.js.html
- // IE9 has createEvent, but this code causes major problems with htmleditor (it
- // blocks all mouse events and maybe more). TODO
- if (!Ext.isIE9m && document.createEvent) {
- // if (DOM compliant)
- API = {
- createHtmlEvent: function(doc, type, bubbles, cancelable) {
- var event = doc.createEvent('HTMLEvents');
- event.initEvent(type, bubbles, cancelable);
- return event;
- },
- createMouseEvent: function(doc, type, bubbles, cancelable, detail, clientX, clientY, ctrlKey, altKey, shiftKey, metaKey, button, relatedTarget) {
- var event = doc.createEvent('MouseEvents'),
- view = doc.defaultView || window;
- if (event.initMouseEvent) {
- event.initMouseEvent(type, bubbles, cancelable, view, detail, clientX, clientY, clientX, clientY, ctrlKey, altKey, shiftKey, metaKey, button, relatedTarget);
- } else {
- // old Safari
- event = doc.createEvent('UIEvents');
- event.initEvent(type, bubbles, cancelable);
- event.view = view;
- event.detail = detail;
- event.screenX = clientX;
- event.screenY = clientY;
- event.clientX = clientX;
- event.clientY = clientY;
- event.ctrlKey = ctrlKey;
- event.altKey = altKey;
- event.metaKey = metaKey;
- event.shiftKey = shiftKey;
- event.button = button;
- event.relatedTarget = relatedTarget;
- }
- return event;
- },
- createUIEvent: function(doc, type, bubbles, cancelable, detail) {
- var event = doc.createEvent('UIEvents'),
- view = doc.defaultView || window;
- event.initUIEvent(type, bubbles, cancelable, view, detail);
- return event;
- },
- fireEvent: function(target, type, event) {
- target.dispatchEvent(event);
- }
- };
- } else if (document.createEventObject) {
- // else if (IE)
- crazyIEButtons = {
- 0: 1,
- 1: 4,
- 2: 2
- };
- API = {
- createHtmlEvent: function(doc, type, bubbles, cancelable) {
- var event = doc.createEventObject();
- event.bubbles = bubbles;
- event.cancelable = cancelable;
- return event;
- },
- createMouseEvent: function(doc, type, bubbles, cancelable, detail, clientX, clientY, ctrlKey, altKey, shiftKey, metaKey, button, relatedTarget) {
- var event = doc.createEventObject();
- event.bubbles = bubbles;
- event.cancelable = cancelable;
- event.detail = detail;
- event.screenX = clientX;
- event.screenY = clientY;
- event.clientX = clientX;
- event.clientY = clientY;
- event.ctrlKey = ctrlKey;
- event.altKey = altKey;
- event.shiftKey = shiftKey;
- event.metaKey = metaKey;
- event.button = crazyIEButtons[button] || button;
- event.relatedTarget = relatedTarget;
- // cannot assign to/fromElement
- return event;
- },
- createUIEvent: function(doc, type, bubbles, cancelable, detail) {
- var event = doc.createEventObject();
- event.bubbles = bubbles;
- event.cancelable = cancelable;
- return event;
- },
- fireEvent: function(target, type, event) {
- target.fireEvent('on' + type, event);
- }
- };
- }
- //----------------
- // HTMLEvents
- Ext.Object.each({
- load: [
- false,
- false
- ],
- unload: [
- false,
- false
- ],
- select: [
- true,
- false
- ],
- change: [
- true,
- false
- ],
- submit: [
- true,
- true
- ],
- reset: [
- true,
- false
- ],
- resize: [
- true,
- false
- ],
- scroll: [
- true,
- false
- ]
- }, function(name, value) {
- var bubbles = value[0],
- cancelable = value[1];
- dispatchers[name] = function(targetEl, srcEvent) {
- var e = API.createHtmlEvent(name, bubbles, cancelable);
- API.fireEvent(targetEl, name, e);
- };
- });
- //----------------
- // MouseEvents
- function createMouseEventDispatcher(type, detail) {
- var cancelable = (type !== 'mousemove');
- return function(targetEl, srcEvent) {
- var xy = srcEvent.getXY(),
- e;
- e = API.createMouseEvent(targetEl.ownerDocument, type, true, cancelable, detail, xy[0], xy[1], srcEvent.ctrlKey, srcEvent.altKey, srcEvent.shiftKey, srcEvent.metaKey, srcEvent.button, srcEvent.relatedTarget);
- API.fireEvent(targetEl, type, e);
- };
- }
- Ext.each([
- 'click',
- 'dblclick',
- 'mousedown',
- 'mouseup',
- 'mouseover',
- 'mousemove',
- 'mouseout'
- ], function(eventName) {
- dispatchers[eventName] = createMouseEventDispatcher(eventName, 1);
- });
- //----------------
- // UIEvents
- Ext.Object.each({
- focusin: [
- true,
- false
- ],
- focusout: [
- true,
- false
- ],
- activate: [
- true,
- true
- ],
- focus: [
- false,
- false
- ],
- blur: [
- false,
- false
- ]
- }, function(name, value) {
- var bubbles = value[0],
- cancelable = value[1];
- dispatchers[name] = function(targetEl, srcEvent) {
- var e = API.createUIEvent(targetEl.ownerDocument, name, bubbles, cancelable, 1);
- API.fireEvent(targetEl, name, e);
- };
- });
- //---------
- if (!API) {
- // not even sure what ancient browsers fall into this category...
- dispatchers = {};
- // never mind all those we just built :P
- API = {};
- }
- function cannotInject(target, srcEvent) {}
- // TODO log something
- return function(target) {
- var me = this,
- dispatcher = dispatchers[me.type] || cannotInject,
- t = target ? (target.dom || target) : me.getTarget();
- dispatcher(t, me);
- };
- }()),
- // call to produce method
- preventDefault: function(browserOnly) {
- var me = this,
- event = me.browserEvent,
- parentEvent = me.parentEvent,
- unselectable, target, fn;
- // This check is for IE8/9. The event object may have been
- // invalidated, so we can't delve into the details of it. If so,
- // just fall out gracefully and don't attempt to do anything.
- // eslint-disable-next-line valid-typeof
- if (typeof event.type !== 'unknown') {
- // In some cases we want to prevent default on the browser event
- // but keep propagating it through our event system. For example,
- // in Checkbox selection where the cells with checkboxes should
- // prevent focusing on mousedown but still fire the click event.
- if (!browserOnly) {
- me.defaultPrevented = true;
- }
- // if the event was created by prototype-chaining a new object to an existing event
- // instance, we need to make sure the parent event is defaultPrevented as well.
- if (parentEvent) {
- parentEvent.defaultPrevented = true;
- }
- if (event.preventDefault) {
- event.preventDefault();
- } else {
- // The purpose of the code below is for preventDefault to stop focus from
- // occurring like it does in other modern browsers. This only happens in
- // IE8/9 when using attachEvent. The use of unselectable seems the most reliable
- // way to prevent this from happening. We need to use a timeout to restore the
- // unselectable state because if we don't setting it has no effect. It's important
- // to set the atrribute to 'on' as opposed to just setting the property on the
- // DOM element. See the link below for a discussion on the issue:
- // http://bugs.jquery.com/ticket/10345
- if (event.type === 'mousedown') {
- target = event.target;
- unselectable = target.getAttribute('unselectable');
- if (unselectable !== 'on') {
- target.setAttribute('unselectable', 'on');
- fn = function() {
- target.setAttribute('unselectable', unselectable);
- };
- // This function is hard to track, with a potential to be called
- // for any HtmlElement in the document. It may be a Fly, it may
- // not belong to any Component, and it may even be created by
- // 3rd party code that we have no control over and cannot intercept
- // the element being destroyed.
- // On the other hand, the function is pretty simple, cannot lead
- // to memory leaks and is only fired once. So, no harm no foul.
- fn.$skipTimerCheck = true;
- Ext.defer(fn, 1);
- }
- }
- // IE9 and earlier do not support preventDefault
- event.returnValue = false;
- // Some keys events require setting the keyCode to -1 to be prevented
- // all ctrl + X and F1 -> F12
- if (event.ctrlKey || event.keyCode > 111 && event.keyCode < 124) {
- event.keyCode = -1;
- }
- }
- }
- return me;
- },
- deprecated: {
- '5.0': {
- methods: {
- /**
- * @method clone
- * @member Ext.event.Event
- * Clones this event.
- * @return {Ext.event.Event} The cloned copy
- * @deprecated 5.0.0 This method is deprecated.
- */
- clone: function() {
- return new this.self(this.browserEvent, this);
- }
- }
- }
- }
- }, function() {
- var Event = this,
- btnMap;
- if (Ext.isIE9m) {
- btnMap = {
- 0: 0,
- 1: 0,
- 4: 1,
- 2: 2
- };
- Event.override({
- statics: {
- /**
- * @member Ext.event.Event
- * When events are attached using IE's attachEvent API instead of
- * addEventListener accessing any members of an event object asynchronously
- * results in "Member not found" error. To work around this we fabricate
- * our own event object by copying all of its members to a new object.
- * @param {Event} browserEvent The native browser event object
- * @private
- * @static
- */
- enableIEAsync: function(browserEvent) {
- var name,
- fakeEvent = {};
- for (name in browserEvent) {
- fakeEvent[name] = browserEvent[name];
- }
- return fakeEvent;
- }
- },
- constructor: function(event, info, touchesMap, identifiers) {
- var me = this;
- me.callParent([
- event,
- info,
- touchesMap,
- identifiers
- ]);
- me.button = btnMap[event.button];
- if (event.type === 'contextmenu') {
- // IE8/9 reports click as 0, so we can at least attempt to infer here
- me.button = 2;
- }
- // IE8 can throw an error when trying to access properties on a browserEvent
- // object when the event has been buffered or delayed. Cache them here
- // so we can access them later.
- me.toElement = event.toElement;
- me.fromElement = event.fromElement;
- },
- mouseLeaveRe: /(mouseout|mouseleave)/,
- mouseEnterRe: /(mouseover|mouseenter)/,
- /**
- * @method enableIEAsync
- * @member Ext.event.Event
- * @inheritdoc Ext.event.Event#static-method-enableIEAsync
- * @private
- */
- enableIEAsync: function(browserEvent) {
- this.browserEvent = this.self.enableIEAsync(browserEvent);
- },
- getRelatedTarget: function(selector, maxDepth, returnEl) {
- var me = this,
- type, target;
- if (!me.relatedTarget) {
- type = me.type;
- if (me.mouseLeaveRe.test(type)) {
- target = me.toElement;
- } else if (me.mouseEnterRe.test(type)) {
- target = me.fromElement;
- }
- if (target) {
- me.relatedTarget = me.self.resolveTextNode(target);
- }
- }
- return me.callParent([
- selector,
- maxDepth,
- returnEl
- ]);
- }
- });
- // We place these listeners to capture Tab and Shift-Tab key strokes
- // and pass this information in the focus/blur event if it happens
- // between keydown/keyup pair.
- document.attachEvent('onkeydown', Ext.event.Event.globalTabKeyDown);
- document.attachEvent('onkeyup', Ext.event.Event.globalTabKeyUp);
- window.attachEvent('onunload', function() {
- document.detachEvent('onkeydown', Ext.event.Event.globalTabKeyDown);
- document.detachEvent('onkeyup', Ext.event.Event.globalTabKeyUp);
- });
- }
- });
- Ext.define('Ext.overrides.event.publisher.Dom', {
- override: 'Ext.event.publisher.Dom'
- }, function(DomPublisher) {
- var focusEvents = {
- focus: true,
- focusin: true,
- focusout: true,
- blur: true
- };
- if (Ext.isIE10m) {
- DomPublisher.override({
- isEventBlocked: function(e) {
- if (!focusEvents[e.type]) {
- return this.callParent([
- e
- ]);
- }
- // eslint-disable-next-line vars-on-top
- var body = document.body,
- ev = e.browserEvent,
- el = Ext.synchronouslyFocusing;
- /* eslint-disable max-len, brace-style */
- // This horrid hack is necessary to work around the issue with input elements
- // in IE10m that can fail to focus under certain conditions. See comment in
- // Ext.dom.Element override.
- if (el && ((ev.type === 'focusout' && (ev.srcElement === el || ev.srcElement === window) && ev.toElement === body) || (ev.type === 'focusin' && (ev.srcElement === body || ev.srcElement === window) && ev.fromElement === el && ev.toElement === null))) {
- return true;
- }
- /* eslint-enable max-len, brace-style */
- return false;
- }
- });
- }
- if (Ext.isIE9m) {
- // eslint-disable-next-line vars-on-top
- var docElement = document.documentElement,
- docBody = document.body,
- prototype = DomPublisher.prototype,
- onDirectEvent, onDirectCaptureEvent;
- // eslint-disable-line no-unused-vars
- prototype.target = document;
- prototype.directBoundListeners = {};
- // This method gets bound to the element scope in addDirectListener so that
- // the currentTarget can be captured using "this".
- onDirectEvent = function(e, publisher, capture) {
- e.target = e.srcElement || window;
- e.currentTarget = this;
- if (capture) {
- // Although directly attached capture listeners are not supported in IE9m
- // we still need to call the handler so at least the event fires.
- publisher.onDirectCaptureEvent(e);
- } else {
- publisher.onDirectEvent(e);
- }
- };
- onDirectCaptureEvent = function(e, publisher) {
- e.target = e.srcElement || window;
- e.currentTarget = this;
- // this, not DomPublisher
- publisher.onDirectCaptureEvent(e);
- };
- DomPublisher.override({
- addDelegatedListener: function(eventName) {
- this.delegatedListeners[eventName] = 1;
- // Use attachEvent for IE9 and below. Even though IE9 strict supports
- // addEventListener, it has issues with using synthetic events.
- this.target.attachEvent('on' + eventName, this.onDelegatedEvent);
- },
- removeDelegatedListener: function(eventName) {
- delete this.delegatedListeners[eventName];
- this.target.detachEvent('on' + eventName, this.onDelegatedEvent);
- },
- addDirectListener: function(eventName, element, capture) {
- var me = this,
- dom = element.dom,
- // binding the listener to the element allows us to capture the
- // "currentTarget" (see onDirectEvent)
- boundFn = Ext.Function.bind(onDirectEvent, dom, [
- me,
- capture
- ], true),
- directBoundListeners = me.directBoundListeners,
- handlers = directBoundListeners[eventName] || (directBoundListeners[eventName] = {});
- handlers[dom.id] = boundFn;
- // may be called with an SVG element here, which
- // does not have the attachEvent method on IE 9 strict
- if (dom.attachEvent) {
- dom.attachEvent('on' + eventName, boundFn);
- } else {
- me.callParent([
- eventName,
- element,
- capture
- ]);
- }
- },
- removeDirectListener: function(eventName, element, capture) {
- var dom = element.dom;
- if (dom.detachEvent) {
- dom.detachEvent('on' + eventName, this.directBoundListeners[eventName][dom.id]);
- } else {
- this.callParent([
- eventName,
- element,
- capture
- ]);
- }
- },
- doDelegatedEvent: function(e) {
- e.target = e.srcElement || window;
- if (e.type === 'focusin') {
- // IE8 sometimes happen to focus <html> element instead of the body
- // eslint-disable-next-line max-len
- e.relatedTarget = e.fromElement === docBody || e.fromElement === docElement ? null : e.fromElement;
- } else if (e.type === 'focusout') {
- // eslint-disable-next-line max-len
- e.relatedTarget = e.toElement === docBody || e.toElement === docElement ? null : e.toElement;
- }
- return this.callParent([
- e
- ]);
- }
- });
- // can't capture any events without addEventListener. Have to have direct
- // listeners for every event that does not bubble.
- Ext.apply(prototype.directEvents, prototype.captureEvents);
- // These do not bubble in IE9m so have to attach direct listeners as well.
- Ext.apply(prototype.directEvents, {
- change: 1,
- input: 1,
- paste: 1
- });
- prototype.captureEvents = {};
- }
- });
- Ext.define('Ext.overrides.event.publisher.Gesture', {
- override: 'Ext.event.publisher.Gesture'
- }, function() {
- if (Ext.isIE9m) {
- this.override({
- updateTouches: function(e, isEnd) {
- var browserEvent = e.browserEvent,
- xy = e.getXY();
- // I don't always set pageX and pageY on the event object, but when I do
- // it's because the Gesture publisher expects an event object that has them.
- browserEvent.pageX = xy[0];
- browserEvent.pageY = xy[1];
- this.callParent([
- e,
- isEnd
- ]);
- },
- doDelegatedEvent: function(e) {
- // Workaround IE's "Member not found" errors when accessing an event
- // object asynchronously. Needed for all gesture handlers because
- // they use requestAnimationFrame (see enableIEAsync for more details)
- this.callParent([
- Ext.event.Event.enableIEAsync(e)
- ]);
- }
- });
- }
- });
- /**
- * @class Ext.dom.Element
- * @override Ext.dom.Element
- */
- Ext.define('Ext.overrides.dom.Element', (function() {
- var Element,
- // we cannot do this yet "= Ext.dom.Element"
- WIN = window,
- DOC = document,
- HIDDEN = 'hidden',
- ISCLIPPED = 'isClipped',
- OVERFLOW = 'overflow',
- OVERFLOWX = 'overflow-x',
- OVERFLOWY = 'overflow-y',
- ORIGINALCLIP = 'originalClip',
- HEIGHT = 'height',
- WIDTH = 'width',
- VISIBILITY = 'visibility',
- DISPLAY = 'display',
- NONE = 'none',
- OFFSETS = 'offsets',
- CLIP = 'clip',
- ORIGINALDISPLAY = 'originalDisplay',
- VISMODE = 'visibilityMode',
- ISVISIBLE = 'isVisible',
- OFFSETCLASS = Ext.baseCSSPrefix + 'hidden-offsets',
- CLIPCLASS = Ext.baseCSSPrefix + 'hidden-clip',
- /* eslint-disable indent */
- boxMarkup = [
- '<div class="{0}-tl" role="presentation">',
- '<div class="{0}-tr" role="presentation">',
- '<div class="{0}-tc" role="presentation"></div>',
- '</div>',
- '</div>',
- '<div class="{0}-ml" role="presentation">',
- '<div class="{0}-mr" role="presentation">',
- '<div class="{0}-mc" role="presentation"></div>',
- '</div>',
- '</div>',
- '<div class="{0}-bl" role="presentation">',
- '<div class="{0}-br" role="presentation">',
- '<div class="{0}-bc" role="presentation"></div>',
- '</div>',
- '</div>'
- ].join(''),
- /* eslint-enable indent */
- scriptTagRe = /(?:<script([^>]*)?>)((\n|\r|.)*?)(?:<\/script>)/ig,
- replaceScriptTagRe = /(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)/ig,
- srcRe = /\ssrc=(['"])(.*?)\1/i,
- nonSpaceRe = /\S/,
- typeRe = /\stype=(['"])(.*?)\1/i,
- adjustDirect2DTableRe = /table-row|table-.*-group/,
- msRe = /^-ms-/,
- camelRe = /(-[a-z])/gi,
- camelReplaceFn = function(m, a) {
- return a.charAt(1).toUpperCase();
- },
- XMASKED = Ext.baseCSSPrefix + "masked",
- XMASKEDRELATIVE = Ext.baseCSSPrefix + "masked-relative",
- EXTELMASKMSG = Ext.baseCSSPrefix + "mask-msg",
- bodyRe = /^body/i,
- propertyCache = {},
- getVisMode = function(el) {
- var data = el.getData(),
- visMode = data[VISMODE];
- if (visMode === undefined) {
- data[VISMODE] = visMode = Element.VISIBILITY;
- }
- return visMode;
- },
- emptyRange = DOC.createRange ? DOC.createRange() : null,
- syncContentFly;
- if (Ext.isIE8) {
- // eslint-disable-next-line vars-on-top
- var garbageBin = DOC.createElement('div'),
- destroyQueue = [],
- // prevent memory leaks in IE8
- // see http://social.msdn.microsoft.com/Forums/ie/en-US/c76967f0-dcf8-47d0-8984-8fe1282a94f5/ie-appendchildremovechild-memory-problem?forum=iewebdevelopment
- // This function is called to fully destroy an element on a timer so that code
- // following the remove call can still access the element.
- clearGarbage,
- clearGarbageFn = function() {
- var len = destroyQueue.length,
- i;
- for (i = 0; i < len; i++) {
- garbageBin.appendChild(destroyQueue[i]);
- }
- garbageBin.innerHTML = '';
- destroyQueue.length = 0;
- };
- clearGarbageFn.$skipTimerCheck = true;
- clearGarbage = Ext.Function.createBuffered(clearGarbageFn, 10);
- }
- return {
- override: 'Ext.dom.Element',
- mixins: [
- 'Ext.util.Animate'
- ],
- uses: [
- 'Ext.dom.GarbageCollector',
- 'Ext.dom.Fly',
- 'Ext.event.publisher.MouseEnterLeave',
- 'Ext.fx.Manager',
- 'Ext.fx.Anim'
- ],
- skipGarbageCollection: false,
- _init: function(E) {
- Element = E;
- // now we can poke this into closure scope
- // We want to expose destroyQueue on the prototype for testing purposes
- if (WIN.__UNIT_TESTING__) {
- E.destroyQueue = destroyQueue;
- }
- },
- statics: {
- normalize: function(prop) {
- if (prop === 'float') {
- prop = Ext.supports.Float ? 'cssFloat' : 'styleFloat';
- }
- // For '-ms-foo' we need msFoo
- return propertyCache[prop] || (propertyCache[prop] = prop.replace(msRe, 'ms-').replace(camelRe, camelReplaceFn));
- }
- },
- /**
- * Convenience method for constructing a KeyMap
- * @param {String/Number/Number[]/Object} key Either a string with the keys to listen for,
- * the numeric key code, array of key codes or an object with the following options:
- * @param {Number/Array} key.key
- * @param {Boolean} key.shift
- * @param {Boolean} key.ctrl
- * @param {Boolean} key.alt
- * @param {Function} fn The function to call
- * @param {Object} [scope] The scope (`this` reference) in which the specified function
- * is executed. Defaults to this Element.
- * @return {Ext.util.KeyMap} The KeyMap created
- */
- addKeyListener: function(key, fn, scope) {
- var config;
- if (typeof key !== 'object' || Ext.isArray(key)) {
- config = {
- target: this,
- key: key,
- fn: fn,
- scope: scope
- };
- } else {
- config = {
- target: this,
- key: key.key,
- shift: key.shift,
- ctrl: key.ctrl,
- alt: key.alt,
- fn: fn,
- scope: scope
- };
- }
- return new Ext.util.KeyMap(config);
- },
- /**
- * Creates a KeyMap for this element
- * @param {Object} config The KeyMap config. See {@link Ext.util.KeyMap} for more details
- * @return {Ext.util.KeyMap} The KeyMap created
- */
- addKeyMap: function(config) {
- return new Ext.util.KeyMap(Ext.apply({
- target: this
- }, config));
- },
- /**
- * @private
- * Returns the fractional portion of this element's measurement in the given dimension.
- * (IE9+ only)
- * @return {Number}
- */
- adjustDirect2DDimension: function(dimension) {
- var me = this,
- dom = me.dom,
- display = me.getStyle('display'),
- inlineDisplay = dom.style.display,
- inlinePosition = dom.style.position,
- originIndex = dimension === WIDTH ? 0 : 1,
- currentStyle = dom.currentStyle,
- floating;
- if (display === 'inline') {
- dom.style.display = 'inline-block';
- }
- dom.style.position = display.match(adjustDirect2DTableRe) ? 'absolute' : 'static';
- // floating will contain digits that appears after the decimal point
- // if height or width are set to auto we fallback to msTransformOrigin calculation
- // Use currentStyle here instead of getStyle. In some difficult to reproduce
- // instances it resets the scrollWidth of the element
- floating = (parseFloat(currentStyle[dimension]) || parseFloat(currentStyle.msTransformOrigin.split(' ')[originIndex]) * 2) % 1;
- dom.style.position = inlinePosition;
- if (display === 'inline') {
- dom.style.display = inlineDisplay;
- }
- return floating;
- },
- /**
- * @private
- */
- afterAnimate: function() {
- var shadow = this.shadow;
- if (shadow && !shadow.disabled && !shadow.animate) {
- shadow.show();
- }
- },
- /**
- * @private
- */
- anchorAnimX: function(anchor) {
- var xName = (anchor === 'l') ? 'right' : 'left';
- this.dom.style[xName] = '0px';
- },
- /**
- * @private
- * process the passed fx configuration.
- */
- anim: function(config) {
- if (!Ext.isObject(config)) {
- return (config) ? {} : false;
- }
- // eslint-disable-next-line vars-on-top
- var me = this,
- duration = config.duration || Ext.fx.Anim.prototype.duration,
- easing = config.easing || 'ease',
- animConfig;
- if (config.stopAnimation) {
- me.stopAnimation();
- }
- Ext.applyIf(config, Ext.fx.Manager.getFxDefaults(me.id));
- // Clear any 'paused' defaults.
- Ext.fx.Manager.setFxDefaults(me.id, {
- delay: 0
- });
- animConfig = {
- // Pass the DOM reference. That's tested first so will be converted
- // to an Ext.fx.Target fastest.
- target: me.dom,
- remove: config.remove,
- alternate: config.alternate || false,
- duration: duration,
- easing: easing,
- callback: config.callback,
- listeners: config.listeners,
- iterations: config.iterations || 1,
- scope: config.scope,
- block: config.block,
- concurrent: config.concurrent,
- delay: config.delay || 0,
- paused: true,
- keyframes: config.keyframes,
- from: config.from || {},
- to: Ext.apply({}, config),
- userConfig: config
- };
- Ext.apply(animConfig.to, config.to);
- // Anim API properties - backward compat
- delete animConfig.to.to;
- delete animConfig.to.from;
- delete animConfig.to.remove;
- delete animConfig.to.alternate;
- delete animConfig.to.keyframes;
- delete animConfig.to.iterations;
- delete animConfig.to.listeners;
- delete animConfig.to.target;
- delete animConfig.to.paused;
- delete animConfig.to.callback;
- delete animConfig.to.scope;
- delete animConfig.to.duration;
- delete animConfig.to.easing;
- delete animConfig.to.concurrent;
- delete animConfig.to.block;
- delete animConfig.to.stopAnimation;
- delete animConfig.to.delay;
- return animConfig;
- },
- /**
- * Calls `{@link #addAnimation}` and returns this Element (for call chaining). For
- * details, see `{@link #addAnimation}`.
- *
- * @param {Object} config Configuration for {@link Ext.fx.Anim}.
- * Note that the {@link Ext.fx.Anim#to to} config is required.
- * @return {Ext.dom.Element} this
- */
- animate: function(config) {
- this.addAnimation(config);
- return this;
- },
- /**
- * Starts a custom animation on this Element.
- *
- * The following properties may be specified in `from`, `to`, and `keyframe` objects:
- *
- * - `x` - The page X position in pixels.
- * - `y` - The page Y position in pixels
- * - `left` - The element's CSS `left` value. Units must be supplied.
- * - `top` - The element's CSS `top` value. Units must be supplied.
- * - `width` - The element's CSS `width` value. Units must be supplied.
- * - `height` - The element's CSS `height` value. Units must be supplied.
- * - `scrollLeft` - The element's `scrollLeft` value.
- * - `scrollTop` - The element's `scrollTop` value.
- * - `opacity` - The element's `opacity` value (between `0` and `1`).
- *
- * **Be aware** that animating an Element which is being used by an Ext Component
- * without in some way informing the Component about the changed element state will
- * result in incorrect Component behaviour. This is because the Component will be
- * using the old state of the element. To avoid this problem, it is now possible
- * to directly animate certain properties of Components.
- *
- * @param {Object} config Configuration for {@link Ext.fx.Anim}.
- * Note that the {@link Ext.fx.Anim#to to} config is required.
- * @return {Ext.fx.Anim} The new animation.
- */
- addAnimation: function(config) {
- var me = this,
- animId = me.dom.id || Ext.id(me.dom),
- listeners, anim, end;
- if (!Ext.fx.Manager.hasFxBlock(animId)) {
- // Bit of gymnastics here to ensure our internal listeners get bound first
- if (config.listeners) {
- listeners = config.listeners;
- delete config.listeners;
- }
- if (config.internalListeners) {
- config.listeners = config.internalListeners;
- delete config.internalListeners;
- }
- end = config.autoEnd;
- delete config.autoEnd;
- anim = new Ext.fx.Anim(me.anim(config));
- anim.on({
- afteranimate: 'afterAnimate',
- beforeanimate: 'beforeAnimate',
- scope: me,
- single: true
- });
- if (listeners) {
- anim.on(listeners);
- }
- Ext.fx.Manager.queueFx(anim);
- if (end) {
- anim.jumpToEnd();
- }
- }
- return anim;
- },
- /**
- * @private
- */
- beforeAnimate: function() {
- var shadow = this.shadow;
- if (shadow && !shadow.disabled && !shadow.animate) {
- shadow.hide();
- }
- },
- /**
- * Wraps the specified element with a special 9 element markup/CSS block that renders
- * by default as a gray container with a gradient background, rounded corners
- * and a 4-way shadow.
- *
- * This special markup is used throughout Ext when box wrapping elements
- * ({@link Ext.button.Button}, {@link Ext.panel.Panel} when
- * {@link Ext.panel.Panel#frame frame=true}, {@link Ext.window.Window}).
- * The markup is of this form:
- *
- * <div class="{0}-tl"><div class="{0}-tr"><div class="{0}-tc"></div></div></div>
- * <div class="{0}-ml"><div class="{0}-mr"><div class="{0}-mc"></div></div></div>
- * <div class="{0}-bl"><div class="{0}-br"><div class="{0}-bc"></div></div></div>
- *
- * Example usage:
- *
- * // Basic box wrap
- * Ext.get("foo").boxWrap();
- *
- * // You can also add a custom class and use CSS inheritance rules to customize
- * // the box look.
- * // 'x-box-blue' is a built-in alternative -- look at the related CSS definitions
- * // as an example for how to create a custom box wrap style.
- * Ext.get("foo").boxWrap().addCls("x-box-blue");
- *
- * @param {String} [cls='x-box'] A base CSS class to apply to the containing wrapper
- * element. Note that there are a number of CSS rules that are dependent on this name
- * to make the overall effect work, so if you supply an alternate base class, make sure
- * you also supply all of the necessary rules.
- * @return {Ext.dom.Element} The outermost wrapping element of the created box structure.
- */
- boxWrap: function(cls) {
- var el;
- cls = cls || Ext.baseCSSPrefix + 'box';
- el = Ext.get(this.insertHtml("beforeBegin", "<div class='" + cls + "' role='presentation'>" + Ext.String.format(boxMarkup, cls) + "</div>"));
- el.selectNode('.' + cls + '-mc').appendChild(this.dom);
- return el;
- },
- /**
- * Removes Empty, or whitespace filled text nodes. Combines adjacent text nodes.
- * @param {Boolean} [forceReclean=false] By default the element keeps track if it has been
- * cleaned already so you can call this over and over. However, if you update the element
- * and need to force a re-clean, you can pass true.
- */
- clean: function(forceReclean) {
- var me = this,
- dom = me.dom,
- data = me.getData(),
- n = dom.firstChild,
- ni = -1,
- nx;
- if (data.isCleaned && forceReclean !== true) {
- return me;
- }
- while (n) {
- nx = n.nextSibling;
- if (n.nodeType === 3) {
- // Remove empty/whitespace text nodes
- if (!(nonSpaceRe.test(n.nodeValue))) {
- dom.removeChild(n);
- }
- // Combine adjacent text nodes
- else if (nx && nx.nodeType === 3) {
- n.appendData(Ext.String.trim(nx.data));
- dom.removeChild(nx);
- nx = n.nextSibling;
- n.nodeIndex = ++ni;
- }
- } else {
- // Recursively clean
- Ext.fly(n, '_clean').clean();
- n.nodeIndex = ++ni;
- }
- n = nx;
- }
- data.isCleaned = true;
- return me;
- },
- /**
- * @method
- * Empties this element. Removes all child nodes.
- */
- empty: emptyRange ? function() {
- var dom = this.dom;
- if (dom.firstChild) {
- emptyRange.setStartBefore(dom.firstChild);
- emptyRange.setEndAfter(dom.lastChild);
- emptyRange.deleteContents();
- }
- } : function() {
- var dom = this.dom;
- while (dom.lastChild) {
- dom.removeChild(dom.lastChild);
- }
- },
- clearListeners: function() {
- this.removeAnchor();
- this.callParent();
- },
- /**
- * Clears positioning back to the default when the document was loaded.
- * @param {String} [value=''] The value to use for the left, right, top, bottom.
- * You could use 'auto'.
- * @return {Ext.dom.Element} this
- */
- clearPositioning: function(value) {
- value = value || '';
- return this.setStyle({
- left: value,
- right: value,
- top: value,
- bottom: value,
- 'z-index': '',
- position: 'static'
- });
- },
- /**
- * Creates a proxy element of this element
- * @param {String/Object} config The class name of the proxy element or a DomHelper config
- * object
- * @param {String/HTMLElement} [renderTo] The element or element id to render the proxy to.
- * Defaults to: document.body.
- * @param {Boolean} [matchBox=false] True to align and size the proxy to this element now.
- * @return {Ext.dom.Element} The new proxy element
- */
- createProxy: function(config, renderTo, matchBox) {
- config = (typeof config === 'object') ? config : {
- tag: "div",
- role: 'presentation',
- cls: config
- };
- // eslint-disable-next-line vars-on-top
- var me = this,
- proxy = renderTo ? Ext.DomHelper.append(renderTo, config, true) : Ext.DomHelper.insertBefore(me.dom, config, true);
- proxy.setVisibilityMode(Element.DISPLAY);
- proxy.hide();
- // check to make sure Element_position.js is loaded
- if (matchBox && me.setBox && me.getBox) {
- proxy.setBox(me.getBox());
- }
- return proxy;
- },
- /**
- * Clears any opacity settings from this element. Required in some cases for IE.
- * @return {Ext.dom.Element} this
- */
- clearOpacity: function() {
- return this.setOpacity('');
- },
- /**
- * Store the current overflow setting and clip overflow on the element - use {@link #unclip}
- * to remove
- * @return {Ext.dom.Element} this
- */
- clip: function() {
- var me = this,
- data = me.getData(),
- style;
- if (!data[ISCLIPPED]) {
- data[ISCLIPPED] = true;
- style = me.getStyle([
- OVERFLOW,
- OVERFLOWX,
- OVERFLOWY
- ]);
- data[ORIGINALCLIP] = {
- o: style[OVERFLOW],
- x: style[OVERFLOWX],
- y: style[OVERFLOWY]
- };
- me.setStyle(OVERFLOW, HIDDEN);
- me.setStyle(OVERFLOWX, HIDDEN);
- me.setStyle(OVERFLOWY, HIDDEN);
- }
- return me;
- },
- destroy: function() {
- var me = this,
- dom = me.dom,
- data = me.peekData(),
- maskEl, maskMsg;
- if (dom) {
- if (me.isAnimate) {
- me.stopAnimation(true);
- }
- me.removeAnchor();
- }
- if (me.deferredFocusTimer) {
- Ext.undefer(me.deferredFocusTimer);
- me.deferredFocusTimer = null;
- }
- me.callParent();
- // prevent memory leaks in IE8
- // see http://social.msdn.microsoft.com/Forums/ie/en-US/c76967f0-dcf8-47d0-8984-8fe1282a94f5/ie-appendchildremovechild-memory-problem?forum=iewebdevelopment
- // must not be document, documentElement, body or window object
- // Have to use != instead of !== for IE8 or it will not recognize that the window
- // objects are equal
- // eslint-disable-next-line eqeqeq
- if (dom && Ext.isIE8 && (dom.window != dom) && (dom.nodeType !== 9) && (dom.tagName !== 'BODY') && (dom.tagName !== 'HTML')) {
- destroyQueue[destroyQueue.length] = dom;
- // Will perform extra IE8 cleanup in 10 milliseconds
- // see http://social.msdn.microsoft.com/Forums/ie/en-US/c76967f0-dcf8-47d0-8984-8fe1282a94f5/ie-appendchildremovechild-memory-problem?forum=iewebdevelopment
- clearGarbage();
- }
- if (data) {
- maskEl = data.maskEl;
- maskMsg = data.maskMsg;
- if (maskEl) {
- maskEl.destroy();
- }
- if (maskMsg) {
- maskMsg.destroy();
- }
- }
- },
- /**
- * Convenience method for setVisibilityMode(Element.DISPLAY).
- * @param {String} [display] What to set display to when visible
- * @return {Ext.dom.Element} this
- */
- enableDisplayMode: function(display) {
- var me = this;
- me.setVisibilityMode(Element.DISPLAY);
- if (display !== undefined) {
- me.getData()[ORIGINALDISPLAY] = display;
- }
- return me;
- },
- /**
- * Fade an element in (from transparent to opaque). The ending opacity can be specified
- * using the `opacity` config option. Usage:
- *
- * // default: fade in from opacity 0 to 100%
- * el.fadeIn();
- *
- * // custom: fade in from opacity 0 to 75% over 2 seconds
- * el.fadeIn({ opacity: .75, duration: 2000});
- *
- * // common config options shown with default values
- * el.fadeIn({
- * opacity: 1, //can be any value between 0 and 1 (e.g. .5)
- * easing: 'easeOut',
- * duration: 500
- * });
- *
- * @param {Object} options (optional) Object literal with any of the {@link Ext.fx.Anim}
- * config options
- * @return {Ext.dom.Element} The Element
- */
- fadeIn: function(options) {
- var me = this,
- dom = me.dom,
- animFly = new Ext.dom.Fly();
- me.animate(Ext.apply({}, options, {
- opacity: 1,
- internalListeners: {
- beforeanimate: function(anim) {
- // Reattach to the DOM in case the caller animated a Fly
- // in which case the dom reference will have changed by now.
- animFly.attach(dom);
- // restore any visibility/display that may have
- // been applied by a fadeout animation
- if (animFly.isStyle('display', 'none')) {
- animFly.setDisplayed('');
- } else {
- animFly.show();
- }
- }
- }
- }));
- return this;
- },
- /**
- * Fade an element out (from opaque to transparent). The ending opacity can be specified
- * using the `opacity` config option. Note that IE may require `useDisplay: true` in order
- * to redisplay correctly. Usage:
- *
- * // default: fade out from the element's current opacity to 0
- * el.fadeOut();
- *
- * // custom: fade out from the element's current opacity to 25% over 2 seconds
- * el.fadeOut({ opacity: .25, duration: 2000});
- *
- * // common config options shown with default values
- * el.fadeOut({
- * opacity: 0, //can be any value between 0 and 1 (e.g. .5)
- * easing: 'easeOut',
- * duration: 500,
- * remove: false,
- * useDisplay: false
- * });
- *
- * @param {Object} options (optional) Object literal with any of the {@link Ext.fx.Anim}
- * config options
- * @return {Ext.dom.Element} The Element
- */
- fadeOut: function(options) {
- var me = this,
- dom = me.dom,
- animFly = new Ext.dom.Fly();
- options = Ext.apply({
- opacity: 0,
- internalListeners: {
- afteranimate: function(anim) {
- if (anim.to.opacity === 0) {
- // Reattach to the DOM in case the caller animated a Fly
- // in which case the dom reference will have changed by now.
- animFly.attach(dom);
- // Reattach to the DOM in case the caller animated a Fly
- // in which case the dom reference will have changed by now.
- animFly.attach(dom);
- if (options.useDisplay) {
- animFly.setDisplayed(false);
- } else {
- animFly.hide();
- }
- }
- }
- }
- }, options);
- me.animate(options);
- return me;
- },
- /**
- * @private
- */
- fixDisplay: function() {
- var me = this;
- if (me.isStyle(DISPLAY, NONE)) {
- me.setStyle(VISIBILITY, HIDDEN);
- me.setStyle(DISPLAY, me._getDisplay());
- // first try reverting to default
- if (me.isStyle(DISPLAY, NONE)) {
- // if that fails, default to block
- me.setStyle(DISPLAY, "block");
- }
- }
- },
- /**
- * Shows a ripple of exploding, attenuating borders to draw attention to an Element. Usage:
- *
- * // default: a single light blue ripple
- * el.frame();
- *
- * // custom: 3 red ripples lasting 3 seconds total
- * el.frame("#ff0000", 3, { duration: 3000 });
- *
- * // common config options shown with default values
- * el.frame("#C3DAF9", 1, {
- * duration: 1000 // duration of each individual ripple.
- * // Note: Easing is not configurable and will be ignored if included
- * });
- *
- * @param {String} [color='#C3DAF9'] The hex color value for the border.
- * @param {Number} [count=1] The number of ripples to display.
- * @param {Object} [obj] Object literal with any of the {@link Ext.fx.Anim} config options
- * @return {Ext.dom.Element} The Element
- */
- frame: function(color, count, obj) {
- var me = this,
- dom = me.dom,
- animFly = new Ext.dom.Fly(),
- beforeAnim;
- color = color || '#C3DAF9';
- count = count || 1;
- obj = obj || {};
- beforeAnim = function() {
- var animScope = this,
- box, proxy, proxyAnim;
- // Reattach to the DOM in case the caller animated a Fly
- // in which case the dom reference will have changed by now.
- animFly.attach(dom);
- animFly.show();
- box = animFly.getBox();
- proxy = Ext.getBody().createChild({
- role: 'presentation',
- id: animFly.dom.id + '-anim-proxy',
- style: {
- position: 'absolute',
- 'pointer-events': 'none',
- 'z-index': 35000,
- border: '0px solid ' + color
- }
- });
- proxyAnim = new Ext.fx.Anim({
- target: proxy,
- duration: obj.duration || 1000,
- iterations: count,
- from: {
- top: box.y,
- left: box.x,
- borderWidth: 0,
- opacity: 1,
- height: box.height,
- width: box.width
- },
- to: {
- top: box.y - 20,
- left: box.x - 20,
- borderWidth: 10,
- opacity: 0,
- height: box.height + 40,
- width: box.width + 40
- }
- });
- proxyAnim.on('afteranimate', function() {
- proxy.destroy();
- // kill the no-op element animation created below
- animScope.end();
- });
- };
- me.animate({
- // See "A Note About Wrapped Animations" at the top of this class:
- duration: (Math.max(obj.duration, 500) * 2) || 2000,
- listeners: {
- beforeanimate: {
- fn: beforeAnim
- }
- },
- callback: obj.callback,
- scope: obj.scope
- });
- return me;
- },
- /**
- * Return the CSS color for the specified CSS attribute. rgb, 3 digit (like `#fff`)
- * and valid values are convert to standard 6 digit hex color.
- * @param {String} attr The css attribute
- * @param {String} defaultValue The default value to use when a valid color isn't found
- * @param {String} [prefix] defaults to #. Use an empty string when working with
- * color anims.
- * @private
- */
- getColor: function(attr, defaultValue, prefix) {
- var v = this.getStyle(attr),
- color = prefix || prefix === '' ? prefix : '#',
- h, len, i;
- if (!v || (/transparent|inherit/.test(v))) {
- return defaultValue;
- }
- if (/^r/.test(v)) {
- v = v.slice(4, v.length - 1).split(',');
- len = v.length;
- for (i = 0; i < len; i++) {
- h = parseInt(v[i], 10);
- color += (h < 16 ? '0' : '') + h.toString(16);
- }
- } else {
- v = v.replace('#', '');
- color += v.length === 3 ? v.replace(/^(\w)(\w)(\w)$/, '$1$1$2$2$3$3') : v;
- }
- return (color.length > 5 ? color.toLowerCase() : defaultValue);
- },
- /**
- * Gets this element's {@link Ext.ElementLoader ElementLoader}
- * @return {Ext.ElementLoader} The loader
- */
- getLoader: function() {
- var me = this,
- data = me.getData(),
- loader = data.loader;
- if (!loader) {
- data.loader = loader = new Ext.ElementLoader({
- target: me
- });
- }
- return loader;
- },
- /**
- * Gets an object with all CSS positioning properties. Useful along with
- * `setPositioning` to get snapshot before performing an update and then restoring
- * the element.
- * @param {Boolean} [autoPx=false] true to return pixel values for "auto" styles.
- * @return {Object}
- */
- getPositioning: function(autoPx) {
- var styles = this.getStyle([
- 'left',
- 'top',
- 'position',
- 'z-index'
- ]),
- dom = this.dom;
- if (autoPx) {
- if (styles.left === 'auto') {
- styles.left = dom.offsetLeft + 'px';
- }
- if (styles.top === 'auto') {
- styles.top = dom.offsetTop + 'px';
- }
- }
- return styles;
- },
- /**
- * Slides the element while fading it out of view. An anchor point can be optionally passed
- * to set the ending point of the effect. Usage:
- *
- * // default: slide the element downward while fading out
- * el.ghost();
- *
- * // custom: slide the element out to the right with a 2-second duration
- * el.ghost('r', { duration: 2000 });
- *
- * // common config options shown with default values
- * el.ghost('b', {
- * easing: 'easeOut',
- * duration: 500
- * });
- *
- * @param {String} [anchor] One of the valid {@link Ext.fx.Anim} anchor positions
- * (defaults to bottom: 'b')
- * @param {Object} [options] Object literal with any of the {@link Ext.fx.Anim}
- * config options
- * @return {Ext.dom.Element} The Element
- */
- ghost: function(anchor, options) {
- var me = this,
- dom = me.dom,
- animFly = new Ext.dom.Fly(),
- beforeAnim;
- anchor = anchor || "b";
- beforeAnim = function() {
- // Reattach to the DOM in case the caller animated a Fly
- // in which case the dom reference will have changed by now.
- animFly.attach(dom);
- // eslint-disable-next-line vars-on-top
- var width = animFly.getWidth(),
- height = animFly.getHeight(),
- xy = animFly.getXY(),
- position = animFly.getPositioning(),
- to = {
- opacity: 0
- };
- switch (anchor) {
- case 't':
- to.y = xy[1] - height;
- break;
- case 'l':
- to.x = xy[0] - width;
- break;
- case 'r':
- to.x = xy[0] + width;
- break;
- case 'b':
- to.y = xy[1] + height;
- break;
- case 'tl':
- to.x = xy[0] - width;
- to.y = xy[1] - height;
- break;
- case 'bl':
- to.x = xy[0] - width;
- to.y = xy[1] + height;
- break;
- case 'br':
- to.x = xy[0] + width;
- to.y = xy[1] + height;
- break;
- case 'tr':
- to.x = xy[0] + width;
- to.y = xy[1] - height;
- break;
- }
- this.to = to;
- this.on('afteranimate', function() {
- // Reattach to the DOM in case the caller animated a Fly
- // in which case the dom reference will have changed by now.
- animFly.attach(dom);
- if (animFly) {
- animFly.hide();
- animFly.clearOpacity();
- animFly.setPositioning(position);
- }
- });
- };
- me.animate(Ext.applyIf(options || {}, {
- duration: 500,
- easing: 'ease-out',
- listeners: {
- beforeanimate: beforeAnim
- }
- }));
- return me;
- },
- getTextSelection: function() {
- var ret, dom, doc, range, textRange;
- ret = this.callParent();
- if (typeof ret[0] !== 'number') {
- dom = this.dom;
- doc = dom.ownerDocument;
- range = doc.selection.createRange();
- textRange = dom.createTextRange();
- textRange.setEndPoint('EndToStart', range);
- ret[0] = textRange.text.length;
- ret[1] = ret[0] + range.text.length;
- }
- return ret;
- },
- /**
- * Hide this element - Uses display mode to determine whether to use "display",
- * "visibility", "offsets", or "clip". See {@link #setVisible}.
- * @param {Boolean/Object} [animate] true for the default animation or a standard
- * Element animation config object
- * @return {Ext.dom.Element} this
- */
- hide: function(animate) {
- // hideMode override
- if (typeof animate === 'string') {
- this.setVisible(false, animate);
- return this;
- }
- this.setVisible(false, this.anim(animate));
- return this;
- },
- /**
- * Highlights the Element by setting a color (applies to the background-color by default,
- * but can be changed using the "attr" config option) and then fading back to the original
- * color. If no original color is available, you should provide the "endColor" config option
- * which will be cleared after the animation. Usage:
- *
- * // default: highlight background to yellow
- * el.highlight();
- *
- * // custom: highlight foreground text to blue for 2 seconds
- * el.highlight("0000ff", { attr: 'color', duration: 2000 });
- *
- * // common config options shown with default values
- * el.highlight("ffff9c", {
- * // can be any valid CSS property (attribute) that supports a color value
- * attr: "backgroundColor",
- * endColor: (current color) or "ffffff",
- * easing: 'easeIn',
- * duration: 1000
- * });
- *
- * @param {String} color (optional) The highlight color. Should be a 6 char hex color
- * without the leading # (defaults to yellow: 'ffff9c')
- * @param {Object} options (optional) Object literal with any of the {@link Ext.fx.Anim}
- * config options
- * @return {Ext.dom.Element} The Element
- */
- highlight: function(color, options) {
- var me = this,
- dom = me.dom,
- from = {},
- animFly = new Ext.dom.Fly(),
- restore, to, attr, lns, event, fn;
- options = options || {};
- lns = options.listeners || {};
- attr = options.attr || 'backgroundColor';
- from[attr] = color || 'ffff9c';
- if (!options.to) {
- to = {};
- to[attr] = options.endColor || me.getColor(attr, 'ffffff', '');
- } else {
- to = options.to;
- }
- // Don't apply directly on lns, since we reference it in our own callbacks below
- options.listeners = Ext.apply(Ext.apply({}, lns), {
- beforeanimate: function() {
- // Reattach to the DOM in case the caller animated a Fly
- // in which case the dom reference will have changed by now.
- animFly.attach(dom);
- restore = dom.style[attr];
- animFly.clearOpacity();
- animFly.show();
- event = lns.beforeanimate;
- if (event) {
- fn = event.fn || event;
- return fn.apply(event.scope || lns.scope || WIN, arguments);
- }
- },
- afteranimate: function() {
- if (dom) {
- dom.style[attr] = restore;
- }
- event = lns.afteranimate;
- if (event) {
- fn = event.fn || event;
- fn.apply(event.scope || lns.scope || WIN, arguments);
- }
- }
- });
- me.animate(Ext.apply({}, options, {
- duration: 1000,
- easing: 'ease-in',
- from: from,
- to: to
- }));
- return me;
- },
- /**
- * Initializes a {@link Ext.dd.DD} drag drop object for this element.
- * @param {String} group The group the DD object is member of
- * @param {Object} config The DD config object
- * @param {Object} overrides An object containing methods to override/implement
- * on the DD object
- * @return {Ext.dd.DD} The DD object
- */
- initDD: function(group, config, overrides) {
- var dd = new Ext.dd.DD(Ext.id(this.dom), group, config);
- return Ext.apply(dd, overrides);
- },
- /**
- * Initializes a {@link Ext.dd.DDProxy} object for this element.
- * @param {String} group The group the DDProxy object is member of
- * @param {Object} config The DDProxy config object
- * @param {Object} overrides An object containing methods to override/implement
- * on the DDProxy object
- * @return {Ext.dd.DDProxy} The DDProxy object
- */
- initDDProxy: function(group, config, overrides) {
- var dd = new Ext.dd.DDProxy(Ext.id(this.dom), group, config);
- return Ext.apply(dd, overrides);
- },
- /**
- * Initializes a {@link Ext.dd.DDTarget} object for this element.
- * @param {String} group The group the DDTarget object is member of
- * @param {Object} config The DDTarget config object
- * @param {Object} overrides An object containing methods to override/implement
- * on the DDTarget object
- * @return {Ext.dd.DDTarget} The DDTarget object
- */
- initDDTarget: function(group, config, overrides) {
- var dd = new Ext.dd.DDTarget(Ext.id(this.dom), group, config);
- return Ext.apply(dd, overrides);
- },
- /**
- * Returns true if this element is masked. Also re-centers any displayed message
- * within the mask.
- *
- * @param {Boolean} [deep] Go up the DOM hierarchy to determine if any parent
- * element is masked.
- *
- * @return {Boolean}
- */
- isMasked: function(deep) {
- var me = this,
- data = me.getData(),
- maskEl = data.maskEl,
- maskMsg = data.maskMsg,
- hasMask = false,
- parent;
- if (maskEl && maskEl.isVisible()) {
- if (maskMsg) {
- maskMsg.center(me);
- }
- hasMask = true;
- } else if (deep) {
- parent = me.findParentNode();
- if (parent) {
- return Ext.fly(parent).isMasked(deep);
- }
- }
- return hasMask;
- },
- /**
- * Direct access to the Ext.ElementLoader {@link Ext.ElementLoader#method-load} method.
- * The method takes the same object parameter as {@link Ext.ElementLoader#method-load}
- * @param {Object} options a options object for Ext.ElementLoader
- * {@link Ext.ElementLoader#method-load}
- * @return {Ext.dom.Element} this
- */
- load: function(options) {
- this.getLoader().load(options);
- return this;
- },
- /**
- * Puts a mask over this element to disable user interaction.
- * This method can only be applied to elements which accept child nodes. Use
- * {@link #unmask} to remove the mask.
- *
- * @param {String} [msg] A message to display in the mask
- * @param {String} [msgCls] A css class to apply to the msg element
- * @param {Number} elHeight (private) Passed by AbstractComponent.mask to avoid the need
- * to interrogate the DOM to get the height
- * @return {Ext.dom.Element} The mask element
- */
- mask: function(msg, msgCls, elHeight) {
- var me = this,
- dom = me.dom,
- data = me.getData(),
- maskEl = data.maskEl,
- maskMsg;
- if (!(bodyRe.test(dom.tagName) && me.getStyle('position') === 'static')) {
- me.addCls(XMASKEDRELATIVE);
- }
- // We always needs to recreate the mask since the DOM element may have been re-created
- if (maskEl) {
- maskEl.destroy();
- }
- maskEl = Ext.DomHelper.append(dom, {
- role: 'presentation',
- cls: Ext.baseCSSPrefix + "mask " + Ext.baseCSSPrefix + "border-box",
- children: {
- role: 'presentation',
- cls: msgCls ? EXTELMASKMSG + " " + msgCls : EXTELMASKMSG,
- cn: {
- tag: 'div',
- role: 'presentation',
- cls: Ext.baseCSSPrefix + 'mask-msg-inner',
- cn: {
- tag: 'div',
- role: 'presentation',
- cls: Ext.baseCSSPrefix + 'mask-msg-text',
- html: msg || ''
- }
- }
- }
- }, true);
- maskMsg = Ext.fly(maskEl.dom.firstChild);
- data.maskEl = maskEl;
- me.addCls(XMASKED);
- maskEl.setDisplayed(true);
- if (typeof msg === 'string') {
- maskMsg.setDisplayed(true);
- maskMsg.center(me);
- } else {
- maskMsg.setDisplayed(false);
- }
- if (dom === DOC.body) {
- maskEl.addCls(Ext.baseCSSPrefix + 'mask-fixed');
- }
- // When masking the body, don't touch its tabbable state
- me.saveTabbableState({
- skipSelf: dom === DOC.body
- });
- // ie will not expand full height automatically
- if (Ext.isIE9m && dom !== DOC.body && me.isStyle('height', 'auto')) {
- maskEl.setSize(undefined, elHeight || me.getHeight());
- }
- return maskEl;
- },
- /**
- * Fades the element out while slowly expanding it in all directions. When the effect
- * is completed, the element will be hidden (visibility = 'hidden') but block elements
- * will still take up space in the document. Usage:
- *
- * // default
- * el.puff();
- *
- * // common config options shown with default values
- * el.puff({
- * easing: 'easeOut',
- * duration: 500,
- * useDisplay: false
- * });
- *
- * @param {Object} obj (optional) Object literal with any of the {@link Ext.fx.Anim}
- * config options
- * @return {Ext.dom.Element} The Element
- */
- puff: function(obj) {
- var me = this,
- dom = me.dom,
- animFly = new Ext.dom.Fly(),
- beforeAnim,
- box = me.getBox(),
- originalStyles;
- originalStyles = me.getStyle([
- 'width',
- 'height',
- 'left',
- 'right',
- 'top',
- 'bottom',
- 'position',
- 'z-index',
- 'font-size',
- 'opacity'
- ], true);
- obj = Ext.applyIf(obj || {}, {
- easing: 'ease-out',
- duration: 500,
- useDisplay: false
- });
- beforeAnim = function() {
- // Reattach to the DOM in case the caller animated a Fly
- // in which case the dom reference will have changed by now.
- animFly.attach(dom);
- animFly.clearOpacity();
- animFly.show();
- this.to = {
- width: box.width * 2,
- height: box.height * 2,
- x: box.x - (box.width / 2),
- y: box.y - (box.height / 2),
- opacity: 0,
- fontSize: '200%'
- };
- this.on('afteranimate', function() {
- // Reattach to the DOM in case the caller animated a Fly
- // in which case the dom reference will have changed by now.
- animFly.attach(dom);
- if (obj.useDisplay) {
- animFly.setDisplayed(false);
- } else {
- animFly.hide();
- }
- animFly.setStyle(originalStyles);
- Ext.callback(obj.callback, obj.scope);
- });
- };
- me.animate({
- duration: obj.duration,
- easing: obj.easing,
- listeners: {
- beforeanimate: {
- fn: beforeAnim
- }
- }
- });
- return me;
- },
- // private
- // used to ensure the mouseup event is captured if it occurs outside of the
- // window in IE9m. The only reason this method exists, (vs just calling
- // el.dom.setCapture() directly) is so that we can override it to emptyFn
- // during testing because setCapture() can wreak havoc on emulated mouse events
- // http://msdn.microsoft.com/en-us/library/windows/desktop/ms646262(v=vs.85).aspx
- setCapture: function() {
- var dom = this.dom;
- if (Ext.isIE9m && dom.setCapture) {
- dom.setCapture();
- }
- },
- /**
- * Set the height of this Element.
- *
- * // change the height to 200px and animate with default configuration
- * Ext.fly('elementId').setHeight(200, true);
- *
- * // change the height to 150px and animate with a custom configuration
- * Ext.fly('elId').setHeight(150, {
- * duration : 500, // animation will have a duration of .5 seconds
- * // will change the content to "finished"
- * callback: function(){ this.setHtml("finished"); }
- * });
- *
- * @param {Number/String} height The new height. This may be one of:
- *
- * - A Number specifying the new height in pixels.
- * - A String used to set the CSS height style. Animation may **not** be used.
- *
- * @param {Boolean/Object} [animate] a standard Element animation config object or `true`
- * for the default animation (`{duration: 350, easing: 'ease-in'}`)
- * @return {Ext.dom.Element} this
- */
- setHeight: function(height, animate) {
- var me = this;
- if (!animate || !me.anim) {
- me.callParent(arguments);
- } else {
- if (!Ext.isObject(animate)) {
- animate = {};
- }
- me.animate(Ext.applyIf({
- to: {
- height: height
- }
- }, animate));
- }
- return me;
- },
- /**
- * Removes "vertical" state from this element (reverses everything done
- * by {@link #setVertical}).
- * @private
- */
- setHorizontal: function() {
- var me = this,
- cls = me.verticalCls;
- delete me.vertical;
- if (cls) {
- delete me.verticalCls;
- me.removeCls(cls);
- }
- // delete the inverted methods and revert to inheriting from the prototype
- delete me.setWidth;
- delete me.setHeight;
- if (!Ext.isIE8) {
- delete me.getWidth;
- delete me.getHeight;
- }
- // revert to inheriting styleHooks from the prototype
- delete me.styleHooks;
- },
- /**
- * Updates the *text* value of this element.
- * Replaces the content of this element with a *single text node* containing
- * the passed text.
- * @param {String} text The text to display in this Element.
- */
- updateText: function(text) {
- var me = this,
- dom, textNode;
- if (dom) {
- textNode = dom.firstChild;
- if (!textNode || (textNode.nodeType !== 3 || textNode.nextSibling)) {
- textNode = DOC.createTextNode();
- me.empty();
- dom.appendChild(textNode);
- }
- if (text) {
- textNode.data = text;
- }
- }
- },
- /**
- * Updates the innerHTML of this element, optionally searching for and processing scripts.
- * @param {String} html The new HTML
- * @param {Boolean} [loadScripts] Pass `true` to look for and process scripts.
- * @param {Function} [callback] For async script loading you can be notified
- * when the update completes.
- * @param {Object} [scope=`this`] The scope (`this` reference) in which to execute
- * the callback.
- *
- * Also used as the scope for any *inline* script source if the `loadScripts` parameter
- * is `true`. Scripts with a `src` attribute cannot be executed in this scope.
- *
- * Defaults to this Element.
- * @return {Ext.dom.Element} this
- */
- setHtml: function(html, loadScripts, callback, scope) {
- var me = this,
- id, dom, interval;
- if (!me.dom) {
- return me;
- }
- html = html || '';
- dom = me.dom;
- if (loadScripts !== true) {
- // Setting innerHtml changes the DOM and replace all dom nodes
- // with the new html. For IE specifically, all dom child nodes get
- // destroyed when removed from DOM tree even if DOM is referenced
- // within some JS file. Thus, before setting innerHTML, remove the
- // children so that they are not destroyed/removed from DOM tree.
- if (Ext.isIE) {
- while (dom.firstChild) {
- dom.removeChild(dom.firstChild);
- }
- }
- dom.innerHTML = html;
- Ext.callback(callback, me);
- return me;
- }
- id = Ext.id();
- html += '<span id="' + id + '" role="presentation"></span>';
- interval = Ext.interval(function() {
- var hd, match, attrs, srcMatch, typeMatch, el, s;
- if (!(el = DOC.getElementById(id))) {
- return false;
- }
- Ext.uninterval(interval);
- Ext.removeNode(el);
- hd = Ext.getHead().dom;
- while ((match = scriptTagRe.exec(html))) {
- attrs = match[1];
- srcMatch = attrs ? attrs.match(srcRe) : false;
- if (srcMatch && srcMatch[2]) {
- s = DOC.createElement("script");
- s.src = srcMatch[2];
- typeMatch = attrs.match(typeRe);
- if (typeMatch && typeMatch[2]) {
- s.type = typeMatch[2];
- }
- hd.appendChild(s);
- } else if (match[2] && match[2].length > 0) {
- if (scope) {
- Ext.functionFactory(match[2]).call(scope);
- } else {
- Ext.globalEval(match[2]);
- }
- }
- }
- Ext.callback(callback, scope || me);
- }, 20);
- dom.innerHTML = html.replace(replaceScriptTagRe, '');
- return me;
- },
- /**
- * Set the opacity of the element
- * @param {Number} opacity The new opacity. 0 = transparent, .5 = 50% visible,
- * 1 = fully visible, etc
- * @param {Boolean/Object} [animate] a standard Element animation config object or `true`
- * for the default animation (`{duration: 350, easing: 'ease-in'}`)
- * @return {Ext.dom.Element} this
- */
- setOpacity: function(opacity, animate) {
- var me = this;
- if (!me.dom) {
- return me;
- }
- if (!animate || !me.anim) {
- me.setStyle('opacity', opacity);
- } else {
- if (typeof animate !== 'object') {
- animate = {
- duration: 350,
- easing: 'ease-in'
- };
- }
- me.animate(Ext.applyIf({
- to: {
- opacity: opacity
- }
- }, animate));
- }
- return me;
- },
- /**
- * Set positioning with an object returned by `getPositioning`.
- * @param {Object} pc
- * @return {Ext.dom.Element} this
- */
- setPositioning: function(pc) {
- return this.setStyle(pc);
- },
- /**
- * Changes this Element's state to "vertical" (rotated 90 or 270 degrees).
- * This involves inverting the getters and setters for height and width,
- * and applying hooks for rotating getters and setters for border/margin/padding.
- * (getWidth becomes getHeight and vice versa), setStyle and getStyle will
- * also return the inverse when height or width are being operated on.
- *
- * @param {Number} angle the angle of rotation - either 90 or 270
- * @param {String} cls an optional css class that contains the required
- * styles for switching the element to vertical orientation. Omit this if
- * the element already contains vertical styling. If cls is provided,
- * it will be removed from the element when {@link #setHorizontal} is called.
- * @private
- */
- setVertical: function(angle, cls) {
- var me = this,
- proto = Element.prototype;
- me.vertical = true;
- if (cls) {
- me.addCls(me.verticalCls = cls);
- }
- me.setWidth = proto.setHeight;
- me.setHeight = proto.setWidth;
- if (!Ext.isIE8) {
- // In browsers that use CSS3 transforms we must invert getHeight and
- // get Width. In IE8 no adjustment is needed because we use
- // a BasicImage filter to rotate the element and the element's
- // offsetWidth and offsetHeight are automatically inverted.
- me.getWidth = proto.getHeight;
- me.getHeight = proto.getWidth;
- }
- // Switch to using the appropriate vertical style hooks
- me.styleHooks = (angle === 270) ? proto.verticalStyleHooks270 : proto.verticalStyleHooks90;
- },
- /**
- * Set the size of this Element. If animation is true, both width and height will be
- * animated concurrently.
- * @param {Number/String} width The new width. This may be one of:
- *
- * - A Number specifying the new width in pixels.
- * - A String used to set the CSS width style. Animation may **not** be used.
- * - A size object in the format `{width: widthValue, height: heightValue}`.
- *
- * @param {Number/String} height The new height. This may be one of:
- *
- * - A Number specifying the new height in pixels.
- * - A String used to set the CSS height style. Animation may **not** be used.
- *
- * @param {Boolean/Object} [animate] a standard Element animation config object or `true`
- * for the default animation (`{duration: 350, easing: 'ease-in'}`)
- *
- * @return {Ext.dom.Element} this
- */
- setSize: function(width, height, animate) {
- var me = this;
- if (Ext.isObject(width)) {
- // in case of object from getSize()
- animate = height;
- height = width.height;
- width = width.width;
- }
- if (!animate || !me.anim) {
- me.dom.style.width = Element.addUnits(width);
- me.dom.style.height = Element.addUnits(height);
- if (me.shadow || me.shim) {
- me.syncUnderlays();
- }
- } else {
- if (animate === true) {
- animate = {};
- }
- me.animate(Ext.applyIf({
- to: {
- width: width,
- height: height
- }
- }, animate));
- }
- return me;
- },
- /**
- * Sets the visibility of the element (see details). If the visibilityMode is set
- * to Element.DISPLAY, it will use the display property to hide the element,
- * otherwise it uses visibility. The default is to hide and show using the
- * visibility property.
- *
- * @param {Boolean} visible Whether the element is visible
- * @param {Boolean/Object} [animate] True for the default animation,
- * or a standard Element animation config object.
- *
- * @return {Ext.dom.Element} this
- */
- setVisible: function(visible, animate) {
- var me = this,
- dom = me.dom,
- animFly,
- visMode = getVisMode(me);
- // hideMode string override
- if (typeof animate === 'string') {
- switch (animate) {
- case DISPLAY:
- visMode = Element.DISPLAY;
- break;
- case VISIBILITY:
- visMode = Element.VISIBILITY;
- break;
- case OFFSETS:
- visMode = Element.OFFSETS;
- break;
- case CLIP:
- visMode = Element.CLIP;
- break;
- }
- me.setVisibilityMode(visMode);
- animate = false;
- }
- if (!animate || !me.anim) {
- if (visMode === Element.DISPLAY) {
- return me.setDisplayed(visible);
- } else if (visMode === Element.OFFSETS) {
- me[visible ? 'removeCls' : 'addCls'](OFFSETCLASS);
- } else if (visMode === Element.CLIP) {
- me[visible ? 'removeCls' : 'addCls'](CLIPCLASS);
- } else if (visMode === Element.VISIBILITY) {
- me.fixDisplay();
- // Show by clearing visibility style.
- // Explicitly setting to "visible" overrides parent visibility setting
- dom.style.visibility = visible ? '' : HIDDEN;
- }
- } else {
- // closure for composites
- if (visible) {
- me.setOpacity(0.01);
- me.setVisible(true);
- }
- if (!Ext.isObject(animate)) {
- animate = {
- duration: 350,
- easing: 'ease-in'
- };
- }
- animFly = new Ext.dom.Fly();
- me.animate(Ext.applyIf({
- callback: function() {
- if (!visible) {
- // Grab the dom again, since the reference may have changed
- // if we use fly
- animFly.attach(dom).setVisible(false).setOpacity(1);
- }
- },
- to: {
- opacity: (visible) ? 1 : 0
- }
- }, animate));
- }
- me.getData()[ISVISIBLE] = visible;
- if (me.shadow || me.shim) {
- me.setUnderlaysVisible(visible);
- }
- return me;
- },
- /**
- * Set the width of this Element.
- *
- * // change the width to 200px and animate with default configuration
- * Ext.fly('elementId').setWidth(200, true);
- *
- * // change the width to 150px and animate with a custom configuration
- * Ext.fly('elId').setWidth(150, {
- * duration : 500, // animation will have a duration of .5 seconds
- * // will change the content to "finished"
- * callback: function(){ this.setHtml("finished"); }
- * });
- *
- * @param {Number/String} width The new width. This may be one of:
- *
- * - A Number specifying the new width in pixels.
- * - A String used to set the CSS width style. Animation may **not** be used.
- *
- * @param {Boolean/Object} [animate] a standard Element animation config object or `true`
- * for the default animation (`{duration: 350, easing: 'ease-in'}`)
- * @return {Ext.dom.Element} this
- */
- setWidth: function(width, animate) {
- var me = this;
- if (!animate || !me.anim) {
- me.callParent(arguments);
- } else {
- if (!Ext.isObject(animate)) {
- animate = {};
- }
- me.animate(Ext.applyIf({
- to: {
- width: width
- }
- }, animate));
- }
- return me;
- },
- setX: function(x, animate) {
- return this.setXY([
- x,
- this.getY()
- ], animate);
- },
- setXY: function(xy, animate) {
- var me = this;
- if (!animate || !me.anim) {
- me.callParent([
- xy
- ]);
- } else {
- if (!Ext.isObject(animate)) {
- animate = {};
- }
- me.animate(Ext.applyIf({
- to: {
- x: xy[0],
- y: xy[1]
- }
- }, animate));
- }
- return this;
- },
- setY: function(y, animate) {
- return this.setXY([
- this.getX(),
- y
- ], animate);
- },
- /**
- * Show this element - Uses display mode to determine whether to use "display",
- * "visibility", "offsets", or "clip". See {@link #setVisible}.
- *
- * @param {Boolean/Object} [animate] true for the default animation or a standard
- * Element animation config object.
- *
- * @return {Ext.dom.Element} this
- */
- show: function(animate) {
- // hideMode override
- if (typeof animate === 'string') {
- this.setVisible(true, animate);
- return this;
- }
- this.setVisible(true, this.anim(animate));
- return this;
- },
- /**
- * Slides the element into view. An anchor point can be optionally passed to set the point
- * of origin for the slide effect. This function automatically handles wrapping the element
- * with a fixed-size container if needed. See the {@link Ext.fx.Anim} class overview
- * for valid anchor point options. Usage:
- *
- * // default: slide the element in from the top
- * el.slideIn();
- *
- * // custom: slide the element in from the right with a 2-second duration
- * el.slideIn('r', { duration: 2000 });
- *
- * // common config options shown with default values
- * el.slideIn('t', {
- * easing: 'easeOut',
- * duration: 500
- * });
- *
- * @param {String} [anchor] One of the valid {@link Ext.fx.Anim} anchor positions
- * (defaults to top: 't')
- * @param {Object} [options] Object literal with any of the {@link Ext.fx.Anim}
- * config options
- * @param {Boolean} options.preserveScroll Set to true if preservation of any descendant
- * elements' `scrollTop` values is required. By default the DOM wrapping operation
- * performed by `slideIn` and `slideOut` causes the browser to lose all scroll positions.
- * @param {Boolean} slideOut
- * @return {Ext.dom.Element} The Element
- */
- slideIn: function(anchor, options, slideOut) {
- var me = this,
- dom = me.dom,
- elStyle = dom.style,
- animFly = new Ext.dom.Fly(),
- beforeAnim, wrapAnim, restoreScroll, wrapDomParentNode;
- anchor = anchor || "t";
- options = options || {};
- beforeAnim = function() {
- var animScope = this,
- listeners = options.listeners,
- box, originalStyles, anim, wrap;
- // Reattach to the DOM in case the caller animated a Fly
- // in which case the dom reference will have changed by now.
- animFly.attach(dom);
- if (!slideOut) {
- animFly.fixDisplay();
- }
- box = animFly.getBox();
- if ((anchor === 't' || anchor === 'b') && box.height === 0) {
- box.height = dom.scrollHeight;
- } else if ((anchor === 'l' || anchor === 'r') && box.width === 0) {
- box.width = dom.scrollWidth;
- }
- originalStyles = animFly.getStyle([
- 'width',
- 'height',
- 'left',
- 'right',
- 'top',
- 'bottom',
- 'position',
- 'z-index'
- ], true);
- animFly.setSize(box.width, box.height);
- // Cache all descendants' scrollTop & scrollLeft values
- // if configured to preserve scroll.
- if (options.preserveScroll) {
- restoreScroll = animFly.cacheScrollValues();
- }
- wrap = animFly.wrap({
- role: 'presentation',
- id: Ext.id() + '-anim-wrap-for-' + dom.id,
- style: {
- visibility: slideOut ? 'visible' : 'hidden'
- }
- });
- wrapDomParentNode = wrap.dom.parentNode;
- wrap.setPositioning(animFly.getPositioning());
- if (wrap.isStyle('position', 'static')) {
- wrap.position('relative');
- }
- animFly.clearPositioning('auto');
- wrap.clip();
- // The wrap will have reset all descendant scrollTops.
- // Restore them if we cached them.
- if (restoreScroll) {
- restoreScroll();
- }
- // This element is temporarily positioned absolute within its wrapper.
- // Restore to its default, CSS-inherited visibility setting.
- // We cannot explicitly poke visibility:visible into its style
- // because that overrides the visibility of the wrap.
- animFly.setStyle({
- visibility: '',
- position: 'absolute'
- });
- if (slideOut) {
- wrap.setSize(box.width, box.height);
- }
- switch (anchor) {
- case 't':
- anim = {
- from: {
- width: box.width + 'px',
- height: '0px'
- },
- to: {
- width: box.width + 'px',
- height: box.height + 'px'
- }
- };
- elStyle.bottom = '0px';
- break;
- case 'l':
- anim = {
- from: {
- width: '0px',
- height: box.height + 'px'
- },
- to: {
- width: box.width + 'px',
- height: box.height + 'px'
- }
- };
- me.anchorAnimX(anchor);
- break;
- case 'r':
- anim = {
- from: {
- x: box.x + box.width,
- width: '0px',
- height: box.height + 'px'
- },
- to: {
- x: box.x,
- width: box.width + 'px',
- height: box.height + 'px'
- }
- };
- me.anchorAnimX(anchor);
- break;
- case 'b':
- anim = {
- from: {
- y: box.y + box.height,
- width: box.width + 'px',
- height: '0px'
- },
- to: {
- y: box.y,
- width: box.width + 'px',
- height: box.height + 'px'
- }
- };
- break;
- case 'tl':
- anim = {
- from: {
- x: box.x,
- y: box.y,
- width: '0px',
- height: '0px'
- },
- to: {
- width: box.width + 'px',
- height: box.height + 'px'
- }
- };
- elStyle.bottom = '0px';
- me.anchorAnimX('l');
- break;
- case 'bl':
- anim = {
- from: {
- y: box.y + box.height,
- width: '0px',
- height: '0px'
- },
- to: {
- y: box.y,
- width: box.width + 'px',
- height: box.height + 'px'
- }
- };
- me.anchorAnimX('l');
- break;
- case 'br':
- anim = {
- from: {
- x: box.x + box.width,
- y: box.y + box.height,
- width: '0px',
- height: '0px'
- },
- to: {
- x: box.x,
- y: box.y,
- width: box.width + 'px',
- height: box.height + 'px'
- }
- };
- me.anchorAnimX('r');
- break;
- case 'tr':
- anim = {
- from: {
- x: box.x + box.width,
- width: '0px',
- height: '0px'
- },
- to: {
- x: box.x,
- width: box.width + 'px',
- height: box.height + 'px'
- }
- };
- elStyle.bottom = '0px';
- me.anchorAnimX('r');
- break;
- }
- wrap.show();
- wrapAnim = Ext.apply({}, options);
- delete wrapAnim.listeners;
- wrapAnim = new Ext.fx.Anim(Ext.applyIf(wrapAnim, {
- target: wrap,
- duration: 500,
- easing: 'ease-out',
- from: slideOut ? anim.to : anim.from,
- to: slideOut ? anim.from : anim.to
- }));
- // In the absence of a callback, this listener MUST be added first
- wrapAnim.on('afteranimate', function() {
- // Reattach to the DOM in case the caller animated a Fly
- // in which case the dom reference will have changed by now.
- animFly.attach(dom);
- animFly.setStyle(originalStyles);
- if (slideOut) {
- if (options.useDisplay) {
- animFly.setDisplayed(false);
- } else {
- animFly.hide();
- }
- }
- if (wrap.dom) {
- if (wrap.dom.parentNode) {
- wrap.dom.parentNode.insertBefore(dom, wrap.dom);
- } else {
- wrapDomParentNode.appendChild(dom);
- }
- wrap.destroy();
- }
- // The unwrap will have reset all descendant scrollTops.
- // Restore them if we cached them.
- if (restoreScroll) {
- restoreScroll();
- }
- // kill the no-op element animation created below
- animScope.end();
- });
- // Add configured listeners after
- if (listeners) {
- wrapAnim.on(listeners);
- }
- };
- me.animate({
- // See "A Note About Wrapped Animations" at the top of this class:
- duration: options.duration ? Math.max(options.duration, 500) * 2 : 1000,
- listeners: {
- beforeanimate: beforeAnim
- }
- });
- // kick off the wrap animation
- return me;
- },
- /**
- * Slides the element out of view. An anchor point can be optionally passed to set the end
- * point for the slide effect. When the effect is completed, the element will be hidden
- * (visibility = 'hidden') but block elements will still take up space in the document.
- * The element must be removed from the DOM using the 'remove' config option if
- * desired. This function automatically handles wrapping the element with a fixed-size
- * container if needed. See the {@link Ext.fx.Anim} class overview for valid anchor point
- * options. Usage:
- *
- * // default: slide the element out to the top
- * el.slideOut();
- *
- * // custom: slide the element out to the right with a 2-second duration
- * el.slideOut('r', { duration: 2000 });
- *
- * // common config options shown with default values
- * el.slideOut('t', {
- * easing: 'easeOut',
- * duration: 500,
- * remove: false,
- * useDisplay: false
- * });
- *
- * @param {String} anchor (optional) One of the valid {@link Ext.fx.Anim} anchor positions
- * (defaults to top: 't')
- * @param {Object} options (optional) Object literal with any of the {@link Ext.fx.Anim}
- * config options
- * @return {Ext.dom.Element} The Element
- */
- slideOut: function(anchor, options) {
- return this.slideIn(anchor, options, true);
- },
- /**
- * Blinks the element as if it was clicked and then collapses on its center (similar to
- * switching off a television). When the effect is completed, the element will be hidden
- * (visibility = 'hidden') but block elements will still take up space in the document.
- * The element must be removed from the DOM using the 'remove' config option if desired.
- * Usage:
- *
- * // default
- * el.switchOff();
- *
- * // all config options shown with default values
- * el.switchOff({
- * easing: 'easeIn',
- * duration: .3,
- * remove: false,
- * useDisplay: false
- * });
- *
- * @param {Object} options (optional) Object literal with any of the {@link Ext.fx.Anim}
- * config options
- * @return {Ext.dom.Element} The Element
- */
- switchOff: function(options) {
- var me = this,
- dom = me.dom,
- animFly = new Ext.dom.Fly(),
- beforeAnim;
- options = Ext.applyIf(options || {}, {
- easing: 'ease-in',
- duration: 500,
- remove: false,
- useDisplay: false
- });
- beforeAnim = function() {
- // Reattach to the DOM in case the caller animated a Fly
- // in which case the dom reference will have changed by now.
- animFly.attach(dom);
- // eslint-disable-next-line vars-on-top
- var animScope = this,
- size = animFly.getSize(),
- xy = animFly.getXY(),
- keyframe, position;
- animFly.clearOpacity();
- animFly.clip();
- position = animFly.getPositioning();
- keyframe = new Ext.fx.Animator({
- target: dom,
- duration: options.duration,
- easing: options.easing,
- keyframes: {
- 33: {
- opacity: 0.3
- },
- 66: {
- height: 1,
- y: xy[1] + size.height / 2
- },
- 100: {
- width: 1,
- x: xy[0] + size.width / 2
- }
- }
- });
- keyframe.on('afteranimate', function() {
- // Reattach to the DOM in case the caller animated a Fly
- // in which case the dom reference will have changed by now.
- animFly.attach(dom);
- if (options.useDisplay) {
- animFly.setDisplayed(false);
- } else {
- animFly.hide();
- }
- animFly.clearOpacity();
- animFly.setPositioning(position);
- animFly.setSize(size);
- // kill the no-op element animation created below
- animScope.end();
- });
- };
- me.animate({
- // See "A Note About Wrapped Animations" at the top of this class:
- duration: (Math.max(options.duration, 500) * 2),
- listeners: {
- beforeanimate: {
- fn: beforeAnim
- }
- },
- callback: options.callback,
- scope: options.scope
- });
- return me;
- },
- /**
- * @private
- * Currently used for updating grid cells without modifying DOM structure
- *
- * Synchronizes content of this Element with the content of the passed element.
- *
- * Style and CSS class are copied from source into this Element, and contents are synced
- * recursively. If a child node is a text node, the textual data is copied.
- */
- syncContent: function(source) {
- source = Ext.getDom(source);
- // eslint-disable-next-line vars-on-top
- var sourceNodes = source.childNodes,
- sourceLen = sourceNodes.length,
- dest = this.dom,
- destNodes = dest.childNodes,
- destLen = destNodes.length,
- i, destNode, sourceNode, sourceStyle, nodeType, newAttrs, attLen, attName, value,
- elData = dest._extData;
- if (!syncContentFly) {
- syncContentFly = new Ext.dom.Fly();
- }
- // Update any attributes who's values have changed..
- newAttrs = source.attributes;
- attLen = newAttrs.length;
- for (i = 0; i < attLen; i++) {
- attName = newAttrs[i].name;
- value = newAttrs[i].value;
- if (attName !== 'id' && dest.getAttribute(attName) !== value) {
- dest.setAttribute(attName, newAttrs[i].value);
- }
- }
- // The element's data is no longer synchronized. We just overwrite it in the DOM
- if (elData) {
- elData.isSynchronized = false;
- }
- // If the number of child nodes does not match, fall back to replacing innerHTML
- if (sourceLen !== destLen) {
- dest.innerHTML = source.innerHTML;
- return;
- }
- // Loop through source nodes.
- // If there are fewer, we must remove excess
- for (i = 0; i < sourceLen; i++) {
- sourceNode = sourceNodes[i];
- destNode = destNodes[i];
- nodeType = sourceNode.nodeType;
- sourceStyle = sourceNode.style;
- // If node structure is out of sync, just drop innerHTML in and return
- if (nodeType !== destNode.nodeType || (nodeType === 1 && sourceNode.tagName !== destNode.tagName)) {
- dest.innerHTML = source.innerHTML;
- return;
- }
- // Update non-Element node (text, comment)
- if (!sourceStyle) {
- destNode.data = sourceNode.data;
- } else // Sync element content
- {
- if (sourceNode.id && destNode.id !== sourceNode.id) {
- destNode.id = sourceNode.id;
- }
- destNode.style.cssText = sourceStyle.cssText;
- destNode.className = sourceNode.className;
- syncContentFly.attach(destNode).syncContent(sourceNode);
- }
- }
- },
- /**
- * Toggles the element's visibility, depending on visibility mode.
- * @param {Boolean/Object} [animate] True for the default animation, or a standard Element
- * animation config object
- * @return {Ext.dom.Element} this
- */
- toggle: function(animate) {
- var me = this;
- me.setVisible(!me.isVisible(), me.anim(animate));
- return me;
- },
- /**
- * Hides a previously applied mask.
- */
- unmask: function() {
- var me = this,
- data = me.getData(),
- maskEl = data.maskEl,
- style;
- if (maskEl) {
- style = maskEl.dom.style;
- // Remove resource-intensive CSS expressions as soon as they are not required.
- if (style.clearExpression) {
- style.clearExpression('width');
- style.clearExpression('height');
- }
- if (maskEl) {
- maskEl.destroy();
- delete data.maskEl;
- }
- me.removeCls([
- XMASKED,
- XMASKEDRELATIVE
- ]);
- }
- me.restoreTabbableState(me.dom === DOC.body);
- },
- /**
- * Return clipping (overflow) to original clipping before {@link #clip} was called
- * @return {Ext.dom.Element} this
- */
- unclip: function() {
- var me = this,
- data = me.getData(),
- clip;
- if (data[ISCLIPPED]) {
- data[ISCLIPPED] = false;
- clip = data[ORIGINALCLIP];
- if (clip.o) {
- me.setStyle(OVERFLOW, clip.o);
- }
- if (clip.x) {
- me.setStyle(OVERFLOWX, clip.x);
- }
- if (clip.y) {
- me.setStyle(OVERFLOWY, clip.y);
- }
- }
- return me;
- },
- translate: function(x, y, z) {
- if (Ext.supports.CssTransforms && !Ext.isIE9m) {
- this.callParent(arguments);
- } else {
- if (x != null) {
- this.dom.style.left = x + 'px';
- }
- if (y != null) {
- this.dom.style.top = y + 'px';
- }
- }
- },
- deprecated: {
- '4.0': {
- methods: {
- /**
- * @method pause
- * Creates a pause before any subsequent queued effects begin. If there are
- * no effects queued after the pause it will have no effect. Usage:
- *
- * el.pause(1);
- *
- * @deprecated 4.0 Use the `delay` config to {@link #animate} instead.
- * @param {Number} ms The length of time to pause (in milliseconds)
- * @return {Ext.dom.Element} The Element
- */
- pause: function(ms) {
- var me = this;
- Ext.fx.Manager.setFxDefaults(me.id, {
- delay: ms
- });
- return me;
- },
- /**
- * @method scale
- * Animates the transition of an element's dimensions from a starting
- * height/width to an ending height/width. This method is a convenience
- * implementation of {@link #shift}. Usage:
- *
- * // change height and width to 100x100 pixels
- * el.scale(100, 100);
- *
- * // common config options shown with default values.
- * // The height and width will default to the element's existing values
- * // if passed as null.
- * el.scale(
- * [element's width],
- * [element's height], {
- * easing: 'easeOut',
- * duration: 350
- * }
- * );
- *
- * @deprecated 4.0 Just use {@link #animate} instead.
- * @param {Number} width The new width (pass undefined to keep the original
- * width)
- * @param {Number} height The new height (pass undefined to keep the original
- * height)
- * @param {Object} options (optional) Object literal with any of the
- * {@link Ext.fx.Anim} config options
- * @return {Ext.dom.Element} The Element
- */
- scale: function(width, height, options) {
- this.animate(Ext.apply({}, options, {
- width: width,
- height: height
- }));
- return this;
- },
- /**
- * @method shift
- * Animates the transition of any combination of an element's dimensions,
- * xy position and/or opacity. Any of these properties not specified in the
- * config object will not be changed. This effect requires that at least one new
- * dimension, position or opacity setting must be passed in on the config object
- * in order for the function to have any effect. Usage:
- *
- * // slide the element horizontally to x position 200
- * // while changing the height and opacity
- * el.shift({ x: 200, height: 50, opacity: .8 });
- *
- * // common config options shown with default values.
- * el.shift({
- * width: [element's width],
- * height: [element's height],
- * x: [element's x position],
- * y: [element's y position],
- * opacity: [element's opacity],
- * easing: 'easeOut',
- * duration: 350
- * });
- *
- * @deprecated 4.0 Just use {@link #animate} instead.
- * @param {Object} options Object literal with any of the {@link Ext.fx.Anim}
- * config options
- * @return {Ext.dom.Element} The Element
- */
- shift: function(options) {
- this.animate(options);
- return this;
- }
- }
- },
- '4.2': {
- methods: {
- /**
- * @method moveTo
- * Sets the position of the element in page coordinates.
- * @param {Number} x X value for new position (coordinates are page-based)
- * @param {Number} y Y value for new position (coordinates are page-based)
- * @param {Boolean/Object} [animate] True for the default animation,
- * or a standard Element animation config object
- * @return {Ext.dom.Element} this
- * @deprecated 4.2.0 Use {@link Ext.dom.Element#setXY} instead.
- */
- moveTo: function(x, y, animate) {
- return this.setXY([
- x,
- y
- ], animate);
- },
- /**
- * @method setBounds
- * Sets the element's position and size in one shot. If animation is true then
- * width, height, x and y will be animated concurrently.
- *
- * @param {Number} x X value for new position (coordinates are page-based)
- * @param {Number} y Y value for new position (coordinates are page-based)
- * @param {Number/String} width The new width. This may be one of:
- *
- * - A Number specifying the new width in pixels
- * - A String used to set the CSS width style. Animation may **not** be used.
- *
- * @param {Number/String} height The new height. This may be one of:
- *
- * - A Number specifying the new height in pixels
- * - A String used to set the CSS height style. Animation may **not** be used.
- *
- * @param {Boolean/Object} [animate] true for the default animation or
- * a standard Element animation config object
- *
- * @return {Ext.dom.Element} this
- * @deprecated 4.2.0 Use {@link Ext.util.Positionable#setBox} instead.
- */
- setBounds: function(x, y, width, height, animate) {
- return this.setBox({
- x: x,
- y: y,
- width: width,
- height: height
- }, animate);
- },
- /**
- * @method setLeftTop
- * Sets the element's left and top positions directly using CSS style
- * @param {Number/String} left Number of pixels or CSS string value to
- * set as the left CSS property value
- * @param {Number/String} top Number of pixels or CSS string value to
- * set as the top CSS property value
- * @return {Ext.dom.Element} this
- * @deprecated 4.2.0 Use {@link Ext.dom.Element#setLocalXY} instead
- */
- setLeftTop: function(left, top) {
- var me = this,
- style = me.dom.style;
- style.left = Element.addUnits(left);
- style.top = Element.addUnits(top);
- if (me.shadow || me.shim) {
- me.syncUnderlays();
- }
- return me;
- },
- /**
- * @method setLocation
- * Sets the position of the element in page coordinates.
- * @param {Number} x X value for new position
- * @param {Number} y Y value for new position
- * @param {Boolean/Object} [animate] True for the default animation,
- * or a standard Element animation config object
- * @return {Ext.dom.Element} this
- * @deprecated 4.2.0 Use {@link Ext.dom.Element#setXY} instead.
- */
- setLocation: function(x, y, animate) {
- return this.setXY([
- x,
- y
- ], animate);
- }
- }
- },
- '5.0': {
- methods: {
- /**
- * @method getAttributeNS
- * Returns the value of a namespaced attribute from the element's underlying
- * DOM node.
- * @param {String} namespace The namespace in which to look for the attribute
- * @param {String} name The attribute name
- * @return {String} The attribute value
- * @deprecated 5.0.0 Please use {@link Ext.dom.Element#getAttribute} instead.
- */
- getAttributeNS: function(namespace, name) {
- return this.getAttribute(name, namespace);
- },
- /**
- * @method getCenterXY
- * Calculates the x, y to center this element on the screen
- * @return {Number[]} The x, y values [x, y]
- * @deprecated 5.0.0 Use {@link Ext.dom.Element#getAlignToXY} instead.
- * el.getAlignToXY(document, 'c-c');
- */
- getCenterXY: function() {
- return this.getAlignToXY(DOC, 'c-c');
- },
- /**
- * @method getComputedHeight
- * Returns either the offsetHeight or the height of this element based on CSS
- * height adjusted by padding or borders when needed to simulate offsetHeight
- * when offsets aren't available. This may not work on display:none elements
- * if a height has not been set using CSS.
- * @return {Number}
- * @deprecated 5.0.0 use {@link Ext.dom.Element#getHeight} instead
- */
- getComputedHeight: function() {
- return Math.max(this.dom.offsetHeight, this.dom.clientHeight) || parseFloat(this.getStyle(HEIGHT)) || 0;
- },
- /**
- * @method getComputedWidth
- * Returns either the offsetWidth or the width of this element based on CSS
- * width adjusted by padding or borders when needed to simulate offsetWidth
- * when offsets aren't available. This may not work on display:none elements
- * if a width has not been set using CSS.
- * @return {Number}
- * @deprecated 5.0.0 use {@link Ext.dom.Element#getWidth} instead.
- */
- getComputedWidth: function() {
- return Math.max(this.dom.offsetWidth, this.dom.clientWidth) || parseFloat(this.getStyle(WIDTH)) || 0;
- },
- /**
- * @method getStyleSize
- * Returns the dimensions of the element available to lay content out in.
- *
- * getStyleSize utilizes prefers style sizing if present, otherwise it chooses
- * the larger of offsetHeight/clientHeight and offsetWidth/clientWidth.
- * To obtain the size excluding scrollbars, use getViewSize.
- *
- * Sizing of the document body is handled at the adapter level which handles
- * special cases for IE and strict modes, etc.
- *
- * @return {Object} Object describing width and height.
- * @return {Number} return.width
- * @return {Number} return.height
- * @deprecated 5.0.0 Use {@link Ext.dom.Element#getSize} instead.
- */
- getStyleSize: function() {
- var me = this,
- d = this.dom,
- isDoc = (d === DOC || d === DOC.body),
- s, w, h;
- // If the body, use static methods
- if (isDoc) {
- return {
- width: Element.getViewportWidth(),
- height: Element.getViewportHeight()
- };
- }
- s = me.getStyle([
- 'height',
- 'width'
- ], true);
- // seek inline
- // Use Styles if they are set
- if (s.width && s.width !== 'auto') {
- w = parseFloat(s.width);
- }
- // Use Styles if they are set
- if (s.height && s.height !== 'auto') {
- h = parseFloat(s.height);
- }
- // Use getWidth/getHeight if style not set.
- return {
- width: w || me.getWidth(true),
- height: h || me.getHeight(true)
- };
- },
- /**
- * @method isBorderBox
- * Returns true if this element uses the border-box-sizing model.
- * This method is deprecated as of version 5.0 because border-box sizing
- * is forced upon all elements via a style sheet rule, and the browsers
- * that do not support border-box (IE6/7 strict mode) are no longer supported.
- * @deprecated 5.0.0 This method is deprecated. Browsers that do not
- * support border-box (IE6/7 strict mode) are no longer supported.
- * @return {Boolean}
- */
- isBorderBox: function() {
- return true;
- },
- /**
- * @method isDisplayed
- * Returns true if display is not "none"
- * @return {Boolean}
- * @deprecated 5.0.0 use element.isStyle('display', 'none');
- */
- isDisplayed: function() {
- return !this.isStyle('display', 'none');
- },
- /**
- * @method focusable
- * Checks whether this element can be focused.
- * @return {Boolean} True if the element is focusable
- * @deprecated 5.0.0 use {@link #isFocusable} instead
- */
- focusable: 'isFocusable'
- }
- }
- }
- };
- })(), function() {
- var Element = Ext.dom.Element,
- proto = Element.prototype,
- useDocForId = !Ext.isIE8,
- DOC = document,
- view = DOC.defaultView,
- opacityRe = /alpha\(opacity=(.*)\)/i,
- trimRe = /^\s+|\s+$/g,
- styleHooks = proto.styleHooks,
- supports = Ext.supports,
- verticalStyleHooks90, verticalStyleHooks270, edges, k, edge, borderWidth, getBorderWidth;
- proto._init(Element);
- delete proto._init;
- Ext.plainTableCls = Ext.baseCSSPrefix + 'table-plain';
- Ext.plainListCls = Ext.baseCSSPrefix + 'list-plain';
- // ensure that any methods added by this override are also added to Ext.CompositeElementLite
- if (Ext.CompositeElementLite) {
- Ext.CompositeElementLite.importElementMethods();
- }
- if (!supports.Opacity && Ext.isIE) {
- Ext.apply(styleHooks.opacity, {
- get: function(dom) {
- var filter = dom.style.filter,
- match, opacity;
- if (filter.match) {
- match = filter.match(opacityRe);
- if (match) {
- opacity = parseFloat(match[1]);
- if (!isNaN(opacity)) {
- return opacity ? opacity / 100 : 0;
- }
- }
- }
- return 1;
- },
- set: function(dom, value) {
- var style = dom.style,
- val = style.filter.replace(opacityRe, '').replace(trimRe, '');
- style.zoom = 1;
- // ensure dom.hasLayout
- // value can be a number or '' or null... so treat falsey as no opacity
- if (typeof (value) === 'number' && value >= 0 && value < 1) {
- value *= 100;
- style.filter = val + (val.length ? ' ' : '') + 'alpha(opacity=' + value + ')';
- } else {
- style.filter = val;
- }
- }
- });
- }
- if (!supports.matchesSelector) {
- // Match basic tagName.ClassName selector syntax for is implementation
- // eslint-disable-next-line vars-on-top
- var simpleSelectorRe = /^([a-z]+|\*)?(?:\.([a-z][a-z\-_0-9]*))?$/i,
- dashRe = /-/g,
- fragment,
- classMatcher = function(tag, cls) {
- var classRe = new RegExp('(?:^|\\s+)' + cls.replace(dashRe, '\\-') + '(?:\\s+|$)');
- if (tag && tag !== '*') {
- tag = tag.toUpperCase();
- return function(el) {
- return el.tagName === tag && classRe.test(el.className);
- };
- }
- return function(el) {
- return classRe.test(el.className);
- };
- },
- tagMatcher = function(tag) {
- tag = tag.toUpperCase();
- return function(el) {
- return el.tagName === tag;
- };
- },
- cache = {};
- proto.matcherCache = cache;
- proto.is = function(selector) {
- var dom = this.dom,
- cls, match, testFn, root, isOrphan, is, tag;
- // Empty selector always matches
- if (!selector) {
- return true;
- }
- // Only Element node types can be matched.
- if (dom.nodeType !== 1) {
- return false;
- }
- // eslint-disable-next-line no-cond-assign
- if (!(testFn = Ext.isFunction(selector) ? selector : cache[selector])) {
- // eslint-disable-next-line no-cond-assign
- if (!(match = selector.match(simpleSelectorRe))) {
- // Not a simple tagName.className selector, do it the hard way
- root = dom.parentNode;
- if (!root) {
- isOrphan = true;
- root = fragment || (fragment = DOC.createDocumentFragment());
- fragment.appendChild(dom);
- }
- is = Ext.Array.indexOf(Ext.fly(root, '_is').query(selector), dom) !== -1;
- if (isOrphan) {
- fragment.removeChild(dom);
- }
- return is;
- }
- tag = match[1];
- cls = match[2];
- cache[selector] = testFn = cls ? classMatcher(tag, cls) : tagMatcher(tag);
- }
- return testFn(dom);
- };
- }
- // IE8 needs its own implementation of getStyle because it doesn't support getComputedStyle
- if (!view || !view.getComputedStyle) {
- proto.getStyle = function(property, inline) {
- var me = this,
- dom = me.dom,
- multiple = typeof property !== 'string',
- prop = property,
- props = prop,
- len = 1,
- isInline = inline,
- styleHooks = me.styleHooks,
- camel, domStyle, values, hook, out, style, i;
- if (multiple) {
- values = {};
- prop = props[0];
- i = 0;
- if (!(len = props.length)) {
- return values;
- }
- }
- if (!dom || dom.documentElement) {
- return values || '';
- }
- domStyle = dom.style;
- if (inline) {
- style = domStyle;
- } else {
- style = dom.currentStyle;
- // fallback to inline style if rendering context not available
- if (!style) {
- isInline = true;
- style = domStyle;
- }
- }
- do {
- hook = styleHooks[prop];
- if (!hook) {
- styleHooks[prop] = hook = {
- name: Element.normalize(prop)
- };
- }
- if (hook.get) {
- out = hook.get(dom, me, isInline, style);
- } else {
- camel = hook.name;
- out = style[camel];
- }
- if (!multiple) {
- return out;
- }
- values[prop] = out;
- prop = props[++i];
- } while (i < len);
- return values;
- };
- }
- // override getStyle for border-*-width
- if (Ext.isIE8) {
- getBorderWidth = function(dom, el, inline, style) {
- if (style[this.styleName] === 'none') {
- return '0px';
- }
- return style[this.name];
- };
- edges = [
- 'Top',
- 'Right',
- 'Bottom',
- 'Left'
- ];
- k = edges.length;
- while (k--) {
- edge = edges[k];
- borderWidth = 'border' + edge + 'Width';
- styleHooks['border-' + edge.toLowerCase() + '-width'] = styleHooks[borderWidth] = {
- name: borderWidth,
- styleName: 'border' + edge + 'Style',
- get: getBorderWidth
- };
- }
- // IE8 has an odd bug with handling font icons in pseudo elements;
- // it will render the icon once and not update it when something
- // like text color is changed via style addition or removal.
- // We have to force icon repaint by adding a style with forced empty
- // pseudo element content, (x-sync-repaint) and removing it back to work
- // around this issue.
- // See this: https://github.com/FortAwesome/Font-Awesome/issues/954
- // and this: https://github.com/twbs/bootstrap/issues/13863
- // eslint-disable-next-line vars-on-top
- var syncRepaintCls = Ext.baseCSSPrefix + 'sync-repaint';
- proto.syncRepaint = function() {
- this.addCls(syncRepaintCls);
- // Measuring element width will make the browser to repaint it
- this.getWidth();
- // Removing empty content makes the icon to appear again and be redrawn
- this.removeCls(syncRepaintCls);
- };
- }
- if (Ext.isIE10m) {
- Ext.override(Element, {
- focus: function(defer, dom) {
- var me = this,
- ex;
- dom = dom || me.dom;
- if (me.deferredFocusTimer) {
- Ext.undefer(me.deferredFocusTimer);
- }
- me.deferredFocusTimer = null;
- if (Number(defer)) {
- me.deferredFocusTimer = Ext.defer(me.focus, defer, me, [
- null,
- dom
- ]);
- } else {
- Ext.GlobalEvents.fireEvent('beforefocus', dom);
- // IE10m has an acute problem with focusing input elements;
- // when the element was just shown and did not have enough
- // time to initialize, focusing it might fail. The problem
- // is somewhat random in nature; most of the time focusing
- // an input element will succeed, failing only occasionally.
- // When it fails, the focus will be thrown to the document
- // body element, with subsequent focusout/focusin event pair
- // on the body, which throws off our focusenter/focusleave
- // processing.
- // Fortunately for us, when this focus failure happens, the
- // resulting focusout event will happen *synchronously*
- // unlike the normal focusing events which IE will fire
- // asynchronously. Also fortunately for us, in most cases
- // trying to focus the given element the second time
- // immediately after it failed to focus the first time
- // seems to do the trick; however when second focus attempt
- // succeeds, it will result in focusout on the body and
- // focusin on the given element, which again wreaks havoc
- // on our focusenter/focusleave handling.
- // The only workable solution we have is to pretend that
- // focus never went to the document body and ignore the
- // focusout and focusin caused by failed first focus attempt.
- // To this end, we fudge the event stream in Focus publisher
- // override.
- if (dom && (dom.tagName === 'INPUT' || dom.tagname === 'TEXTAREA')) {
- Ext.synchronouslyFocusing = document.activeElement;
- }
- // Also note that trying to focus an unfocusable element
- // might throw an exception in IE8. What a cute idea, MS. :(
- try {
- dom.focus();
- } catch (xcpt) {
- ex = xcpt;
- }
- // Ok so now we have this situation when we tried to focus
- // the first time but did not succeed. Let's try again but
- // not if there was an exception the first time - when the
- // "focus failure" happens it does so silently. :(
- if (Ext.synchronouslyFocusing && document.activeElement !== dom && !ex) {
- dom.focus();
- }
- Ext.synchronouslyFocusing = null;
- }
- return me;
- }
- });
- }
- Ext.apply(Ext, {
- /**
- * `true` to automatically uncache orphaned Ext.Elements periodically. If set to
- * `false`, the application will be required to clean up orphaned Ext.Elements and
- * it's listeners as to not cause memory leakage.
- * @member Ext
- */
- enableGarbageCollector: true,
- // In sencha v5 isBorderBox is no longer needed since all supported browsers
- // support border-box, but it is hard coded to true for backward compatibility
- isBorderBox: true,
- /**
- * @property {Boolean} useShims
- * @member Ext
- * Set to `true` to use a {@link Ext.util.Floating#shim shim} on all floating Components
- * and {@link Ext.LoadMask LoadMasks}
- */
- useShims: false,
- getElementById: function(id) {
- var el = DOC.getElementById(id),
- detachedBodyEl;
- if (!el && (detachedBodyEl = Ext.detachedBodyEl)) {
- el = detachedBodyEl.dom.querySelector(Ext.makeIdSelector(id));
- }
- return el;
- },
- /**
- * Applies event listeners to elements by selectors when the document is ready.
- * The event name is specified with an `@` suffix.
- *
- * Ext.addBehaviors({
- * // add a listener for click on all anchors in element with id foo
- * '#foo a@click': function(e, t){
- * // do something
- * },
- *
- * // add the same listener to multiple selectors (separated by comma BEFORE the @)
- * '#foo a, #bar span.some-class@mouseover': function(){
- * // do something
- * }
- * });
- *
- * @param {Object} obj The list of behaviors to apply
- * @member Ext
- */
- addBehaviors: function(obj) {
- // simple cache for applying multiple behaviors to same selector
- // does query multiple times
- var cache = {},
- parts, b, s;
- if (!Ext.isReady) {
- Ext.onInternalReady(function() {
- Ext.addBehaviors(obj);
- });
- } else {
- for (b in obj) {
- if ((parts = b.split('@'))[1]) {
- // for Object prototype breakers
- s = parts[0];
- if (!cache[s]) {
- cache[s] = Ext.fly(document).select(s, true);
- }
- cache[s].on(parts[1], obj[b]);
- }
- }
- cache = null;
- }
- }
- });
- if (Ext.isIE9m) {
- Ext.getElementById = function(id) {
- var el = DOC.getElementById(id),
- detachedBodyEl;
- if (!el && (detachedBodyEl = Ext.detachedBodyEl)) {
- el = detachedBodyEl.dom.all[id];
- }
- return el;
- };
- proto.getById = function(id, asDom) {
- var dom = this.dom,
- ret = null,
- entry, el;
- if (dom) {
- // for normal elements getElementById is the best solution, but if the el is
- // not part of the document.body, we need to use all[]
- el = (useDocForId && DOC.getElementById(id)) || dom.all[id];
- if (el) {
- if (asDom) {
- ret = el;
- } else {
- // calling Element.get here is a real hit (2x slower) because it has to
- // redetermine that we are giving it a dom el.
- entry = Ext.cache[id];
- if (entry) {
- if (entry.skipGarbageCollection || !Ext.isGarbage(entry.dom)) {
- ret = entry;
- } else {
- Ext.raise("Stale Element with id '" + el.id + "' found in Element cache. " + "Make sure to clean up Element instances using destroy()");
- entry.destroy();
- }
- }
- ret = ret || new Ext.Element(el);
- }
- }
- }
- return ret;
- };
- } else if (!DOC.querySelector) {
- Ext.getDetachedBody = Ext.getBody;
- Ext.getElementById = function(id) {
- return DOC.getElementById(id);
- };
- proto.getById = function(id, asDom) {
- var dom = DOC.getElementById(id);
- return asDom ? dom : (dom ? Ext.get(dom) : null);
- };
- }
- if (Ext.isIE && !(Ext.isIE9p && DOC.documentMode >= 9)) {
- // Essentially all web browsers (Firefox, Internet Explorer, recent versions of Opera,
- // Safari, Konqueror, and iCab, as a non-exhaustive list) return null when the specified
- // attribute does not exist on the specified element.
- // The DOM specification says that the correct return value in this case is actually
- // the empty string, and some DOM implementations implement this behavior.
- // The implementation of getAttribute in XUL (Gecko) actually follows the specification
- // and returns an empty string. Consequently, you should use hasAttribute to check
- // for an attribute's existence prior to calling getAttribute() if it is possible that
- // the requested attribute does not exist on the specified element.
- //
- // https://developer.mozilla.org/en-US/docs/DOM/element.getAttribute
- // http://www.w3.org/TR/DOM-Level-2-Core/core.html#ID-745549614
- proto.getAttribute = function(name, ns) {
- var d = this.dom,
- type;
- if (ns) {
- type = typeof d[ns + ":" + name];
- if (type !== 'undefined' && type !== 'unknown') {
- return d[ns + ":" + name] || null;
- }
- return null;
- }
- if (name === "for") {
- name = "htmlFor";
- }
- return d[name] || null;
- };
- }
- Ext.onInternalReady(function() {
- var transparentRe = /^(?:transparent|(?:rgba[(](?:\s*\d+\s*[,]){3}\s*0\s*[)]))$/i,
- origSetWidth = proto.setWidth,
- origSetHeight = proto.setHeight,
- origSetSize = proto.setSize,
- origUnselectable = proto.unselectable,
- pxRe = /^\d+(?:\.\d*)?px$/i,
- colorStyles, i, name, camel;
- if (supports.FixedTableWidthBug) {
- // EXTJSIV-12665
- // https://bugs.webkit.org/show_bug.cgi?id=130239
- // Webkit browsers fail to layout correctly when a form field's width is less
- // than the min-width of the body element. The only way to fix it seems to be
- // to toggle the display style of the field's element before and after setting
- // the width. Note: once the bug has been corrected by toggling the element's
- // display, successive calls to setWidth will work without the hack. It's only
- // when going from naturally widthed to having an explicit width that the bug
- // occurs.
- styleHooks.width = {
- name: 'width',
- set: function(dom, value, el) {
- var style = dom.style,
- needsFix = el._needsTableWidthFix,
- origDisplay = style.display;
- if (needsFix) {
- style.display = 'none';
- }
- style.width = value;
- if (needsFix) {
- // repaint
- // eslint-disable-next-line no-unused-expressions
- dom.scrollWidth;
- style.display = origDisplay;
- }
- }
- };
- proto.setWidth = function(width, animate) {
- var me = this,
- dom = me.dom,
- style = dom.style,
- needsFix = me._needsTableWidthFix,
- origDisplay = style.display;
- if (needsFix && !animate) {
- style.display = 'none';
- }
- origSetWidth.call(me, width, animate);
- if (needsFix && !animate) {
- // repaint
- // eslint-disable-next-line no-unused-expressions
- dom.scrollWidth;
- style.display = origDisplay;
- }
- return me;
- };
- proto.setSize = function(width, height, animate) {
- var me = this,
- dom = me.dom,
- style = dom.style,
- needsFix = me._needsTableWidthFix,
- origDisplay = style.display;
- if (needsFix && !animate) {
- style.display = 'none';
- }
- origSetSize.call(me, width, height, animate);
- if (needsFix && !animate) {
- // repaint
- // eslint-disable-next-line no-unused-expressions
- dom.scrollWidth;
- style.display = origDisplay;
- }
- return me;
- };
- }
- if (Ext.isIE8) {
- styleHooks.height = {
- name: 'height',
- set: function(dom, value, el) {
- var component = el.component,
- frameInfo, frameBodyStyle;
- if (component && component._syncFrameHeight && el === component.el) {
- frameBodyStyle = component.frameBody.dom.style;
- if (pxRe.test(value)) {
- frameInfo = component.getFrameInfo();
- if (frameInfo) {
- frameBodyStyle.height = (parseInt(value, 10) - frameInfo.height) + 'px';
- }
- } else if (!value || value === 'auto') {
- frameBodyStyle.height = '';
- }
- }
- dom.style.height = value;
- }
- };
- proto.setHeight = function(height, animate) {
- var component = this.component,
- frameInfo, frameBodyStyle;
- if (component && component._syncFrameHeight && this === component.el) {
- frameBodyStyle = component.frameBody.dom.style;
- if (!height || height === 'auto') {
- frameBodyStyle.height = '';
- } else {
- frameInfo = component.getFrameInfo();
- if (frameInfo) {
- frameBodyStyle.height = (height - frameInfo.height) + 'px';
- }
- }
- }
- return origSetHeight.call(this, height, animate);
- };
- proto.setSize = function(width, height, animate) {
- var component = this.component,
- frameInfo, frameBodyStyle;
- if (component && component._syncFrameHeight && this === component.el) {
- frameBodyStyle = component.frameBody.dom.style;
- if (!height || height === 'auto') {
- frameBodyStyle.height = '';
- } else {
- frameInfo = component.getFrameInfo();
- if (frameInfo) {
- frameBodyStyle.height = (height - frameInfo.height) + 'px';
- }
- }
- }
- return origSetSize.call(this, width, height, animate);
- };
- // Override for IE8 which throws an error setting innerHTML when inside
- // an event handler invoked from that element.
- proto.setText = function(text) {
- var dom = this.dom;
- // Remove all child nodes, leave only a single textNode
- if (!(dom.childNodes.length === 1 && dom.firstChild.nodeType === 3)) {
- while (dom.lastChild && dom.lastChild.nodeType !== 3) {
- dom.removeChild(dom.lastChild);
- }
- dom.appendChild(document.createTextNode());
- }
- // Set the data of the textNode
- dom.firstChild.data = text;
- };
- proto.unselectable = function() {
- origUnselectable.call(this);
- this.dom.onselectstart = function() {
- return false;
- };
- };
- }
- function fixTransparent(dom, el, inline, style) {
- var value = style[this.name] || '';
- return transparentRe.test(value) ? 'transparent' : value;
- }
- /*
- * Helper function to create the function that will restore the selection.
- */
- function makeSelectionRestoreFn(activeEl, start, end) {
- return function() {
- activeEl.selectionStart = start;
- activeEl.selectionEnd = end;
- };
- }
- /*
- * Creates a function to call to clean up problems with the work-around for the
- * WebKit RightMargin bug. The work-around is to add "display: 'inline-block'" to
- * the element before calling getComputedStyle and then to restore its original
- * display value. The problem with this is that it corrupts the selection of an
- * INPUT or TEXTAREA element (as in the "I-beam" goes away but the focus remains).
- * To cleanup after this, we need to capture the selection of any such element and
- * then restore it after we have restored the display style.
- *
- * @param {HTMLElement} target The top-most element being adjusted.
- * @private
- */
- function getRightMarginFixCleaner(target) {
- var hasInputBug = supports.DisplayChangeInputSelectionBug,
- hasTextAreaBug = supports.DisplayChangeTextAreaSelectionBug,
- activeEl, tag, start, end;
- if (hasInputBug || hasTextAreaBug) {
- activeEl = Element.getActiveElement();
- tag = activeEl && activeEl.tagName;
- if ((hasTextAreaBug && tag === 'TEXTAREA') || (hasInputBug && tag === 'INPUT' && activeEl.type === 'text')) {
- if (Ext.fly(target).isAncestor(activeEl)) {
- start = activeEl.selectionStart;
- end = activeEl.selectionEnd;
- if (Ext.isNumber(start) && Ext.isNumber(end)) {
- // to be safe...
- // We don't create the raw closure here inline because that
- // will be costly even if we don't want to return it (nested
- // function decls and exprs are often instantiated on entry
- // regardless of whether execution ever reaches them):
- return makeSelectionRestoreFn(activeEl, start, end);
- }
- }
- }
- }
- return Ext.emptyFn;
- }
- // avoid special cases, just return a nop
- function fixRightMargin(dom, el, inline, style) {
- var result = style.marginRight,
- domStyle, display;
- // Ignore cases when the margin is correctly reported as 0, the bug only shows
- // numbers larger.
- if (result !== '0px') {
- domStyle = dom.style;
- display = domStyle.display;
- domStyle.display = 'inline-block';
- // eslint-disable-next-line max-len
- result = (inline ? style : dom.ownerDocument.defaultView.getComputedStyle(dom, null)).marginRight;
- domStyle.display = display;
- }
- return result;
- }
- function fixRightMarginAndInputFocus(dom, el, inline, style) {
- var result = style.marginRight,
- domStyle, cleaner, display;
- if (result !== '0px') {
- domStyle = dom.style;
- cleaner = getRightMarginFixCleaner(dom);
- display = domStyle.display;
- domStyle.display = 'inline-block';
- // eslint-disable-next-line max-len
- result = (inline ? style : dom.ownerDocument.defaultView.getComputedStyle(dom, '')).marginRight;
- domStyle.display = display;
- cleaner();
- }
- return result;
- }
- // TODO - this was fixed in Safari 3 - verify if this is still an issue
- // Fix bug caused by this: https://bugs.webkit.org/show_bug.cgi?id=13343
- if (!supports.RightMargin) {
- styleHooks.marginRight = styleHooks['margin-right'] = {
- name: 'marginRight',
- // TODO - Touch should use conditional compilation here or ensure that the
- // underlying Ext.supports flags are set correctly...
- // eslint-disable-next-line max-len
- get: (supports.DisplayChangeInputSelectionBug || supports.DisplayChangeTextAreaSelectionBug) ? fixRightMarginAndInputFocus : fixRightMargin
- };
- }
- if (!supports.TransparentColor) {
- colorStyles = [
- 'background-color',
- 'border-color',
- 'color',
- 'outline-color'
- ];
- for (i = colorStyles.length; i--; ) {
- name = colorStyles[i];
- camel = Element.normalize(name);
- styleHooks[name] = styleHooks[camel] = {
- name: camel,
- get: fixTransparent
- };
- }
- }
- // When elements are rotated 80 or 270 degrees, their border, margin and padding hooks
- // need to be rotated as well.
- proto.verticalStyleHooks90 = verticalStyleHooks90 = Ext.Object.chain(styleHooks);
- proto.verticalStyleHooks270 = verticalStyleHooks270 = Ext.Object.chain(styleHooks);
- verticalStyleHooks90.width = styleHooks.height || {
- name: 'height'
- };
- verticalStyleHooks90.height = styleHooks.width || {
- name: 'width'
- };
- verticalStyleHooks90['margin-top'] = {
- name: 'marginLeft'
- };
- verticalStyleHooks90['margin-right'] = {
- name: 'marginTop'
- };
- verticalStyleHooks90['margin-bottom'] = {
- name: 'marginRight'
- };
- verticalStyleHooks90['margin-left'] = {
- name: 'marginBottom'
- };
- verticalStyleHooks90['padding-top'] = {
- name: 'paddingLeft'
- };
- verticalStyleHooks90['padding-right'] = {
- name: 'paddingTop'
- };
- verticalStyleHooks90['padding-bottom'] = {
- name: 'paddingRight'
- };
- verticalStyleHooks90['padding-left'] = {
- name: 'paddingBottom'
- };
- verticalStyleHooks90['border-top'] = {
- name: 'borderLeft'
- };
- verticalStyleHooks90['border-right'] = {
- name: 'borderTop'
- };
- verticalStyleHooks90['border-bottom'] = {
- name: 'borderRight'
- };
- verticalStyleHooks90['border-left'] = {
- name: 'borderBottom'
- };
- verticalStyleHooks270.width = styleHooks.height || {
- name: 'height'
- };
- verticalStyleHooks270.height = styleHooks.width || {
- name: 'width'
- };
- verticalStyleHooks270['margin-top'] = {
- name: 'marginRight'
- };
- verticalStyleHooks270['margin-right'] = {
- name: 'marginBottom'
- };
- verticalStyleHooks270['margin-bottom'] = {
- name: 'marginLeft'
- };
- verticalStyleHooks270['margin-left'] = {
- name: 'marginTop'
- };
- verticalStyleHooks270['padding-top'] = {
- name: 'paddingRight'
- };
- verticalStyleHooks270['padding-right'] = {
- name: 'paddingBottom'
- };
- verticalStyleHooks270['padding-bottom'] = {
- name: 'paddingLeft'
- };
- verticalStyleHooks270['padding-left'] = {
- name: 'paddingTop'
- };
- verticalStyleHooks270['border-top'] = {
- name: 'borderRight'
- };
- verticalStyleHooks270['border-right'] = {
- name: 'borderBottom'
- };
- verticalStyleHooks270['border-bottom'] = {
- name: 'borderLeft'
- };
- verticalStyleHooks270['border-left'] = {
- name: 'borderTop'
- };
- /**
- * @property {Boolean} scopeCss
- * @member Ext
- * Set this to true before onReady to prevent any styling from being added to
- * the body element. By default a few styles such as font-family, and color
- * are added to the body element via a "x-body" class. When this is set to
- * `true` the "x-body" class is not added to the body element, but is added
- * to the elements of root-level containers instead.
- */
- if (!Ext.scopeCss) {
- Ext.getBody().addCls(Ext.baseCSSPrefix + 'body');
- }
- }, null, {
- priority: 1500
- });
- });
- // onReady
- // @tag core
- /**
- * @class Ext.GlobalEvents
- */
- Ext.define('Ext.overrides.GlobalEvents', {
- override: 'Ext.GlobalEvents',
- /**
- * @event resumelayouts
- * Fires after global layout processing has been resumed in {@link
- * Ext.Component#resumeLayouts}.
- */
- attachListeners: function() {
- var me = this,
- docElement, bufferedFn;
- // In IE9- when using legacy onresize event via attachEvent or onresize property,
- // the event may fire for *content size changes* as well as actual document view
- // size changes. See this: https://msdn.microsoft.com/en-us/library/ms536959(v=vs.85).aspx
- // and this: http://stackoverflow.com/questions/1852751/window-resize-event-firing-in-internet-explorer
- // The amount of these events firing all at once can be entirely staggering, and they
- // often happen during layouts so we have to be über careful to execute as few JavaScript
- // statements as possible to improve overall framework performance.
- if (Ext.isIE8) {
- docElement = Ext.getDoc().dom.documentElement;
- bufferedFn = Ext.Function.createBuffered(me.fireResize, me.resizeBuffer, me);
- Ext.getWin().dom.attachEvent('onresize', function() {
- if (docElement.clientWidth !== Ext.GlobalEvents.curWidth || docElement.clientHeight !== Ext.GlobalEvents.curHeight) {
- bufferedFn();
- }
- });
- }
- me.callParent();
- },
- deprecated: {
- 5: {
- methods: {
- addListener: function(ename, fn, scope, options, order, caller, eventOptions) {
- var name, readyFn;
- // The "ready" event was removed from Ext.globalEvents in 5.0 in favor of
- // Ext.onReady(). This function adds compatibility for the ready event
- if (ename === 'ready') {
- readyFn = fn;
- } else if (typeof ename !== 'string') {
- for (name in ename) {
- if (name === 'ready') {
- readyFn = ename[name];
- }
- }
- }
- if (readyFn) {
- Ext.log.warn("Ext.on('ready', fn) is deprecated. " + "Please use Ext.onReady(fn) instead.");
- Ext.onReady(readyFn);
- }
- this.callParent([
- ename,
- fn,
- scope,
- options,
- order,
- caller,
- eventOptions
- ]);
- }
- }
- }
- }
- });
- /**
- * @class Ext.plugin.Abstract
- */
- Ext.define('Ext.overrides.plugin.Abstract', {
- override: 'Ext.plugin.Abstract',
- $configStrict: false,
- $configPrefixed: false,
- disabled: false,
- /**
- * @cfg {String|Array} stateEvents
- * The configured list of stateEvents used to (optionally) participate in Owner Component's
- * state management.
- * @member Ext.plugin.Abstract
- */
- /**
- * @method
- * The getState method is invoked by the client Component's State mixin when one or more of the
- * specified {@link #stateEvents} are raised.
- *
- * The supplied implementation is empty. If plugin Subclasses are to (optionally) participate
- * in the client Component's state management, implementers should provide a suitable method
- * which returns a state object.
- * @return {Object} state
- * @member Ext.plugin.Abstract
- */
- getState: null,
- /**
- * @method
- * The applyState method is invoked by the client Component's State mixin after initComponent
- * method has been run for the client.
- *
- * The supplied implementation is empty. If plugin Subclasses are to (optionally) participate
- * in the client Component's state management, implementers should provide a suitable method
- * to utilize it.
- * @param {Object} state The current plugin state object to be applied.
- * @param {Object} allState The current aggregate state of the Component and all plugins.
- * @member Ext.plugin.Abstract
- */
- applyState: null,
- /**
- * The base implementation just sets the plugin's `disabled` flag to `false`
- *
- * Plugin subclasses which need more complex processing may implement an overriding
- * implementation.
- * @member Ext.plugin.Abstract
- */
- enable: function() {
- this.disabled = false;
- },
- /**
- * The base implementation just sets the plugin's `disabled` flag to `true`
- *
- * Plugin subclasses which need more complex processing may implement an overriding
- * implementation.
- * @member Ext.plugin.Abstract
- */
- disable: function() {
- this.disabled = true;
- }
- });
- /**
- * @class Ext.Widget
- */
- Ext.define('Ext.overrides.Widget', {
- override: 'Ext.Widget',
- uses: [
- 'Ext.Component',
- 'Ext.layout.component.Auto'
- ],
- $configStrict: false,
- isComponent: true,
- liquidLayout: true,
- // in Ext JS the rendered flag is set as soon as a component has its element. Since
- // widgets always have an element when constructed, they are always considered to be
- // "rendered"
- rendered: true,
- rendering: true,
- config: {
- renderTo: null
- },
- constructor: function(config) {
- var me = this,
- renderTo;
- me.callParent([
- config
- ]);
- // initialize the component layout
- me.getComponentLayout();
- renderTo = me.getRenderTo();
- if (renderTo) {
- me.render(renderTo);
- }
- },
- addClsWithUI: function(cls) {
- this.el.addCls(cls);
- },
- afterComponentLayout: Ext.emptyFn,
- updateLayout: function() {
- var owner = this.getRefOwner();
- if (owner) {
- owner.updateLayout();
- }
- },
- destroy: function() {
- var me = this,
- ownerCt = me.ownerCt;
- if (ownerCt && ownerCt.remove) {
- ownerCt.remove(me, false);
- }
- me.callParent();
- },
- finishRender: function() {
- this.rendering = false;
- this.initBindable();
- this.initKeyMap();
- },
- getAnimationProps: function() {
- // see Ext.util.Animate mixin
- return {};
- },
- getComponentLayout: function() {
- var me = this,
- layout = me.componentLayout;
- if (!layout) {
- layout = me.componentLayout = new Ext.layout.component.Auto();
- layout.setOwner(me);
- }
- return layout;
- },
- getEl: function() {
- return this.element;
- },
- /**
- * @private
- * Needed for when widget is rendered into a grid cell. The class to add to the cell element.
- * @member Ext.Widget
- */
- getTdCls: function() {
- return Ext.baseCSSPrefix + this.getTdType() + '-' + (this.ui || 'default') + '-cell';
- },
- /**
- * @private
- * Partner method to {@link #getTdCls}.
- *
- * Returns the base type for the component. Defaults to return `this.xtype`, but
- * All derived classes of {@link Ext.form.field.Text TextField} can return the type 'textfield',
- * and all derived classes of {@link Ext.button.Button Button} can return the type 'button'
- * @member Ext.Widget
- */
- getTdType: function() {
- return this.xtype;
- },
- getItemId: function() {
- // needed by ComponentQuery
- return this.itemId || this.id;
- },
- getSizeModel: function() {
- return Ext.Component.prototype.getSizeModel.apply(this, arguments);
- },
- onAdded: function(container, pos, instanced) {
- var me = this;
- me.ownerCt = container;
- me.onInheritedAdd(me, instanced);
- // this component is no longer detached from the body
- me.isDetached = false;
- },
- onRemoved: function(destroying) {
- this.onInheritedRemove(destroying);
- this.ownerCt = this.ownerLayout = null;
- },
- parseBox: function(box) {
- return Ext.Element.parseBox(box);
- },
- removeClsWithUI: function(cls) {
- this.el.removeCls(cls);
- },
- render: function(container, position) {
- var me = this,
- element = me.element,
- proto = Ext.Component.prototype,
- nextSibling;
- if (!me.ownerCt || me.floating) {
- if (Ext.scopeCss) {
- element.addCls(proto.rootCls);
- }
- element.addCls(proto.borderBoxCls);
- }
- if (position) {
- nextSibling = container.childNodes[position];
- if (nextSibling) {
- Ext.fly(container).insertBefore(element, nextSibling);
- return;
- }
- }
- Ext.fly(container).appendChild(element);
- me.finishRender();
- },
- setPosition: function(x, y) {
- this.el.setLocalXY(x, y);
- },
- up: function() {
- return Ext.Component.prototype.up.apply(this, arguments);
- },
- isAncestor: function() {
- return Ext.Component.prototype.isAncestor.apply(this, arguments);
- },
- onFocusEnter: function() {
- return Ext.Component.prototype.onFocusEnter.apply(this, arguments);
- },
- onFocusLeave: function() {
- return Ext.Component.prototype.onFocusLeave.apply(this, arguments);
- },
- isLayoutChild: function(candidate) {
- var ownerCt = this.ownerCt;
- return ownerCt ? (ownerCt === candidate || ownerCt.isLayoutChild(candidate)) : false;
- },
- privates: {
- doAddListener: function(name, fn, scope, options, order, caller, manager) {
- if (name === 'painted' || name === 'resize') {
- this.element.doAddListener(name, fn, scope || this, options, order);
- }
- this.callParent([
- name,
- fn,
- scope,
- options,
- order,
- caller,
- manager
- ]);
- },
- doRemoveListener: function(name, fn, scope) {
- if (name === 'painted' || name === 'resize') {
- this.element.doRemoveListener(name, fn, scope);
- }
- this.callParent([
- name,
- fn,
- scope
- ]);
- }
- }
- }, function(Cls) {
- var prototype = Cls.prototype;
- if (Ext.isIE9m) {
- // Since IE8/9 don't not support Object.defineProperty correctly we can't add the reference
- // nodes on demand, so we just fall back to adding all references up front.
- prototype.addElementReferenceOnDemand = prototype.addElementReference;
- }
- });
- /**
- * @class Ext.Progress
- *
- * @example
- * Ext.create({
- * xtype: 'grid',
- * title: 'Simpsons',
- * store: {
- * data: [
- * { name: 'Lisa', progress: .159 },
- * { name: 'Bart', progress: .216 },
- * { name: 'Homer', progress: .55 },
- * { name: 'Maggie', progress: .167 },
- * { name: 'Marge', progress: .145 }
- * ]
- * },
- * columns: [
- * { text: 'Name', dataIndex: 'name' },
- * {
- * text: 'Progress',
- * xtype: 'widgetcolumn',
- * width: 120,
- * dataIndex: 'progress',
- * widget: {
- * xtype: 'progress'
- * }
- * }
- * ],
- * height: 200,
- * width: 400,
- * renderTo: Ext.getBody()
- * });
- */
- Ext.define('Ext.overrides.Progress', {
- override: 'Ext.Progress',
- config: {
- ui: 'default'
- },
- updateWidth: function(width, oldWidth) {
- var me = this;
- me.callParent([
- width,
- oldWidth
- ]);
- width -= me.element.getBorderWidth('lr');
- me.backgroundEl.setWidth(width);
- me.textEl.setWidth(width);
- },
- privates: {
- startBarAnimation: function(o) {
- this.barEl.animate(o);
- },
- stopBarAnimation: function() {
- this.barEl.stopAnimation();
- }
- }
- });
- /**
- * @class Ext.mixin.Focusable
- */
- Ext.define('Ext.overrides.mixin.Focusable', {
- override: 'Ext.Component',
- /**
- * @cfg {String} [focusCls='focus'] CSS class suffix that will be used to
- * compose the CSS class name that will be added to Component's {@link #focusClsEl},
- * and removed when Component blurs.
- *
- * **Note** that this is not a full CSS class name; this suffix will be combined
- * with component's UI class via {@link #addClsWithUI} and {@link #removeClsWithUI} methods.
- */
- focusCls: 'focus',
- /**
- * Try to focus this component.
- *
- * If this component is disabled, a close relation will be targeted for focus instead
- * to keep focus localized for keyboard users.
- * @param {Mixed} [selectText] If applicable, `true` to also select all the text in this
- * component, or an array consisting of start and end (defaults to start) position of selection.
- * @param {Boolean/Number} [delay] Delay the focus this number of milliseconds (true for
- * 10 milliseconds).
- * @param {Function} [callback] Only needed if the `delay` parameter is used. A function to call
- * upon focus.
- * @param {Function} [scope] Only needed if the `delay` parameter is used. The scope (`this`
- * reference) in which to execute the callback.
- * @return {Ext.Component} The focused Component. Usually `this` Component. Some Containers may
- * delegate focus to a descendant Component ({@link Ext.window.Window Window}s can do this
- * through their {@link Ext.window.Window#defaultFocus defaultFocus} config option. If this
- * component is disabled, a closely related component will be focused and that will be returned.
- */
- focus: function(selectText, delay, callback, scope) {
- var me = this,
- containerScrollTop;
- if ((!me.focusable && !me.isContainer) || me.destroyed || me.destroying) {
- return me;
- }
- // If delay is wanted, queue a call to this function.
- if (delay) {
- me.getFocusTask().delay(Ext.isNumber(delay) ? delay : 10, me.focus, me, [
- selectText,
- false,
- callback,
- scope
- ]);
- return me;
- }
- // An immediate focus call must cancel any outstanding delayed focus calls.
- me.cancelFocus();
- if (me.floating && me.container && me.container.dom) {
- containerScrollTop = me.container.dom.scrollTop;
- }
- // Core Focusable method will return true if focusing was attempted
- if (me.mixins.focusable.focus.apply(me, arguments) !== false) {
- if (callback) {
- Ext.callback(callback, scope);
- }
- // Focusing a floating Component brings it to the front of its stack.
- // this is performed by its zIndexManager. Pass preventFocus true to avoid recursion.
- if (me.floating && containerScrollTop !== undefined) {
- me.container.dom.scrollTop = containerScrollTop;
- }
- }
- return me;
- },
- /**
- * Cancel any deferred focus on this component
- * @protected
- */
- cancelFocus: function() {
- var me = this,
- task = me.getFocusTask();
- if (task) {
- task.cancel();
- }
- },
- /**
- * @method
- * Template method to do any pre-blur processing.
- * @protected
- * @param {Ext.event.Event} e The event object
- */
- beforeBlur: Ext.emptyFn,
- /**
- * @method
- * Template method to do any post-blur processing.
- * @protected
- * @param {Ext.event.Event} e The event object
- */
- postBlur: Ext.emptyFn,
- /**
- * @method
- * Template method to do any pre-focus processing.
- * @protected
- * @param {Ext.event.Event} e The event object
- */
- beforeFocus: Ext.emptyFn,
- /**
- * @method
- * Template method to do any post-focus processing.
- * @protected
- * @param {Ext.event.Event} e The event object
- */
- postFocus: Ext.emptyFn,
- onFocusEnter: function(e) {
- var me = this;
- if (me.destroying || me.destroyed) {
- return;
- }
- // Focusing must being a floating component to the front.
- // Only bring to front if this component is not the manager's
- // topmost component (may be a result of focusOnToFront).
- if (me.floating && me !== me.zIndexManager.getActive()) {
- me.toFront(true);
- }
- me.callParent([
- e
- ]);
- },
- destroyFocusable: function() {
- var me = this;
- // Calling cancelFocus() will assign focusTask property,
- // which we don't want during destruction
- if (me.focusTask) {
- me.focusTask.stop(me.focus, me);
- }
- me.callParent();
- },
- privates: {
- addFocusCls: function(e) {
- var me = this,
- focusCls = me.focusCls,
- el;
- if (focusCls) {
- el = me.getFocusClsEl(e);
- if (el) {
- el.addCls(me.addClsWithUI(focusCls, true));
- }
- }
- },
- removeFocusCls: function(e) {
- var me = this,
- focusCls = me.focusCls,
- el;
- if (focusCls) {
- el = me.getFocusClsEl(e);
- if (el) {
- el.removeCls(me.removeClsWithUI(focusCls, true));
- }
- }
- },
- /**
- * @private
- */
- getFocusTask: function() {
- if (!this.focusTask) {
- this.focusTask = Ext.focusTask;
- }
- return this.focusTask;
- },
- updateMaskState: function(state, mask) {
- var me = this,
- ariaEl = me.ariaEl.dom,
- skipMask = me.getInherited().disabled && me.getInherited().disableMask,
- value;
- if (state) {
- me.disableTabbing();
- if (!skipMask) {
- me.setMasked(true);
- }
- if (ariaEl) {
- ariaEl.setAttribute('aria-busy', 'true');
- // It is possible that ariaEl already has aria-describedby attribute;
- // in that case we need to save it to restore later.
- value = ariaEl.getAttribute('aria-describedby');
- if (value) {
- me._savedAriaDescribedBy = value;
- }
- ariaEl.setAttribute('aria-describedby', mask.ariaEl.id);
- }
- } else {
- me.enableTabbing();
- if (!skipMask) {
- me.setMasked(false);
- }
- if (ariaEl) {
- ariaEl.removeAttribute('aria-busy');
- value = ariaEl.getAttribute('aria-describedby');
- ariaEl.removeAttribute('aria-describedby');
- if (value === mask.ariaEl.id && me._savedAriaDescribedBy) {
- ariaEl.setAttribute('aria-describedby', me._savedAriaDescribedBy);
- delete me._savedAriaDescribedBy;
- }
- }
- }
- }
- }
- }, function() {
- // One global DelayedTask to assign focus
- // So that the last focus call wins.
- if (!Ext.focusTask) {
- Ext.focusTask = new Ext.util.DelayedTask();
- }
- });
- Ext.define('Ext.overrides.app.domain.Component', {
- override: 'Ext.app.domain.Component',
- requires: [
- 'Ext.Component'
- ]
- }, function(ComponentDomain) {
- // The core Component domain monitors events on the Ext.Widget class
- // in Ext Components are not widgets so we need to monitor Ext.Component as well.
- ComponentDomain.monitor(Ext.Component);
- });
- // This is an override because it must be loaded very early, possibly before Ext.app.Application
- // in dev mode so that Ext.application() can be called.
- // Being an override also ensures that it is only included in a built app if Ext.app.Application
- // is present.
- //
- // @override Ext.app.Application
- /**
- * @method application
- * @member Ext
- * Loads Ext.app.Application class and starts it up with given configuration after the
- * page is ready.
- *
- * See `Ext.app.Application` for details.
- *
- * @param {Object/String} config Application config object or name of a class derived
- * from Ext.app.Application.
- */
- Ext.application = function(config) {
- var createApp = function(App) {
- // This won't be called until App class has been created.
- Ext.onReady(function() {
- var Viewport = Ext.viewport;
- // eslint-disable-next-line dot-notation
- Viewport = Viewport && Viewport['Viewport'];
- if (Viewport && Viewport.setup) {
- Viewport.setup(App.prototype.config.viewport);
- }
- Ext.app.Application.instance = new App();
- });
- };
- if (typeof config === "string") {
- Ext.require(config, function() {
- createApp(Ext.ClassManager.get(config));
- });
- } else {
- config = Ext.apply({
- extend: 'Ext.app.Application'
- }, // can be replaced by config!
- config);
- // We have to process "paths" before creating Application class,
- // or `requires` won't work.
- Ext.app.setupPaths(config.name, config.appFolder, config.paths);
- config['paths processed'] = true;
- // Let Ext.define do the hard work but don't assign a class name.
- Ext.define(config.name + ".$application", config, function() {
- createApp(this);
- });
- }
- };
- /**
- * @class Ext.app.Application
- */
- Ext.define('Ext.overrides.app.Application', {
- override: 'Ext.app.Application',
- uses: [
- 'Ext.tip.QuickTipManager'
- ],
- // @cmd-auto-dependency {aliasPrefix: "view.", mvc: true, requires: ["Ext.plugin.Viewport"]}
- /**
- * @cfg {Boolean/String} [autoCreateViewport=false]
- * @deprecated 5.1 Instead use {@link #mainView}
- * @member Ext.app.Application
- */
- autoCreateViewport: false,
- config: {
- /**
- * @cfg {Boolean} enableQuickTips
- * @deprecated 6.2.0 Use {@link #quickTips}.
- */
- enableQuickTips: null
- },
- /**
- * @cfg {Boolean} quickTips
- * True to automatically set up Ext.tip.QuickTip support.
- *
- * @since 6.2.0
- */
- quickTips: true,
- updateEnableQuickTips: function(enableQuickTips) {
- this.setQuickTips(enableQuickTips);
- },
- applyMainView: function(mainView) {
- var view, proto, config, protoPlugins, configPlugins;
- if (typeof mainView === 'string') {
- view = this.getView(mainView);
- config = {};
- } else {
- config = mainView;
- view = Ext.ClassManager.getByConfig(mainView);
- }
- proto = view.prototype;
- if (!proto.isViewport) {
- // Need to copy over any plugins defined on the prototype and on the config.
- protoPlugins = Ext.Array.from(proto.plugins);
- configPlugins = Ext.Array.from(config.plugins);
- config = Ext.apply({}, config);
- config.plugins = [
- 'viewport'
- ].concat(protoPlugins, configPlugins);
- }
- return view.create(config);
- },
- getDependencies: function(cls, data, requires) {
- var Controller = Ext.app.Controller,
- proto = cls.prototype,
- namespace = data.$namespace,
- viewportClass = data.autoCreateViewport;
- if (viewportClass) {
- if (!namespace) {
- Ext.raise("[Ext.app.Application] Can't resolve namespace for " + data.$className + ", did you forget to specify 'name' property?");
- }
- if (viewportClass === true) {
- viewportClass = 'Viewport';
- } else {
- requires.push('Ext.plugin.Viewport');
- }
- Controller.processDependencies(proto, requires, namespace, 'view', viewportClass);
- }
- },
- onBeforeLaunch: function() {
- var me = this,
- autoCreateViewport = me.autoCreateViewport;
- if (me.getQuickTips()) {
- me.initQuickTips();
- }
- if (autoCreateViewport) {
- me.initViewport();
- }
- this.callParent(arguments);
- },
- getViewportName: function() {
- var name = null,
- autoCreate = this.autoCreateViewport;
- if (autoCreate) {
- name = (autoCreate === true) ? 'Viewport' : autoCreate;
- }
- return name;
- },
- initViewport: function() {
- this.setMainView(this.getViewportName());
- },
- initQuickTips: function() {
- Ext.tip.QuickTipManager.init();
- }
- });
- Ext.define('Ext.overrides.app.domain.View', {
- override: 'Ext.app.domain.View',
- requires: [
- 'Ext.Component'
- ],
- constructor: function(controller) {
- this.callParent([
- controller
- ]);
- // The base class handles Ext.Widget, which encompasses
- // component for modern, so we only need the override here.
- this.monitoredClasses.push(Ext.Component);
- }
- });
- /**
- * @class Ext.dom.Helper
- */
- Ext.define('Ext.overrides.dom.Helper', (function() {
- var tableRe = /^(?:table|thead|tbody|tr|td)$/i,
- tableElRe = /td|tr|tbody|thead/i,
- ts = '<table>',
- te = '</table>',
- tbs = ts + '<tbody>',
- tbe = '</tbody>' + te,
- trs = tbs + '<tr>',
- tre = '</tr>' + tbe;
- return {
- override: 'Ext.dom.Helper',
- ieInsertHtml: function(where, el, html) {
- var frag = null;
- // IE's incomplete table implementation: http://www.ericvasilik.com/2006/07/code-karma.html
- if (Ext.isIE9m && tableRe.test(el.tagName)) {
- frag = this.insertIntoTable(el.tagName.toLowerCase(), where, el, html);
- }
- return frag;
- },
- ieOverwrite: function(el, html) {
- // IE Inserting HTML into a table/tbody/tr requires extra processing:
- // http://www.ericvasilik.com/2006/07/code-karma.html
- if (Ext.isIE9m && tableRe.test(el.tagName)) {
- // Clearing table elements requires removal of all elements.
- while (el.firstChild) {
- el.removeChild(el.firstChild);
- }
- if (html) {
- return this.insertHtml('afterbegin', el, html);
- }
- }
- },
- ieTable: function(depth, openingTags, htmlContent, closingTags) {
- var i = -1,
- el = this.detachedDiv,
- ns, nx;
- el.innerHTML = [
- openingTags,
- htmlContent,
- closingTags
- ].join('');
- while (++i < depth) {
- el = el.firstChild;
- }
- // If the result is multiple siblings, then encapsulate them into one fragment.
- ns = el.nextSibling;
- if (ns) {
- ns = el;
- el = document.createDocumentFragment();
- while (ns) {
- nx = ns.nextSibling;
- el.appendChild(ns);
- ns = nx;
- }
- }
- return el;
- },
- /**
- * @private
- * @method insertIntoTable
- * @member Ext.dom.Helper
- * workaround for broken table implementation in IE9m
- * http://www.ericvasilik.com/2006/07/code-karma.html
- */
- insertIntoTable: function(tag, where, destinationEl, html) {
- var node, before,
- bb = where === 'beforebegin',
- ab = where === 'afterbegin',
- be = where === 'beforeend',
- ae = where === 'afterend';
- if (tag === 'td' && (ab || be) || !tableElRe.test(tag) && (bb || ae)) {
- return null;
- }
- /* eslint-disable indent, multiline-ternary, no-multi-spaces */
- before = bb ? destinationEl : ae ? destinationEl.nextSibling : ab ? destinationEl.firstChild : null;
- /* eslint-enable indent, multiline-ternary, no-multi-spaces */
- if (bb || ae) {
- destinationEl = destinationEl.parentNode;
- }
- if (tag === 'td' || (tag === 'tr' && (be || ab))) {
- node = this.ieTable(4, trs, html, tre);
- } else if (((tag === 'tbody' || tag === 'thead') && (be || ab)) || (tag === 'tr' && (bb || ae))) {
- node = this.ieTable(3, tbs, html, tbe);
- } else {
- node = this.ieTable(2, ts, html, te);
- }
- destinationEl.insertBefore(node, before);
- return node;
- }
- };
- })());
- /**
- * @class Ext.list.AbstractTreeItem
- */
- Ext.define('Ext.overrides.list.AbstractTreeItem', {
- override: 'Ext.list.AbstractTreeItem',
- // This config is used by TreeIten, however to support the generic API (RootItem),
- // we need this up here.
- config: {
- floated: null
- }
- });
- /**
- * @class Ext.list.TreeItem
- */
- Ext.define('Ext.overrides.list.TreeItem', {
- override: 'Ext.list.TreeItem',
- // Implement a setter.
- // There *is* no "floated" config in Classic.
- // We're still an inner item, we just get put inside a Container.
- setFloated: function(floated) {
- var me = this,
- el = me.element,
- placeholder = me.placeholder,
- node, wasExpanded;
- if (me.treeItemFloated !== floated) {
- if (floated) {
- placeholder = el.clone(false, true);
- // shallow, asDom
- placeholder.id += '-placeholder';
- // avoid duplicate id
- me.placeholder = Ext.get(placeholder);
- me.wasExpanded = me.getExpanded();
- me.setExpanded(true);
- el.addCls(me.floatedCls);
- el.dom.parentNode.insertBefore(placeholder, el.dom);
- me.floater = me.createFloater();
- }
- // toolkit-specific
- else if (placeholder) {
- wasExpanded = me.wasExpanded;
- node = me.getNode();
- me.setExpanded(wasExpanded);
- if (!wasExpanded && node.isExpanded()) {
- // If we have been floating and expanded a child, we may have been
- // expanded as part of the ancestors. Attempt to restore state.
- me.preventAnimation = true;
- node.collapse();
- me.preventAnimation = false;
- }
- me.floater.remove(me, false);
- // don't destroy
- el.removeCls(me.floatedCls);
- placeholder.dom.parentNode.insertBefore(el.dom, placeholder.dom);
- placeholder.destroy();
- me.floater.destroy();
- me.placeholder = me.floater = null;
- }
- // Use an internal property name. We are NOT really floated
- me.treeItemFloated = floated;
- }
- },
- getFloated: function() {
- return this.treeItemFloated;
- },
- runAnimation: function(animation) {
- return this.itemContainer.addAnimation(animation);
- },
- stopAnimation: function(animation) {
- animation.jumpToEnd();
- },
- privates: {
- createFloater: function() {
- var me = this,
- owner = me.getOwner(),
- ownerTree = me.up('treelist'),
- floater,
- toolElement = me.getToolElement(),
- expandedWidth = ownerTree.expandedWidth,
- defaultListWidth = ownerTree.defaultListWidth;
- if (expandedWidth === null) {
- expandedWidth = defaultListWidth;
- }
- me.floater = floater = new Ext.container.Container({
- cls: ownerTree.self.prototype.element.cls + ' ' + ownerTree.uiPrefix + ownerTree.getUi() + ' ' + Ext.baseCSSPrefix + 'treelist-floater',
- floating: true,
- // We do not get element resize events on IE8
- // so fall back to 6.0.1 sizing to 200 wide.
- width: Ext.isIE8 ? defaultListWidth : (expandedWidth - toolElement.getWidth()),
- shadow: false,
- hidden: true,
- renderTo: Ext.getBody(),
- listeners: {
- element: 'el',
- click: function(e) {
- return owner.onClick(e);
- }
- }
- });
- floater.add(me);
- floater.show();
- floater.el.alignTo(toolElement, 'tr?');
- return floater;
- }
- }
- });
- /**
- * @class Ext.list.Tree
- */
- Ext.define('Ext.overrides.list.Tree', {
- override: 'Ext.list.Tree',
- canMeasure: true,
- constructor: function(config) {
- this.callParent([
- config
- ]);
- // Track size so that we can track the expanded size
- // for use by the floated state of items when in micro mode.
- // Browsers where this event is not supported, fall back to a width
- // of 200px for floated tree items.
- if (!Ext.isIE8) {
- this.element.on('resize', 'onElResize', this);
- }
- },
- beforeLayout: function() {
- this.syncIconSize();
- },
- onElResize: function(el, details) {
- if (!this.getMicro() && this.canMeasure) {
- this.expandedWidth = details.width;
- }
- },
- privates: {
- defaultListWidth: 200,
- expandedWidth: null
- }
- });
- /**
- * @class Ext.sparkline.Base
- */
- Ext.define('Ext.override.sparkline.Base', {
- override: 'Ext.sparkline.Base',
- statics: {
- constructTip: function() {
- // eslint-disable-next-line dot-notation
- return new Ext.tip['ToolTip']({
- id: 'sparklines-tooltip',
- showDelay: 0,
- dismissDelay: 0,
- hideDelay: 400
- });
- }
- },
- onMouseMove: function(e) {
- this.getSharedTooltip().triggerEvent = e;
- this.callParent([
- e
- ]);
- },
- onMouseLeave: function(e) {
- this.callParent([
- e
- ]);
- this.getSharedTooltip().target = null;
- },
- privates: {
- hideTip: function() {
- var tip = this.getSharedTooltip();
- tip.target = null;
- tip.hide();
- },
- showTip: function() {
- var tip = this.getSharedTooltip();
- tip.target = this.el;
- tip.onTargetOver(tip.triggerEvent);
- }
- }
- }, function(Cls) {
- // If we are on a VML platform (IE8 - TODO: remove this when that retires)...
- if (!Ext.supports.Canvas) {
- Cls.prototype.element = {
- tag: 'span',
- reference: 'element',
- listeners: {
- mouseenter: 'onMouseEnter',
- mouseleave: 'onMouseLeave',
- mousemove: 'onMouseMove'
- },
- style: {
- display: 'inline-block',
- position: 'relative',
- overflow: 'hidden',
- margin: '0px',
- padding: '0px',
- verticalAlign: 'top',
- cursor: 'default'
- },
- children: [
- {
- tag: 'svml:group',
- reference: 'groupEl',
- coordorigin: '0 0',
- coordsize: '0 0',
- style: 'position:absolute;width:0;height:0;pointer-events:none'
- }
- ]
- };
- }
- });
- /**
- * @class Ext.app.ViewController
- */
- /**
- * @method beforeRender
- * @template
- * Template method called by the owning component's
- * {@link Ext.Component#method-beforeRender beforeRender} method.
- * @param {Ext.Component} component The owner component attached to the
- * ViewController
- */
- /**
- * @method afterRender
- * @template
- * Template method called by the owning component's
- * {@link Ext.Component#method-afterRender afterRender} method.
- * @param {Ext.Component} component The owner component attached to the
- * ViewController
- */
- /**
- * @method boxReady
- * @template
- * Template method called by the owning component's
- * {@link Ext.Component#method-onBoxReady onBoxReady} method.
- * @param {Ext.Component} component The owner component attached to the
- * ViewController
- */
- /**
- * @class Ext.form.field.Checkbox
- */
- Ext.define(null, {
- override: 'Ext.form.field.Checkbox',
- compatibility: Ext.isIE8,
- // IE8 does not support change event but it has propertychange which is even better
- changeEventName: 'propertychange',
- onChangeEvent: function(e) {
- // IE8 propertychange fires for *any* property change but we're only interested in checked
- // We also don't want to react to propertychange fired as the result of assigning
- // checked property in setRawValue().
- if (this.duringSetRawValue || e.browserEvent.propertyName !== 'checked') {
- return;
- }
- this.callParent([
- e
- ]);
- },
- updateCheckedCls: function(checked) {
- var me = this,
- displayEl = me.displayEl;
- me.callParent([
- checked
- ]);
- // IE8 has a bug with font icons and pseudo-elements
- if (displayEl && checked !== me.lastValue) {
- displayEl.repaint();
- }
- }
- });
- /**
- * @class Ext.form.field.Radio
- */
- Ext.define(null, {
- override: 'Ext.form.field.Radio',
- compatibility: Ext.isIE8,
- getSubTplData: function(fieldData) {
- var data = this.callParent([
- fieldData
- ]);
- // Rendering a radio button with checked attribute
- // will have a curious side effect in IE8: the DOM
- // node will have checked property set to `true` but
- // radio group (radios with the same name attribute)
- // will behave as if no radio is checked in the group;
- // tabbing into the group will select first or last
- // button instead of the checked one.
- // So instead of rendering the attribute we will set
- // checked value in the DOM after rendering. Apparently
- // such a tiny nudge is enough for the browser to behave.
- delete data.checked;
- return data;
- },
- afterRender: function() {
- this.callParent();
- if (this.checked) {
- this.inputEl.dom.checked = true;
- }
- },
- onChange: function(newValue, oldValue) {
- // We don't need to bother updating other radio buttons in IE8
- // since it will fire propertychange event on any change, not only false -> true.
- // This is unlike standard compliant browsers, see main class.
- this.callSuper([
- newValue,
- oldValue
- ]);
- }
- });
- /**
- * @class Ext.scroll.Scroller
- */
- Ext.define(null, {
- override: 'Ext.scroll.Scroller',
- compatibility: Ext.isIE8,
- privates: {
- // Important note: this code had to be copied as a whole
- // because the scrollLeft assignment trickery only works
- // reliably when it is done within the same function context.
- doScrollTo: function(x, y, animate) {
- var me = this,
- element = me.getScrollElement(),
- maxPosition, dom, to, xInf, yInf, ret, deferred, callback;
- if (element && !element.destroyed) {
- dom = element.dom;
- xInf = (x === Infinity);
- yInf = (y === Infinity);
- if (xInf || yInf) {
- maxPosition = me.getMaxPosition();
- if (xInf) {
- x = maxPosition.x;
- }
- if (yInf) {
- y = maxPosition.y;
- }
- }
- if (x !== null) {
- x = me.convertX(x);
- }
- if (animate) {
- to = {};
- if (y != null) {
- to.scrollTop = y;
- }
- if (x != null) {
- to.scrollLeft = x;
- }
- animate = Ext.mergeIf({
- to: {
- scrollTop: y,
- scrollLeft: x
- }
- }, animate);
- deferred = new Ext.Deferred();
- callback = animate.callback;
- animate.callback = function() {
- if (callback) {
- callback.call(animate.scope || Ext.global, arguments);
- }
- // The callback will be called if the element is destroyed
- if (me.destroyed) {
- deferred.reject();
- } else {
- deferred.resolve();
- }
- };
- element.animate(animate);
- ret = deferred.promise;
- } else {
- // When we need to assign both scrollTop and scrollLeft,
- // IE8 might fire scroll event on the first assignment
- // but not on the second; that behavior is unlike the other
- // browsers which will wait for the second assignment
- // to happen before firing the event. This leads to our
- // scrollstart event firing prematurely, when the scrolling
- // has not actually finished yet.
- // To work around that, we ignore the first event and then
- // force another one by assigning scrollLeft the second time.
- if ((x != null && x !== 0) && y != null) {
- me.deferDomScroll = true;
- }
- if (y != null) {
- dom.scrollTop = y;
- }
- if (x != null) {
- dom.scrollLeft = x;
- }
- if (me.deferDomScroll) {
- me.deferDomScroll = false;
- // Reading the DOM makes sure the second assignment will fire the event.
- // eslint-disable-next-line no-unused-expressions
- +dom.scrollLeft;
- dom.scrollLeft = x;
- // eslint-disable-next-line no-unused-expressions
- +dom.scrollTop;
- dom.scrollTop = y;
- }
- ret = Ext.Deferred.getCachedResolved();
- }
- // Our position object will need refreshing before returning.
- me.positionDirty = true;
- } else {
- ret = Ext.Deferred.getCachedRejected();
- }
- return ret;
- },
- onDomScroll: function() {
- var me = this;
- if (me.deferDomScroll) {
- return;
- }
- me.callParent();
- }
- }
- });
|