| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436843784388439844084418442844384448445844684478448844984508451845284538454845584568457845884598460846184628463846484658466846784688469847084718472847384748475847684778478847984808481848284838484848584868487848884898490849184928493849484958496849784988499850085018502850385048505850685078508850985108511851285138514851585168517851885198520852185228523852485258526852785288529853085318532853385348535853685378538853985408541854285438544854585468547854885498550855185528553855485558556855785588559856085618562856385648565856685678568856985708571857285738574857585768577857885798580858185828583858485858586858785888589859085918592859385948595859685978598859986008601860286038604860586068607860886098610861186128613861486158616861786188619862086218622862386248625862686278628862986308631863286338634863586368637863886398640864186428643864486458646864786488649865086518652865386548655865686578658865986608661866286638664866586668667866886698670867186728673867486758676867786788679868086818682868386848685868686878688868986908691869286938694869586968697869886998700870187028703870487058706870787088709871087118712871387148715871687178718871987208721872287238724872587268727872887298730873187328733873487358736873787388739874087418742874387448745874687478748874987508751875287538754875587568757875887598760876187628763876487658766876787688769877087718772877387748775877687778778877987808781878287838784878587868787878887898790879187928793879487958796879787988799880088018802880388048805880688078808880988108811881288138814881588168817881888198820882188228823882488258826882788288829883088318832883388348835883688378838883988408841884288438844884588468847884888498850885188528853885488558856885788588859886088618862886388648865886688678868886988708871887288738874887588768877887888798880888188828883888488858886888788888889889088918892889388948895889688978898889989008901890289038904890589068907890889098910891189128913891489158916891789188919892089218922892389248925892689278928892989308931893289338934893589368937893889398940894189428943894489458946894789488949895089518952895389548955895689578958895989608961896289638964896589668967896889698970897189728973897489758976897789788979898089818982898389848985898689878988898989908991899289938994899589968997899889999000900190029003900490059006900790089009901090119012901390149015901690179018901990209021902290239024902590269027902890299030903190329033903490359036903790389039904090419042904390449045904690479048904990509051905290539054905590569057905890599060906190629063906490659066906790689069907090719072907390749075907690779078907990809081908290839084908590869087908890899090909190929093909490959096909790989099910091019102910391049105910691079108910991109111911291139114911591169117911891199120912191229123912491259126912791289129913091319132913391349135913691379138913991409141914291439144914591469147914891499150915191529153915491559156915791589159916091619162916391649165916691679168916991709171917291739174917591769177917891799180918191829183918491859186918791889189919091919192919391949195919691979198919992009201920292039204920592069207920892099210921192129213921492159216921792189219922092219222922392249225922692279228922992309231923292339234923592369237923892399240924192429243924492459246924792489249925092519252925392549255925692579258925992609261926292639264926592669267926892699270927192729273927492759276927792789279928092819282928392849285928692879288928992909291929292939294929592969297929892999300930193029303930493059306930793089309931093119312931393149315931693179318931993209321932293239324932593269327932893299330933193329333933493359336933793389339934093419342934393449345934693479348934993509351935293539354935593569357935893599360936193629363936493659366936793689369937093719372937393749375937693779378937993809381938293839384938593869387938893899390939193929393939493959396939793989399940094019402940394049405940694079408940994109411941294139414941594169417941894199420942194229423942494259426942794289429943094319432943394349435943694379438943994409441944294439444944594469447944894499450945194529453945494559456945794589459946094619462946394649465946694679468946994709471947294739474947594769477947894799480948194829483948494859486948794889489949094919492949394949495949694979498949995009501950295039504950595069507950895099510951195129513951495159516951795189519952095219522952395249525952695279528952995309531953295339534953595369537953895399540954195429543954495459546954795489549955095519552955395549555955695579558955995609561956295639564956595669567956895699570957195729573957495759576957795789579958095819582958395849585958695879588958995909591959295939594959595969597959895999600960196029603960496059606960796089609961096119612961396149615961696179618961996209621962296239624962596269627962896299630963196329633963496359636963796389639964096419642964396449645964696479648964996509651965296539654965596569657965896599660966196629663966496659666966796689669967096719672967396749675967696779678967996809681968296839684968596869687968896899690969196929693969496959696969796989699970097019702970397049705970697079708970997109711971297139714971597169717971897199720972197229723972497259726972797289729973097319732973397349735973697379738973997409741974297439744974597469747974897499750975197529753975497559756975797589759976097619762976397649765976697679768976997709771977297739774977597769777977897799780978197829783978497859786978797889789979097919792979397949795979697979798979998009801980298039804980598069807980898099810981198129813981498159816981798189819982098219822982398249825982698279828982998309831983298339834983598369837983898399840984198429843984498459846984798489849985098519852985398549855985698579858985998609861986298639864986598669867986898699870987198729873987498759876987798789879988098819882988398849885988698879888988998909891989298939894989598969897989898999900990199029903990499059906990799089909991099119912991399149915991699179918991999209921992299239924992599269927992899299930993199329933993499359936993799389939994099419942994399449945994699479948994999509951995299539954995599569957995899599960996199629963996499659966996799689969997099719972997399749975997699779978997999809981998299839984998599869987998899899990999199929993999499959996999799989999100001000110002100031000410005100061000710008100091001010011100121001310014100151001610017100181001910020100211002210023100241002510026100271002810029100301003110032100331003410035100361003710038100391004010041100421004310044100451004610047100481004910050100511005210053100541005510056100571005810059100601006110062100631006410065100661006710068100691007010071100721007310074100751007610077100781007910080100811008210083100841008510086100871008810089100901009110092100931009410095100961009710098100991010010101101021010310104101051010610107101081010910110101111011210113101141011510116101171011810119101201012110122101231012410125101261012710128101291013010131101321013310134101351013610137101381013910140101411014210143101441014510146101471014810149101501015110152101531015410155101561015710158101591016010161101621016310164101651016610167101681016910170101711017210173101741017510176101771017810179101801018110182101831018410185101861018710188101891019010191101921019310194101951019610197101981019910200102011020210203102041020510206102071020810209102101021110212102131021410215102161021710218102191022010221102221022310224102251022610227102281022910230102311023210233102341023510236102371023810239102401024110242102431024410245102461024710248102491025010251102521025310254102551025610257102581025910260102611026210263102641026510266102671026810269102701027110272102731027410275102761027710278102791028010281102821028310284102851028610287102881028910290102911029210293102941029510296102971029810299103001030110302103031030410305103061030710308103091031010311103121031310314103151031610317103181031910320103211032210323103241032510326103271032810329103301033110332103331033410335103361033710338103391034010341103421034310344103451034610347103481034910350103511035210353103541035510356103571035810359103601036110362103631036410365103661036710368103691037010371103721037310374103751037610377103781037910380103811038210383103841038510386103871038810389103901039110392103931039410395103961039710398103991040010401104021040310404104051040610407104081040910410104111041210413104141041510416104171041810419104201042110422104231042410425104261042710428104291043010431104321043310434104351043610437104381043910440104411044210443104441044510446104471044810449104501045110452104531045410455104561045710458104591046010461104621046310464104651046610467104681046910470104711047210473104741047510476104771047810479104801048110482104831048410485104861048710488104891049010491104921049310494104951049610497104981049910500105011050210503105041050510506105071050810509105101051110512105131051410515105161051710518105191052010521105221052310524105251052610527105281052910530105311053210533105341053510536105371053810539105401054110542105431054410545105461054710548105491055010551105521055310554105551055610557105581055910560105611056210563105641056510566105671056810569105701057110572105731057410575105761057710578105791058010581105821058310584105851058610587105881058910590105911059210593105941059510596105971059810599106001060110602106031060410605106061060710608106091061010611106121061310614106151061610617106181061910620106211062210623106241062510626106271062810629106301063110632106331063410635106361063710638106391064010641106421064310644106451064610647106481064910650106511065210653106541065510656106571065810659106601066110662106631066410665106661066710668106691067010671106721067310674106751067610677106781067910680106811068210683106841068510686106871068810689106901069110692106931069410695106961069710698106991070010701107021070310704107051070610707107081070910710107111071210713107141071510716107171071810719107201072110722107231072410725107261072710728107291073010731107321073310734107351073610737107381073910740107411074210743107441074510746107471074810749107501075110752107531075410755107561075710758107591076010761107621076310764107651076610767107681076910770107711077210773107741077510776107771077810779107801078110782107831078410785107861078710788107891079010791107921079310794107951079610797107981079910800108011080210803108041080510806108071080810809108101081110812108131081410815108161081710818108191082010821108221082310824108251082610827108281082910830108311083210833108341083510836108371083810839108401084110842108431084410845108461084710848108491085010851108521085310854108551085610857108581085910860108611086210863108641086510866108671086810869108701087110872108731087410875108761087710878108791088010881108821088310884108851088610887108881088910890108911089210893108941089510896108971089810899109001090110902109031090410905109061090710908109091091010911109121091310914109151091610917109181091910920109211092210923109241092510926109271092810929109301093110932109331093410935109361093710938109391094010941109421094310944109451094610947109481094910950109511095210953109541095510956109571095810959109601096110962109631096410965109661096710968109691097010971109721097310974109751097610977109781097910980109811098210983109841098510986109871098810989109901099110992109931099410995109961099710998109991100011001110021100311004110051100611007110081100911010110111101211013110141101511016110171101811019110201102111022110231102411025110261102711028110291103011031110321103311034110351103611037110381103911040110411104211043110441104511046110471104811049110501105111052110531105411055110561105711058110591106011061110621106311064110651106611067110681106911070110711107211073110741107511076110771107811079110801108111082110831108411085110861108711088110891109011091110921109311094110951109611097110981109911100111011110211103111041110511106111071110811109111101111111112111131111411115111161111711118111191112011121111221112311124111251112611127111281112911130111311113211133111341113511136111371113811139111401114111142111431114411145111461114711148111491115011151111521115311154111551115611157111581115911160111611116211163111641116511166111671116811169111701117111172111731117411175111761117711178111791118011181111821118311184111851118611187111881118911190111911119211193111941119511196111971119811199112001120111202112031120411205112061120711208112091121011211112121121311214112151121611217112181121911220112211122211223112241122511226112271122811229112301123111232112331123411235112361123711238112391124011241112421124311244112451124611247112481124911250112511125211253112541125511256112571125811259112601126111262112631126411265112661126711268112691127011271112721127311274112751127611277112781127911280112811128211283112841128511286112871128811289112901129111292112931129411295112961129711298112991130011301113021130311304113051130611307113081130911310113111131211313113141131511316113171131811319113201132111322113231132411325113261132711328113291133011331113321133311334113351133611337113381133911340113411134211343113441134511346113471134811349113501135111352113531135411355113561135711358113591136011361113621136311364113651136611367113681136911370113711137211373113741137511376113771137811379113801138111382113831138411385113861138711388113891139011391113921139311394113951139611397113981139911400114011140211403114041140511406114071140811409114101141111412114131141411415114161141711418114191142011421114221142311424114251142611427114281142911430114311143211433114341143511436114371143811439114401144111442114431144411445114461144711448114491145011451114521145311454114551145611457114581145911460114611146211463114641146511466114671146811469114701147111472114731147411475114761147711478114791148011481114821148311484114851148611487114881148911490114911149211493114941149511496114971149811499115001150111502115031150411505115061150711508115091151011511115121151311514115151151611517115181151911520115211152211523115241152511526115271152811529115301153111532115331153411535115361153711538115391154011541115421154311544115451154611547115481154911550115511155211553115541155511556115571155811559115601156111562115631156411565115661156711568115691157011571115721157311574115751157611577115781157911580115811158211583115841158511586115871158811589115901159111592115931159411595115961159711598115991160011601116021160311604116051160611607116081160911610116111161211613116141161511616116171161811619116201162111622116231162411625116261162711628116291163011631116321163311634116351163611637116381163911640116411164211643116441164511646116471164811649116501165111652116531165411655116561165711658116591166011661116621166311664116651166611667116681166911670116711167211673116741167511676116771167811679116801168111682116831168411685116861168711688116891169011691116921169311694116951169611697116981169911700117011170211703117041170511706117071170811709117101171111712117131171411715117161171711718117191172011721117221172311724117251172611727117281172911730117311173211733117341173511736117371173811739117401174111742117431174411745117461174711748117491175011751117521175311754117551175611757117581175911760117611176211763117641176511766117671176811769117701177111772117731177411775117761177711778117791178011781117821178311784117851178611787117881178911790117911179211793117941179511796117971179811799118001180111802118031180411805118061180711808118091181011811118121181311814118151181611817118181181911820118211182211823118241182511826118271182811829118301183111832118331183411835118361183711838118391184011841118421184311844118451184611847118481184911850118511185211853118541185511856118571185811859118601186111862118631186411865118661186711868118691187011871118721187311874118751187611877118781187911880118811188211883118841188511886118871188811889118901189111892118931189411895118961189711898118991190011901119021190311904119051190611907119081190911910119111191211913119141191511916119171191811919119201192111922119231192411925119261192711928119291193011931119321193311934119351193611937119381193911940119411194211943119441194511946119471194811949119501195111952119531195411955119561195711958119591196011961119621196311964119651196611967119681196911970119711197211973119741197511976119771197811979119801198111982119831198411985119861198711988119891199011991119921199311994119951199611997119981199912000120011200212003120041200512006120071200812009120101201112012120131201412015120161201712018120191202012021120221202312024120251202612027120281202912030120311203212033120341203512036120371203812039120401204112042120431204412045120461204712048120491205012051120521205312054120551205612057120581205912060120611206212063120641206512066120671206812069120701207112072120731207412075120761207712078120791208012081120821208312084120851208612087120881208912090120911209212093120941209512096120971209812099121001210112102121031210412105121061210712108121091211012111121121211312114121151211612117121181211912120121211212212123121241212512126121271212812129121301213112132121331213412135121361213712138121391214012141121421214312144121451214612147121481214912150121511215212153121541215512156121571215812159121601216112162121631216412165121661216712168121691217012171121721217312174121751217612177121781217912180121811218212183121841218512186121871218812189121901219112192121931219412195121961219712198121991220012201122021220312204122051220612207122081220912210122111221212213122141221512216122171221812219122201222112222122231222412225122261222712228122291223012231122321223312234122351223612237122381223912240122411224212243122441224512246122471224812249122501225112252122531225412255122561225712258122591226012261122621226312264122651226612267122681226912270122711227212273122741227512276122771227812279122801228112282122831228412285122861228712288122891229012291122921229312294122951229612297122981229912300123011230212303123041230512306123071230812309123101231112312123131231412315123161231712318123191232012321123221232312324123251232612327123281232912330123311233212333123341233512336123371233812339123401234112342123431234412345123461234712348123491235012351123521235312354123551235612357123581235912360123611236212363123641236512366123671236812369123701237112372123731237412375123761237712378123791238012381123821238312384123851238612387123881238912390123911239212393123941239512396123971239812399124001240112402124031240412405124061240712408124091241012411124121241312414124151241612417124181241912420124211242212423124241242512426124271242812429124301243112432124331243412435124361243712438124391244012441124421244312444124451244612447124481244912450124511245212453124541245512456124571245812459124601246112462124631246412465124661246712468124691247012471124721247312474124751247612477124781247912480124811248212483124841248512486124871248812489124901249112492124931249412495124961249712498124991250012501125021250312504125051250612507125081250912510125111251212513125141251512516125171251812519125201252112522125231252412525125261252712528125291253012531125321253312534125351253612537125381253912540125411254212543125441254512546125471254812549125501255112552125531255412555125561255712558125591256012561125621256312564125651256612567125681256912570125711257212573125741257512576125771257812579125801258112582125831258412585125861258712588125891259012591125921259312594125951259612597125981259912600126011260212603126041260512606126071260812609126101261112612126131261412615126161261712618126191262012621126221262312624126251262612627126281262912630126311263212633126341263512636126371263812639126401264112642126431264412645126461264712648126491265012651126521265312654126551265612657126581265912660126611266212663126641266512666126671266812669126701267112672126731267412675126761267712678126791268012681126821268312684126851268612687126881268912690126911269212693126941269512696126971269812699127001270112702127031270412705127061270712708127091271012711127121271312714127151271612717127181271912720127211272212723127241272512726127271272812729127301273112732127331273412735127361273712738127391274012741127421274312744127451274612747127481274912750127511275212753127541275512756127571275812759127601276112762127631276412765127661276712768127691277012771127721277312774127751277612777127781277912780127811278212783127841278512786127871278812789127901279112792127931279412795127961279712798127991280012801128021280312804128051280612807128081280912810128111281212813128141281512816128171281812819128201282112822128231282412825128261282712828128291283012831128321283312834128351283612837128381283912840128411284212843128441284512846128471284812849128501285112852128531285412855128561285712858128591286012861128621286312864128651286612867128681286912870128711287212873128741287512876128771287812879128801288112882128831288412885128861288712888128891289012891128921289312894128951289612897128981289912900129011290212903129041290512906129071290812909129101291112912129131291412915129161291712918129191292012921129221292312924129251292612927129281292912930129311293212933129341293512936129371293812939129401294112942129431294412945129461294712948129491295012951129521295312954129551295612957129581295912960129611296212963129641296512966129671296812969129701297112972129731297412975129761297712978129791298012981129821298312984129851298612987129881298912990129911299212993129941299512996129971299812999130001300113002130031300413005130061300713008130091301013011130121301313014130151301613017130181301913020130211302213023130241302513026130271302813029130301303113032130331303413035130361303713038130391304013041130421304313044130451304613047130481304913050130511305213053130541305513056130571305813059130601306113062130631306413065130661306713068130691307013071130721307313074130751307613077130781307913080130811308213083130841308513086130871308813089130901309113092130931309413095130961309713098130991310013101131021310313104131051310613107131081310913110131111311213113131141311513116131171311813119131201312113122131231312413125131261312713128131291313013131131321313313134131351313613137131381313913140131411314213143131441314513146131471314813149131501315113152131531315413155131561315713158131591316013161131621316313164131651316613167131681316913170131711317213173131741317513176131771317813179131801318113182131831318413185131861318713188131891319013191131921319313194131951319613197131981319913200132011320213203132041320513206132071320813209132101321113212132131321413215132161321713218132191322013221132221322313224132251322613227132281322913230132311323213233132341323513236132371323813239132401324113242132431324413245132461324713248132491325013251132521325313254132551325613257132581325913260132611326213263132641326513266132671326813269132701327113272132731327413275132761327713278132791328013281132821328313284132851328613287132881328913290132911329213293132941329513296132971329813299133001330113302133031330413305133061330713308133091331013311133121331313314133151331613317133181331913320133211332213323133241332513326133271332813329133301333113332133331333413335133361333713338133391334013341133421334313344133451334613347133481334913350133511335213353133541335513356133571335813359133601336113362133631336413365133661336713368133691337013371133721337313374133751337613377133781337913380133811338213383133841338513386133871338813389133901339113392133931339413395133961339713398133991340013401134021340313404134051340613407134081340913410134111341213413134141341513416134171341813419134201342113422134231342413425134261342713428134291343013431134321343313434134351343613437134381343913440134411344213443134441344513446134471344813449134501345113452134531345413455134561345713458134591346013461134621346313464134651346613467134681346913470134711347213473134741347513476134771347813479134801348113482134831348413485134861348713488134891349013491134921349313494134951349613497134981349913500135011350213503135041350513506135071350813509135101351113512135131351413515135161351713518135191352013521135221352313524135251352613527135281352913530135311353213533135341353513536135371353813539135401354113542135431354413545135461354713548135491355013551135521355313554135551355613557135581355913560135611356213563135641356513566135671356813569135701357113572135731357413575135761357713578135791358013581135821358313584135851358613587135881358913590135911359213593135941359513596135971359813599136001360113602136031360413605136061360713608136091361013611136121361313614136151361613617136181361913620136211362213623136241362513626136271362813629136301363113632136331363413635136361363713638136391364013641136421364313644136451364613647136481364913650136511365213653136541365513656136571365813659136601366113662136631366413665136661366713668136691367013671136721367313674136751367613677136781367913680136811368213683136841368513686136871368813689136901369113692136931369413695136961369713698136991370013701137021370313704137051370613707137081370913710137111371213713137141371513716137171371813719137201372113722137231372413725137261372713728137291373013731137321373313734137351373613737137381373913740137411374213743137441374513746137471374813749137501375113752137531375413755137561375713758137591376013761137621376313764137651376613767137681376913770137711377213773137741377513776137771377813779137801378113782137831378413785137861378713788137891379013791137921379313794137951379613797137981379913800138011380213803138041380513806138071380813809138101381113812138131381413815138161381713818138191382013821138221382313824138251382613827138281382913830138311383213833138341383513836138371383813839138401384113842138431384413845138461384713848138491385013851138521385313854138551385613857138581385913860138611386213863138641386513866138671386813869138701387113872138731387413875138761387713878138791388013881138821388313884138851388613887138881388913890138911389213893138941389513896138971389813899139001390113902139031390413905139061390713908139091391013911139121391313914139151391613917139181391913920139211392213923139241392513926139271392813929139301393113932139331393413935139361393713938139391394013941139421394313944139451394613947139481394913950139511395213953139541395513956139571395813959139601396113962139631396413965139661396713968139691397013971139721397313974139751397613977139781397913980139811398213983139841398513986139871398813989139901399113992139931399413995139961399713998139991400014001140021400314004140051400614007140081400914010140111401214013140141401514016140171401814019140201402114022140231402414025140261402714028140291403014031140321403314034140351403614037140381403914040140411404214043140441404514046140471404814049140501405114052140531405414055140561405714058140591406014061140621406314064140651406614067140681406914070140711407214073140741407514076140771407814079140801408114082140831408414085140861408714088140891409014091140921409314094140951409614097140981409914100141011410214103141041410514106141071410814109141101411114112141131411414115141161411714118141191412014121141221412314124141251412614127141281412914130141311413214133141341413514136141371413814139141401414114142141431414414145141461414714148141491415014151141521415314154141551415614157141581415914160141611416214163141641416514166141671416814169141701417114172141731417414175141761417714178141791418014181141821418314184141851418614187141881418914190141911419214193141941419514196141971419814199142001420114202142031420414205142061420714208142091421014211142121421314214142151421614217142181421914220142211422214223142241422514226142271422814229142301423114232142331423414235142361423714238142391424014241142421424314244142451424614247142481424914250142511425214253142541425514256142571425814259142601426114262142631426414265142661426714268142691427014271142721427314274142751427614277142781427914280142811428214283142841428514286142871428814289142901429114292142931429414295142961429714298142991430014301143021430314304143051430614307143081430914310143111431214313143141431514316143171431814319143201432114322143231432414325143261432714328143291433014331143321433314334143351433614337143381433914340143411434214343143441434514346143471434814349143501435114352143531435414355143561435714358143591436014361143621436314364143651436614367143681436914370143711437214373143741437514376143771437814379143801438114382143831438414385143861438714388143891439014391143921439314394143951439614397143981439914400144011440214403144041440514406144071440814409144101441114412144131441414415144161441714418144191442014421144221442314424144251442614427144281442914430144311443214433144341443514436144371443814439144401444114442144431444414445144461444714448144491445014451144521445314454144551445614457144581445914460144611446214463144641446514466144671446814469144701447114472144731447414475144761447714478144791448014481144821448314484144851448614487144881448914490144911449214493144941449514496144971449814499145001450114502145031450414505145061450714508145091451014511145121451314514145151451614517145181451914520145211452214523145241452514526145271452814529145301453114532145331453414535145361453714538145391454014541145421454314544145451454614547145481454914550145511455214553145541455514556145571455814559145601456114562145631456414565145661456714568145691457014571145721457314574145751457614577145781457914580145811458214583145841458514586145871458814589145901459114592145931459414595145961459714598145991460014601146021460314604146051460614607146081460914610146111461214613146141461514616146171461814619146201462114622146231462414625146261462714628146291463014631146321463314634146351463614637146381463914640146411464214643146441464514646146471464814649146501465114652146531465414655146561465714658146591466014661146621466314664146651466614667146681466914670146711467214673146741467514676146771467814679146801468114682146831468414685146861468714688146891469014691146921469314694146951469614697146981469914700147011470214703147041470514706147071470814709147101471114712147131471414715147161471714718147191472014721147221472314724147251472614727147281472914730147311473214733147341473514736147371473814739147401474114742147431474414745147461474714748147491475014751147521475314754147551475614757147581475914760147611476214763147641476514766147671476814769147701477114772147731477414775147761477714778147791478014781147821478314784147851478614787147881478914790147911479214793147941479514796147971479814799148001480114802148031480414805148061480714808148091481014811148121481314814148151481614817148181481914820148211482214823148241482514826148271482814829148301483114832148331483414835148361483714838148391484014841148421484314844148451484614847148481484914850148511485214853148541485514856148571485814859148601486114862148631486414865148661486714868148691487014871148721487314874148751487614877148781487914880148811488214883148841488514886148871488814889148901489114892148931489414895148961489714898148991490014901149021490314904149051490614907149081490914910149111491214913149141491514916149171491814919149201492114922149231492414925149261492714928149291493014931149321493314934149351493614937149381493914940149411494214943149441494514946149471494814949149501495114952149531495414955149561495714958149591496014961149621496314964149651496614967149681496914970149711497214973149741497514976149771497814979149801498114982149831498414985149861498714988149891499014991149921499314994149951499614997149981499915000150011500215003150041500515006150071500815009150101501115012150131501415015150161501715018150191502015021150221502315024150251502615027150281502915030150311503215033150341503515036150371503815039150401504115042150431504415045150461504715048150491505015051150521505315054150551505615057150581505915060150611506215063150641506515066150671506815069150701507115072150731507415075150761507715078150791508015081150821508315084150851508615087150881508915090150911509215093150941509515096150971509815099151001510115102151031510415105151061510715108151091511015111151121511315114151151511615117151181511915120151211512215123151241512515126151271512815129151301513115132151331513415135151361513715138151391514015141151421514315144151451514615147151481514915150151511515215153151541515515156151571515815159151601516115162151631516415165151661516715168151691517015171151721517315174151751517615177151781517915180151811518215183151841518515186151871518815189151901519115192151931519415195151961519715198151991520015201152021520315204152051520615207152081520915210152111521215213152141521515216152171521815219152201522115222152231522415225152261522715228152291523015231152321523315234152351523615237152381523915240152411524215243152441524515246152471524815249152501525115252152531525415255152561525715258152591526015261152621526315264152651526615267152681526915270152711527215273152741527515276152771527815279152801528115282152831528415285152861528715288152891529015291152921529315294152951529615297152981529915300153011530215303153041530515306153071530815309153101531115312153131531415315153161531715318153191532015321153221532315324153251532615327153281532915330153311533215333153341533515336153371533815339153401534115342153431534415345153461534715348153491535015351153521535315354153551535615357153581535915360153611536215363153641536515366153671536815369153701537115372153731537415375153761537715378153791538015381153821538315384153851538615387153881538915390153911539215393153941539515396153971539815399154001540115402154031540415405154061540715408154091541015411154121541315414154151541615417154181541915420154211542215423154241542515426154271542815429154301543115432154331543415435154361543715438154391544015441154421544315444154451544615447154481544915450154511545215453154541545515456154571545815459154601546115462154631546415465154661546715468154691547015471154721547315474154751547615477154781547915480154811548215483154841548515486154871548815489154901549115492154931549415495154961549715498154991550015501155021550315504155051550615507155081550915510155111551215513155141551515516155171551815519155201552115522155231552415525155261552715528155291553015531155321553315534155351553615537155381553915540155411554215543155441554515546155471554815549155501555115552155531555415555155561555715558155591556015561155621556315564155651556615567155681556915570155711557215573155741557515576155771557815579155801558115582155831558415585155861558715588155891559015591155921559315594155951559615597155981559915600156011560215603156041560515606156071560815609156101561115612156131561415615156161561715618156191562015621156221562315624156251562615627156281562915630156311563215633156341563515636156371563815639156401564115642156431564415645156461564715648156491565015651156521565315654156551565615657156581565915660156611566215663156641566515666156671566815669156701567115672156731567415675156761567715678156791568015681156821568315684156851568615687156881568915690156911569215693156941569515696156971569815699157001570115702157031570415705157061570715708157091571015711157121571315714157151571615717157181571915720157211572215723157241572515726157271572815729157301573115732157331573415735157361573715738157391574015741157421574315744157451574615747157481574915750157511575215753157541575515756157571575815759157601576115762157631576415765157661576715768157691577015771157721577315774157751577615777157781577915780157811578215783157841578515786157871578815789157901579115792157931579415795157961579715798157991580015801158021580315804158051580615807158081580915810158111581215813158141581515816158171581815819158201582115822158231582415825158261582715828158291583015831158321583315834158351583615837158381583915840158411584215843158441584515846158471584815849158501585115852158531585415855158561585715858158591586015861158621586315864158651586615867158681586915870158711587215873158741587515876158771587815879158801588115882158831588415885158861588715888158891589015891158921589315894158951589615897158981589915900159011590215903159041590515906159071590815909159101591115912159131591415915159161591715918159191592015921159221592315924159251592615927159281592915930159311593215933159341593515936159371593815939159401594115942159431594415945159461594715948159491595015951159521595315954159551595615957159581595915960159611596215963159641596515966159671596815969159701597115972159731597415975159761597715978159791598015981159821598315984159851598615987159881598915990159911599215993159941599515996159971599815999160001600116002160031600416005160061600716008160091601016011160121601316014160151601616017160181601916020160211602216023160241602516026160271602816029160301603116032160331603416035160361603716038160391604016041160421604316044160451604616047160481604916050160511605216053160541605516056160571605816059160601606116062160631606416065160661606716068160691607016071160721607316074160751607616077160781607916080160811608216083160841608516086160871608816089160901609116092160931609416095160961609716098160991610016101161021610316104161051610616107161081610916110161111611216113161141611516116161171611816119161201612116122161231612416125161261612716128161291613016131161321613316134161351613616137161381613916140161411614216143161441614516146161471614816149161501615116152161531615416155161561615716158161591616016161161621616316164161651616616167161681616916170161711617216173161741617516176161771617816179161801618116182161831618416185161861618716188161891619016191161921619316194161951619616197161981619916200162011620216203162041620516206162071620816209162101621116212162131621416215162161621716218162191622016221162221622316224162251622616227162281622916230162311623216233162341623516236162371623816239162401624116242162431624416245162461624716248162491625016251162521625316254162551625616257162581625916260162611626216263162641626516266162671626816269162701627116272162731627416275162761627716278162791628016281162821628316284162851628616287162881628916290162911629216293162941629516296162971629816299163001630116302163031630416305163061630716308163091631016311163121631316314163151631616317163181631916320163211632216323163241632516326163271632816329163301633116332163331633416335163361633716338163391634016341163421634316344163451634616347163481634916350163511635216353163541635516356163571635816359163601636116362163631636416365163661636716368163691637016371163721637316374163751637616377163781637916380163811638216383163841638516386163871638816389163901639116392163931639416395163961639716398163991640016401164021640316404164051640616407164081640916410164111641216413164141641516416164171641816419164201642116422164231642416425164261642716428164291643016431164321643316434164351643616437164381643916440164411644216443164441644516446164471644816449164501645116452164531645416455164561645716458164591646016461164621646316464164651646616467164681646916470164711647216473164741647516476164771647816479164801648116482164831648416485164861648716488164891649016491164921649316494164951649616497164981649916500165011650216503165041650516506165071650816509165101651116512165131651416515165161651716518165191652016521165221652316524165251652616527165281652916530165311653216533165341653516536165371653816539165401654116542165431654416545165461654716548165491655016551165521655316554165551655616557165581655916560165611656216563165641656516566165671656816569165701657116572165731657416575165761657716578165791658016581165821658316584165851658616587165881658916590165911659216593165941659516596165971659816599166001660116602166031660416605166061660716608166091661016611166121661316614166151661616617166181661916620166211662216623166241662516626166271662816629166301663116632166331663416635166361663716638166391664016641166421664316644166451664616647166481664916650166511665216653166541665516656166571665816659166601666116662166631666416665166661666716668166691667016671166721667316674166751667616677166781667916680166811668216683166841668516686166871668816689166901669116692166931669416695166961669716698166991670016701167021670316704167051670616707167081670916710167111671216713167141671516716167171671816719167201672116722167231672416725167261672716728167291673016731167321673316734167351673616737167381673916740167411674216743167441674516746167471674816749167501675116752167531675416755167561675716758167591676016761167621676316764167651676616767167681676916770167711677216773167741677516776167771677816779167801678116782167831678416785167861678716788167891679016791167921679316794167951679616797167981679916800168011680216803168041680516806168071680816809168101681116812168131681416815168161681716818168191682016821168221682316824168251682616827168281682916830168311683216833168341683516836168371683816839168401684116842168431684416845168461684716848168491685016851168521685316854168551685616857168581685916860168611686216863168641686516866168671686816869168701687116872168731687416875168761687716878168791688016881168821688316884168851688616887168881688916890168911689216893168941689516896168971689816899169001690116902169031690416905169061690716908169091691016911169121691316914169151691616917169181691916920169211692216923169241692516926169271692816929169301693116932169331693416935169361693716938169391694016941169421694316944169451694616947169481694916950169511695216953169541695516956169571695816959169601696116962169631696416965169661696716968169691697016971169721697316974169751697616977169781697916980169811698216983169841698516986169871698816989169901699116992169931699416995169961699716998169991700017001170021700317004170051700617007170081700917010170111701217013170141701517016170171701817019170201702117022170231702417025170261702717028170291703017031170321703317034170351703617037170381703917040170411704217043170441704517046170471704817049170501705117052170531705417055170561705717058170591706017061170621706317064170651706617067170681706917070170711707217073170741707517076170771707817079170801708117082170831708417085170861708717088170891709017091170921709317094170951709617097170981709917100171011710217103171041710517106171071710817109171101711117112171131711417115171161711717118171191712017121171221712317124171251712617127171281712917130171311713217133171341713517136171371713817139171401714117142171431714417145171461714717148171491715017151171521715317154171551715617157171581715917160171611716217163171641716517166171671716817169171701717117172171731717417175171761717717178171791718017181171821718317184171851718617187171881718917190171911719217193171941719517196171971719817199172001720117202172031720417205172061720717208172091721017211172121721317214172151721617217172181721917220172211722217223172241722517226172271722817229172301723117232172331723417235172361723717238172391724017241172421724317244172451724617247172481724917250172511725217253172541725517256172571725817259172601726117262172631726417265172661726717268172691727017271172721727317274172751727617277172781727917280172811728217283172841728517286172871728817289172901729117292172931729417295172961729717298172991730017301173021730317304173051730617307173081730917310173111731217313173141731517316173171731817319173201732117322173231732417325173261732717328173291733017331173321733317334173351733617337173381733917340173411734217343173441734517346173471734817349173501735117352173531735417355173561735717358173591736017361173621736317364173651736617367173681736917370173711737217373173741737517376173771737817379173801738117382173831738417385173861738717388173891739017391173921739317394173951739617397173981739917400174011740217403174041740517406174071740817409174101741117412174131741417415174161741717418174191742017421174221742317424174251742617427174281742917430174311743217433174341743517436174371743817439174401744117442174431744417445174461744717448174491745017451174521745317454174551745617457174581745917460174611746217463174641746517466174671746817469174701747117472174731747417475174761747717478174791748017481174821748317484174851748617487174881748917490174911749217493174941749517496174971749817499175001750117502175031750417505175061750717508175091751017511175121751317514175151751617517175181751917520175211752217523175241752517526175271752817529175301753117532175331753417535175361753717538175391754017541175421754317544175451754617547175481754917550175511755217553175541755517556175571755817559175601756117562175631756417565175661756717568175691757017571175721757317574175751757617577175781757917580175811758217583175841758517586175871758817589175901759117592175931759417595175961759717598175991760017601176021760317604176051760617607176081760917610176111761217613176141761517616176171761817619176201762117622176231762417625176261762717628176291763017631176321763317634176351763617637176381763917640176411764217643176441764517646176471764817649176501765117652176531765417655176561765717658176591766017661176621766317664176651766617667176681766917670176711767217673176741767517676176771767817679176801768117682176831768417685176861768717688176891769017691176921769317694176951769617697176981769917700177011770217703177041770517706177071770817709177101771117712177131771417715177161771717718177191772017721177221772317724177251772617727177281772917730177311773217733177341773517736177371773817739177401774117742177431774417745177461774717748177491775017751177521775317754177551775617757177581775917760177611776217763177641776517766177671776817769177701777117772177731777417775177761777717778177791778017781177821778317784177851778617787177881778917790177911779217793177941779517796177971779817799178001780117802178031780417805178061780717808178091781017811178121781317814178151781617817178181781917820178211782217823178241782517826178271782817829178301783117832178331783417835178361783717838178391784017841178421784317844178451784617847178481784917850178511785217853178541785517856178571785817859178601786117862178631786417865178661786717868178691787017871178721787317874178751787617877178781787917880178811788217883178841788517886178871788817889178901789117892178931789417895178961789717898178991790017901179021790317904179051790617907179081790917910179111791217913179141791517916179171791817919179201792117922179231792417925179261792717928179291793017931179321793317934179351793617937179381793917940179411794217943179441794517946179471794817949179501795117952179531795417955179561795717958179591796017961179621796317964179651796617967179681796917970179711797217973179741797517976179771797817979179801798117982179831798417985179861798717988179891799017991179921799317994179951799617997179981799918000180011800218003180041800518006180071800818009180101801118012180131801418015180161801718018180191802018021180221802318024180251802618027180281802918030180311803218033180341803518036180371803818039180401804118042180431804418045180461804718048180491805018051180521805318054180551805618057180581805918060180611806218063180641806518066180671806818069180701807118072180731807418075180761807718078180791808018081180821808318084180851808618087180881808918090180911809218093180941809518096180971809818099181001810118102181031810418105181061810718108181091811018111181121811318114181151811618117181181811918120181211812218123181241812518126181271812818129181301813118132181331813418135181361813718138181391814018141181421814318144181451814618147181481814918150181511815218153181541815518156181571815818159181601816118162181631816418165181661816718168181691817018171181721817318174181751817618177181781817918180181811818218183181841818518186181871818818189181901819118192181931819418195181961819718198181991820018201182021820318204182051820618207182081820918210182111821218213182141821518216182171821818219182201822118222182231822418225182261822718228182291823018231182321823318234182351823618237182381823918240182411824218243182441824518246182471824818249182501825118252182531825418255182561825718258182591826018261182621826318264182651826618267182681826918270182711827218273182741827518276182771827818279182801828118282182831828418285182861828718288182891829018291182921829318294182951829618297182981829918300183011830218303183041830518306183071830818309183101831118312183131831418315183161831718318183191832018321183221832318324183251832618327183281832918330183311833218333183341833518336183371833818339183401834118342183431834418345183461834718348183491835018351183521835318354183551835618357183581835918360183611836218363183641836518366183671836818369183701837118372183731837418375183761837718378183791838018381183821838318384183851838618387183881838918390183911839218393183941839518396183971839818399184001840118402184031840418405184061840718408184091841018411184121841318414184151841618417184181841918420184211842218423184241842518426184271842818429184301843118432184331843418435184361843718438184391844018441184421844318444184451844618447184481844918450184511845218453184541845518456184571845818459184601846118462184631846418465184661846718468184691847018471184721847318474184751847618477184781847918480184811848218483184841848518486184871848818489184901849118492184931849418495184961849718498184991850018501185021850318504185051850618507185081850918510185111851218513185141851518516185171851818519185201852118522185231852418525185261852718528185291853018531185321853318534185351853618537185381853918540185411854218543185441854518546185471854818549185501855118552185531855418555185561855718558185591856018561185621856318564185651856618567185681856918570185711857218573185741857518576185771857818579185801858118582185831858418585185861858718588185891859018591185921859318594185951859618597185981859918600186011860218603186041860518606186071860818609186101861118612186131861418615186161861718618186191862018621186221862318624186251862618627186281862918630186311863218633186341863518636186371863818639186401864118642186431864418645186461864718648186491865018651186521865318654186551865618657186581865918660186611866218663186641866518666186671866818669186701867118672186731867418675186761867718678186791868018681186821868318684186851868618687186881868918690186911869218693186941869518696186971869818699187001870118702187031870418705187061870718708187091871018711187121871318714187151871618717187181871918720187211872218723187241872518726187271872818729187301873118732187331873418735187361873718738187391874018741187421874318744187451874618747187481874918750187511875218753187541875518756187571875818759187601876118762187631876418765187661876718768187691877018771187721877318774187751877618777187781877918780187811878218783187841878518786187871878818789187901879118792187931879418795187961879718798187991880018801188021880318804188051880618807188081880918810188111881218813188141881518816188171881818819188201882118822188231882418825188261882718828188291883018831188321883318834188351883618837188381883918840188411884218843188441884518846188471884818849188501885118852188531885418855188561885718858188591886018861188621886318864188651886618867188681886918870188711887218873188741887518876188771887818879188801888118882188831888418885188861888718888188891889018891188921889318894188951889618897188981889918900189011890218903189041890518906189071890818909189101891118912189131891418915189161891718918189191892018921189221892318924189251892618927189281892918930189311893218933189341893518936189371893818939189401894118942189431894418945189461894718948189491895018951189521895318954189551895618957189581895918960189611896218963189641896518966189671896818969189701897118972189731897418975189761897718978189791898018981189821898318984189851898618987189881898918990189911899218993189941899518996189971899818999190001900119002190031900419005190061900719008190091901019011190121901319014190151901619017190181901919020190211902219023190241902519026190271902819029190301903119032190331903419035190361903719038190391904019041190421904319044190451904619047190481904919050190511905219053190541905519056190571905819059190601906119062190631906419065190661906719068190691907019071190721907319074190751907619077190781907919080190811908219083190841908519086190871908819089190901909119092190931909419095190961909719098190991910019101191021910319104191051910619107191081910919110191111911219113191141911519116191171911819119191201912119122191231912419125191261912719128191291913019131191321913319134191351913619137191381913919140191411914219143191441914519146191471914819149191501915119152191531915419155191561915719158191591916019161191621916319164191651916619167191681916919170191711917219173191741917519176191771917819179191801918119182191831918419185191861918719188191891919019191191921919319194191951919619197191981919919200192011920219203192041920519206192071920819209192101921119212192131921419215192161921719218192191922019221192221922319224192251922619227192281922919230192311923219233192341923519236192371923819239192401924119242192431924419245192461924719248192491925019251192521925319254192551925619257192581925919260192611926219263192641926519266192671926819269192701927119272192731927419275192761927719278192791928019281192821928319284192851928619287192881928919290192911929219293192941929519296192971929819299193001930119302193031930419305193061930719308193091931019311193121931319314193151931619317193181931919320193211932219323193241932519326193271932819329193301933119332193331933419335193361933719338193391934019341193421934319344193451934619347193481934919350193511935219353193541935519356193571935819359193601936119362193631936419365193661936719368193691937019371193721937319374193751937619377193781937919380193811938219383193841938519386193871938819389193901939119392193931939419395193961939719398193991940019401194021940319404194051940619407194081940919410194111941219413194141941519416194171941819419194201942119422194231942419425194261942719428194291943019431194321943319434194351943619437194381943919440194411944219443194441944519446194471944819449194501945119452194531945419455194561945719458194591946019461194621946319464194651946619467194681946919470194711947219473194741947519476194771947819479194801948119482194831948419485194861948719488194891949019491194921949319494194951949619497194981949919500195011950219503195041950519506195071950819509195101951119512195131951419515195161951719518195191952019521195221952319524195251952619527195281952919530195311953219533195341953519536195371953819539195401954119542195431954419545195461954719548195491955019551195521955319554195551955619557195581955919560195611956219563195641956519566195671956819569195701957119572195731957419575195761957719578195791958019581195821958319584195851958619587195881958919590195911959219593195941959519596195971959819599196001960119602196031960419605196061960719608196091961019611196121961319614196151961619617196181961919620196211962219623196241962519626196271962819629196301963119632196331963419635196361963719638196391964019641196421964319644196451964619647196481964919650196511965219653196541965519656196571965819659196601966119662196631966419665196661966719668196691967019671196721967319674196751967619677196781967919680196811968219683196841968519686196871968819689196901969119692196931969419695196961969719698196991970019701197021970319704197051970619707197081970919710197111971219713197141971519716197171971819719197201972119722197231972419725197261972719728197291973019731197321973319734197351973619737197381973919740197411974219743197441974519746197471974819749197501975119752197531975419755197561975719758197591976019761197621976319764197651976619767197681976919770197711977219773197741977519776197771977819779197801978119782197831978419785197861978719788197891979019791197921979319794197951979619797197981979919800198011980219803198041980519806198071980819809198101981119812198131981419815198161981719818198191982019821198221982319824198251982619827198281982919830198311983219833198341983519836198371983819839198401984119842198431984419845198461984719848198491985019851198521985319854198551985619857198581985919860198611986219863198641986519866198671986819869198701987119872198731987419875198761987719878198791988019881198821988319884198851988619887198881988919890198911989219893198941989519896198971989819899199001990119902199031990419905199061990719908199091991019911199121991319914199151991619917199181991919920199211992219923199241992519926199271992819929199301993119932199331993419935199361993719938199391994019941199421994319944199451994619947199481994919950199511995219953199541995519956199571995819959199601996119962199631996419965199661996719968199691997019971199721997319974199751997619977199781997919980199811998219983199841998519986199871998819989199901999119992199931999419995199961999719998199992000020001200022000320004200052000620007200082000920010200112001220013200142001520016200172001820019200202002120022200232002420025200262002720028200292003020031200322003320034200352003620037200382003920040200412004220043200442004520046200472004820049200502005120052200532005420055200562005720058200592006020061200622006320064200652006620067200682006920070200712007220073200742007520076200772007820079200802008120082200832008420085200862008720088200892009020091200922009320094200952009620097200982009920100201012010220103201042010520106201072010820109201102011120112201132011420115201162011720118201192012020121201222012320124201252012620127201282012920130201312013220133201342013520136201372013820139201402014120142201432014420145201462014720148201492015020151201522015320154201552015620157201582015920160201612016220163201642016520166201672016820169201702017120172201732017420175201762017720178201792018020181201822018320184201852018620187201882018920190201912019220193201942019520196201972019820199202002020120202202032020420205202062020720208202092021020211202122021320214202152021620217202182021920220202212022220223202242022520226202272022820229202302023120232202332023420235202362023720238202392024020241202422024320244202452024620247202482024920250202512025220253202542025520256202572025820259202602026120262202632026420265202662026720268202692027020271202722027320274202752027620277202782027920280202812028220283202842028520286202872028820289202902029120292202932029420295202962029720298202992030020301203022030320304203052030620307203082030920310203112031220313203142031520316203172031820319203202032120322203232032420325203262032720328203292033020331203322033320334203352033620337203382033920340203412034220343203442034520346203472034820349203502035120352203532035420355203562035720358203592036020361203622036320364203652036620367203682036920370203712037220373203742037520376203772037820379203802038120382203832038420385203862038720388203892039020391203922039320394203952039620397203982039920400204012040220403204042040520406204072040820409204102041120412204132041420415204162041720418204192042020421204222042320424204252042620427204282042920430204312043220433204342043520436204372043820439204402044120442204432044420445204462044720448204492045020451204522045320454204552045620457204582045920460204612046220463204642046520466204672046820469204702047120472204732047420475204762047720478204792048020481204822048320484204852048620487204882048920490204912049220493204942049520496204972049820499205002050120502205032050420505205062050720508205092051020511205122051320514205152051620517205182051920520205212052220523205242052520526205272052820529205302053120532205332053420535205362053720538205392054020541205422054320544205452054620547205482054920550205512055220553205542055520556205572055820559205602056120562205632056420565205662056720568205692057020571205722057320574205752057620577205782057920580205812058220583205842058520586205872058820589205902059120592205932059420595205962059720598205992060020601206022060320604206052060620607206082060920610206112061220613206142061520616206172061820619206202062120622206232062420625206262062720628206292063020631206322063320634206352063620637206382063920640206412064220643206442064520646206472064820649206502065120652206532065420655206562065720658206592066020661206622066320664206652066620667206682066920670206712067220673206742067520676206772067820679206802068120682206832068420685206862068720688206892069020691206922069320694206952069620697206982069920700207012070220703207042070520706207072070820709207102071120712207132071420715207162071720718207192072020721207222072320724207252072620727207282072920730207312073220733207342073520736207372073820739207402074120742207432074420745207462074720748207492075020751207522075320754207552075620757207582075920760207612076220763207642076520766207672076820769207702077120772207732077420775207762077720778207792078020781207822078320784207852078620787207882078920790207912079220793207942079520796207972079820799208002080120802208032080420805208062080720808208092081020811208122081320814208152081620817208182081920820208212082220823208242082520826208272082820829208302083120832208332083420835208362083720838208392084020841208422084320844208452084620847208482084920850208512085220853208542085520856208572085820859208602086120862208632086420865208662086720868208692087020871208722087320874208752087620877208782087920880208812088220883208842088520886208872088820889208902089120892208932089420895208962089720898208992090020901209022090320904209052090620907209082090920910209112091220913209142091520916209172091820919209202092120922209232092420925209262092720928209292093020931209322093320934209352093620937209382093920940209412094220943209442094520946209472094820949209502095120952209532095420955209562095720958209592096020961209622096320964209652096620967209682096920970209712097220973209742097520976209772097820979209802098120982209832098420985209862098720988209892099020991209922099320994209952099620997209982099921000210012100221003210042100521006210072100821009210102101121012210132101421015210162101721018210192102021021210222102321024210252102621027210282102921030210312103221033210342103521036210372103821039210402104121042210432104421045210462104721048210492105021051210522105321054210552105621057210582105921060210612106221063210642106521066210672106821069210702107121072210732107421075210762107721078210792108021081210822108321084210852108621087210882108921090210912109221093210942109521096210972109821099211002110121102211032110421105211062110721108211092111021111211122111321114211152111621117211182111921120211212112221123211242112521126211272112821129211302113121132211332113421135211362113721138211392114021141211422114321144211452114621147211482114921150211512115221153211542115521156211572115821159211602116121162211632116421165211662116721168211692117021171211722117321174211752117621177211782117921180211812118221183211842118521186211872118821189211902119121192211932119421195211962119721198211992120021201212022120321204212052120621207212082120921210212112121221213212142121521216212172121821219212202122121222212232122421225212262122721228212292123021231212322123321234212352123621237212382123921240212412124221243212442124521246212472124821249212502125121252212532125421255212562125721258212592126021261212622126321264212652126621267212682126921270212712127221273212742127521276212772127821279212802128121282212832128421285212862128721288212892129021291212922129321294212952129621297212982129921300213012130221303213042130521306213072130821309213102131121312213132131421315213162131721318213192132021321213222132321324213252132621327213282132921330213312133221333213342133521336213372133821339213402134121342213432134421345213462134721348213492135021351213522135321354213552135621357213582135921360213612136221363213642136521366213672136821369213702137121372213732137421375213762137721378213792138021381213822138321384213852138621387213882138921390213912139221393213942139521396213972139821399214002140121402214032140421405214062140721408214092141021411214122141321414214152141621417214182141921420214212142221423214242142521426214272142821429214302143121432214332143421435214362143721438214392144021441214422144321444214452144621447214482144921450214512145221453214542145521456214572145821459214602146121462214632146421465214662146721468214692147021471214722147321474214752147621477214782147921480214812148221483214842148521486214872148821489214902149121492214932149421495214962149721498214992150021501215022150321504215052150621507215082150921510215112151221513215142151521516215172151821519215202152121522215232152421525215262152721528215292153021531215322153321534215352153621537215382153921540215412154221543215442154521546215472154821549215502155121552215532155421555215562155721558215592156021561215622156321564215652156621567215682156921570215712157221573215742157521576215772157821579215802158121582215832158421585215862158721588215892159021591215922159321594215952159621597215982159921600216012160221603216042160521606216072160821609216102161121612216132161421615216162161721618216192162021621216222162321624216252162621627216282162921630216312163221633216342163521636216372163821639216402164121642216432164421645216462164721648216492165021651216522165321654216552165621657216582165921660216612166221663216642166521666216672166821669216702167121672216732167421675216762167721678216792168021681216822168321684216852168621687216882168921690216912169221693216942169521696216972169821699217002170121702217032170421705217062170721708217092171021711217122171321714217152171621717217182171921720217212172221723217242172521726217272172821729217302173121732217332173421735217362173721738217392174021741217422174321744217452174621747217482174921750217512175221753217542175521756217572175821759217602176121762217632176421765217662176721768217692177021771217722177321774217752177621777217782177921780217812178221783217842178521786217872178821789217902179121792217932179421795217962179721798217992180021801218022180321804218052180621807218082180921810218112181221813218142181521816218172181821819218202182121822218232182421825218262182721828218292183021831218322183321834218352183621837218382183921840218412184221843218442184521846218472184821849218502185121852218532185421855218562185721858218592186021861218622186321864218652186621867218682186921870218712187221873218742187521876218772187821879218802188121882218832188421885218862188721888218892189021891218922189321894218952189621897218982189921900219012190221903219042190521906219072190821909219102191121912219132191421915219162191721918219192192021921219222192321924219252192621927219282192921930219312193221933219342193521936219372193821939219402194121942219432194421945219462194721948219492195021951219522195321954219552195621957219582195921960219612196221963219642196521966219672196821969219702197121972219732197421975219762197721978219792198021981219822198321984219852198621987219882198921990219912199221993219942199521996219972199821999220002200122002220032200422005220062200722008220092201022011220122201322014220152201622017220182201922020220212202222023220242202522026220272202822029220302203122032220332203422035220362203722038220392204022041220422204322044220452204622047220482204922050220512205222053220542205522056220572205822059220602206122062220632206422065220662206722068220692207022071220722207322074220752207622077220782207922080220812208222083220842208522086220872208822089220902209122092220932209422095220962209722098220992210022101221022210322104221052210622107221082210922110221112211222113221142211522116221172211822119221202212122122221232212422125221262212722128221292213022131221322213322134221352213622137221382213922140221412214222143221442214522146221472214822149221502215122152221532215422155221562215722158221592216022161221622216322164221652216622167221682216922170221712217222173221742217522176221772217822179221802218122182221832218422185221862218722188221892219022191221922219322194221952219622197221982219922200222012220222203222042220522206222072220822209222102221122212222132221422215222162221722218222192222022221222222222322224222252222622227222282222922230222312223222233222342223522236222372223822239222402224122242222432224422245222462224722248222492225022251222522225322254222552225622257222582225922260222612226222263222642226522266222672226822269222702227122272222732227422275222762227722278222792228022281222822228322284222852228622287222882228922290222912229222293222942229522296222972229822299223002230122302223032230422305223062230722308223092231022311223122231322314223152231622317223182231922320223212232222323223242232522326223272232822329223302233122332223332233422335223362233722338223392234022341223422234322344223452234622347223482234922350223512235222353223542235522356223572235822359223602236122362223632236422365223662236722368223692237022371223722237322374223752237622377223782237922380223812238222383223842238522386223872238822389223902239122392223932239422395223962239722398223992240022401224022240322404224052240622407224082240922410224112241222413224142241522416224172241822419224202242122422224232242422425224262242722428224292243022431224322243322434224352243622437224382243922440224412244222443224442244522446224472244822449224502245122452224532245422455224562245722458224592246022461224622246322464224652246622467224682246922470224712247222473224742247522476224772247822479224802248122482224832248422485224862248722488224892249022491224922249322494224952249622497224982249922500225012250222503225042250522506225072250822509225102251122512225132251422515225162251722518225192252022521225222252322524225252252622527225282252922530225312253222533225342253522536225372253822539225402254122542225432254422545225462254722548225492255022551225522255322554225552255622557225582255922560225612256222563225642256522566225672256822569225702257122572225732257422575225762257722578225792258022581225822258322584225852258622587225882258922590225912259222593225942259522596225972259822599226002260122602226032260422605226062260722608226092261022611226122261322614226152261622617226182261922620226212262222623226242262522626226272262822629226302263122632226332263422635226362263722638226392264022641226422264322644226452264622647226482264922650226512265222653226542265522656226572265822659226602266122662226632266422665226662266722668226692267022671226722267322674226752267622677226782267922680226812268222683226842268522686226872268822689226902269122692226932269422695226962269722698226992270022701227022270322704227052270622707227082270922710227112271222713227142271522716227172271822719227202272122722227232272422725227262272722728227292273022731227322273322734227352273622737227382273922740227412274222743227442274522746227472274822749227502275122752227532275422755227562275722758227592276022761227622276322764227652276622767227682276922770227712277222773227742277522776227772277822779227802278122782227832278422785227862278722788227892279022791227922279322794227952279622797227982279922800228012280222803228042280522806228072280822809228102281122812228132281422815228162281722818228192282022821228222282322824228252282622827228282282922830228312283222833228342283522836228372283822839228402284122842228432284422845228462284722848228492285022851228522285322854228552285622857228582285922860228612286222863228642286522866228672286822869228702287122872228732287422875228762287722878228792288022881228822288322884228852288622887228882288922890228912289222893228942289522896228972289822899229002290122902229032290422905229062290722908229092291022911229122291322914229152291622917229182291922920229212292222923229242292522926229272292822929229302293122932229332293422935229362293722938229392294022941229422294322944229452294622947229482294922950229512295222953229542295522956229572295822959229602296122962229632296422965229662296722968229692297022971229722297322974229752297622977229782297922980229812298222983229842298522986229872298822989229902299122992229932299422995229962299722998229992300023001230022300323004230052300623007230082300923010230112301223013230142301523016230172301823019230202302123022230232302423025230262302723028230292303023031230322303323034230352303623037230382303923040230412304223043230442304523046230472304823049230502305123052230532305423055230562305723058230592306023061230622306323064230652306623067230682306923070230712307223073230742307523076230772307823079230802308123082230832308423085230862308723088230892309023091230922309323094230952309623097230982309923100231012310223103231042310523106231072310823109231102311123112231132311423115231162311723118231192312023121231222312323124231252312623127231282312923130231312313223133231342313523136231372313823139231402314123142231432314423145231462314723148231492315023151231522315323154231552315623157231582315923160231612316223163231642316523166231672316823169231702317123172231732317423175231762317723178231792318023181231822318323184231852318623187231882318923190231912319223193231942319523196231972319823199232002320123202232032320423205232062320723208232092321023211232122321323214232152321623217232182321923220232212322223223232242322523226232272322823229232302323123232232332323423235232362323723238232392324023241232422324323244232452324623247232482324923250232512325223253232542325523256232572325823259232602326123262232632326423265232662326723268232692327023271232722327323274232752327623277232782327923280232812328223283232842328523286232872328823289232902329123292232932329423295232962329723298232992330023301233022330323304233052330623307233082330923310233112331223313233142331523316233172331823319233202332123322233232332423325233262332723328233292333023331233322333323334233352333623337233382333923340233412334223343233442334523346233472334823349233502335123352233532335423355233562335723358233592336023361233622336323364233652336623367233682336923370233712337223373233742337523376233772337823379233802338123382233832338423385233862338723388233892339023391233922339323394233952339623397233982339923400234012340223403234042340523406234072340823409234102341123412234132341423415234162341723418234192342023421234222342323424234252342623427234282342923430234312343223433234342343523436234372343823439234402344123442234432344423445234462344723448234492345023451234522345323454234552345623457234582345923460234612346223463234642346523466234672346823469234702347123472234732347423475234762347723478234792348023481234822348323484234852348623487234882348923490234912349223493234942349523496234972349823499235002350123502235032350423505235062350723508235092351023511235122351323514235152351623517235182351923520235212352223523235242352523526235272352823529235302353123532235332353423535235362353723538235392354023541235422354323544235452354623547235482354923550235512355223553235542355523556235572355823559235602356123562235632356423565235662356723568235692357023571235722357323574235752357623577235782357923580235812358223583235842358523586235872358823589235902359123592235932359423595235962359723598235992360023601236022360323604236052360623607236082360923610236112361223613236142361523616236172361823619236202362123622236232362423625236262362723628236292363023631236322363323634236352363623637236382363923640236412364223643236442364523646236472364823649236502365123652236532365423655236562365723658236592366023661236622366323664236652366623667236682366923670236712367223673236742367523676236772367823679236802368123682236832368423685236862368723688236892369023691236922369323694236952369623697236982369923700237012370223703237042370523706237072370823709237102371123712237132371423715237162371723718237192372023721237222372323724237252372623727237282372923730237312373223733237342373523736237372373823739237402374123742237432374423745237462374723748237492375023751237522375323754237552375623757237582375923760237612376223763237642376523766237672376823769237702377123772237732377423775237762377723778237792378023781237822378323784237852378623787237882378923790237912379223793237942379523796237972379823799238002380123802238032380423805238062380723808238092381023811238122381323814238152381623817238182381923820238212382223823238242382523826238272382823829238302383123832238332383423835238362383723838238392384023841238422384323844238452384623847238482384923850238512385223853238542385523856238572385823859238602386123862238632386423865238662386723868238692387023871238722387323874238752387623877238782387923880238812388223883238842388523886238872388823889238902389123892238932389423895238962389723898238992390023901239022390323904239052390623907239082390923910239112391223913239142391523916239172391823919239202392123922239232392423925239262392723928239292393023931239322393323934239352393623937239382393923940239412394223943239442394523946239472394823949239502395123952239532395423955239562395723958239592396023961239622396323964239652396623967239682396923970239712397223973239742397523976239772397823979239802398123982239832398423985239862398723988239892399023991239922399323994239952399623997239982399924000240012400224003240042400524006240072400824009240102401124012240132401424015240162401724018240192402024021240222402324024240252402624027240282402924030240312403224033240342403524036240372403824039240402404124042240432404424045240462404724048240492405024051240522405324054240552405624057240582405924060240612406224063240642406524066240672406824069240702407124072240732407424075240762407724078240792408024081240822408324084240852408624087240882408924090240912409224093240942409524096240972409824099241002410124102241032410424105241062410724108241092411024111241122411324114241152411624117241182411924120241212412224123241242412524126241272412824129241302413124132241332413424135241362413724138241392414024141241422414324144241452414624147241482414924150241512415224153241542415524156241572415824159241602416124162241632416424165241662416724168241692417024171241722417324174241752417624177241782417924180241812418224183241842418524186241872418824189241902419124192241932419424195241962419724198241992420024201242022420324204242052420624207242082420924210242112421224213242142421524216242172421824219242202422124222242232422424225242262422724228242292423024231242322423324234242352423624237242382423924240242412424224243242442424524246242472424824249242502425124252242532425424255242562425724258242592426024261242622426324264242652426624267242682426924270242712427224273242742427524276242772427824279242802428124282242832428424285242862428724288242892429024291242922429324294242952429624297242982429924300243012430224303243042430524306243072430824309243102431124312243132431424315243162431724318243192432024321243222432324324243252432624327243282432924330243312433224333243342433524336243372433824339243402434124342243432434424345243462434724348243492435024351243522435324354243552435624357243582435924360243612436224363243642436524366243672436824369243702437124372243732437424375243762437724378243792438024381243822438324384243852438624387243882438924390243912439224393243942439524396243972439824399244002440124402244032440424405244062440724408244092441024411244122441324414244152441624417244182441924420244212442224423244242442524426244272442824429244302443124432244332443424435244362443724438244392444024441244422444324444244452444624447244482444924450244512445224453244542445524456244572445824459244602446124462244632446424465244662446724468244692447024471244722447324474244752447624477244782447924480244812448224483244842448524486244872448824489244902449124492244932449424495244962449724498244992450024501245022450324504245052450624507245082450924510245112451224513245142451524516245172451824519245202452124522245232452424525245262452724528245292453024531245322453324534245352453624537245382453924540245412454224543245442454524546245472454824549245502455124552245532455424555245562455724558245592456024561245622456324564245652456624567245682456924570245712457224573245742457524576245772457824579245802458124582245832458424585245862458724588245892459024591245922459324594245952459624597245982459924600246012460224603246042460524606246072460824609246102461124612246132461424615246162461724618246192462024621246222462324624246252462624627246282462924630246312463224633246342463524636246372463824639246402464124642246432464424645246462464724648246492465024651246522465324654246552465624657246582465924660246612466224663246642466524666246672466824669246702467124672246732467424675246762467724678246792468024681246822468324684246852468624687246882468924690246912469224693246942469524696246972469824699247002470124702247032470424705247062470724708247092471024711247122471324714247152471624717247182471924720247212472224723247242472524726247272472824729247302473124732247332473424735247362473724738247392474024741247422474324744247452474624747247482474924750247512475224753247542475524756247572475824759247602476124762247632476424765247662476724768247692477024771247722477324774247752477624777247782477924780247812478224783247842478524786247872478824789247902479124792247932479424795247962479724798247992480024801248022480324804248052480624807248082480924810248112481224813248142481524816248172481824819248202482124822248232482424825248262482724828248292483024831248322483324834248352483624837248382483924840248412484224843248442484524846248472484824849248502485124852248532485424855248562485724858248592486024861248622486324864248652486624867248682486924870248712487224873248742487524876248772487824879248802488124882248832488424885248862488724888248892489024891248922489324894248952489624897248982489924900249012490224903249042490524906249072490824909249102491124912249132491424915249162491724918249192492024921249222492324924249252492624927249282492924930249312493224933249342493524936249372493824939249402494124942249432494424945249462494724948249492495024951249522495324954249552495624957249582495924960249612496224963249642496524966249672496824969249702497124972249732497424975249762497724978249792498024981249822498324984249852498624987249882498924990249912499224993249942499524996249972499824999250002500125002250032500425005250062500725008250092501025011250122501325014250152501625017250182501925020250212502225023250242502525026250272502825029250302503125032250332503425035250362503725038250392504025041250422504325044250452504625047250482504925050250512505225053250542505525056250572505825059250602506125062250632506425065250662506725068250692507025071250722507325074250752507625077250782507925080250812508225083250842508525086250872508825089250902509125092250932509425095250962509725098250992510025101251022510325104251052510625107251082510925110251112511225113251142511525116251172511825119251202512125122251232512425125251262512725128251292513025131251322513325134251352513625137251382513925140251412514225143251442514525146251472514825149251502515125152251532515425155251562515725158251592516025161251622516325164251652516625167251682516925170251712517225173251742517525176251772517825179251802518125182251832518425185251862518725188251892519025191251922519325194251952519625197251982519925200252012520225203252042520525206252072520825209252102521125212252132521425215252162521725218252192522025221252222522325224252252522625227252282522925230252312523225233252342523525236252372523825239252402524125242252432524425245252462524725248252492525025251252522525325254252552525625257252582525925260252612526225263252642526525266252672526825269252702527125272252732527425275252762527725278252792528025281252822528325284252852528625287252882528925290252912529225293252942529525296252972529825299253002530125302253032530425305253062530725308253092531025311253122531325314253152531625317253182531925320253212532225323253242532525326253272532825329253302533125332253332533425335253362533725338253392534025341253422534325344253452534625347253482534925350253512535225353253542535525356253572535825359253602536125362253632536425365253662536725368253692537025371253722537325374253752537625377253782537925380253812538225383253842538525386253872538825389253902539125392253932539425395253962539725398253992540025401254022540325404254052540625407254082540925410254112541225413254142541525416254172541825419254202542125422254232542425425254262542725428254292543025431254322543325434254352543625437254382543925440254412544225443254442544525446254472544825449254502545125452254532545425455254562545725458254592546025461254622546325464254652546625467254682546925470254712547225473254742547525476254772547825479254802548125482254832548425485254862548725488254892549025491254922549325494254952549625497254982549925500255012550225503255042550525506255072550825509255102551125512255132551425515255162551725518255192552025521255222552325524255252552625527255282552925530255312553225533255342553525536255372553825539255402554125542255432554425545255462554725548255492555025551255522555325554255552555625557255582555925560255612556225563255642556525566255672556825569255702557125572255732557425575255762557725578255792558025581255822558325584255852558625587255882558925590255912559225593255942559525596255972559825599256002560125602256032560425605256062560725608256092561025611256122561325614256152561625617256182561925620256212562225623256242562525626256272562825629256302563125632256332563425635256362563725638256392564025641256422564325644256452564625647256482564925650256512565225653256542565525656256572565825659256602566125662256632566425665256662566725668256692567025671256722567325674256752567625677256782567925680256812568225683256842568525686256872568825689256902569125692256932569425695256962569725698256992570025701257022570325704257052570625707257082570925710257112571225713257142571525716257172571825719257202572125722257232572425725257262572725728257292573025731257322573325734257352573625737257382573925740257412574225743257442574525746257472574825749257502575125752257532575425755257562575725758257592576025761257622576325764257652576625767257682576925770257712577225773257742577525776257772577825779257802578125782257832578425785257862578725788257892579025791257922579325794257952579625797257982579925800258012580225803258042580525806258072580825809258102581125812258132581425815258162581725818258192582025821258222582325824258252582625827258282582925830258312583225833258342583525836258372583825839258402584125842258432584425845258462584725848258492585025851258522585325854258552585625857258582585925860258612586225863258642586525866258672586825869258702587125872258732587425875258762587725878258792588025881258822588325884258852588625887258882588925890258912589225893258942589525896258972589825899259002590125902259032590425905259062590725908259092591025911259122591325914259152591625917259182591925920259212592225923259242592525926259272592825929259302593125932259332593425935259362593725938259392594025941259422594325944259452594625947259482594925950259512595225953259542595525956259572595825959259602596125962259632596425965259662596725968259692597025971259722597325974259752597625977259782597925980259812598225983259842598525986259872598825989259902599125992259932599425995259962599725998259992600026001260022600326004260052600626007260082600926010260112601226013260142601526016260172601826019260202602126022260232602426025260262602726028260292603026031260322603326034260352603626037260382603926040260412604226043260442604526046260472604826049260502605126052260532605426055260562605726058260592606026061260622606326064260652606626067260682606926070260712607226073260742607526076260772607826079260802608126082260832608426085260862608726088260892609026091260922609326094260952609626097260982609926100261012610226103261042610526106261072610826109261102611126112261132611426115261162611726118261192612026121261222612326124261252612626127261282612926130261312613226133261342613526136261372613826139261402614126142261432614426145261462614726148261492615026151261522615326154261552615626157261582615926160261612616226163261642616526166261672616826169261702617126172261732617426175261762617726178261792618026181261822618326184261852618626187261882618926190261912619226193261942619526196261972619826199262002620126202262032620426205262062620726208262092621026211262122621326214262152621626217262182621926220262212622226223262242622526226262272622826229262302623126232262332623426235262362623726238262392624026241262422624326244262452624626247262482624926250262512625226253262542625526256262572625826259262602626126262262632626426265262662626726268262692627026271262722627326274262752627626277262782627926280262812628226283262842628526286262872628826289262902629126292262932629426295262962629726298262992630026301263022630326304263052630626307263082630926310263112631226313263142631526316263172631826319263202632126322263232632426325263262632726328263292633026331263322633326334263352633626337263382633926340263412634226343263442634526346263472634826349263502635126352263532635426355263562635726358263592636026361263622636326364263652636626367263682636926370263712637226373263742637526376263772637826379263802638126382263832638426385263862638726388263892639026391263922639326394263952639626397263982639926400264012640226403264042640526406264072640826409264102641126412264132641426415264162641726418264192642026421264222642326424264252642626427264282642926430264312643226433264342643526436264372643826439264402644126442264432644426445264462644726448264492645026451264522645326454264552645626457264582645926460264612646226463264642646526466264672646826469264702647126472264732647426475264762647726478264792648026481264822648326484264852648626487264882648926490264912649226493264942649526496264972649826499265002650126502265032650426505265062650726508265092651026511265122651326514265152651626517265182651926520265212652226523265242652526526265272652826529265302653126532265332653426535265362653726538265392654026541265422654326544265452654626547265482654926550265512655226553265542655526556265572655826559265602656126562265632656426565265662656726568265692657026571265722657326574265752657626577265782657926580265812658226583265842658526586265872658826589265902659126592265932659426595265962659726598265992660026601266022660326604266052660626607266082660926610266112661226613266142661526616266172661826619266202662126622266232662426625266262662726628266292663026631266322663326634266352663626637266382663926640266412664226643266442664526646266472664826649266502665126652266532665426655266562665726658266592666026661266622666326664266652666626667266682666926670266712667226673266742667526676266772667826679266802668126682266832668426685266862668726688266892669026691266922669326694266952669626697266982669926700267012670226703267042670526706267072670826709267102671126712267132671426715267162671726718267192672026721267222672326724267252672626727267282672926730267312673226733267342673526736267372673826739267402674126742267432674426745267462674726748267492675026751267522675326754267552675626757267582675926760267612676226763267642676526766267672676826769267702677126772267732677426775267762677726778267792678026781267822678326784267852678626787267882678926790267912679226793267942679526796267972679826799268002680126802268032680426805268062680726808268092681026811268122681326814268152681626817268182681926820268212682226823268242682526826268272682826829268302683126832268332683426835268362683726838268392684026841268422684326844268452684626847268482684926850268512685226853268542685526856268572685826859268602686126862268632686426865268662686726868268692687026871268722687326874268752687626877268782687926880268812688226883268842688526886268872688826889268902689126892268932689426895268962689726898268992690026901269022690326904269052690626907269082690926910269112691226913269142691526916269172691826919269202692126922269232692426925269262692726928269292693026931269322693326934269352693626937269382693926940269412694226943269442694526946269472694826949269502695126952269532695426955269562695726958269592696026961269622696326964269652696626967269682696926970269712697226973269742697526976269772697826979269802698126982269832698426985269862698726988269892699026991269922699326994269952699626997269982699927000270012700227003270042700527006270072700827009270102701127012270132701427015270162701727018270192702027021270222702327024270252702627027270282702927030270312703227033270342703527036270372703827039270402704127042270432704427045270462704727048270492705027051270522705327054270552705627057270582705927060270612706227063270642706527066270672706827069270702707127072270732707427075270762707727078270792708027081270822708327084270852708627087270882708927090270912709227093270942709527096270972709827099271002710127102271032710427105271062710727108271092711027111271122711327114271152711627117271182711927120271212712227123271242712527126271272712827129271302713127132271332713427135271362713727138271392714027141271422714327144271452714627147271482714927150271512715227153271542715527156271572715827159271602716127162271632716427165271662716727168271692717027171271722717327174271752717627177271782717927180271812718227183271842718527186271872718827189271902719127192271932719427195271962719727198271992720027201272022720327204272052720627207272082720927210272112721227213272142721527216272172721827219272202722127222272232722427225272262722727228272292723027231272322723327234272352723627237272382723927240272412724227243272442724527246272472724827249272502725127252272532725427255272562725727258272592726027261272622726327264272652726627267272682726927270272712727227273272742727527276272772727827279272802728127282272832728427285272862728727288272892729027291272922729327294272952729627297272982729927300273012730227303273042730527306273072730827309273102731127312273132731427315273162731727318273192732027321273222732327324273252732627327273282732927330273312733227333273342733527336273372733827339273402734127342273432734427345273462734727348273492735027351273522735327354273552735627357273582735927360273612736227363273642736527366273672736827369273702737127372273732737427375273762737727378273792738027381273822738327384273852738627387273882738927390273912739227393273942739527396273972739827399274002740127402274032740427405274062740727408274092741027411274122741327414274152741627417274182741927420274212742227423274242742527426274272742827429274302743127432274332743427435274362743727438274392744027441274422744327444274452744627447274482744927450274512745227453274542745527456274572745827459274602746127462274632746427465274662746727468274692747027471274722747327474274752747627477274782747927480274812748227483274842748527486274872748827489274902749127492274932749427495274962749727498274992750027501275022750327504275052750627507275082750927510275112751227513275142751527516275172751827519275202752127522275232752427525275262752727528275292753027531275322753327534275352753627537275382753927540275412754227543275442754527546275472754827549275502755127552275532755427555275562755727558275592756027561275622756327564275652756627567275682756927570275712757227573275742757527576275772757827579275802758127582275832758427585275862758727588275892759027591275922759327594275952759627597275982759927600276012760227603276042760527606276072760827609276102761127612276132761427615276162761727618276192762027621276222762327624276252762627627276282762927630276312763227633276342763527636276372763827639276402764127642276432764427645276462764727648276492765027651276522765327654276552765627657276582765927660276612766227663276642766527666276672766827669276702767127672276732767427675276762767727678276792768027681276822768327684276852768627687276882768927690276912769227693276942769527696276972769827699277002770127702277032770427705277062770727708277092771027711277122771327714277152771627717277182771927720277212772227723277242772527726277272772827729277302773127732277332773427735277362773727738277392774027741277422774327744277452774627747277482774927750277512775227753277542775527756277572775827759277602776127762277632776427765277662776727768277692777027771277722777327774277752777627777277782777927780277812778227783277842778527786277872778827789277902779127792277932779427795277962779727798277992780027801278022780327804278052780627807278082780927810278112781227813278142781527816278172781827819278202782127822278232782427825278262782727828278292783027831278322783327834278352783627837278382783927840278412784227843278442784527846278472784827849278502785127852278532785427855278562785727858278592786027861278622786327864278652786627867278682786927870278712787227873278742787527876278772787827879278802788127882278832788427885278862788727888278892789027891278922789327894278952789627897278982789927900279012790227903279042790527906279072790827909279102791127912279132791427915279162791727918279192792027921279222792327924279252792627927279282792927930279312793227933279342793527936279372793827939279402794127942279432794427945279462794727948279492795027951279522795327954279552795627957279582795927960279612796227963279642796527966279672796827969279702797127972279732797427975279762797727978279792798027981279822798327984279852798627987279882798927990279912799227993279942799527996279972799827999280002800128002280032800428005280062800728008280092801028011280122801328014280152801628017280182801928020280212802228023280242802528026280272802828029280302803128032280332803428035280362803728038280392804028041280422804328044280452804628047280482804928050280512805228053280542805528056280572805828059280602806128062280632806428065280662806728068280692807028071280722807328074280752807628077280782807928080280812808228083280842808528086280872808828089280902809128092280932809428095280962809728098280992810028101281022810328104281052810628107281082810928110281112811228113281142811528116281172811828119281202812128122281232812428125281262812728128281292813028131281322813328134281352813628137281382813928140281412814228143281442814528146281472814828149281502815128152281532815428155281562815728158281592816028161281622816328164281652816628167281682816928170281712817228173281742817528176281772817828179281802818128182281832818428185281862818728188281892819028191281922819328194281952819628197281982819928200282012820228203282042820528206282072820828209282102821128212282132821428215282162821728218282192822028221282222822328224282252822628227282282822928230282312823228233282342823528236282372823828239282402824128242282432824428245282462824728248282492825028251282522825328254282552825628257282582825928260282612826228263282642826528266282672826828269282702827128272282732827428275282762827728278282792828028281282822828328284282852828628287282882828928290282912829228293282942829528296282972829828299283002830128302283032830428305283062830728308283092831028311283122831328314283152831628317283182831928320283212832228323283242832528326283272832828329283302833128332283332833428335283362833728338283392834028341283422834328344283452834628347283482834928350283512835228353283542835528356283572835828359283602836128362283632836428365283662836728368283692837028371283722837328374283752837628377283782837928380283812838228383283842838528386283872838828389283902839128392283932839428395283962839728398283992840028401284022840328404284052840628407284082840928410284112841228413284142841528416284172841828419284202842128422284232842428425284262842728428284292843028431284322843328434284352843628437284382843928440284412844228443284442844528446284472844828449284502845128452284532845428455284562845728458284592846028461284622846328464284652846628467284682846928470284712847228473284742847528476284772847828479284802848128482284832848428485284862848728488284892849028491284922849328494284952849628497284982849928500285012850228503285042850528506285072850828509285102851128512285132851428515285162851728518285192852028521285222852328524285252852628527285282852928530285312853228533285342853528536285372853828539285402854128542285432854428545285462854728548285492855028551285522855328554285552855628557285582855928560285612856228563285642856528566285672856828569285702857128572285732857428575285762857728578285792858028581285822858328584285852858628587285882858928590285912859228593285942859528596285972859828599286002860128602286032860428605286062860728608286092861028611286122861328614286152861628617286182861928620286212862228623286242862528626286272862828629286302863128632286332863428635286362863728638286392864028641286422864328644286452864628647286482864928650286512865228653286542865528656286572865828659286602866128662286632866428665286662866728668286692867028671286722867328674286752867628677286782867928680286812868228683286842868528686286872868828689286902869128692286932869428695286962869728698286992870028701287022870328704287052870628707287082870928710287112871228713287142871528716287172871828719287202872128722287232872428725287262872728728287292873028731287322873328734287352873628737287382873928740287412874228743287442874528746287472874828749287502875128752287532875428755287562875728758287592876028761287622876328764287652876628767287682876928770287712877228773287742877528776287772877828779287802878128782287832878428785287862878728788287892879028791287922879328794287952879628797287982879928800288012880228803288042880528806288072880828809288102881128812288132881428815288162881728818288192882028821288222882328824288252882628827288282882928830288312883228833288342883528836288372883828839288402884128842288432884428845288462884728848288492885028851288522885328854288552885628857288582885928860288612886228863288642886528866288672886828869288702887128872288732887428875288762887728878288792888028881288822888328884288852888628887288882888928890288912889228893288942889528896288972889828899289002890128902289032890428905289062890728908289092891028911289122891328914289152891628917289182891928920289212892228923289242892528926289272892828929289302893128932289332893428935289362893728938289392894028941289422894328944289452894628947289482894928950289512895228953289542895528956289572895828959289602896128962289632896428965289662896728968289692897028971289722897328974289752897628977289782897928980289812898228983289842898528986289872898828989289902899128992289932899428995289962899728998289992900029001290022900329004290052900629007290082900929010290112901229013290142901529016290172901829019290202902129022290232902429025290262902729028290292903029031290322903329034290352903629037290382903929040290412904229043290442904529046290472904829049290502905129052290532905429055290562905729058290592906029061290622906329064290652906629067290682906929070290712907229073290742907529076290772907829079290802908129082290832908429085290862908729088290892909029091290922909329094290952909629097290982909929100291012910229103291042910529106291072910829109291102911129112291132911429115291162911729118291192912029121291222912329124291252912629127291282912929130291312913229133291342913529136291372913829139291402914129142291432914429145291462914729148291492915029151291522915329154291552915629157291582915929160291612916229163291642916529166291672916829169291702917129172291732917429175291762917729178291792918029181291822918329184291852918629187291882918929190291912919229193291942919529196291972919829199292002920129202292032920429205292062920729208292092921029211292122921329214292152921629217292182921929220292212922229223292242922529226292272922829229292302923129232292332923429235292362923729238292392924029241292422924329244292452924629247292482924929250292512925229253292542925529256292572925829259292602926129262292632926429265292662926729268292692927029271292722927329274292752927629277292782927929280292812928229283292842928529286292872928829289292902929129292292932929429295292962929729298292992930029301293022930329304293052930629307293082930929310293112931229313293142931529316293172931829319293202932129322293232932429325293262932729328293292933029331293322933329334293352933629337293382933929340293412934229343293442934529346293472934829349293502935129352293532935429355293562935729358293592936029361293622936329364293652936629367293682936929370293712937229373293742937529376293772937829379293802938129382293832938429385293862938729388293892939029391293922939329394293952939629397293982939929400294012940229403294042940529406294072940829409294102941129412294132941429415294162941729418294192942029421294222942329424294252942629427294282942929430294312943229433294342943529436294372943829439294402944129442294432944429445294462944729448294492945029451294522945329454294552945629457294582945929460294612946229463294642946529466294672946829469294702947129472294732947429475294762947729478294792948029481294822948329484294852948629487294882948929490294912949229493294942949529496294972949829499295002950129502295032950429505295062950729508295092951029511295122951329514295152951629517295182951929520295212952229523295242952529526295272952829529295302953129532295332953429535295362953729538295392954029541295422954329544295452954629547295482954929550295512955229553295542955529556295572955829559295602956129562295632956429565295662956729568295692957029571295722957329574295752957629577295782957929580295812958229583295842958529586295872958829589295902959129592295932959429595295962959729598295992960029601296022960329604296052960629607296082960929610296112961229613296142961529616296172961829619296202962129622296232962429625296262962729628296292963029631296322963329634296352963629637296382963929640296412964229643296442964529646296472964829649296502965129652296532965429655296562965729658296592966029661296622966329664296652966629667296682966929670296712967229673296742967529676296772967829679296802968129682296832968429685296862968729688296892969029691296922969329694296952969629697296982969929700297012970229703297042970529706297072970829709297102971129712297132971429715297162971729718297192972029721297222972329724297252972629727297282972929730297312973229733297342973529736297372973829739297402974129742297432974429745297462974729748297492975029751297522975329754297552975629757297582975929760297612976229763297642976529766297672976829769297702977129772297732977429775297762977729778297792978029781297822978329784297852978629787297882978929790297912979229793297942979529796297972979829799298002980129802298032980429805298062980729808298092981029811298122981329814298152981629817298182981929820298212982229823298242982529826298272982829829298302983129832298332983429835298362983729838298392984029841298422984329844298452984629847298482984929850298512985229853298542985529856298572985829859298602986129862298632986429865298662986729868298692987029871298722987329874298752987629877298782987929880298812988229883298842988529886298872988829889298902989129892298932989429895298962989729898298992990029901299022990329904299052990629907299082990929910299112991229913299142991529916299172991829919299202992129922299232992429925299262992729928299292993029931299322993329934299352993629937299382993929940299412994229943299442994529946299472994829949299502995129952299532995429955299562995729958299592996029961299622996329964299652996629967299682996929970299712997229973299742997529976299772997829979299802998129982299832998429985299862998729988299892999029991299922999329994299952999629997299982999930000300013000230003300043000530006300073000830009300103001130012300133001430015300163001730018300193002030021300223002330024300253002630027300283002930030300313003230033300343003530036300373003830039300403004130042300433004430045300463004730048300493005030051300523005330054300553005630057300583005930060300613006230063300643006530066300673006830069300703007130072300733007430075300763007730078300793008030081300823008330084300853008630087300883008930090300913009230093300943009530096300973009830099301003010130102301033010430105301063010730108301093011030111301123011330114301153011630117301183011930120301213012230123301243012530126301273012830129301303013130132301333013430135301363013730138301393014030141301423014330144301453014630147301483014930150301513015230153301543015530156301573015830159301603016130162301633016430165301663016730168301693017030171301723017330174301753017630177301783017930180301813018230183301843018530186301873018830189301903019130192301933019430195301963019730198301993020030201302023020330204302053020630207302083020930210302113021230213302143021530216302173021830219302203022130222302233022430225302263022730228302293023030231302323023330234302353023630237302383023930240302413024230243302443024530246302473024830249302503025130252302533025430255302563025730258302593026030261302623026330264302653026630267302683026930270302713027230273302743027530276302773027830279302803028130282302833028430285302863028730288302893029030291302923029330294302953029630297302983029930300303013030230303303043030530306303073030830309303103031130312303133031430315303163031730318303193032030321303223032330324303253032630327303283032930330303313033230333303343033530336303373033830339303403034130342303433034430345303463034730348303493035030351303523035330354303553035630357303583035930360303613036230363303643036530366303673036830369303703037130372303733037430375303763037730378303793038030381303823038330384303853038630387303883038930390303913039230393303943039530396303973039830399304003040130402304033040430405304063040730408304093041030411304123041330414304153041630417304183041930420304213042230423304243042530426304273042830429304303043130432304333043430435304363043730438304393044030441304423044330444304453044630447304483044930450304513045230453304543045530456304573045830459304603046130462304633046430465304663046730468304693047030471304723047330474304753047630477304783047930480304813048230483304843048530486304873048830489304903049130492304933049430495304963049730498304993050030501305023050330504305053050630507305083050930510305113051230513305143051530516305173051830519305203052130522305233052430525305263052730528305293053030531305323053330534305353053630537305383053930540305413054230543305443054530546305473054830549305503055130552305533055430555305563055730558305593056030561305623056330564305653056630567305683056930570305713057230573305743057530576305773057830579305803058130582305833058430585305863058730588305893059030591305923059330594305953059630597305983059930600306013060230603306043060530606306073060830609306103061130612306133061430615306163061730618306193062030621306223062330624306253062630627306283062930630306313063230633306343063530636306373063830639306403064130642306433064430645306463064730648306493065030651306523065330654306553065630657306583065930660306613066230663306643066530666306673066830669306703067130672306733067430675306763067730678306793068030681306823068330684306853068630687306883068930690306913069230693306943069530696306973069830699307003070130702307033070430705307063070730708307093071030711307123071330714307153071630717307183071930720307213072230723307243072530726307273072830729307303073130732307333073430735307363073730738307393074030741307423074330744307453074630747307483074930750307513075230753307543075530756307573075830759307603076130762307633076430765307663076730768307693077030771307723077330774307753077630777307783077930780307813078230783307843078530786307873078830789307903079130792307933079430795307963079730798307993080030801308023080330804308053080630807308083080930810308113081230813308143081530816308173081830819308203082130822308233082430825308263082730828308293083030831308323083330834308353083630837308383083930840308413084230843308443084530846308473084830849308503085130852308533085430855308563085730858308593086030861308623086330864308653086630867308683086930870308713087230873308743087530876308773087830879308803088130882308833088430885308863088730888308893089030891308923089330894308953089630897308983089930900309013090230903309043090530906309073090830909309103091130912309133091430915309163091730918309193092030921309223092330924309253092630927309283092930930309313093230933309343093530936309373093830939309403094130942309433094430945309463094730948309493095030951309523095330954309553095630957309583095930960309613096230963309643096530966309673096830969309703097130972309733097430975309763097730978309793098030981309823098330984309853098630987309883098930990309913099230993309943099530996309973099830999310003100131002310033100431005310063100731008310093101031011310123101331014310153101631017310183101931020310213102231023310243102531026310273102831029310303103131032310333103431035310363103731038310393104031041310423104331044310453104631047310483104931050310513105231053310543105531056310573105831059310603106131062310633106431065310663106731068310693107031071310723107331074310753107631077310783107931080310813108231083310843108531086310873108831089310903109131092310933109431095310963109731098310993110031101311023110331104311053110631107311083110931110311113111231113311143111531116311173111831119311203112131122311233112431125311263112731128311293113031131311323113331134311353113631137311383113931140311413114231143311443114531146311473114831149311503115131152311533115431155311563115731158311593116031161311623116331164311653116631167311683116931170311713117231173311743117531176311773117831179311803118131182311833118431185311863118731188311893119031191311923119331194311953119631197311983119931200312013120231203312043120531206312073120831209312103121131212312133121431215312163121731218312193122031221312223122331224312253122631227312283122931230312313123231233312343123531236312373123831239312403124131242312433124431245312463124731248312493125031251312523125331254312553125631257312583125931260312613126231263312643126531266312673126831269312703127131272312733127431275312763127731278312793128031281312823128331284312853128631287312883128931290312913129231293312943129531296312973129831299313003130131302313033130431305313063130731308313093131031311313123131331314313153131631317313183131931320313213132231323313243132531326313273132831329313303133131332313333133431335313363133731338313393134031341313423134331344313453134631347313483134931350313513135231353313543135531356313573135831359313603136131362313633136431365313663136731368313693137031371313723137331374313753137631377313783137931380313813138231383313843138531386313873138831389313903139131392313933139431395313963139731398313993140031401314023140331404314053140631407314083140931410314113141231413314143141531416314173141831419314203142131422314233142431425314263142731428314293143031431314323143331434314353143631437314383143931440314413144231443314443144531446314473144831449314503145131452314533145431455314563145731458314593146031461314623146331464314653146631467314683146931470314713147231473314743147531476314773147831479314803148131482314833148431485314863148731488314893149031491314923149331494314953149631497314983149931500315013150231503315043150531506315073150831509315103151131512315133151431515315163151731518315193152031521315223152331524315253152631527315283152931530315313153231533315343153531536315373153831539315403154131542315433154431545315463154731548315493155031551315523155331554315553155631557315583155931560315613156231563315643156531566315673156831569315703157131572315733157431575315763157731578315793158031581315823158331584315853158631587315883158931590315913159231593315943159531596315973159831599316003160131602316033160431605316063160731608316093161031611316123161331614316153161631617316183161931620316213162231623316243162531626316273162831629316303163131632316333163431635316363163731638316393164031641316423164331644316453164631647316483164931650316513165231653316543165531656316573165831659316603166131662316633166431665316663166731668316693167031671316723167331674316753167631677316783167931680316813168231683316843168531686316873168831689316903169131692316933169431695316963169731698316993170031701317023170331704317053170631707317083170931710317113171231713317143171531716317173171831719317203172131722317233172431725317263172731728317293173031731317323173331734317353173631737317383173931740317413174231743317443174531746317473174831749317503175131752317533175431755317563175731758317593176031761317623176331764317653176631767317683176931770317713177231773317743177531776317773177831779317803178131782317833178431785317863178731788317893179031791317923179331794317953179631797317983179931800318013180231803318043180531806318073180831809318103181131812318133181431815318163181731818318193182031821318223182331824318253182631827318283182931830318313183231833318343183531836318373183831839318403184131842318433184431845318463184731848318493185031851318523185331854318553185631857318583185931860318613186231863318643186531866318673186831869318703187131872318733187431875318763187731878318793188031881318823188331884318853188631887318883188931890318913189231893318943189531896318973189831899319003190131902319033190431905319063190731908319093191031911319123191331914319153191631917319183191931920319213192231923319243192531926319273192831929319303193131932319333193431935319363193731938319393194031941319423194331944319453194631947319483194931950319513195231953319543195531956319573195831959319603196131962319633196431965319663196731968319693197031971319723197331974319753197631977319783197931980319813198231983319843198531986319873198831989319903199131992319933199431995319963199731998319993200032001320023200332004320053200632007320083200932010320113201232013320143201532016320173201832019320203202132022320233202432025320263202732028320293203032031320323203332034320353203632037320383203932040320413204232043320443204532046320473204832049320503205132052320533205432055320563205732058320593206032061320623206332064320653206632067320683206932070320713207232073320743207532076320773207832079320803208132082320833208432085320863208732088320893209032091320923209332094320953209632097320983209932100321013210232103321043210532106321073210832109321103211132112321133211432115321163211732118321193212032121321223212332124321253212632127321283212932130321313213232133321343213532136321373213832139321403214132142321433214432145321463214732148321493215032151321523215332154321553215632157321583215932160321613216232163321643216532166321673216832169321703217132172321733217432175321763217732178321793218032181321823218332184321853218632187321883218932190321913219232193321943219532196321973219832199322003220132202322033220432205322063220732208322093221032211322123221332214322153221632217322183221932220322213222232223322243222532226322273222832229322303223132232322333223432235322363223732238322393224032241322423224332244322453224632247322483224932250322513225232253322543225532256322573225832259322603226132262322633226432265322663226732268322693227032271322723227332274322753227632277322783227932280322813228232283322843228532286322873228832289322903229132292322933229432295322963229732298322993230032301323023230332304323053230632307323083230932310323113231232313323143231532316323173231832319323203232132322323233232432325323263232732328323293233032331323323233332334323353233632337323383233932340323413234232343323443234532346323473234832349323503235132352323533235432355323563235732358323593236032361323623236332364323653236632367323683236932370323713237232373323743237532376323773237832379323803238132382323833238432385323863238732388323893239032391323923239332394323953239632397323983239932400324013240232403324043240532406324073240832409324103241132412324133241432415324163241732418324193242032421324223242332424324253242632427324283242932430324313243232433324343243532436324373243832439324403244132442324433244432445324463244732448324493245032451324523245332454324553245632457324583245932460324613246232463324643246532466324673246832469324703247132472324733247432475324763247732478324793248032481324823248332484324853248632487324883248932490324913249232493324943249532496324973249832499325003250132502325033250432505325063250732508325093251032511325123251332514325153251632517325183251932520325213252232523325243252532526325273252832529325303253132532325333253432535325363253732538325393254032541325423254332544325453254632547325483254932550325513255232553325543255532556325573255832559325603256132562325633256432565325663256732568325693257032571325723257332574325753257632577325783257932580325813258232583325843258532586325873258832589325903259132592325933259432595325963259732598325993260032601326023260332604326053260632607326083260932610326113261232613326143261532616326173261832619326203262132622326233262432625326263262732628326293263032631326323263332634326353263632637326383263932640326413264232643326443264532646326473264832649326503265132652326533265432655326563265732658326593266032661326623266332664326653266632667326683266932670326713267232673326743267532676326773267832679326803268132682326833268432685326863268732688326893269032691326923269332694326953269632697326983269932700327013270232703327043270532706327073270832709327103271132712327133271432715327163271732718327193272032721327223272332724327253272632727327283272932730327313273232733327343273532736327373273832739327403274132742327433274432745327463274732748327493275032751327523275332754327553275632757327583275932760327613276232763327643276532766327673276832769327703277132772327733277432775327763277732778327793278032781327823278332784327853278632787327883278932790327913279232793327943279532796327973279832799328003280132802328033280432805328063280732808328093281032811328123281332814328153281632817328183281932820328213282232823328243282532826328273282832829328303283132832328333283432835328363283732838328393284032841328423284332844328453284632847328483284932850328513285232853328543285532856328573285832859328603286132862328633286432865328663286732868328693287032871328723287332874328753287632877328783287932880328813288232883328843288532886328873288832889328903289132892328933289432895328963289732898328993290032901329023290332904329053290632907329083290932910329113291232913329143291532916329173291832919329203292132922329233292432925329263292732928329293293032931329323293332934329353293632937329383293932940329413294232943329443294532946329473294832949329503295132952329533295432955329563295732958329593296032961329623296332964329653296632967329683296932970329713297232973329743297532976329773297832979329803298132982329833298432985329863298732988329893299032991329923299332994329953299632997329983299933000330013300233003330043300533006330073300833009330103301133012330133301433015330163301733018330193302033021330223302333024330253302633027330283302933030330313303233033330343303533036330373303833039330403304133042330433304433045330463304733048330493305033051330523305333054330553305633057330583305933060330613306233063330643306533066330673306833069330703307133072330733307433075330763307733078330793308033081330823308333084330853308633087330883308933090330913309233093330943309533096330973309833099331003310133102331033310433105331063310733108331093311033111331123311333114331153311633117331183311933120331213312233123331243312533126331273312833129331303313133132331333313433135331363313733138331393314033141331423314333144331453314633147331483314933150331513315233153331543315533156331573315833159331603316133162331633316433165331663316733168331693317033171331723317333174331753317633177331783317933180331813318233183331843318533186331873318833189331903319133192331933319433195331963319733198331993320033201332023320333204332053320633207332083320933210332113321233213332143321533216332173321833219332203322133222332233322433225332263322733228332293323033231332323323333234332353323633237332383323933240332413324233243332443324533246332473324833249332503325133252332533325433255332563325733258332593326033261332623326333264332653326633267332683326933270332713327233273332743327533276332773327833279332803328133282332833328433285332863328733288332893329033291332923329333294332953329633297332983329933300333013330233303333043330533306333073330833309333103331133312333133331433315333163331733318333193332033321333223332333324333253332633327333283332933330333313333233333333343333533336333373333833339333403334133342333433334433345333463334733348333493335033351333523335333354333553335633357333583335933360333613336233363333643336533366333673336833369333703337133372333733337433375333763337733378333793338033381333823338333384333853338633387333883338933390333913339233393333943339533396333973339833399334003340133402334033340433405334063340733408334093341033411334123341333414334153341633417334183341933420334213342233423334243342533426334273342833429334303343133432334333343433435334363343733438334393344033441334423344333444334453344633447334483344933450334513345233453334543345533456334573345833459334603346133462334633346433465334663346733468334693347033471334723347333474334753347633477334783347933480334813348233483334843348533486334873348833489334903349133492334933349433495334963349733498334993350033501335023350333504335053350633507335083350933510335113351233513335143351533516335173351833519335203352133522335233352433525335263352733528335293353033531335323353333534335353353633537335383353933540335413354233543335443354533546335473354833549335503355133552335533355433555335563355733558335593356033561335623356333564335653356633567335683356933570335713357233573335743357533576335773357833579335803358133582335833358433585335863358733588335893359033591335923359333594335953359633597335983359933600336013360233603336043360533606336073360833609336103361133612336133361433615336163361733618336193362033621336223362333624336253362633627336283362933630336313363233633336343363533636336373363833639336403364133642336433364433645336463364733648336493365033651336523365333654336553365633657336583365933660336613366233663336643366533666336673366833669336703367133672336733367433675336763367733678336793368033681336823368333684336853368633687336883368933690336913369233693336943369533696336973369833699337003370133702337033370433705337063370733708337093371033711337123371333714337153371633717337183371933720337213372233723337243372533726337273372833729337303373133732337333373433735337363373733738337393374033741337423374333744337453374633747337483374933750337513375233753337543375533756337573375833759337603376133762337633376433765337663376733768337693377033771337723377333774337753377633777337783377933780337813378233783337843378533786337873378833789337903379133792337933379433795337963379733798337993380033801338023380333804338053380633807338083380933810338113381233813338143381533816338173381833819338203382133822338233382433825338263382733828338293383033831338323383333834338353383633837338383383933840338413384233843338443384533846338473384833849338503385133852338533385433855338563385733858338593386033861338623386333864338653386633867338683386933870338713387233873338743387533876338773387833879338803388133882338833388433885338863388733888338893389033891338923389333894338953389633897338983389933900339013390233903339043390533906339073390833909339103391133912339133391433915339163391733918339193392033921339223392333924339253392633927339283392933930339313393233933339343393533936339373393833939339403394133942339433394433945339463394733948339493395033951339523395333954339553395633957339583395933960339613396233963339643396533966339673396833969339703397133972339733397433975339763397733978339793398033981339823398333984339853398633987339883398933990339913399233993339943399533996339973399833999340003400134002340033400434005340063400734008340093401034011340123401334014340153401634017340183401934020340213402234023340243402534026340273402834029340303403134032340333403434035340363403734038340393404034041340423404334044340453404634047340483404934050340513405234053340543405534056340573405834059340603406134062340633406434065340663406734068340693407034071340723407334074340753407634077340783407934080340813408234083340843408534086340873408834089340903409134092340933409434095340963409734098340993410034101341023410334104341053410634107341083410934110341113411234113341143411534116341173411834119341203412134122341233412434125341263412734128341293413034131341323413334134341353413634137341383413934140341413414234143341443414534146341473414834149341503415134152341533415434155341563415734158341593416034161341623416334164341653416634167341683416934170341713417234173341743417534176341773417834179341803418134182341833418434185341863418734188341893419034191341923419334194341953419634197341983419934200342013420234203342043420534206342073420834209342103421134212342133421434215342163421734218342193422034221342223422334224342253422634227342283422934230342313423234233342343423534236342373423834239342403424134242342433424434245342463424734248342493425034251342523425334254342553425634257342583425934260342613426234263342643426534266342673426834269342703427134272342733427434275342763427734278342793428034281342823428334284342853428634287342883428934290342913429234293342943429534296342973429834299343003430134302343033430434305343063430734308343093431034311343123431334314343153431634317343183431934320343213432234323343243432534326343273432834329343303433134332343333433434335343363433734338343393434034341343423434334344343453434634347343483434934350343513435234353343543435534356343573435834359343603436134362343633436434365343663436734368343693437034371343723437334374343753437634377343783437934380343813438234383343843438534386343873438834389343903439134392343933439434395343963439734398343993440034401344023440334404344053440634407344083440934410344113441234413344143441534416344173441834419344203442134422344233442434425344263442734428344293443034431344323443334434344353443634437344383443934440344413444234443344443444534446344473444834449344503445134452344533445434455344563445734458344593446034461344623446334464344653446634467344683446934470344713447234473344743447534476344773447834479344803448134482344833448434485344863448734488344893449034491344923449334494344953449634497344983449934500345013450234503345043450534506345073450834509345103451134512345133451434515345163451734518345193452034521345223452334524345253452634527345283452934530345313453234533345343453534536345373453834539345403454134542345433454434545345463454734548345493455034551345523455334554345553455634557345583455934560345613456234563345643456534566345673456834569345703457134572345733457434575345763457734578345793458034581345823458334584345853458634587345883458934590345913459234593345943459534596345973459834599346003460134602346033460434605346063460734608346093461034611346123461334614346153461634617346183461934620346213462234623346243462534626346273462834629346303463134632346333463434635346363463734638346393464034641346423464334644346453464634647346483464934650346513465234653346543465534656346573465834659346603466134662346633466434665346663466734668346693467034671346723467334674346753467634677346783467934680346813468234683346843468534686346873468834689346903469134692346933469434695346963469734698346993470034701347023470334704347053470634707347083470934710347113471234713347143471534716347173471834719347203472134722347233472434725347263472734728347293473034731347323473334734347353473634737347383473934740347413474234743347443474534746347473474834749347503475134752347533475434755347563475734758347593476034761347623476334764347653476634767347683476934770347713477234773347743477534776347773477834779347803478134782347833478434785347863478734788347893479034791347923479334794347953479634797347983479934800348013480234803348043480534806348073480834809348103481134812348133481434815348163481734818348193482034821348223482334824348253482634827348283482934830348313483234833348343483534836348373483834839348403484134842348433484434845348463484734848348493485034851348523485334854348553485634857348583485934860348613486234863348643486534866348673486834869348703487134872348733487434875348763487734878348793488034881348823488334884348853488634887348883488934890348913489234893348943489534896348973489834899349003490134902349033490434905349063490734908349093491034911349123491334914349153491634917349183491934920349213492234923349243492534926349273492834929349303493134932349333493434935349363493734938349393494034941349423494334944349453494634947349483494934950349513495234953349543495534956349573495834959349603496134962349633496434965349663496734968349693497034971349723497334974349753497634977349783497934980349813498234983349843498534986349873498834989349903499134992349933499434995349963499734998349993500035001350023500335004350053500635007350083500935010350113501235013350143501535016350173501835019350203502135022350233502435025350263502735028350293503035031350323503335034350353503635037350383503935040350413504235043350443504535046350473504835049350503505135052350533505435055350563505735058350593506035061350623506335064350653506635067350683506935070350713507235073350743507535076350773507835079350803508135082350833508435085350863508735088350893509035091350923509335094350953509635097350983509935100351013510235103351043510535106351073510835109351103511135112351133511435115351163511735118351193512035121351223512335124351253512635127351283512935130351313513235133351343513535136351373513835139351403514135142351433514435145351463514735148351493515035151351523515335154351553515635157351583515935160351613516235163351643516535166351673516835169351703517135172351733517435175351763517735178351793518035181351823518335184351853518635187351883518935190351913519235193351943519535196351973519835199352003520135202352033520435205352063520735208352093521035211352123521335214352153521635217352183521935220352213522235223352243522535226352273522835229352303523135232352333523435235352363523735238352393524035241352423524335244352453524635247352483524935250352513525235253352543525535256352573525835259352603526135262352633526435265352663526735268352693527035271352723527335274352753527635277352783527935280352813528235283352843528535286352873528835289352903529135292352933529435295352963529735298352993530035301353023530335304353053530635307353083530935310353113531235313353143531535316353173531835319353203532135322353233532435325353263532735328353293533035331353323533335334353353533635337353383533935340353413534235343353443534535346353473534835349353503535135352353533535435355353563535735358353593536035361353623536335364353653536635367353683536935370353713537235373353743537535376353773537835379353803538135382353833538435385353863538735388353893539035391353923539335394353953539635397353983539935400354013540235403354043540535406354073540835409354103541135412354133541435415354163541735418354193542035421354223542335424354253542635427354283542935430354313543235433354343543535436354373543835439354403544135442354433544435445354463544735448354493545035451354523545335454354553545635457354583545935460354613546235463354643546535466354673546835469354703547135472354733547435475354763547735478354793548035481354823548335484354853548635487354883548935490354913549235493354943549535496354973549835499355003550135502355033550435505355063550735508355093551035511355123551335514355153551635517355183551935520355213552235523355243552535526355273552835529355303553135532355333553435535355363553735538355393554035541355423554335544355453554635547355483554935550355513555235553355543555535556355573555835559355603556135562355633556435565355663556735568355693557035571355723557335574355753557635577355783557935580355813558235583355843558535586355873558835589355903559135592355933559435595355963559735598355993560035601356023560335604356053560635607356083560935610356113561235613356143561535616356173561835619356203562135622356233562435625356263562735628356293563035631356323563335634356353563635637356383563935640356413564235643356443564535646356473564835649356503565135652356533565435655356563565735658356593566035661356623566335664356653566635667356683566935670356713567235673356743567535676356773567835679356803568135682356833568435685356863568735688356893569035691356923569335694356953569635697356983569935700357013570235703357043570535706357073570835709357103571135712357133571435715357163571735718357193572035721357223572335724357253572635727357283572935730357313573235733357343573535736357373573835739357403574135742357433574435745357463574735748357493575035751357523575335754357553575635757357583575935760357613576235763357643576535766357673576835769357703577135772357733577435775357763577735778357793578035781357823578335784357853578635787357883578935790357913579235793357943579535796357973579835799358003580135802358033580435805358063580735808358093581035811358123581335814358153581635817358183581935820358213582235823358243582535826358273582835829358303583135832358333583435835358363583735838358393584035841358423584335844358453584635847358483584935850358513585235853358543585535856358573585835859358603586135862358633586435865358663586735868358693587035871358723587335874358753587635877358783587935880358813588235883358843588535886358873588835889358903589135892358933589435895358963589735898358993590035901359023590335904359053590635907359083590935910359113591235913359143591535916359173591835919359203592135922359233592435925359263592735928359293593035931359323593335934359353593635937359383593935940359413594235943359443594535946359473594835949359503595135952359533595435955359563595735958359593596035961359623596335964359653596635967359683596935970359713597235973359743597535976359773597835979359803598135982359833598435985359863598735988359893599035991359923599335994359953599635997359983599936000360013600236003360043600536006360073600836009360103601136012360133601436015360163601736018360193602036021360223602336024360253602636027360283602936030360313603236033360343603536036360373603836039360403604136042360433604436045360463604736048360493605036051360523605336054360553605636057360583605936060360613606236063360643606536066360673606836069360703607136072360733607436075360763607736078360793608036081360823608336084360853608636087360883608936090360913609236093360943609536096360973609836099361003610136102361033610436105361063610736108361093611036111361123611336114361153611636117361183611936120361213612236123361243612536126361273612836129361303613136132361333613436135361363613736138361393614036141361423614336144361453614636147361483614936150361513615236153361543615536156361573615836159361603616136162361633616436165361663616736168361693617036171361723617336174361753617636177361783617936180361813618236183361843618536186361873618836189361903619136192361933619436195361963619736198361993620036201362023620336204362053620636207362083620936210362113621236213362143621536216362173621836219362203622136222362233622436225362263622736228362293623036231362323623336234362353623636237362383623936240362413624236243362443624536246362473624836249362503625136252362533625436255362563625736258362593626036261362623626336264362653626636267362683626936270362713627236273362743627536276362773627836279362803628136282362833628436285362863628736288362893629036291362923629336294362953629636297362983629936300363013630236303363043630536306363073630836309363103631136312363133631436315363163631736318363193632036321363223632336324363253632636327363283632936330363313633236333363343633536336363373633836339363403634136342363433634436345363463634736348363493635036351363523635336354363553635636357363583635936360363613636236363363643636536366363673636836369363703637136372363733637436375363763637736378363793638036381363823638336384363853638636387363883638936390363913639236393363943639536396363973639836399364003640136402364033640436405364063640736408364093641036411364123641336414364153641636417364183641936420364213642236423364243642536426364273642836429364303643136432364333643436435364363643736438364393644036441364423644336444364453644636447364483644936450364513645236453364543645536456364573645836459364603646136462364633646436465364663646736468364693647036471364723647336474364753647636477364783647936480364813648236483364843648536486364873648836489364903649136492364933649436495364963649736498364993650036501365023650336504365053650636507365083650936510365113651236513365143651536516365173651836519365203652136522365233652436525365263652736528365293653036531365323653336534365353653636537365383653936540365413654236543365443654536546365473654836549365503655136552365533655436555365563655736558365593656036561365623656336564365653656636567365683656936570365713657236573365743657536576365773657836579365803658136582365833658436585365863658736588365893659036591365923659336594365953659636597365983659936600366013660236603366043660536606366073660836609366103661136612366133661436615366163661736618366193662036621366223662336624366253662636627366283662936630366313663236633366343663536636366373663836639366403664136642366433664436645366463664736648366493665036651366523665336654366553665636657366583665936660366613666236663366643666536666366673666836669366703667136672366733667436675366763667736678366793668036681366823668336684366853668636687366883668936690366913669236693366943669536696366973669836699367003670136702367033670436705367063670736708367093671036711367123671336714367153671636717367183671936720367213672236723367243672536726367273672836729367303673136732367333673436735367363673736738367393674036741367423674336744367453674636747367483674936750367513675236753367543675536756367573675836759367603676136762367633676436765367663676736768367693677036771367723677336774367753677636777367783677936780367813678236783367843678536786367873678836789367903679136792367933679436795367963679736798367993680036801368023680336804368053680636807368083680936810368113681236813368143681536816368173681836819368203682136822368233682436825368263682736828368293683036831368323683336834368353683636837368383683936840368413684236843368443684536846368473684836849368503685136852368533685436855368563685736858368593686036861368623686336864368653686636867368683686936870368713687236873368743687536876368773687836879368803688136882368833688436885368863688736888368893689036891368923689336894368953689636897368983689936900369013690236903369043690536906369073690836909369103691136912369133691436915369163691736918369193692036921369223692336924369253692636927369283692936930369313693236933369343693536936369373693836939369403694136942369433694436945369463694736948369493695036951369523695336954369553695636957369583695936960369613696236963369643696536966369673696836969369703697136972369733697436975369763697736978369793698036981369823698336984369853698636987369883698936990369913699236993369943699536996369973699836999370003700137002370033700437005370063700737008370093701037011370123701337014370153701637017370183701937020370213702237023370243702537026370273702837029370303703137032370333703437035370363703737038370393704037041370423704337044370453704637047370483704937050370513705237053370543705537056370573705837059370603706137062370633706437065370663706737068370693707037071370723707337074370753707637077370783707937080370813708237083370843708537086370873708837089370903709137092370933709437095370963709737098370993710037101371023710337104371053710637107371083710937110371113711237113371143711537116371173711837119371203712137122371233712437125371263712737128371293713037131371323713337134371353713637137371383713937140371413714237143371443714537146371473714837149371503715137152371533715437155371563715737158371593716037161371623716337164371653716637167371683716937170371713717237173371743717537176371773717837179371803718137182371833718437185371863718737188371893719037191371923719337194371953719637197371983719937200372013720237203372043720537206372073720837209372103721137212372133721437215372163721737218372193722037221372223722337224372253722637227372283722937230372313723237233372343723537236372373723837239372403724137242372433724437245372463724737248372493725037251372523725337254372553725637257372583725937260372613726237263372643726537266372673726837269372703727137272372733727437275372763727737278372793728037281372823728337284372853728637287372883728937290372913729237293372943729537296372973729837299373003730137302373033730437305373063730737308373093731037311373123731337314373153731637317373183731937320373213732237323373243732537326373273732837329373303733137332373333733437335373363733737338373393734037341373423734337344373453734637347373483734937350373513735237353373543735537356373573735837359373603736137362373633736437365373663736737368373693737037371373723737337374373753737637377373783737937380373813738237383373843738537386373873738837389373903739137392373933739437395373963739737398373993740037401374023740337404374053740637407374083740937410374113741237413374143741537416374173741837419374203742137422374233742437425374263742737428374293743037431374323743337434374353743637437374383743937440374413744237443374443744537446374473744837449374503745137452374533745437455374563745737458374593746037461374623746337464374653746637467374683746937470374713747237473374743747537476374773747837479374803748137482374833748437485374863748737488374893749037491374923749337494374953749637497374983749937500375013750237503375043750537506375073750837509375103751137512375133751437515375163751737518375193752037521375223752337524375253752637527375283752937530375313753237533375343753537536375373753837539375403754137542375433754437545375463754737548375493755037551375523755337554375553755637557375583755937560375613756237563375643756537566375673756837569375703757137572375733757437575375763757737578375793758037581375823758337584375853758637587375883758937590375913759237593375943759537596375973759837599376003760137602376033760437605376063760737608376093761037611376123761337614376153761637617376183761937620376213762237623376243762537626376273762837629376303763137632376333763437635376363763737638376393764037641376423764337644376453764637647376483764937650376513765237653376543765537656376573765837659376603766137662376633766437665376663766737668376693767037671376723767337674376753767637677376783767937680376813768237683376843768537686376873768837689376903769137692376933769437695376963769737698376993770037701377023770337704377053770637707377083770937710377113771237713377143771537716377173771837719377203772137722377233772437725377263772737728377293773037731377323773337734377353773637737377383773937740377413774237743377443774537746377473774837749377503775137752377533775437755377563775737758377593776037761377623776337764377653776637767377683776937770377713777237773377743777537776377773777837779377803778137782377833778437785377863778737788377893779037791377923779337794377953779637797377983779937800378013780237803378043780537806378073780837809378103781137812378133781437815378163781737818378193782037821378223782337824378253782637827378283782937830378313783237833378343783537836378373783837839378403784137842378433784437845378463784737848378493785037851378523785337854378553785637857378583785937860378613786237863378643786537866378673786837869378703787137872378733787437875378763787737878378793788037881378823788337884378853788637887378883788937890378913789237893378943789537896378973789837899379003790137902379033790437905379063790737908379093791037911379123791337914379153791637917379183791937920379213792237923379243792537926379273792837929379303793137932379333793437935379363793737938379393794037941379423794337944379453794637947379483794937950379513795237953379543795537956379573795837959379603796137962379633796437965379663796737968379693797037971379723797337974379753797637977379783797937980379813798237983379843798537986379873798837989379903799137992379933799437995379963799737998379993800038001380023800338004380053800638007380083800938010380113801238013380143801538016380173801838019380203802138022380233802438025380263802738028380293803038031380323803338034380353803638037380383803938040380413804238043380443804538046380473804838049380503805138052380533805438055380563805738058380593806038061380623806338064380653806638067380683806938070380713807238073380743807538076380773807838079380803808138082380833808438085380863808738088380893809038091380923809338094380953809638097380983809938100381013810238103381043810538106381073810838109381103811138112381133811438115381163811738118381193812038121381223812338124381253812638127381283812938130381313813238133381343813538136381373813838139381403814138142381433814438145381463814738148381493815038151381523815338154381553815638157381583815938160381613816238163381643816538166381673816838169381703817138172381733817438175381763817738178381793818038181381823818338184381853818638187381883818938190381913819238193381943819538196381973819838199382003820138202382033820438205382063820738208382093821038211382123821338214382153821638217382183821938220382213822238223382243822538226382273822838229382303823138232382333823438235382363823738238382393824038241382423824338244382453824638247382483824938250382513825238253382543825538256382573825838259382603826138262382633826438265382663826738268382693827038271382723827338274382753827638277382783827938280382813828238283382843828538286382873828838289382903829138292382933829438295382963829738298382993830038301383023830338304383053830638307383083830938310383113831238313383143831538316383173831838319383203832138322383233832438325383263832738328383293833038331383323833338334383353833638337383383833938340383413834238343383443834538346383473834838349383503835138352383533835438355383563835738358383593836038361383623836338364383653836638367383683836938370383713837238373383743837538376383773837838379383803838138382383833838438385383863838738388383893839038391383923839338394383953839638397383983839938400384013840238403384043840538406384073840838409384103841138412384133841438415384163841738418384193842038421384223842338424384253842638427384283842938430384313843238433384343843538436384373843838439384403844138442384433844438445384463844738448384493845038451384523845338454384553845638457384583845938460384613846238463384643846538466384673846838469384703847138472384733847438475384763847738478384793848038481384823848338484384853848638487384883848938490384913849238493384943849538496384973849838499385003850138502385033850438505385063850738508385093851038511385123851338514385153851638517385183851938520385213852238523385243852538526385273852838529385303853138532385333853438535385363853738538385393854038541385423854338544385453854638547385483854938550385513855238553385543855538556385573855838559385603856138562385633856438565385663856738568385693857038571385723857338574385753857638577385783857938580385813858238583385843858538586385873858838589385903859138592385933859438595385963859738598385993860038601386023860338604386053860638607386083860938610386113861238613386143861538616386173861838619386203862138622386233862438625386263862738628386293863038631386323863338634386353863638637386383863938640386413864238643386443864538646386473864838649386503865138652386533865438655386563865738658386593866038661386623866338664386653866638667386683866938670386713867238673386743867538676386773867838679386803868138682386833868438685386863868738688386893869038691386923869338694386953869638697386983869938700387013870238703387043870538706387073870838709387103871138712387133871438715387163871738718387193872038721387223872338724387253872638727387283872938730387313873238733387343873538736387373873838739387403874138742387433874438745387463874738748387493875038751387523875338754387553875638757387583875938760387613876238763387643876538766387673876838769387703877138772387733877438775387763877738778387793878038781387823878338784387853878638787387883878938790387913879238793387943879538796387973879838799388003880138802388033880438805388063880738808388093881038811388123881338814388153881638817388183881938820388213882238823388243882538826388273882838829388303883138832388333883438835388363883738838388393884038841388423884338844388453884638847388483884938850388513885238853388543885538856388573885838859388603886138862388633886438865388663886738868388693887038871388723887338874388753887638877388783887938880388813888238883388843888538886388873888838889388903889138892388933889438895388963889738898388993890038901389023890338904389053890638907389083890938910389113891238913389143891538916389173891838919389203892138922389233892438925389263892738928389293893038931389323893338934389353893638937389383893938940389413894238943389443894538946389473894838949389503895138952389533895438955389563895738958389593896038961389623896338964389653896638967389683896938970389713897238973389743897538976389773897838979389803898138982389833898438985389863898738988389893899038991389923899338994389953899638997389983899939000390013900239003390043900539006390073900839009390103901139012390133901439015390163901739018390193902039021390223902339024390253902639027390283902939030390313903239033390343903539036390373903839039390403904139042390433904439045390463904739048390493905039051390523905339054390553905639057390583905939060390613906239063390643906539066390673906839069390703907139072390733907439075390763907739078390793908039081390823908339084390853908639087390883908939090390913909239093390943909539096390973909839099391003910139102391033910439105391063910739108391093911039111391123911339114391153911639117391183911939120391213912239123391243912539126391273912839129391303913139132391333913439135391363913739138391393914039141391423914339144391453914639147391483914939150391513915239153391543915539156391573915839159391603916139162391633916439165391663916739168391693917039171391723917339174391753917639177391783917939180391813918239183391843918539186391873918839189391903919139192391933919439195391963919739198391993920039201392023920339204392053920639207392083920939210392113921239213392143921539216392173921839219392203922139222392233922439225392263922739228392293923039231392323923339234392353923639237392383923939240392413924239243392443924539246392473924839249392503925139252392533925439255392563925739258392593926039261392623926339264392653926639267392683926939270392713927239273392743927539276392773927839279392803928139282392833928439285392863928739288392893929039291392923929339294392953929639297392983929939300393013930239303393043930539306393073930839309393103931139312393133931439315393163931739318393193932039321393223932339324393253932639327393283932939330393313933239333393343933539336393373933839339393403934139342393433934439345393463934739348393493935039351393523935339354393553935639357393583935939360393613936239363393643936539366393673936839369393703937139372393733937439375393763937739378393793938039381393823938339384393853938639387393883938939390393913939239393393943939539396393973939839399394003940139402394033940439405394063940739408394093941039411394123941339414394153941639417394183941939420394213942239423394243942539426394273942839429394303943139432394333943439435394363943739438394393944039441394423944339444394453944639447394483944939450394513945239453394543945539456394573945839459394603946139462394633946439465394663946739468394693947039471394723947339474394753947639477394783947939480394813948239483394843948539486394873948839489394903949139492394933949439495394963949739498394993950039501395023950339504395053950639507395083950939510395113951239513395143951539516395173951839519395203952139522395233952439525395263952739528395293953039531395323953339534395353953639537395383953939540395413954239543395443954539546395473954839549395503955139552395533955439555395563955739558395593956039561395623956339564395653956639567395683956939570395713957239573395743957539576395773957839579395803958139582395833958439585395863958739588395893959039591395923959339594395953959639597395983959939600396013960239603396043960539606396073960839609396103961139612396133961439615396163961739618396193962039621396223962339624396253962639627396283962939630396313963239633396343963539636396373963839639396403964139642396433964439645396463964739648396493965039651396523965339654396553965639657396583965939660396613966239663396643966539666396673966839669396703967139672396733967439675396763967739678396793968039681396823968339684396853968639687396883968939690396913969239693396943969539696396973969839699397003970139702397033970439705397063970739708397093971039711397123971339714397153971639717397183971939720397213972239723397243972539726397273972839729397303973139732397333973439735397363973739738397393974039741397423974339744397453974639747397483974939750397513975239753397543975539756397573975839759397603976139762397633976439765397663976739768397693977039771397723977339774397753977639777397783977939780397813978239783397843978539786397873978839789397903979139792397933979439795397963979739798397993980039801398023980339804398053980639807398083980939810398113981239813398143981539816398173981839819398203982139822398233982439825398263982739828398293983039831398323983339834398353983639837398383983939840398413984239843398443984539846398473984839849398503985139852398533985439855398563985739858398593986039861398623986339864398653986639867398683986939870398713987239873398743987539876398773987839879398803988139882398833988439885398863988739888398893989039891398923989339894398953989639897398983989939900399013990239903399043990539906399073990839909399103991139912399133991439915399163991739918399193992039921399223992339924399253992639927399283992939930399313993239933399343993539936399373993839939399403994139942399433994439945399463994739948399493995039951399523995339954399553995639957399583995939960399613996239963399643996539966399673996839969399703997139972399733997439975399763997739978399793998039981399823998339984399853998639987399883998939990399913999239993399943999539996399973999839999400004000140002400034000440005400064000740008400094001040011400124001340014400154001640017400184001940020400214002240023400244002540026400274002840029400304003140032400334003440035400364003740038400394004040041400424004340044400454004640047400484004940050400514005240053400544005540056400574005840059400604006140062400634006440065400664006740068400694007040071400724007340074400754007640077400784007940080400814008240083400844008540086400874008840089400904009140092400934009440095400964009740098400994010040101401024010340104401054010640107401084010940110401114011240113401144011540116401174011840119401204012140122401234012440125401264012740128401294013040131401324013340134401354013640137401384013940140401414014240143401444014540146401474014840149401504015140152401534015440155401564015740158401594016040161401624016340164401654016640167401684016940170401714017240173401744017540176401774017840179401804018140182401834018440185401864018740188401894019040191401924019340194401954019640197401984019940200402014020240203402044020540206402074020840209402104021140212402134021440215402164021740218402194022040221402224022340224402254022640227402284022940230402314023240233402344023540236402374023840239402404024140242402434024440245402464024740248402494025040251402524025340254402554025640257402584025940260402614026240263402644026540266402674026840269402704027140272402734027440275402764027740278402794028040281402824028340284402854028640287402884028940290402914029240293402944029540296402974029840299403004030140302403034030440305403064030740308403094031040311403124031340314403154031640317403184031940320403214032240323403244032540326403274032840329403304033140332403334033440335403364033740338403394034040341403424034340344403454034640347403484034940350403514035240353403544035540356403574035840359403604036140362403634036440365403664036740368403694037040371403724037340374403754037640377403784037940380403814038240383403844038540386403874038840389403904039140392403934039440395403964039740398403994040040401404024040340404404054040640407404084040940410404114041240413404144041540416404174041840419404204042140422404234042440425404264042740428404294043040431404324043340434404354043640437404384043940440404414044240443404444044540446404474044840449404504045140452404534045440455404564045740458404594046040461404624046340464404654046640467404684046940470404714047240473404744047540476404774047840479404804048140482404834048440485404864048740488404894049040491404924049340494404954049640497404984049940500405014050240503405044050540506405074050840509405104051140512405134051440515405164051740518405194052040521405224052340524405254052640527405284052940530405314053240533405344053540536405374053840539405404054140542405434054440545405464054740548405494055040551405524055340554405554055640557405584055940560405614056240563405644056540566405674056840569405704057140572405734057440575405764057740578405794058040581405824058340584405854058640587405884058940590405914059240593405944059540596405974059840599406004060140602406034060440605406064060740608406094061040611406124061340614406154061640617406184061940620406214062240623406244062540626406274062840629406304063140632406334063440635406364063740638406394064040641406424064340644406454064640647406484064940650406514065240653406544065540656406574065840659406604066140662406634066440665406664066740668406694067040671406724067340674406754067640677406784067940680406814068240683406844068540686406874068840689406904069140692406934069440695406964069740698406994070040701407024070340704407054070640707407084070940710407114071240713407144071540716407174071840719407204072140722407234072440725407264072740728407294073040731407324073340734407354073640737407384073940740407414074240743407444074540746407474074840749407504075140752407534075440755407564075740758407594076040761407624076340764407654076640767407684076940770407714077240773407744077540776407774077840779407804078140782407834078440785407864078740788407894079040791407924079340794407954079640797407984079940800408014080240803408044080540806408074080840809408104081140812408134081440815408164081740818408194082040821408224082340824408254082640827408284082940830408314083240833408344083540836408374083840839408404084140842408434084440845408464084740848408494085040851408524085340854408554085640857408584085940860408614086240863408644086540866408674086840869408704087140872408734087440875408764087740878408794088040881408824088340884408854088640887408884088940890408914089240893408944089540896408974089840899409004090140902409034090440905409064090740908409094091040911409124091340914409154091640917409184091940920409214092240923409244092540926409274092840929409304093140932409334093440935409364093740938409394094040941409424094340944409454094640947409484094940950409514095240953409544095540956409574095840959409604096140962409634096440965409664096740968409694097040971409724097340974409754097640977409784097940980409814098240983409844098540986409874098840989409904099140992409934099440995409964099740998409994100041001410024100341004410054100641007410084100941010410114101241013410144101541016410174101841019410204102141022410234102441025410264102741028410294103041031410324103341034410354103641037410384103941040410414104241043410444104541046410474104841049410504105141052410534105441055410564105741058410594106041061410624106341064410654106641067410684106941070410714107241073410744107541076410774107841079410804108141082410834108441085410864108741088410894109041091410924109341094410954109641097410984109941100411014110241103411044110541106411074110841109411104111141112411134111441115411164111741118411194112041121411224112341124411254112641127411284112941130411314113241133411344113541136411374113841139411404114141142411434114441145411464114741148411494115041151411524115341154411554115641157411584115941160411614116241163411644116541166411674116841169411704117141172411734117441175411764117741178411794118041181411824118341184411854118641187411884118941190411914119241193411944119541196411974119841199412004120141202412034120441205412064120741208412094121041211412124121341214412154121641217412184121941220412214122241223412244122541226412274122841229412304123141232412334123441235412364123741238412394124041241412424124341244412454124641247412484124941250412514125241253412544125541256412574125841259412604126141262412634126441265412664126741268412694127041271412724127341274412754127641277412784127941280412814128241283412844128541286412874128841289412904129141292412934129441295412964129741298412994130041301413024130341304413054130641307413084130941310413114131241313413144131541316413174131841319413204132141322413234132441325413264132741328413294133041331413324133341334413354133641337413384133941340413414134241343413444134541346413474134841349413504135141352413534135441355413564135741358413594136041361413624136341364413654136641367413684136941370413714137241373413744137541376413774137841379413804138141382413834138441385413864138741388413894139041391413924139341394413954139641397413984139941400414014140241403414044140541406414074140841409414104141141412414134141441415414164141741418414194142041421414224142341424414254142641427414284142941430414314143241433414344143541436414374143841439414404144141442414434144441445414464144741448414494145041451414524145341454414554145641457414584145941460414614146241463414644146541466414674146841469414704147141472414734147441475414764147741478414794148041481414824148341484414854148641487414884148941490414914149241493414944149541496414974149841499415004150141502415034150441505415064150741508415094151041511415124151341514415154151641517415184151941520415214152241523415244152541526415274152841529415304153141532415334153441535415364153741538415394154041541415424154341544415454154641547415484154941550415514155241553415544155541556415574155841559415604156141562415634156441565415664156741568415694157041571415724157341574415754157641577415784157941580415814158241583415844158541586415874158841589415904159141592415934159441595415964159741598415994160041601416024160341604416054160641607416084160941610416114161241613416144161541616416174161841619416204162141622416234162441625416264162741628416294163041631416324163341634416354163641637416384163941640416414164241643416444164541646416474164841649416504165141652416534165441655416564165741658416594166041661416624166341664416654166641667416684166941670416714167241673416744167541676416774167841679416804168141682416834168441685416864168741688416894169041691416924169341694416954169641697416984169941700417014170241703417044170541706417074170841709417104171141712417134171441715417164171741718417194172041721417224172341724417254172641727417284172941730417314173241733417344173541736417374173841739417404174141742417434174441745417464174741748417494175041751417524175341754417554175641757417584175941760417614176241763417644176541766417674176841769417704177141772417734177441775417764177741778417794178041781417824178341784417854178641787417884178941790417914179241793417944179541796417974179841799418004180141802418034180441805418064180741808418094181041811418124181341814418154181641817418184181941820418214182241823418244182541826418274182841829418304183141832418334183441835418364183741838418394184041841418424184341844418454184641847418484184941850418514185241853418544185541856418574185841859418604186141862418634186441865418664186741868418694187041871418724187341874418754187641877418784187941880418814188241883418844188541886418874188841889418904189141892418934189441895418964189741898418994190041901419024190341904419054190641907419084190941910419114191241913419144191541916419174191841919419204192141922419234192441925419264192741928419294193041931419324193341934419354193641937419384193941940419414194241943419444194541946419474194841949419504195141952419534195441955419564195741958419594196041961419624196341964419654196641967419684196941970419714197241973419744197541976419774197841979419804198141982419834198441985419864198741988419894199041991419924199341994419954199641997419984199942000420014200242003420044200542006420074200842009420104201142012420134201442015420164201742018420194202042021420224202342024420254202642027420284202942030420314203242033420344203542036420374203842039420404204142042420434204442045420464204742048420494205042051420524205342054420554205642057420584205942060420614206242063420644206542066420674206842069420704207142072420734207442075420764207742078420794208042081420824208342084420854208642087420884208942090420914209242093420944209542096420974209842099421004210142102421034210442105421064210742108421094211042111421124211342114421154211642117421184211942120421214212242123421244212542126421274212842129421304213142132421334213442135421364213742138421394214042141421424214342144421454214642147421484214942150421514215242153421544215542156421574215842159421604216142162421634216442165421664216742168421694217042171421724217342174421754217642177421784217942180421814218242183421844218542186421874218842189421904219142192421934219442195421964219742198421994220042201422024220342204422054220642207422084220942210422114221242213422144221542216422174221842219422204222142222422234222442225422264222742228422294223042231422324223342234422354223642237422384223942240422414224242243422444224542246422474224842249422504225142252422534225442255422564225742258422594226042261422624226342264422654226642267422684226942270422714227242273422744227542276422774227842279422804228142282422834228442285422864228742288422894229042291422924229342294422954229642297422984229942300423014230242303423044230542306423074230842309423104231142312423134231442315423164231742318423194232042321423224232342324423254232642327423284232942330423314233242333423344233542336423374233842339423404234142342423434234442345423464234742348423494235042351423524235342354423554235642357423584235942360423614236242363423644236542366423674236842369423704237142372423734237442375423764237742378423794238042381423824238342384423854238642387423884238942390423914239242393423944239542396423974239842399424004240142402424034240442405424064240742408424094241042411424124241342414424154241642417424184241942420424214242242423424244242542426424274242842429424304243142432424334243442435424364243742438424394244042441424424244342444424454244642447424484244942450424514245242453424544245542456424574245842459424604246142462424634246442465424664246742468424694247042471424724247342474424754247642477424784247942480424814248242483424844248542486424874248842489424904249142492424934249442495424964249742498424994250042501425024250342504425054250642507425084250942510425114251242513425144251542516425174251842519425204252142522425234252442525425264252742528425294253042531425324253342534425354253642537425384253942540425414254242543425444254542546425474254842549425504255142552425534255442555425564255742558425594256042561425624256342564425654256642567425684256942570425714257242573425744257542576425774257842579425804258142582425834258442585425864258742588425894259042591425924259342594425954259642597425984259942600426014260242603426044260542606426074260842609426104261142612426134261442615426164261742618426194262042621426224262342624426254262642627426284262942630426314263242633426344263542636426374263842639426404264142642426434264442645426464264742648426494265042651426524265342654426554265642657426584265942660426614266242663426644266542666426674266842669426704267142672426734267442675426764267742678426794268042681426824268342684426854268642687426884268942690426914269242693426944269542696426974269842699427004270142702427034270442705427064270742708427094271042711427124271342714427154271642717427184271942720427214272242723427244272542726427274272842729427304273142732427334273442735427364273742738427394274042741427424274342744427454274642747427484274942750427514275242753427544275542756427574275842759427604276142762427634276442765427664276742768427694277042771427724277342774427754277642777427784277942780427814278242783427844278542786427874278842789427904279142792427934279442795427964279742798427994280042801428024280342804428054280642807428084280942810428114281242813428144281542816428174281842819428204282142822428234282442825428264282742828428294283042831428324283342834428354283642837428384283942840428414284242843428444284542846428474284842849428504285142852428534285442855428564285742858428594286042861428624286342864428654286642867428684286942870428714287242873428744287542876428774287842879428804288142882428834288442885428864288742888428894289042891428924289342894428954289642897428984289942900429014290242903429044290542906429074290842909429104291142912429134291442915429164291742918429194292042921429224292342924429254292642927429284292942930429314293242933429344293542936429374293842939429404294142942429434294442945429464294742948429494295042951429524295342954429554295642957429584295942960429614296242963429644296542966429674296842969429704297142972429734297442975429764297742978429794298042981429824298342984429854298642987429884298942990429914299242993429944299542996429974299842999430004300143002430034300443005430064300743008430094301043011430124301343014430154301643017430184301943020430214302243023430244302543026430274302843029430304303143032430334303443035430364303743038430394304043041430424304343044430454304643047430484304943050430514305243053430544305543056430574305843059430604306143062430634306443065430664306743068430694307043071430724307343074430754307643077430784307943080430814308243083430844308543086430874308843089430904309143092430934309443095430964309743098430994310043101431024310343104431054310643107431084310943110431114311243113431144311543116431174311843119431204312143122431234312443125431264312743128431294313043131431324313343134431354313643137431384313943140431414314243143431444314543146431474314843149431504315143152431534315443155431564315743158431594316043161431624316343164431654316643167431684316943170431714317243173431744317543176431774317843179431804318143182431834318443185431864318743188431894319043191431924319343194431954319643197431984319943200432014320243203432044320543206432074320843209432104321143212432134321443215432164321743218432194322043221432224322343224432254322643227432284322943230432314323243233432344323543236432374323843239432404324143242432434324443245432464324743248432494325043251432524325343254432554325643257432584325943260432614326243263432644326543266432674326843269432704327143272432734327443275432764327743278432794328043281432824328343284432854328643287432884328943290432914329243293432944329543296432974329843299433004330143302433034330443305433064330743308433094331043311433124331343314433154331643317433184331943320433214332243323433244332543326433274332843329433304333143332433334333443335433364333743338433394334043341433424334343344433454334643347433484334943350433514335243353433544335543356433574335843359433604336143362433634336443365433664336743368433694337043371433724337343374433754337643377433784337943380433814338243383433844338543386433874338843389433904339143392433934339443395433964339743398433994340043401434024340343404434054340643407434084340943410434114341243413434144341543416434174341843419434204342143422434234342443425434264342743428434294343043431434324343343434434354343643437434384343943440434414344243443434444344543446434474344843449434504345143452434534345443455434564345743458434594346043461434624346343464434654346643467434684346943470434714347243473434744347543476434774347843479434804348143482434834348443485434864348743488434894349043491434924349343494434954349643497434984349943500435014350243503435044350543506435074350843509435104351143512435134351443515435164351743518435194352043521435224352343524435254352643527435284352943530435314353243533435344353543536435374353843539435404354143542435434354443545435464354743548435494355043551435524355343554435554355643557435584355943560435614356243563435644356543566435674356843569435704357143572435734357443575435764357743578435794358043581435824358343584435854358643587435884358943590435914359243593435944359543596435974359843599436004360143602436034360443605436064360743608436094361043611436124361343614436154361643617436184361943620436214362243623436244362543626436274362843629436304363143632436334363443635436364363743638436394364043641436424364343644436454364643647436484364943650436514365243653436544365543656436574365843659436604366143662436634366443665436664366743668436694367043671436724367343674436754367643677436784367943680436814368243683436844368543686436874368843689436904369143692436934369443695436964369743698436994370043701437024370343704437054370643707437084370943710437114371243713437144371543716437174371843719437204372143722437234372443725437264372743728437294373043731437324373343734437354373643737437384373943740437414374243743437444374543746437474374843749437504375143752437534375443755437564375743758437594376043761437624376343764437654376643767437684376943770437714377243773437744377543776437774377843779437804378143782437834378443785437864378743788437894379043791437924379343794437954379643797437984379943800438014380243803438044380543806438074380843809438104381143812438134381443815438164381743818438194382043821438224382343824438254382643827438284382943830438314383243833438344383543836438374383843839438404384143842438434384443845438464384743848438494385043851438524385343854438554385643857438584385943860438614386243863438644386543866438674386843869438704387143872438734387443875438764387743878438794388043881438824388343884438854388643887438884388943890438914389243893438944389543896438974389843899439004390143902439034390443905439064390743908439094391043911439124391343914439154391643917439184391943920439214392243923439244392543926439274392843929439304393143932439334393443935439364393743938439394394043941439424394343944439454394643947439484394943950439514395243953439544395543956439574395843959439604396143962439634396443965439664396743968439694397043971439724397343974439754397643977439784397943980439814398243983439844398543986439874398843989439904399143992439934399443995439964399743998439994400044001440024400344004440054400644007440084400944010440114401244013440144401544016440174401844019440204402144022440234402444025440264402744028440294403044031440324403344034440354403644037440384403944040440414404244043440444404544046440474404844049440504405144052440534405444055440564405744058440594406044061440624406344064440654406644067440684406944070440714407244073440744407544076440774407844079440804408144082440834408444085440864408744088440894409044091440924409344094440954409644097440984409944100441014410244103441044410544106441074410844109441104411144112441134411444115441164411744118441194412044121441224412344124441254412644127441284412944130441314413244133441344413544136441374413844139441404414144142441434414444145441464414744148441494415044151441524415344154441554415644157441584415944160441614416244163441644416544166441674416844169441704417144172441734417444175441764417744178441794418044181441824418344184441854418644187441884418944190441914419244193441944419544196441974419844199442004420144202442034420444205442064420744208442094421044211442124421344214442154421644217442184421944220442214422244223442244422544226442274422844229442304423144232442334423444235442364423744238442394424044241442424424344244442454424644247442484424944250442514425244253442544425544256442574425844259442604426144262442634426444265442664426744268442694427044271442724427344274442754427644277442784427944280442814428244283442844428544286442874428844289442904429144292442934429444295442964429744298442994430044301443024430344304443054430644307443084430944310443114431244313443144431544316443174431844319443204432144322443234432444325443264432744328443294433044331443324433344334443354433644337443384433944340443414434244343443444434544346443474434844349443504435144352443534435444355443564435744358443594436044361443624436344364443654436644367443684436944370443714437244373443744437544376443774437844379443804438144382443834438444385443864438744388443894439044391443924439344394443954439644397443984439944400444014440244403444044440544406444074440844409444104441144412444134441444415444164441744418444194442044421444224442344424444254442644427444284442944430444314443244433444344443544436444374443844439444404444144442444434444444445444464444744448444494445044451444524445344454444554445644457444584445944460444614446244463444644446544466444674446844469444704447144472444734447444475444764447744478444794448044481444824448344484444854448644487444884448944490444914449244493444944449544496444974449844499445004450144502445034450444505445064450744508445094451044511445124451344514445154451644517445184451944520445214452244523445244452544526445274452844529445304453144532445334453444535445364453744538445394454044541445424454344544445454454644547445484454944550445514455244553445544455544556445574455844559445604456144562445634456444565445664456744568445694457044571445724457344574445754457644577445784457944580445814458244583445844458544586445874458844589445904459144592445934459444595445964459744598445994460044601446024460344604446054460644607446084460944610446114461244613446144461544616446174461844619446204462144622446234462444625446264462744628446294463044631446324463344634446354463644637446384463944640446414464244643446444464544646446474464844649446504465144652446534465444655446564465744658446594466044661446624466344664446654466644667446684466944670446714467244673446744467544676446774467844679446804468144682446834468444685446864468744688446894469044691446924469344694446954469644697446984469944700447014470244703447044470544706447074470844709447104471144712447134471444715447164471744718447194472044721447224472344724447254472644727447284472944730447314473244733447344473544736447374473844739447404474144742447434474444745447464474744748447494475044751447524475344754447554475644757447584475944760447614476244763447644476544766447674476844769447704477144772447734477444775447764477744778447794478044781447824478344784447854478644787447884478944790447914479244793447944479544796447974479844799448004480144802448034480444805448064480744808448094481044811448124481344814448154481644817448184481944820448214482244823448244482544826448274482844829448304483144832448334483444835448364483744838448394484044841448424484344844448454484644847448484484944850448514485244853448544485544856448574485844859448604486144862448634486444865448664486744868448694487044871448724487344874448754487644877448784487944880448814488244883448844488544886448874488844889448904489144892448934489444895448964489744898448994490044901449024490344904449054490644907449084490944910449114491244913449144491544916449174491844919449204492144922449234492444925449264492744928449294493044931449324493344934449354493644937449384493944940449414494244943449444494544946449474494844949449504495144952449534495444955449564495744958449594496044961449624496344964449654496644967449684496944970449714497244973449744497544976449774497844979449804498144982449834498444985449864498744988449894499044991449924499344994449954499644997449984499945000450014500245003450044500545006450074500845009450104501145012450134501445015450164501745018450194502045021450224502345024450254502645027450284502945030450314503245033450344503545036450374503845039450404504145042450434504445045450464504745048450494505045051450524505345054450554505645057450584505945060450614506245063450644506545066450674506845069450704507145072450734507445075450764507745078450794508045081450824508345084450854508645087450884508945090450914509245093450944509545096450974509845099451004510145102451034510445105451064510745108451094511045111451124511345114451154511645117451184511945120451214512245123451244512545126451274512845129451304513145132451334513445135451364513745138451394514045141451424514345144451454514645147451484514945150451514515245153451544515545156451574515845159451604516145162451634516445165451664516745168451694517045171451724517345174451754517645177451784517945180451814518245183451844518545186451874518845189451904519145192451934519445195451964519745198451994520045201452024520345204452054520645207452084520945210452114521245213452144521545216452174521845219452204522145222452234522445225452264522745228452294523045231452324523345234452354523645237452384523945240452414524245243452444524545246452474524845249452504525145252452534525445255452564525745258452594526045261452624526345264452654526645267452684526945270452714527245273452744527545276452774527845279452804528145282452834528445285452864528745288452894529045291452924529345294452954529645297452984529945300453014530245303453044530545306453074530845309453104531145312453134531445315453164531745318453194532045321453224532345324453254532645327453284532945330453314533245333453344533545336453374533845339453404534145342453434534445345453464534745348453494535045351453524535345354453554535645357453584535945360453614536245363453644536545366453674536845369453704537145372453734537445375453764537745378453794538045381453824538345384453854538645387453884538945390453914539245393453944539545396453974539845399454004540145402454034540445405454064540745408454094541045411454124541345414454154541645417454184541945420454214542245423454244542545426454274542845429454304543145432454334543445435454364543745438454394544045441454424544345444454454544645447454484544945450454514545245453454544545545456454574545845459454604546145462454634546445465454664546745468454694547045471454724547345474454754547645477454784547945480454814548245483454844548545486454874548845489454904549145492454934549445495454964549745498454994550045501455024550345504455054550645507455084550945510455114551245513455144551545516455174551845519455204552145522455234552445525455264552745528455294553045531455324553345534455354553645537455384553945540455414554245543455444554545546455474554845549455504555145552455534555445555455564555745558455594556045561455624556345564455654556645567455684556945570455714557245573455744557545576455774557845579455804558145582455834558445585455864558745588455894559045591455924559345594455954559645597455984559945600456014560245603456044560545606456074560845609456104561145612456134561445615456164561745618456194562045621456224562345624456254562645627456284562945630456314563245633456344563545636456374563845639456404564145642456434564445645456464564745648456494565045651456524565345654456554565645657456584565945660456614566245663456644566545666456674566845669456704567145672456734567445675456764567745678456794568045681456824568345684456854568645687456884568945690456914569245693456944569545696456974569845699457004570145702457034570445705457064570745708457094571045711457124571345714457154571645717457184571945720457214572245723457244572545726457274572845729457304573145732457334573445735457364573745738457394574045741457424574345744457454574645747457484574945750457514575245753457544575545756457574575845759457604576145762457634576445765457664576745768457694577045771457724577345774457754577645777457784577945780457814578245783457844578545786457874578845789457904579145792457934579445795457964579745798457994580045801458024580345804458054580645807458084580945810458114581245813458144581545816458174581845819458204582145822458234582445825458264582745828458294583045831458324583345834458354583645837458384583945840458414584245843458444584545846458474584845849458504585145852458534585445855458564585745858458594586045861458624586345864458654586645867458684586945870458714587245873458744587545876458774587845879458804588145882458834588445885458864588745888458894589045891458924589345894458954589645897458984589945900459014590245903459044590545906459074590845909459104591145912459134591445915459164591745918459194592045921459224592345924459254592645927459284592945930459314593245933459344593545936459374593845939459404594145942459434594445945459464594745948459494595045951459524595345954459554595645957459584595945960459614596245963459644596545966459674596845969459704597145972459734597445975459764597745978459794598045981459824598345984459854598645987459884598945990459914599245993459944599545996459974599845999460004600146002460034600446005460064600746008460094601046011460124601346014460154601646017460184601946020460214602246023460244602546026460274602846029460304603146032460334603446035460364603746038460394604046041460424604346044460454604646047460484604946050460514605246053460544605546056460574605846059460604606146062460634606446065460664606746068460694607046071460724607346074460754607646077460784607946080460814608246083460844608546086460874608846089460904609146092460934609446095460964609746098460994610046101461024610346104461054610646107461084610946110461114611246113461144611546116461174611846119461204612146122461234612446125461264612746128461294613046131461324613346134461354613646137461384613946140461414614246143461444614546146461474614846149461504615146152461534615446155461564615746158461594616046161461624616346164461654616646167461684616946170461714617246173461744617546176461774617846179461804618146182461834618446185461864618746188461894619046191461924619346194461954619646197461984619946200462014620246203462044620546206462074620846209462104621146212462134621446215462164621746218462194622046221462224622346224462254622646227462284622946230462314623246233462344623546236462374623846239462404624146242462434624446245462464624746248462494625046251462524625346254462554625646257462584625946260462614626246263462644626546266462674626846269462704627146272462734627446275462764627746278462794628046281462824628346284462854628646287462884628946290462914629246293462944629546296462974629846299463004630146302463034630446305463064630746308463094631046311463124631346314463154631646317463184631946320463214632246323463244632546326463274632846329463304633146332463334633446335463364633746338463394634046341463424634346344463454634646347463484634946350463514635246353463544635546356463574635846359463604636146362463634636446365463664636746368463694637046371463724637346374463754637646377463784637946380463814638246383463844638546386463874638846389463904639146392463934639446395463964639746398463994640046401464024640346404464054640646407464084640946410464114641246413464144641546416464174641846419464204642146422464234642446425464264642746428464294643046431464324643346434464354643646437464384643946440464414644246443464444644546446464474644846449464504645146452464534645446455464564645746458464594646046461464624646346464464654646646467464684646946470464714647246473464744647546476464774647846479464804648146482464834648446485464864648746488464894649046491464924649346494464954649646497464984649946500465014650246503465044650546506465074650846509465104651146512465134651446515465164651746518465194652046521465224652346524465254652646527465284652946530465314653246533465344653546536465374653846539465404654146542465434654446545465464654746548465494655046551465524655346554465554655646557465584655946560465614656246563465644656546566465674656846569465704657146572465734657446575465764657746578465794658046581465824658346584465854658646587465884658946590465914659246593465944659546596465974659846599466004660146602466034660446605466064660746608466094661046611466124661346614466154661646617466184661946620466214662246623466244662546626466274662846629466304663146632466334663446635466364663746638466394664046641466424664346644466454664646647466484664946650466514665246653466544665546656466574665846659466604666146662466634666446665466664666746668466694667046671466724667346674466754667646677466784667946680466814668246683466844668546686466874668846689466904669146692466934669446695466964669746698466994670046701467024670346704467054670646707467084670946710467114671246713467144671546716467174671846719467204672146722467234672446725467264672746728467294673046731467324673346734467354673646737467384673946740467414674246743467444674546746467474674846749467504675146752467534675446755467564675746758467594676046761467624676346764467654676646767467684676946770467714677246773467744677546776467774677846779467804678146782467834678446785467864678746788467894679046791467924679346794467954679646797467984679946800468014680246803468044680546806468074680846809468104681146812468134681446815468164681746818468194682046821468224682346824468254682646827468284682946830468314683246833468344683546836468374683846839468404684146842468434684446845468464684746848468494685046851468524685346854468554685646857468584685946860468614686246863468644686546866468674686846869468704687146872468734687446875468764687746878468794688046881468824688346884468854688646887468884688946890468914689246893468944689546896468974689846899469004690146902469034690446905469064690746908469094691046911469124691346914469154691646917469184691946920469214692246923469244692546926469274692846929469304693146932469334693446935469364693746938469394694046941469424694346944469454694646947469484694946950469514695246953469544695546956469574695846959469604696146962469634696446965469664696746968469694697046971469724697346974469754697646977469784697946980469814698246983469844698546986469874698846989469904699146992469934699446995469964699746998469994700047001470024700347004470054700647007470084700947010470114701247013470144701547016470174701847019470204702147022470234702447025470264702747028470294703047031470324703347034470354703647037470384703947040470414704247043470444704547046470474704847049470504705147052470534705447055470564705747058470594706047061470624706347064470654706647067470684706947070470714707247073470744707547076470774707847079470804708147082470834708447085470864708747088470894709047091470924709347094470954709647097470984709947100471014710247103471044710547106471074710847109471104711147112471134711447115471164711747118471194712047121471224712347124471254712647127471284712947130471314713247133471344713547136471374713847139471404714147142471434714447145471464714747148471494715047151471524715347154471554715647157471584715947160471614716247163471644716547166471674716847169471704717147172471734717447175471764717747178471794718047181471824718347184471854718647187471884718947190471914719247193471944719547196471974719847199472004720147202472034720447205472064720747208472094721047211472124721347214472154721647217472184721947220472214722247223472244722547226472274722847229472304723147232472334723447235472364723747238472394724047241472424724347244472454724647247472484724947250472514725247253472544725547256472574725847259472604726147262472634726447265472664726747268472694727047271472724727347274472754727647277472784727947280472814728247283472844728547286472874728847289472904729147292472934729447295472964729747298472994730047301473024730347304473054730647307473084730947310473114731247313473144731547316473174731847319473204732147322473234732447325473264732747328473294733047331473324733347334473354733647337473384733947340473414734247343473444734547346473474734847349473504735147352473534735447355473564735747358473594736047361473624736347364473654736647367473684736947370473714737247373473744737547376473774737847379473804738147382473834738447385473864738747388473894739047391473924739347394473954739647397473984739947400474014740247403474044740547406474074740847409474104741147412474134741447415474164741747418474194742047421474224742347424474254742647427474284742947430474314743247433474344743547436474374743847439474404744147442474434744447445474464744747448474494745047451474524745347454474554745647457474584745947460474614746247463474644746547466474674746847469474704747147472474734747447475474764747747478474794748047481474824748347484474854748647487474884748947490474914749247493474944749547496474974749847499475004750147502475034750447505475064750747508475094751047511475124751347514475154751647517475184751947520475214752247523475244752547526475274752847529475304753147532475334753447535475364753747538475394754047541475424754347544475454754647547475484754947550475514755247553475544755547556475574755847559475604756147562475634756447565475664756747568475694757047571475724757347574475754757647577475784757947580475814758247583475844758547586475874758847589475904759147592475934759447595475964759747598475994760047601476024760347604476054760647607476084760947610476114761247613476144761547616476174761847619476204762147622476234762447625476264762747628476294763047631476324763347634476354763647637476384763947640476414764247643476444764547646476474764847649476504765147652476534765447655476564765747658476594766047661476624766347664476654766647667476684766947670476714767247673476744767547676476774767847679476804768147682476834768447685476864768747688476894769047691476924769347694476954769647697476984769947700477014770247703477044770547706477074770847709477104771147712477134771447715477164771747718477194772047721477224772347724477254772647727477284772947730477314773247733477344773547736477374773847739477404774147742477434774447745477464774747748477494775047751477524775347754477554775647757477584775947760477614776247763477644776547766477674776847769477704777147772477734777447775477764777747778477794778047781477824778347784477854778647787477884778947790477914779247793477944779547796477974779847799478004780147802478034780447805478064780747808478094781047811478124781347814478154781647817478184781947820478214782247823478244782547826478274782847829478304783147832478334783447835478364783747838478394784047841478424784347844478454784647847478484784947850478514785247853478544785547856478574785847859478604786147862478634786447865478664786747868478694787047871478724787347874478754787647877478784787947880478814788247883478844788547886478874788847889478904789147892478934789447895478964789747898478994790047901479024790347904479054790647907479084790947910479114791247913479144791547916479174791847919479204792147922479234792447925479264792747928479294793047931479324793347934479354793647937479384793947940479414794247943479444794547946479474794847949479504795147952479534795447955479564795747958479594796047961479624796347964479654796647967479684796947970479714797247973479744797547976479774797847979479804798147982479834798447985479864798747988479894799047991479924799347994479954799647997479984799948000480014800248003480044800548006480074800848009480104801148012480134801448015480164801748018480194802048021480224802348024480254802648027480284802948030480314803248033480344803548036480374803848039480404804148042480434804448045480464804748048480494805048051480524805348054480554805648057480584805948060480614806248063480644806548066480674806848069480704807148072480734807448075480764807748078480794808048081480824808348084480854808648087480884808948090480914809248093480944809548096480974809848099481004810148102481034810448105481064810748108481094811048111481124811348114481154811648117481184811948120481214812248123481244812548126481274812848129481304813148132481334813448135481364813748138481394814048141481424814348144481454814648147481484814948150481514815248153481544815548156481574815848159481604816148162481634816448165481664816748168481694817048171481724817348174481754817648177481784817948180481814818248183481844818548186481874818848189481904819148192481934819448195481964819748198481994820048201482024820348204482054820648207482084820948210482114821248213482144821548216482174821848219482204822148222482234822448225482264822748228482294823048231482324823348234482354823648237482384823948240482414824248243482444824548246482474824848249482504825148252482534825448255482564825748258482594826048261482624826348264482654826648267482684826948270482714827248273482744827548276482774827848279482804828148282482834828448285482864828748288482894829048291482924829348294482954829648297482984829948300483014830248303483044830548306483074830848309483104831148312483134831448315483164831748318483194832048321483224832348324483254832648327483284832948330483314833248333483344833548336483374833848339483404834148342483434834448345483464834748348483494835048351483524835348354483554835648357483584835948360483614836248363483644836548366483674836848369483704837148372483734837448375483764837748378483794838048381483824838348384483854838648387483884838948390483914839248393483944839548396483974839848399484004840148402484034840448405484064840748408484094841048411484124841348414484154841648417484184841948420484214842248423484244842548426484274842848429484304843148432484334843448435484364843748438484394844048441484424844348444484454844648447484484844948450484514845248453484544845548456484574845848459484604846148462484634846448465484664846748468484694847048471484724847348474484754847648477484784847948480484814848248483484844848548486484874848848489484904849148492484934849448495484964849748498484994850048501485024850348504485054850648507485084850948510485114851248513485144851548516485174851848519485204852148522485234852448525485264852748528485294853048531485324853348534485354853648537485384853948540485414854248543485444854548546485474854848549485504855148552485534855448555485564855748558485594856048561485624856348564485654856648567485684856948570485714857248573485744857548576485774857848579485804858148582485834858448585485864858748588485894859048591485924859348594485954859648597485984859948600486014860248603486044860548606486074860848609486104861148612486134861448615486164861748618486194862048621486224862348624486254862648627486284862948630486314863248633486344863548636486374863848639486404864148642486434864448645486464864748648486494865048651486524865348654486554865648657486584865948660486614866248663486644866548666486674866848669486704867148672486734867448675486764867748678486794868048681486824868348684486854868648687486884868948690486914869248693486944869548696486974869848699487004870148702487034870448705487064870748708487094871048711487124871348714487154871648717487184871948720487214872248723487244872548726487274872848729487304873148732487334873448735487364873748738487394874048741487424874348744487454874648747487484874948750487514875248753487544875548756487574875848759487604876148762487634876448765487664876748768487694877048771487724877348774487754877648777487784877948780487814878248783487844878548786487874878848789487904879148792487934879448795487964879748798487994880048801488024880348804488054880648807488084880948810488114881248813488144881548816488174881848819488204882148822488234882448825488264882748828488294883048831488324883348834488354883648837488384883948840488414884248843488444884548846488474884848849488504885148852488534885448855488564885748858488594886048861488624886348864488654886648867488684886948870488714887248873488744887548876488774887848879488804888148882488834888448885488864888748888488894889048891488924889348894488954889648897488984889948900489014890248903489044890548906489074890848909489104891148912489134891448915489164891748918489194892048921489224892348924489254892648927489284892948930489314893248933489344893548936489374893848939489404894148942489434894448945489464894748948489494895048951489524895348954489554895648957489584895948960489614896248963489644896548966489674896848969489704897148972489734897448975489764897748978489794898048981489824898348984489854898648987489884898948990489914899248993489944899548996489974899848999490004900149002490034900449005490064900749008490094901049011490124901349014490154901649017490184901949020490214902249023490244902549026490274902849029490304903149032490334903449035490364903749038490394904049041490424904349044490454904649047490484904949050490514905249053490544905549056490574905849059490604906149062490634906449065490664906749068490694907049071490724907349074490754907649077490784907949080490814908249083490844908549086490874908849089490904909149092490934909449095490964909749098490994910049101491024910349104491054910649107491084910949110491114911249113491144911549116491174911849119491204912149122491234912449125491264912749128491294913049131491324913349134491354913649137491384913949140491414914249143491444914549146491474914849149491504915149152491534915449155491564915749158491594916049161491624916349164491654916649167491684916949170491714917249173491744917549176491774917849179491804918149182491834918449185491864918749188491894919049191491924919349194491954919649197491984919949200492014920249203492044920549206492074920849209492104921149212492134921449215492164921749218492194922049221492224922349224492254922649227492284922949230492314923249233492344923549236492374923849239492404924149242492434924449245492464924749248492494925049251492524925349254492554925649257492584925949260492614926249263492644926549266492674926849269492704927149272492734927449275492764927749278492794928049281492824928349284492854928649287492884928949290492914929249293492944929549296492974929849299493004930149302493034930449305493064930749308493094931049311493124931349314493154931649317493184931949320493214932249323493244932549326493274932849329493304933149332493334933449335493364933749338493394934049341493424934349344493454934649347493484934949350493514935249353493544935549356493574935849359493604936149362493634936449365493664936749368493694937049371493724937349374493754937649377493784937949380493814938249383493844938549386493874938849389493904939149392493934939449395493964939749398493994940049401494024940349404494054940649407494084940949410494114941249413494144941549416494174941849419494204942149422494234942449425494264942749428494294943049431494324943349434494354943649437494384943949440494414944249443494444944549446494474944849449494504945149452494534945449455494564945749458494594946049461494624946349464494654946649467494684946949470494714947249473494744947549476494774947849479494804948149482494834948449485494864948749488494894949049491494924949349494494954949649497494984949949500495014950249503495044950549506495074950849509495104951149512495134951449515495164951749518495194952049521495224952349524495254952649527495284952949530495314953249533495344953549536495374953849539495404954149542495434954449545495464954749548495494955049551495524955349554495554955649557495584955949560495614956249563495644956549566495674956849569495704957149572495734957449575495764957749578495794958049581495824958349584495854958649587495884958949590495914959249593495944959549596495974959849599496004960149602496034960449605496064960749608496094961049611496124961349614496154961649617496184961949620496214962249623496244962549626496274962849629496304963149632496334963449635496364963749638496394964049641496424964349644496454964649647496484964949650496514965249653496544965549656496574965849659496604966149662496634966449665496664966749668496694967049671496724967349674496754967649677496784967949680496814968249683496844968549686496874968849689496904969149692496934969449695496964969749698496994970049701497024970349704497054970649707497084970949710497114971249713497144971549716497174971849719497204972149722497234972449725497264972749728497294973049731497324973349734497354973649737497384973949740497414974249743497444974549746497474974849749497504975149752497534975449755497564975749758497594976049761497624976349764497654976649767497684976949770497714977249773497744977549776497774977849779497804978149782497834978449785497864978749788497894979049791497924979349794497954979649797497984979949800498014980249803498044980549806498074980849809498104981149812498134981449815498164981749818498194982049821498224982349824498254982649827498284982949830498314983249833498344983549836498374983849839498404984149842498434984449845498464984749848498494985049851498524985349854498554985649857498584985949860498614986249863498644986549866498674986849869498704987149872498734987449875498764987749878498794988049881498824988349884498854988649887498884988949890498914989249893498944989549896498974989849899499004990149902499034990449905499064990749908499094991049911499124991349914499154991649917499184991949920499214992249923499244992549926499274992849929499304993149932499334993449935499364993749938499394994049941499424994349944499454994649947499484994949950499514995249953499544995549956499574995849959499604996149962499634996449965499664996749968499694997049971499724997349974499754997649977499784997949980499814998249983499844998549986499874998849989499904999149992499934999449995499964999749998499995000050001500025000350004500055000650007500085000950010500115001250013500145001550016500175001850019500205002150022500235002450025500265002750028500295003050031500325003350034500355003650037500385003950040500415004250043500445004550046500475004850049500505005150052500535005450055500565005750058500595006050061500625006350064500655006650067500685006950070500715007250073500745007550076500775007850079500805008150082500835008450085500865008750088500895009050091500925009350094500955009650097500985009950100501015010250103501045010550106501075010850109501105011150112501135011450115501165011750118501195012050121501225012350124501255012650127501285012950130501315013250133501345013550136501375013850139501405014150142501435014450145501465014750148501495015050151501525015350154501555015650157501585015950160501615016250163501645016550166501675016850169501705017150172501735017450175501765017750178501795018050181501825018350184501855018650187501885018950190501915019250193501945019550196501975019850199502005020150202502035020450205502065020750208502095021050211502125021350214502155021650217502185021950220502215022250223502245022550226502275022850229502305023150232502335023450235502365023750238502395024050241502425024350244502455024650247502485024950250502515025250253502545025550256502575025850259502605026150262502635026450265502665026750268502695027050271502725027350274502755027650277502785027950280502815028250283502845028550286502875028850289502905029150292502935029450295502965029750298502995030050301503025030350304503055030650307503085030950310503115031250313503145031550316503175031850319503205032150322503235032450325503265032750328503295033050331503325033350334503355033650337503385033950340503415034250343503445034550346503475034850349503505035150352503535035450355503565035750358503595036050361503625036350364503655036650367503685036950370503715037250373503745037550376503775037850379503805038150382503835038450385503865038750388503895039050391503925039350394503955039650397503985039950400504015040250403504045040550406504075040850409504105041150412504135041450415504165041750418504195042050421504225042350424504255042650427504285042950430504315043250433504345043550436504375043850439504405044150442504435044450445504465044750448504495045050451504525045350454504555045650457504585045950460504615046250463504645046550466504675046850469504705047150472504735047450475504765047750478504795048050481504825048350484504855048650487504885048950490504915049250493504945049550496504975049850499505005050150502505035050450505505065050750508505095051050511505125051350514505155051650517505185051950520505215052250523505245052550526505275052850529505305053150532505335053450535505365053750538505395054050541505425054350544505455054650547505485054950550505515055250553505545055550556505575055850559505605056150562505635056450565505665056750568505695057050571505725057350574505755057650577505785057950580505815058250583505845058550586505875058850589505905059150592505935059450595505965059750598505995060050601506025060350604506055060650607506085060950610506115061250613506145061550616506175061850619506205062150622506235062450625506265062750628506295063050631506325063350634506355063650637506385063950640506415064250643506445064550646506475064850649506505065150652506535065450655506565065750658506595066050661506625066350664506655066650667506685066950670506715067250673506745067550676506775067850679506805068150682506835068450685506865068750688506895069050691506925069350694506955069650697506985069950700507015070250703507045070550706507075070850709507105071150712507135071450715507165071750718507195072050721507225072350724507255072650727507285072950730507315073250733507345073550736507375073850739507405074150742507435074450745507465074750748507495075050751507525075350754507555075650757507585075950760507615076250763507645076550766507675076850769507705077150772507735077450775507765077750778507795078050781507825078350784507855078650787507885078950790507915079250793507945079550796507975079850799508005080150802508035080450805508065080750808508095081050811508125081350814508155081650817508185081950820508215082250823508245082550826508275082850829508305083150832508335083450835508365083750838508395084050841508425084350844508455084650847508485084950850508515085250853508545085550856508575085850859508605086150862508635086450865508665086750868508695087050871508725087350874508755087650877508785087950880508815088250883508845088550886508875088850889508905089150892508935089450895508965089750898508995090050901509025090350904509055090650907509085090950910509115091250913509145091550916509175091850919509205092150922509235092450925509265092750928509295093050931509325093350934509355093650937509385093950940509415094250943509445094550946509475094850949509505095150952509535095450955509565095750958509595096050961509625096350964509655096650967509685096950970509715097250973509745097550976509775097850979509805098150982509835098450985509865098750988509895099050991509925099350994509955099650997509985099951000510015100251003510045100551006510075100851009510105101151012510135101451015510165101751018510195102051021510225102351024510255102651027510285102951030510315103251033510345103551036510375103851039510405104151042510435104451045510465104751048510495105051051510525105351054510555105651057510585105951060510615106251063510645106551066510675106851069510705107151072510735107451075510765107751078510795108051081510825108351084510855108651087510885108951090510915109251093510945109551096510975109851099511005110151102511035110451105511065110751108511095111051111511125111351114511155111651117511185111951120511215112251123511245112551126511275112851129511305113151132511335113451135511365113751138511395114051141511425114351144511455114651147511485114951150511515115251153511545115551156511575115851159511605116151162511635116451165511665116751168511695117051171511725117351174511755117651177511785117951180511815118251183511845118551186511875118851189511905119151192511935119451195511965119751198511995120051201512025120351204512055120651207512085120951210512115121251213512145121551216512175121851219512205122151222512235122451225512265122751228512295123051231512325123351234512355123651237512385123951240512415124251243512445124551246512475124851249512505125151252512535125451255512565125751258512595126051261512625126351264512655126651267512685126951270512715127251273512745127551276512775127851279512805128151282512835128451285512865128751288512895129051291512925129351294512955129651297512985129951300513015130251303513045130551306513075130851309513105131151312513135131451315513165131751318513195132051321513225132351324513255132651327513285132951330513315133251333513345133551336513375133851339513405134151342513435134451345513465134751348513495135051351513525135351354513555135651357513585135951360513615136251363513645136551366513675136851369513705137151372513735137451375513765137751378513795138051381513825138351384513855138651387513885138951390513915139251393513945139551396513975139851399514005140151402514035140451405514065140751408514095141051411514125141351414514155141651417514185141951420514215142251423514245142551426514275142851429514305143151432514335143451435514365143751438514395144051441514425144351444514455144651447514485144951450514515145251453514545145551456514575145851459514605146151462514635146451465514665146751468514695147051471514725147351474514755147651477514785147951480514815148251483514845148551486514875148851489514905149151492514935149451495514965149751498514995150051501515025150351504515055150651507515085150951510515115151251513515145151551516515175151851519515205152151522515235152451525515265152751528515295153051531515325153351534515355153651537515385153951540515415154251543515445154551546515475154851549515505155151552515535155451555515565155751558515595156051561515625156351564515655156651567515685156951570515715157251573515745157551576515775157851579515805158151582515835158451585515865158751588515895159051591515925159351594515955159651597515985159951600516015160251603516045160551606516075160851609516105161151612516135161451615516165161751618516195162051621516225162351624516255162651627516285162951630516315163251633516345163551636516375163851639516405164151642516435164451645516465164751648516495165051651516525165351654516555165651657516585165951660516615166251663516645166551666516675166851669516705167151672516735167451675516765167751678516795168051681516825168351684516855168651687516885168951690516915169251693516945169551696516975169851699517005170151702517035170451705517065170751708517095171051711517125171351714517155171651717517185171951720517215172251723517245172551726517275172851729517305173151732517335173451735517365173751738517395174051741517425174351744517455174651747517485174951750517515175251753517545175551756517575175851759517605176151762517635176451765517665176751768517695177051771517725177351774517755177651777517785177951780517815178251783517845178551786517875178851789517905179151792517935179451795517965179751798517995180051801518025180351804518055180651807518085180951810518115181251813518145181551816518175181851819518205182151822518235182451825518265182751828518295183051831518325183351834518355183651837518385183951840518415184251843518445184551846518475184851849518505185151852518535185451855518565185751858518595186051861518625186351864518655186651867518685186951870518715187251873518745187551876518775187851879518805188151882518835188451885518865188751888518895189051891518925189351894518955189651897518985189951900519015190251903519045190551906519075190851909519105191151912519135191451915519165191751918519195192051921519225192351924519255192651927519285192951930519315193251933519345193551936519375193851939519405194151942519435194451945519465194751948519495195051951519525195351954519555195651957519585195951960519615196251963519645196551966519675196851969519705197151972519735197451975519765197751978519795198051981519825198351984519855198651987519885198951990519915199251993519945199551996519975199851999520005200152002520035200452005520065200752008520095201052011520125201352014520155201652017520185201952020520215202252023520245202552026520275202852029520305203152032520335203452035520365203752038520395204052041520425204352044520455204652047520485204952050520515205252053520545205552056520575205852059520605206152062520635206452065520665206752068520695207052071520725207352074520755207652077520785207952080520815208252083520845208552086520875208852089520905209152092520935209452095520965209752098520995210052101521025210352104521055210652107521085210952110521115211252113521145211552116521175211852119521205212152122521235212452125521265212752128521295213052131521325213352134521355213652137521385213952140521415214252143521445214552146521475214852149521505215152152521535215452155521565215752158521595216052161521625216352164521655216652167521685216952170521715217252173521745217552176521775217852179521805218152182521835218452185521865218752188521895219052191521925219352194521955219652197521985219952200522015220252203522045220552206522075220852209522105221152212522135221452215522165221752218522195222052221522225222352224522255222652227522285222952230522315223252233522345223552236522375223852239522405224152242522435224452245522465224752248522495225052251522525225352254522555225652257522585225952260522615226252263522645226552266522675226852269522705227152272522735227452275522765227752278522795228052281522825228352284522855228652287522885228952290522915229252293522945229552296522975229852299523005230152302523035230452305523065230752308523095231052311523125231352314523155231652317523185231952320523215232252323523245232552326523275232852329523305233152332523335233452335523365233752338523395234052341523425234352344523455234652347523485234952350523515235252353523545235552356523575235852359523605236152362523635236452365523665236752368523695237052371523725237352374523755237652377523785237952380523815238252383523845238552386523875238852389523905239152392523935239452395523965239752398523995240052401524025240352404524055240652407524085240952410524115241252413524145241552416524175241852419524205242152422524235242452425524265242752428524295243052431524325243352434524355243652437524385243952440524415244252443524445244552446524475244852449524505245152452524535245452455524565245752458524595246052461524625246352464524655246652467524685246952470524715247252473524745247552476524775247852479524805248152482524835248452485524865248752488524895249052491524925249352494524955249652497524985249952500525015250252503525045250552506525075250852509525105251152512525135251452515525165251752518525195252052521525225252352524525255252652527525285252952530525315253252533525345253552536525375253852539525405254152542525435254452545525465254752548525495255052551525525255352554525555255652557525585255952560525615256252563525645256552566525675256852569525705257152572525735257452575525765257752578525795258052581525825258352584525855258652587525885258952590525915259252593525945259552596525975259852599526005260152602526035260452605526065260752608526095261052611526125261352614526155261652617526185261952620526215262252623526245262552626526275262852629526305263152632526335263452635526365263752638526395264052641526425264352644526455264652647526485264952650526515265252653526545265552656526575265852659526605266152662526635266452665526665266752668526695267052671526725267352674526755267652677526785267952680526815268252683526845268552686526875268852689526905269152692526935269452695526965269752698526995270052701527025270352704527055270652707527085270952710527115271252713527145271552716527175271852719527205272152722527235272452725527265272752728527295273052731527325273352734527355273652737527385273952740527415274252743527445274552746527475274852749527505275152752527535275452755527565275752758527595276052761527625276352764527655276652767527685276952770527715277252773527745277552776527775277852779527805278152782527835278452785527865278752788527895279052791527925279352794527955279652797527985279952800528015280252803528045280552806528075280852809528105281152812528135281452815528165281752818528195282052821528225282352824528255282652827528285282952830528315283252833528345283552836528375283852839528405284152842528435284452845528465284752848528495285052851528525285352854528555285652857528585285952860528615286252863528645286552866528675286852869528705287152872528735287452875528765287752878528795288052881528825288352884528855288652887528885288952890528915289252893528945289552896528975289852899529005290152902529035290452905529065290752908529095291052911529125291352914529155291652917529185291952920529215292252923529245292552926529275292852929529305293152932529335293452935529365293752938529395294052941529425294352944529455294652947529485294952950529515295252953529545295552956529575295852959529605296152962529635296452965529665296752968529695297052971529725297352974529755297652977529785297952980529815298252983529845298552986529875298852989529905299152992529935299452995529965299752998529995300053001530025300353004530055300653007530085300953010530115301253013530145301553016530175301853019530205302153022530235302453025530265302753028530295303053031530325303353034530355303653037530385303953040530415304253043530445304553046530475304853049530505305153052530535305453055530565305753058530595306053061530625306353064530655306653067530685306953070530715307253073530745307553076530775307853079530805308153082530835308453085530865308753088530895309053091530925309353094530955309653097530985309953100531015310253103531045310553106531075310853109531105311153112531135311453115531165311753118531195312053121531225312353124531255312653127531285312953130531315313253133531345313553136531375313853139531405314153142531435314453145531465314753148531495315053151531525315353154531555315653157531585315953160531615316253163531645316553166531675316853169531705317153172531735317453175531765317753178531795318053181531825318353184531855318653187531885318953190531915319253193531945319553196531975319853199532005320153202532035320453205532065320753208532095321053211532125321353214532155321653217532185321953220532215322253223532245322553226532275322853229532305323153232532335323453235532365323753238532395324053241532425324353244532455324653247532485324953250532515325253253532545325553256532575325853259532605326153262532635326453265532665326753268532695327053271532725327353274532755327653277532785327953280532815328253283532845328553286532875328853289532905329153292532935329453295532965329753298532995330053301533025330353304533055330653307533085330953310533115331253313533145331553316533175331853319533205332153322533235332453325533265332753328533295333053331533325333353334533355333653337533385333953340533415334253343533445334553346533475334853349533505335153352533535335453355533565335753358533595336053361533625336353364533655336653367533685336953370533715337253373533745337553376533775337853379533805338153382533835338453385533865338753388533895339053391533925339353394533955339653397533985339953400534015340253403534045340553406534075340853409534105341153412534135341453415534165341753418534195342053421534225342353424534255342653427534285342953430534315343253433534345343553436534375343853439534405344153442534435344453445534465344753448534495345053451534525345353454534555345653457534585345953460534615346253463534645346553466534675346853469534705347153472534735347453475534765347753478534795348053481534825348353484534855348653487534885348953490534915349253493534945349553496534975349853499535005350153502535035350453505535065350753508535095351053511535125351353514535155351653517535185351953520535215352253523535245352553526535275352853529535305353153532535335353453535535365353753538535395354053541535425354353544535455354653547535485354953550535515355253553535545355553556535575355853559535605356153562535635356453565535665356753568535695357053571535725357353574535755357653577535785357953580535815358253583535845358553586535875358853589535905359153592535935359453595535965359753598535995360053601536025360353604536055360653607536085360953610536115361253613536145361553616536175361853619536205362153622536235362453625536265362753628536295363053631536325363353634536355363653637536385363953640536415364253643536445364553646536475364853649536505365153652536535365453655536565365753658536595366053661536625366353664536655366653667536685366953670536715367253673536745367553676536775367853679536805368153682536835368453685536865368753688536895369053691536925369353694536955369653697536985369953700537015370253703537045370553706537075370853709537105371153712537135371453715537165371753718537195372053721537225372353724537255372653727537285372953730537315373253733537345373553736537375373853739537405374153742537435374453745537465374753748537495375053751537525375353754537555375653757537585375953760537615376253763537645376553766537675376853769537705377153772537735377453775537765377753778537795378053781537825378353784537855378653787537885378953790537915379253793537945379553796537975379853799538005380153802538035380453805538065380753808538095381053811538125381353814538155381653817538185381953820538215382253823538245382553826538275382853829538305383153832538335383453835538365383753838538395384053841538425384353844538455384653847538485384953850538515385253853538545385553856538575385853859538605386153862538635386453865538665386753868538695387053871538725387353874538755387653877538785387953880538815388253883538845388553886538875388853889538905389153892538935389453895538965389753898538995390053901539025390353904539055390653907539085390953910539115391253913539145391553916539175391853919539205392153922539235392453925539265392753928539295393053931539325393353934539355393653937539385393953940539415394253943539445394553946539475394853949539505395153952539535395453955539565395753958539595396053961539625396353964539655396653967539685396953970539715397253973539745397553976539775397853979539805398153982539835398453985539865398753988539895399053991539925399353994539955399653997539985399954000540015400254003540045400554006540075400854009540105401154012540135401454015540165401754018540195402054021540225402354024540255402654027540285402954030540315403254033540345403554036540375403854039540405404154042540435404454045540465404754048540495405054051540525405354054540555405654057540585405954060540615406254063540645406554066540675406854069540705407154072540735407454075540765407754078540795408054081540825408354084540855408654087540885408954090540915409254093540945409554096540975409854099541005410154102541035410454105541065410754108541095411054111541125411354114541155411654117541185411954120541215412254123541245412554126541275412854129541305413154132541335413454135541365413754138541395414054141541425414354144541455414654147541485414954150541515415254153541545415554156541575415854159541605416154162541635416454165541665416754168541695417054171541725417354174541755417654177541785417954180541815418254183541845418554186541875418854189541905419154192541935419454195541965419754198541995420054201542025420354204542055420654207542085420954210542115421254213542145421554216542175421854219542205422154222542235422454225542265422754228542295423054231542325423354234542355423654237542385423954240542415424254243542445424554246542475424854249542505425154252542535425454255542565425754258542595426054261542625426354264542655426654267542685426954270542715427254273542745427554276542775427854279542805428154282542835428454285542865428754288542895429054291542925429354294542955429654297542985429954300543015430254303543045430554306543075430854309543105431154312543135431454315543165431754318543195432054321543225432354324543255432654327543285432954330543315433254333543345433554336543375433854339543405434154342543435434454345543465434754348543495435054351543525435354354543555435654357543585435954360543615436254363543645436554366543675436854369543705437154372543735437454375543765437754378543795438054381543825438354384543855438654387543885438954390543915439254393543945439554396543975439854399544005440154402544035440454405544065440754408544095441054411544125441354414544155441654417544185441954420544215442254423544245442554426544275442854429544305443154432544335443454435544365443754438544395444054441544425444354444544455444654447544485444954450544515445254453544545445554456544575445854459544605446154462544635446454465544665446754468544695447054471544725447354474544755447654477544785447954480544815448254483544845448554486544875448854489544905449154492544935449454495544965449754498544995450054501545025450354504545055450654507545085450954510545115451254513545145451554516545175451854519545205452154522545235452454525545265452754528545295453054531545325453354534545355453654537545385453954540545415454254543545445454554546545475454854549545505455154552545535455454555545565455754558545595456054561545625456354564545655456654567545685456954570545715457254573545745457554576545775457854579545805458154582545835458454585545865458754588545895459054591545925459354594545955459654597545985459954600546015460254603546045460554606546075460854609546105461154612546135461454615546165461754618546195462054621546225462354624546255462654627546285462954630546315463254633546345463554636546375463854639546405464154642546435464454645546465464754648546495465054651546525465354654546555465654657546585465954660546615466254663546645466554666546675466854669546705467154672546735467454675546765467754678546795468054681546825468354684546855468654687546885468954690546915469254693546945469554696546975469854699547005470154702547035470454705547065470754708547095471054711547125471354714547155471654717547185471954720547215472254723547245472554726547275472854729547305473154732547335473454735547365473754738547395474054741547425474354744547455474654747547485474954750547515475254753547545475554756547575475854759547605476154762547635476454765547665476754768547695477054771547725477354774547755477654777547785477954780547815478254783547845478554786547875478854789547905479154792547935479454795547965479754798547995480054801548025480354804548055480654807548085480954810548115481254813548145481554816548175481854819548205482154822548235482454825548265482754828548295483054831548325483354834548355483654837548385483954840548415484254843548445484554846548475484854849548505485154852548535485454855548565485754858548595486054861548625486354864548655486654867548685486954870548715487254873548745487554876548775487854879548805488154882548835488454885548865488754888548895489054891548925489354894548955489654897548985489954900549015490254903549045490554906549075490854909549105491154912549135491454915549165491754918549195492054921549225492354924549255492654927549285492954930549315493254933549345493554936549375493854939549405494154942549435494454945549465494754948549495495054951549525495354954549555495654957549585495954960549615496254963549645496554966549675496854969549705497154972549735497454975549765497754978549795498054981549825498354984549855498654987549885498954990549915499254993549945499554996549975499854999550005500155002550035500455005550065500755008550095501055011550125501355014550155501655017550185501955020550215502255023550245502555026550275502855029550305503155032550335503455035550365503755038550395504055041550425504355044550455504655047550485504955050550515505255053550545505555056550575505855059550605506155062550635506455065550665506755068550695507055071550725507355074550755507655077550785507955080550815508255083550845508555086550875508855089550905509155092550935509455095550965509755098550995510055101551025510355104551055510655107551085510955110551115511255113551145511555116551175511855119551205512155122551235512455125551265512755128551295513055131551325513355134551355513655137551385513955140551415514255143551445514555146551475514855149551505515155152551535515455155551565515755158551595516055161551625516355164551655516655167551685516955170551715517255173551745517555176551775517855179551805518155182551835518455185551865518755188551895519055191551925519355194551955519655197551985519955200552015520255203552045520555206552075520855209552105521155212552135521455215552165521755218552195522055221552225522355224552255522655227552285522955230552315523255233552345523555236552375523855239552405524155242552435524455245552465524755248552495525055251552525525355254552555525655257552585525955260552615526255263552645526555266552675526855269552705527155272552735527455275552765527755278552795528055281552825528355284552855528655287552885528955290552915529255293552945529555296552975529855299553005530155302553035530455305553065530755308553095531055311553125531355314553155531655317553185531955320553215532255323553245532555326553275532855329553305533155332553335533455335553365533755338553395534055341553425534355344553455534655347553485534955350553515535255353553545535555356553575535855359553605536155362553635536455365553665536755368553695537055371553725537355374553755537655377553785537955380553815538255383553845538555386553875538855389553905539155392553935539455395553965539755398553995540055401554025540355404554055540655407554085540955410554115541255413554145541555416554175541855419554205542155422554235542455425554265542755428554295543055431554325543355434554355543655437554385543955440554415544255443554445544555446554475544855449554505545155452554535545455455554565545755458554595546055461554625546355464554655546655467554685546955470554715547255473554745547555476554775547855479554805548155482554835548455485554865548755488554895549055491554925549355494554955549655497554985549955500555015550255503555045550555506555075550855509555105551155512555135551455515555165551755518555195552055521555225552355524555255552655527555285552955530555315553255533555345553555536555375553855539555405554155542555435554455545555465554755548555495555055551555525555355554555555555655557555585555955560555615556255563555645556555566555675556855569555705557155572555735557455575555765557755578555795558055581555825558355584555855558655587555885558955590555915559255593555945559555596555975559855599556005560155602556035560455605556065560755608556095561055611556125561355614556155561655617556185561955620556215562255623556245562555626556275562855629556305563155632556335563455635556365563755638556395564055641556425564355644556455564655647556485564955650556515565255653556545565555656556575565855659556605566155662556635566455665556665566755668556695567055671556725567355674556755567655677556785567955680556815568255683556845568555686556875568855689556905569155692556935569455695556965569755698556995570055701557025570355704557055570655707557085570955710557115571255713557145571555716557175571855719557205572155722557235572455725557265572755728557295573055731557325573355734557355573655737557385573955740557415574255743557445574555746557475574855749557505575155752557535575455755557565575755758557595576055761557625576355764557655576655767557685576955770557715577255773557745577555776557775577855779557805578155782557835578455785557865578755788557895579055791557925579355794557955579655797557985579955800558015580255803558045580555806558075580855809558105581155812558135581455815558165581755818558195582055821558225582355824558255582655827558285582955830558315583255833558345583555836558375583855839558405584155842558435584455845558465584755848558495585055851558525585355854558555585655857558585585955860558615586255863558645586555866558675586855869558705587155872558735587455875558765587755878558795588055881558825588355884558855588655887558885588955890558915589255893558945589555896558975589855899559005590155902559035590455905559065590755908559095591055911559125591355914559155591655917559185591955920559215592255923559245592555926559275592855929559305593155932559335593455935559365593755938559395594055941559425594355944559455594655947559485594955950559515595255953559545595555956559575595855959559605596155962559635596455965559665596755968559695597055971559725597355974559755597655977559785597955980559815598255983559845598555986559875598855989559905599155992559935599455995559965599755998559995600056001560025600356004560055600656007560085600956010560115601256013560145601556016560175601856019560205602156022560235602456025560265602756028560295603056031560325603356034560355603656037560385603956040560415604256043560445604556046560475604856049560505605156052560535605456055560565605756058560595606056061560625606356064560655606656067560685606956070560715607256073560745607556076560775607856079560805608156082560835608456085560865608756088560895609056091560925609356094560955609656097560985609956100561015610256103561045610556106561075610856109561105611156112561135611456115561165611756118561195612056121561225612356124561255612656127561285612956130561315613256133561345613556136561375613856139561405614156142561435614456145561465614756148561495615056151561525615356154561555615656157561585615956160561615616256163561645616556166561675616856169561705617156172561735617456175561765617756178561795618056181561825618356184561855618656187561885618956190561915619256193561945619556196561975619856199562005620156202562035620456205562065620756208562095621056211562125621356214562155621656217562185621956220562215622256223562245622556226562275622856229562305623156232562335623456235562365623756238562395624056241562425624356244562455624656247562485624956250562515625256253562545625556256562575625856259562605626156262562635626456265562665626756268562695627056271562725627356274562755627656277562785627956280562815628256283562845628556286562875628856289562905629156292562935629456295562965629756298562995630056301563025630356304563055630656307563085630956310563115631256313563145631556316563175631856319563205632156322563235632456325563265632756328563295633056331563325633356334563355633656337563385633956340563415634256343563445634556346563475634856349563505635156352563535635456355563565635756358563595636056361563625636356364563655636656367563685636956370563715637256373563745637556376563775637856379563805638156382563835638456385563865638756388563895639056391563925639356394563955639656397563985639956400564015640256403564045640556406564075640856409564105641156412564135641456415564165641756418564195642056421564225642356424564255642656427564285642956430564315643256433564345643556436564375643856439564405644156442564435644456445564465644756448564495645056451564525645356454564555645656457564585645956460564615646256463564645646556466564675646856469564705647156472564735647456475564765647756478564795648056481564825648356484564855648656487564885648956490564915649256493564945649556496564975649856499565005650156502565035650456505565065650756508565095651056511565125651356514565155651656517565185651956520565215652256523565245652556526565275652856529565305653156532565335653456535565365653756538565395654056541565425654356544565455654656547565485654956550565515655256553565545655556556565575655856559565605656156562565635656456565565665656756568565695657056571565725657356574565755657656577565785657956580565815658256583565845658556586565875658856589565905659156592565935659456595565965659756598565995660056601566025660356604566055660656607566085660956610566115661256613566145661556616566175661856619566205662156622566235662456625566265662756628566295663056631566325663356634566355663656637566385663956640566415664256643566445664556646566475664856649566505665156652566535665456655566565665756658566595666056661566625666356664566655666656667566685666956670566715667256673566745667556676566775667856679566805668156682566835668456685566865668756688566895669056691566925669356694566955669656697566985669956700567015670256703567045670556706567075670856709567105671156712567135671456715567165671756718567195672056721567225672356724567255672656727567285672956730567315673256733567345673556736567375673856739567405674156742567435674456745567465674756748567495675056751567525675356754567555675656757567585675956760567615676256763567645676556766567675676856769567705677156772567735677456775567765677756778567795678056781567825678356784567855678656787567885678956790567915679256793567945679556796567975679856799568005680156802568035680456805568065680756808568095681056811568125681356814568155681656817568185681956820568215682256823568245682556826568275682856829568305683156832568335683456835568365683756838568395684056841568425684356844568455684656847568485684956850568515685256853568545685556856568575685856859568605686156862568635686456865568665686756868568695687056871568725687356874568755687656877568785687956880568815688256883568845688556886568875688856889568905689156892568935689456895568965689756898568995690056901569025690356904569055690656907569085690956910569115691256913569145691556916569175691856919569205692156922569235692456925569265692756928569295693056931569325693356934569355693656937569385693956940569415694256943569445694556946569475694856949569505695156952569535695456955569565695756958569595696056961569625696356964569655696656967569685696956970569715697256973569745697556976569775697856979569805698156982569835698456985569865698756988569895699056991569925699356994569955699656997569985699957000570015700257003570045700557006570075700857009570105701157012570135701457015570165701757018570195702057021570225702357024570255702657027570285702957030570315703257033570345703557036570375703857039570405704157042570435704457045570465704757048570495705057051570525705357054570555705657057570585705957060570615706257063570645706557066570675706857069570705707157072570735707457075570765707757078570795708057081570825708357084570855708657087570885708957090570915709257093570945709557096570975709857099571005710157102571035710457105571065710757108571095711057111571125711357114571155711657117571185711957120571215712257123571245712557126571275712857129571305713157132571335713457135571365713757138571395714057141571425714357144571455714657147571485714957150571515715257153571545715557156571575715857159571605716157162571635716457165571665716757168571695717057171571725717357174571755717657177571785717957180571815718257183571845718557186571875718857189571905719157192571935719457195571965719757198571995720057201572025720357204572055720657207572085720957210572115721257213572145721557216572175721857219572205722157222572235722457225572265722757228572295723057231572325723357234572355723657237572385723957240572415724257243572445724557246572475724857249572505725157252572535725457255572565725757258572595726057261572625726357264572655726657267572685726957270572715727257273572745727557276572775727857279572805728157282572835728457285572865728757288572895729057291572925729357294572955729657297572985729957300573015730257303573045730557306573075730857309573105731157312573135731457315573165731757318573195732057321573225732357324573255732657327573285732957330573315733257333573345733557336573375733857339573405734157342573435734457345573465734757348573495735057351573525735357354573555735657357573585735957360573615736257363573645736557366573675736857369573705737157372573735737457375573765737757378573795738057381573825738357384573855738657387573885738957390573915739257393573945739557396573975739857399574005740157402574035740457405574065740757408574095741057411574125741357414574155741657417574185741957420574215742257423574245742557426574275742857429574305743157432574335743457435574365743757438574395744057441574425744357444574455744657447574485744957450574515745257453574545745557456574575745857459574605746157462574635746457465574665746757468574695747057471574725747357474574755747657477574785747957480574815748257483574845748557486574875748857489574905749157492574935749457495574965749757498574995750057501575025750357504575055750657507575085750957510575115751257513575145751557516575175751857519575205752157522575235752457525575265752757528575295753057531575325753357534575355753657537575385753957540575415754257543575445754557546575475754857549575505755157552575535755457555575565755757558575595756057561575625756357564575655756657567575685756957570575715757257573575745757557576575775757857579575805758157582575835758457585575865758757588575895759057591575925759357594575955759657597575985759957600576015760257603576045760557606576075760857609576105761157612576135761457615576165761757618576195762057621576225762357624576255762657627576285762957630576315763257633576345763557636576375763857639576405764157642576435764457645576465764757648576495765057651576525765357654576555765657657576585765957660576615766257663576645766557666576675766857669576705767157672576735767457675576765767757678576795768057681576825768357684576855768657687576885768957690576915769257693576945769557696576975769857699577005770157702577035770457705577065770757708577095771057711577125771357714577155771657717577185771957720577215772257723577245772557726577275772857729577305773157732577335773457735577365773757738577395774057741577425774357744577455774657747577485774957750577515775257753577545775557756577575775857759577605776157762577635776457765577665776757768577695777057771577725777357774577755777657777577785777957780577815778257783577845778557786577875778857789577905779157792577935779457795577965779757798577995780057801578025780357804578055780657807578085780957810578115781257813578145781557816578175781857819578205782157822578235782457825578265782757828578295783057831578325783357834578355783657837578385783957840578415784257843578445784557846578475784857849578505785157852578535785457855578565785757858578595786057861578625786357864578655786657867578685786957870578715787257873578745787557876578775787857879578805788157882578835788457885578865788757888578895789057891578925789357894578955789657897578985789957900579015790257903579045790557906579075790857909579105791157912579135791457915579165791757918579195792057921579225792357924579255792657927579285792957930579315793257933579345793557936579375793857939579405794157942579435794457945579465794757948579495795057951579525795357954579555795657957579585795957960579615796257963579645796557966579675796857969579705797157972579735797457975579765797757978579795798057981579825798357984579855798657987579885798957990579915799257993579945799557996579975799857999580005800158002580035800458005580065800758008580095801058011580125801358014580155801658017580185801958020580215802258023580245802558026580275802858029580305803158032580335803458035580365803758038580395804058041580425804358044580455804658047580485804958050580515805258053580545805558056580575805858059580605806158062580635806458065580665806758068580695807058071580725807358074580755807658077580785807958080580815808258083580845808558086580875808858089580905809158092580935809458095580965809758098580995810058101581025810358104581055810658107581085810958110581115811258113581145811558116581175811858119581205812158122581235812458125581265812758128581295813058131581325813358134581355813658137581385813958140581415814258143581445814558146581475814858149581505815158152581535815458155581565815758158581595816058161581625816358164581655816658167581685816958170581715817258173581745817558176581775817858179581805818158182581835818458185581865818758188581895819058191581925819358194581955819658197581985819958200582015820258203582045820558206582075820858209582105821158212582135821458215582165821758218582195822058221582225822358224582255822658227582285822958230582315823258233582345823558236582375823858239582405824158242582435824458245582465824758248582495825058251582525825358254582555825658257582585825958260582615826258263582645826558266582675826858269582705827158272582735827458275582765827758278582795828058281582825828358284582855828658287582885828958290582915829258293582945829558296582975829858299583005830158302583035830458305583065830758308583095831058311583125831358314583155831658317583185831958320583215832258323583245832558326583275832858329583305833158332583335833458335583365833758338583395834058341583425834358344583455834658347583485834958350583515835258353583545835558356583575835858359583605836158362583635836458365583665836758368583695837058371583725837358374583755837658377583785837958380583815838258383583845838558386583875838858389583905839158392583935839458395583965839758398583995840058401584025840358404584055840658407584085840958410584115841258413584145841558416584175841858419584205842158422584235842458425584265842758428584295843058431584325843358434584355843658437584385843958440584415844258443584445844558446584475844858449584505845158452584535845458455584565845758458584595846058461584625846358464584655846658467584685846958470584715847258473584745847558476584775847858479584805848158482584835848458485584865848758488584895849058491584925849358494584955849658497584985849958500585015850258503585045850558506585075850858509585105851158512585135851458515585165851758518585195852058521585225852358524585255852658527585285852958530585315853258533585345853558536585375853858539585405854158542585435854458545585465854758548585495855058551585525855358554585555855658557585585855958560585615856258563585645856558566585675856858569585705857158572585735857458575585765857758578585795858058581585825858358584585855858658587585885858958590585915859258593585945859558596585975859858599586005860158602586035860458605586065860758608586095861058611586125861358614586155861658617586185861958620586215862258623586245862558626586275862858629586305863158632586335863458635586365863758638586395864058641586425864358644586455864658647586485864958650586515865258653586545865558656586575865858659586605866158662586635866458665586665866758668586695867058671586725867358674586755867658677586785867958680586815868258683586845868558686586875868858689586905869158692586935869458695586965869758698586995870058701587025870358704587055870658707587085870958710587115871258713587145871558716587175871858719587205872158722587235872458725587265872758728587295873058731587325873358734587355873658737587385873958740587415874258743587445874558746587475874858749587505875158752587535875458755587565875758758587595876058761587625876358764587655876658767587685876958770587715877258773587745877558776587775877858779587805878158782587835878458785587865878758788587895879058791587925879358794587955879658797587985879958800588015880258803588045880558806588075880858809588105881158812588135881458815588165881758818588195882058821588225882358824588255882658827588285882958830588315883258833588345883558836588375883858839588405884158842588435884458845588465884758848588495885058851588525885358854588555885658857588585885958860588615886258863588645886558866588675886858869588705887158872588735887458875588765887758878588795888058881588825888358884588855888658887588885888958890588915889258893588945889558896588975889858899589005890158902589035890458905589065890758908589095891058911589125891358914589155891658917589185891958920589215892258923589245892558926589275892858929589305893158932589335893458935589365893758938589395894058941589425894358944589455894658947589485894958950589515895258953589545895558956589575895858959589605896158962589635896458965589665896758968589695897058971589725897358974589755897658977589785897958980589815898258983589845898558986589875898858989589905899158992589935899458995589965899758998589995900059001590025900359004590055900659007590085900959010590115901259013590145901559016590175901859019590205902159022590235902459025590265902759028590295903059031590325903359034590355903659037590385903959040590415904259043590445904559046590475904859049590505905159052590535905459055590565905759058590595906059061590625906359064590655906659067590685906959070590715907259073590745907559076590775907859079590805908159082590835908459085590865908759088590895909059091590925909359094590955909659097590985909959100591015910259103591045910559106591075910859109591105911159112591135911459115591165911759118591195912059121591225912359124591255912659127591285912959130591315913259133591345913559136591375913859139591405914159142591435914459145591465914759148591495915059151591525915359154591555915659157591585915959160591615916259163591645916559166591675916859169591705917159172591735917459175591765917759178591795918059181591825918359184591855918659187591885918959190591915919259193591945919559196591975919859199592005920159202592035920459205592065920759208592095921059211592125921359214592155921659217592185921959220592215922259223592245922559226592275922859229592305923159232592335923459235592365923759238592395924059241592425924359244592455924659247592485924959250592515925259253592545925559256592575925859259592605926159262592635926459265592665926759268592695927059271592725927359274592755927659277592785927959280592815928259283592845928559286592875928859289592905929159292592935929459295592965929759298592995930059301593025930359304593055930659307593085930959310593115931259313593145931559316593175931859319593205932159322593235932459325593265932759328593295933059331593325933359334593355933659337593385933959340593415934259343593445934559346593475934859349593505935159352593535935459355593565935759358593595936059361593625936359364593655936659367593685936959370593715937259373593745937559376593775937859379593805938159382593835938459385593865938759388593895939059391593925939359394593955939659397593985939959400594015940259403594045940559406594075940859409594105941159412594135941459415594165941759418594195942059421594225942359424594255942659427594285942959430594315943259433594345943559436594375943859439594405944159442594435944459445594465944759448594495945059451594525945359454594555945659457594585945959460594615946259463594645946559466594675946859469594705947159472594735947459475594765947759478594795948059481594825948359484594855948659487594885948959490594915949259493594945949559496594975949859499595005950159502595035950459505595065950759508595095951059511595125951359514595155951659517595185951959520595215952259523595245952559526595275952859529595305953159532595335953459535595365953759538595395954059541595425954359544595455954659547595485954959550595515955259553595545955559556595575955859559595605956159562595635956459565595665956759568595695957059571595725957359574595755957659577595785957959580595815958259583595845958559586595875958859589595905959159592595935959459595595965959759598595995960059601596025960359604596055960659607596085960959610596115961259613596145961559616596175961859619596205962159622596235962459625596265962759628596295963059631596325963359634596355963659637596385963959640596415964259643596445964559646596475964859649596505965159652596535965459655596565965759658596595966059661596625966359664596655966659667596685966959670596715967259673596745967559676596775967859679596805968159682596835968459685596865968759688596895969059691596925969359694596955969659697596985969959700597015970259703597045970559706597075970859709597105971159712597135971459715597165971759718597195972059721597225972359724597255972659727597285972959730597315973259733597345973559736597375973859739597405974159742597435974459745597465974759748597495975059751597525975359754597555975659757597585975959760597615976259763597645976559766597675976859769597705977159772597735977459775597765977759778597795978059781597825978359784597855978659787597885978959790597915979259793597945979559796597975979859799598005980159802598035980459805598065980759808598095981059811598125981359814598155981659817598185981959820598215982259823598245982559826598275982859829598305983159832598335983459835598365983759838598395984059841598425984359844598455984659847598485984959850598515985259853598545985559856598575985859859598605986159862598635986459865598665986759868598695987059871598725987359874598755987659877598785987959880598815988259883598845988559886598875988859889598905989159892598935989459895598965989759898598995990059901599025990359904599055990659907599085990959910599115991259913599145991559916599175991859919599205992159922599235992459925599265992759928599295993059931599325993359934599355993659937599385993959940599415994259943599445994559946599475994859949599505995159952599535995459955599565995759958599595996059961599625996359964599655996659967599685996959970599715997259973599745997559976599775997859979599805998159982599835998459985599865998759988599895999059991599925999359994599955999659997599985999960000600016000260003600046000560006600076000860009600106001160012600136001460015600166001760018600196002060021600226002360024600256002660027600286002960030600316003260033600346003560036600376003860039600406004160042600436004460045600466004760048600496005060051600526005360054600556005660057600586005960060600616006260063600646006560066600676006860069600706007160072600736007460075600766007760078600796008060081600826008360084600856008660087600886008960090600916009260093600946009560096600976009860099601006010160102601036010460105601066010760108601096011060111601126011360114601156011660117601186011960120601216012260123601246012560126601276012860129601306013160132601336013460135601366013760138601396014060141601426014360144601456014660147601486014960150601516015260153601546015560156601576015860159601606016160162601636016460165601666016760168601696017060171601726017360174601756017660177601786017960180601816018260183601846018560186601876018860189601906019160192601936019460195601966019760198601996020060201602026020360204602056020660207602086020960210602116021260213602146021560216602176021860219602206022160222602236022460225602266022760228602296023060231602326023360234602356023660237602386023960240602416024260243602446024560246602476024860249602506025160252602536025460255602566025760258602596026060261602626026360264602656026660267602686026960270602716027260273602746027560276602776027860279602806028160282602836028460285602866028760288602896029060291602926029360294602956029660297602986029960300603016030260303603046030560306603076030860309603106031160312603136031460315603166031760318603196032060321603226032360324603256032660327603286032960330603316033260333603346033560336603376033860339603406034160342603436034460345603466034760348603496035060351603526035360354603556035660357603586035960360603616036260363603646036560366603676036860369603706037160372603736037460375603766037760378603796038060381603826038360384603856038660387603886038960390603916039260393603946039560396603976039860399604006040160402604036040460405604066040760408604096041060411604126041360414604156041660417604186041960420604216042260423604246042560426604276042860429604306043160432604336043460435604366043760438604396044060441604426044360444604456044660447604486044960450604516045260453604546045560456604576045860459604606046160462604636046460465604666046760468604696047060471604726047360474604756047660477604786047960480604816048260483604846048560486604876048860489604906049160492604936049460495604966049760498604996050060501605026050360504605056050660507605086050960510605116051260513605146051560516605176051860519605206052160522605236052460525605266052760528605296053060531605326053360534605356053660537605386053960540605416054260543605446054560546605476054860549605506055160552605536055460555605566055760558605596056060561605626056360564605656056660567605686056960570605716057260573605746057560576605776057860579605806058160582605836058460585605866058760588605896059060591605926059360594605956059660597605986059960600606016060260603606046060560606606076060860609606106061160612606136061460615606166061760618606196062060621606226062360624606256062660627606286062960630606316063260633606346063560636606376063860639606406064160642606436064460645606466064760648606496065060651606526065360654606556065660657606586065960660606616066260663606646066560666606676066860669606706067160672606736067460675606766067760678606796068060681606826068360684606856068660687606886068960690606916069260693606946069560696606976069860699607006070160702607036070460705607066070760708607096071060711607126071360714607156071660717607186071960720607216072260723607246072560726607276072860729607306073160732607336073460735607366073760738607396074060741607426074360744607456074660747607486074960750607516075260753607546075560756607576075860759607606076160762607636076460765607666076760768607696077060771607726077360774607756077660777607786077960780607816078260783607846078560786607876078860789607906079160792607936079460795607966079760798607996080060801608026080360804608056080660807608086080960810608116081260813608146081560816608176081860819608206082160822608236082460825608266082760828608296083060831608326083360834608356083660837608386083960840608416084260843608446084560846608476084860849608506085160852608536085460855608566085760858608596086060861608626086360864608656086660867608686086960870608716087260873608746087560876608776087860879608806088160882608836088460885608866088760888608896089060891608926089360894608956089660897608986089960900609016090260903609046090560906609076090860909609106091160912609136091460915609166091760918609196092060921609226092360924609256092660927609286092960930609316093260933609346093560936609376093860939609406094160942609436094460945609466094760948609496095060951609526095360954609556095660957609586095960960609616096260963609646096560966609676096860969609706097160972609736097460975609766097760978609796098060981609826098360984609856098660987609886098960990609916099260993609946099560996609976099860999610006100161002610036100461005610066100761008610096101061011610126101361014610156101661017610186101961020610216102261023610246102561026610276102861029610306103161032610336103461035610366103761038610396104061041610426104361044610456104661047610486104961050610516105261053610546105561056610576105861059610606106161062610636106461065610666106761068610696107061071610726107361074610756107661077610786107961080610816108261083610846108561086610876108861089610906109161092610936109461095610966109761098610996110061101611026110361104611056110661107611086110961110611116111261113611146111561116611176111861119611206112161122611236112461125611266112761128611296113061131611326113361134611356113661137611386113961140611416114261143611446114561146611476114861149611506115161152611536115461155611566115761158611596116061161611626116361164611656116661167611686116961170611716117261173611746117561176611776117861179611806118161182611836118461185611866118761188611896119061191611926119361194611956119661197611986119961200612016120261203612046120561206612076120861209612106121161212612136121461215612166121761218612196122061221612226122361224612256122661227612286122961230612316123261233612346123561236612376123861239612406124161242612436124461245612466124761248612496125061251612526125361254612556125661257612586125961260612616126261263612646126561266612676126861269612706127161272612736127461275612766127761278612796128061281612826128361284612856128661287612886128961290612916129261293612946129561296612976129861299613006130161302613036130461305613066130761308613096131061311613126131361314613156131661317613186131961320613216132261323613246132561326613276132861329613306133161332613336133461335613366133761338613396134061341613426134361344613456134661347613486134961350613516135261353613546135561356613576135861359613606136161362613636136461365613666136761368613696137061371613726137361374613756137661377613786137961380613816138261383613846138561386613876138861389613906139161392613936139461395613966139761398613996140061401614026140361404614056140661407614086140961410614116141261413614146141561416614176141861419614206142161422614236142461425614266142761428614296143061431614326143361434614356143661437614386143961440614416144261443614446144561446614476144861449614506145161452614536145461455614566145761458614596146061461614626146361464614656146661467614686146961470614716147261473614746147561476614776147861479614806148161482614836148461485614866148761488614896149061491614926149361494614956149661497614986149961500615016150261503615046150561506615076150861509615106151161512615136151461515615166151761518615196152061521615226152361524615256152661527615286152961530615316153261533615346153561536615376153861539615406154161542615436154461545615466154761548615496155061551615526155361554615556155661557615586155961560615616156261563615646156561566615676156861569615706157161572615736157461575615766157761578615796158061581615826158361584615856158661587615886158961590615916159261593615946159561596615976159861599616006160161602616036160461605616066160761608616096161061611616126161361614616156161661617616186161961620616216162261623616246162561626616276162861629616306163161632616336163461635616366163761638616396164061641616426164361644616456164661647616486164961650616516165261653616546165561656616576165861659616606166161662616636166461665616666166761668616696167061671616726167361674616756167661677616786167961680616816168261683616846168561686616876168861689616906169161692616936169461695616966169761698616996170061701617026170361704617056170661707617086170961710617116171261713617146171561716617176171861719617206172161722617236172461725617266172761728617296173061731617326173361734617356173661737617386173961740617416174261743617446174561746617476174861749617506175161752617536175461755617566175761758617596176061761617626176361764617656176661767617686176961770617716177261773617746177561776617776177861779617806178161782617836178461785617866178761788617896179061791617926179361794617956179661797617986179961800618016180261803618046180561806618076180861809618106181161812618136181461815618166181761818618196182061821618226182361824618256182661827618286182961830618316183261833618346183561836618376183861839618406184161842618436184461845618466184761848618496185061851618526185361854618556185661857618586185961860618616186261863618646186561866618676186861869618706187161872618736187461875618766187761878618796188061881618826188361884618856188661887618886188961890618916189261893618946189561896618976189861899619006190161902619036190461905619066190761908619096191061911619126191361914619156191661917619186191961920619216192261923619246192561926619276192861929619306193161932619336193461935619366193761938619396194061941619426194361944619456194661947619486194961950619516195261953619546195561956619576195861959619606196161962619636196461965619666196761968619696197061971619726197361974619756197661977619786197961980619816198261983619846198561986619876198861989619906199161992619936199461995619966199761998619996200062001620026200362004620056200662007620086200962010620116201262013620146201562016620176201862019620206202162022620236202462025620266202762028620296203062031620326203362034620356203662037620386203962040620416204262043620446204562046620476204862049620506205162052620536205462055620566205762058620596206062061620626206362064620656206662067620686206962070620716207262073620746207562076620776207862079620806208162082620836208462085620866208762088620896209062091620926209362094620956209662097620986209962100621016210262103621046210562106621076210862109621106211162112621136211462115621166211762118621196212062121621226212362124621256212662127621286212962130621316213262133621346213562136621376213862139621406214162142621436214462145621466214762148621496215062151621526215362154621556215662157621586215962160621616216262163621646216562166621676216862169621706217162172621736217462175621766217762178621796218062181621826218362184621856218662187621886218962190621916219262193621946219562196621976219862199622006220162202622036220462205622066220762208622096221062211622126221362214622156221662217622186221962220622216222262223622246222562226622276222862229622306223162232622336223462235622366223762238622396224062241622426224362244622456224662247622486224962250622516225262253622546225562256622576225862259622606226162262622636226462265622666226762268622696227062271622726227362274622756227662277622786227962280622816228262283622846228562286622876228862289622906229162292622936229462295622966229762298622996230062301623026230362304623056230662307623086230962310623116231262313623146231562316623176231862319623206232162322623236232462325623266232762328623296233062331623326233362334623356233662337623386233962340623416234262343623446234562346623476234862349623506235162352623536235462355623566235762358623596236062361623626236362364623656236662367623686236962370623716237262373623746237562376623776237862379623806238162382623836238462385623866238762388623896239062391623926239362394623956239662397623986239962400624016240262403624046240562406624076240862409624106241162412624136241462415624166241762418624196242062421624226242362424624256242662427624286242962430624316243262433624346243562436624376243862439624406244162442624436244462445624466244762448624496245062451624526245362454624556245662457624586245962460624616246262463624646246562466624676246862469624706247162472624736247462475624766247762478624796248062481624826248362484624856248662487624886248962490624916249262493624946249562496624976249862499625006250162502625036250462505625066250762508625096251062511625126251362514625156251662517625186251962520625216252262523625246252562526625276252862529625306253162532625336253462535625366253762538625396254062541625426254362544625456254662547625486254962550625516255262553625546255562556625576255862559625606256162562625636256462565625666256762568625696257062571625726257362574625756257662577625786257962580625816258262583625846258562586625876258862589625906259162592625936259462595625966259762598625996260062601626026260362604626056260662607626086260962610626116261262613626146261562616626176261862619626206262162622626236262462625626266262762628626296263062631626326263362634626356263662637626386263962640626416264262643626446264562646626476264862649626506265162652626536265462655626566265762658626596266062661626626266362664626656266662667626686266962670626716267262673626746267562676626776267862679626806268162682626836268462685626866268762688626896269062691626926269362694626956269662697626986269962700627016270262703627046270562706627076270862709627106271162712627136271462715627166271762718627196272062721627226272362724627256272662727627286272962730627316273262733627346273562736627376273862739627406274162742627436274462745627466274762748627496275062751627526275362754627556275662757627586275962760627616276262763627646276562766627676276862769627706277162772627736277462775627766277762778627796278062781627826278362784627856278662787627886278962790627916279262793627946279562796627976279862799628006280162802628036280462805628066280762808628096281062811628126281362814628156281662817628186281962820628216282262823628246282562826628276282862829628306283162832628336283462835628366283762838628396284062841628426284362844628456284662847628486284962850628516285262853628546285562856628576285862859628606286162862628636286462865628666286762868628696287062871628726287362874628756287662877628786287962880628816288262883628846288562886628876288862889628906289162892628936289462895628966289762898628996290062901629026290362904629056290662907629086290962910629116291262913629146291562916629176291862919629206292162922629236292462925629266292762928629296293062931629326293362934629356293662937629386293962940629416294262943629446294562946629476294862949629506295162952629536295462955629566295762958629596296062961629626296362964629656296662967629686296962970629716297262973629746297562976629776297862979629806298162982629836298462985629866298762988629896299062991629926299362994629956299662997629986299963000630016300263003630046300563006630076300863009630106301163012630136301463015630166301763018630196302063021630226302363024630256302663027630286302963030630316303263033630346303563036630376303863039630406304163042630436304463045630466304763048630496305063051630526305363054630556305663057630586305963060630616306263063630646306563066630676306863069630706307163072630736307463075630766307763078630796308063081630826308363084630856308663087630886308963090630916309263093630946309563096630976309863099631006310163102631036310463105631066310763108631096311063111631126311363114631156311663117631186311963120631216312263123631246312563126631276312863129631306313163132631336313463135631366313763138631396314063141631426314363144631456314663147631486314963150631516315263153631546315563156631576315863159631606316163162631636316463165631666316763168631696317063171631726317363174631756317663177631786317963180631816318263183631846318563186631876318863189631906319163192631936319463195631966319763198631996320063201632026320363204632056320663207632086320963210632116321263213632146321563216632176321863219632206322163222632236322463225632266322763228632296323063231632326323363234632356323663237632386323963240632416324263243632446324563246632476324863249632506325163252632536325463255632566325763258632596326063261632626326363264632656326663267632686326963270632716327263273632746327563276632776327863279632806328163282632836328463285632866328763288632896329063291632926329363294632956329663297632986329963300633016330263303633046330563306633076330863309633106331163312633136331463315633166331763318633196332063321633226332363324633256332663327633286332963330633316333263333633346333563336633376333863339633406334163342633436334463345633466334763348633496335063351633526335363354633556335663357633586335963360633616336263363633646336563366633676336863369633706337163372633736337463375633766337763378633796338063381633826338363384633856338663387633886338963390633916339263393633946339563396633976339863399634006340163402634036340463405634066340763408634096341063411634126341363414634156341663417634186341963420634216342263423634246342563426634276342863429634306343163432634336343463435634366343763438634396344063441634426344363444634456344663447634486344963450634516345263453634546345563456634576345863459634606346163462634636346463465634666346763468634696347063471634726347363474634756347663477634786347963480634816348263483634846348563486634876348863489634906349163492634936349463495634966349763498634996350063501635026350363504635056350663507635086350963510635116351263513635146351563516635176351863519635206352163522635236352463525635266352763528635296353063531635326353363534635356353663537635386353963540635416354263543635446354563546635476354863549635506355163552635536355463555635566355763558635596356063561635626356363564635656356663567635686356963570635716357263573635746357563576635776357863579635806358163582635836358463585635866358763588635896359063591635926359363594635956359663597635986359963600636016360263603636046360563606636076360863609636106361163612636136361463615636166361763618636196362063621636226362363624636256362663627636286362963630636316363263633636346363563636636376363863639636406364163642636436364463645636466364763648636496365063651636526365363654636556365663657636586365963660636616366263663636646366563666636676366863669636706367163672636736367463675636766367763678636796368063681636826368363684636856368663687636886368963690636916369263693636946369563696636976369863699637006370163702637036370463705637066370763708637096371063711637126371363714637156371663717637186371963720637216372263723637246372563726637276372863729637306373163732637336373463735637366373763738637396374063741637426374363744637456374663747637486374963750637516375263753637546375563756637576375863759637606376163762637636376463765637666376763768637696377063771637726377363774637756377663777637786377963780637816378263783637846378563786637876378863789637906379163792637936379463795637966379763798637996380063801638026380363804638056380663807638086380963810638116381263813638146381563816638176381863819638206382163822638236382463825638266382763828638296383063831638326383363834638356383663837638386383963840638416384263843638446384563846638476384863849638506385163852638536385463855638566385763858638596386063861638626386363864638656386663867638686386963870638716387263873638746387563876638776387863879638806388163882638836388463885638866388763888638896389063891638926389363894638956389663897638986389963900639016390263903639046390563906639076390863909639106391163912639136391463915639166391763918639196392063921639226392363924639256392663927639286392963930639316393263933639346393563936639376393863939639406394163942639436394463945639466394763948639496395063951639526395363954639556395663957639586395963960639616396263963639646396563966639676396863969639706397163972639736397463975639766397763978639796398063981639826398363984639856398663987639886398963990639916399263993639946399563996639976399863999640006400164002640036400464005640066400764008640096401064011640126401364014640156401664017640186401964020640216402264023640246402564026640276402864029640306403164032640336403464035640366403764038640396404064041640426404364044640456404664047640486404964050640516405264053640546405564056640576405864059640606406164062640636406464065640666406764068640696407064071640726407364074640756407664077640786407964080640816408264083640846408564086640876408864089640906409164092640936409464095640966409764098640996410064101641026410364104641056410664107641086410964110641116411264113641146411564116641176411864119641206412164122641236412464125641266412764128641296413064131641326413364134641356413664137641386413964140641416414264143641446414564146641476414864149641506415164152641536415464155641566415764158641596416064161641626416364164641656416664167641686416964170641716417264173641746417564176641776417864179641806418164182641836418464185641866418764188641896419064191641926419364194641956419664197641986419964200642016420264203642046420564206642076420864209642106421164212642136421464215642166421764218642196422064221642226422364224642256422664227642286422964230642316423264233642346423564236642376423864239642406424164242642436424464245642466424764248642496425064251642526425364254642556425664257642586425964260642616426264263642646426564266642676426864269642706427164272642736427464275642766427764278642796428064281642826428364284642856428664287642886428964290642916429264293642946429564296642976429864299643006430164302643036430464305643066430764308643096431064311643126431364314643156431664317643186431964320643216432264323643246432564326643276432864329643306433164332643336433464335643366433764338643396434064341643426434364344643456434664347643486434964350643516435264353643546435564356643576435864359643606436164362643636436464365643666436764368643696437064371643726437364374643756437664377643786437964380643816438264383643846438564386643876438864389643906439164392643936439464395643966439764398643996440064401644026440364404644056440664407644086440964410644116441264413644146441564416644176441864419644206442164422644236442464425644266442764428644296443064431644326443364434644356443664437644386443964440644416444264443644446444564446644476444864449644506445164452644536445464455644566445764458644596446064461644626446364464644656446664467644686446964470644716447264473644746447564476644776447864479644806448164482644836448464485644866448764488644896449064491644926449364494644956449664497644986449964500645016450264503645046450564506645076450864509645106451164512645136451464515645166451764518645196452064521645226452364524645256452664527645286452964530645316453264533645346453564536645376453864539645406454164542645436454464545645466454764548645496455064551645526455364554645556455664557645586455964560645616456264563645646456564566645676456864569645706457164572645736457464575645766457764578645796458064581645826458364584645856458664587645886458964590645916459264593645946459564596645976459864599646006460164602646036460464605646066460764608646096461064611646126461364614646156461664617646186461964620646216462264623646246462564626646276462864629646306463164632646336463464635646366463764638646396464064641646426464364644646456464664647646486464964650646516465264653646546465564656646576465864659646606466164662646636466464665646666466764668646696467064671646726467364674646756467664677646786467964680646816468264683646846468564686646876468864689646906469164692646936469464695646966469764698646996470064701647026470364704647056470664707647086470964710647116471264713647146471564716647176471864719647206472164722647236472464725647266472764728647296473064731647326473364734647356473664737647386473964740647416474264743647446474564746647476474864749647506475164752647536475464755647566475764758647596476064761647626476364764647656476664767647686476964770647716477264773647746477564776647776477864779647806478164782647836478464785647866478764788647896479064791647926479364794647956479664797647986479964800648016480264803648046480564806648076480864809648106481164812648136481464815648166481764818648196482064821648226482364824648256482664827648286482964830648316483264833648346483564836648376483864839648406484164842648436484464845648466484764848648496485064851648526485364854648556485664857648586485964860648616486264863648646486564866648676486864869648706487164872648736487464875648766487764878648796488064881648826488364884648856488664887648886488964890648916489264893648946489564896648976489864899649006490164902649036490464905649066490764908649096491064911649126491364914649156491664917649186491964920649216492264923649246492564926649276492864929649306493164932649336493464935649366493764938649396494064941649426494364944649456494664947649486494964950649516495264953649546495564956649576495864959649606496164962649636496464965649666496764968649696497064971649726497364974649756497664977649786497964980649816498264983649846498564986649876498864989649906499164992649936499464995649966499764998649996500065001650026500365004650056500665007650086500965010650116501265013650146501565016650176501865019650206502165022650236502465025650266502765028650296503065031650326503365034650356503665037650386503965040650416504265043650446504565046650476504865049650506505165052650536505465055650566505765058650596506065061650626506365064650656506665067650686506965070650716507265073650746507565076650776507865079650806508165082650836508465085650866508765088650896509065091650926509365094650956509665097650986509965100651016510265103651046510565106651076510865109651106511165112651136511465115651166511765118651196512065121651226512365124651256512665127651286512965130651316513265133651346513565136651376513865139651406514165142651436514465145651466514765148651496515065151651526515365154651556515665157651586515965160651616516265163651646516565166651676516865169651706517165172651736517465175651766517765178651796518065181651826518365184651856518665187651886518965190651916519265193651946519565196651976519865199652006520165202652036520465205652066520765208652096521065211652126521365214652156521665217652186521965220652216522265223652246522565226652276522865229652306523165232652336523465235652366523765238652396524065241652426524365244652456524665247652486524965250652516525265253652546525565256652576525865259652606526165262652636526465265652666526765268652696527065271652726527365274652756527665277652786527965280652816528265283652846528565286652876528865289652906529165292652936529465295652966529765298652996530065301653026530365304653056530665307653086530965310653116531265313653146531565316653176531865319653206532165322653236532465325653266532765328653296533065331653326533365334653356533665337653386533965340653416534265343653446534565346653476534865349653506535165352653536535465355653566535765358653596536065361653626536365364653656536665367653686536965370653716537265373653746537565376653776537865379653806538165382653836538465385653866538765388653896539065391653926539365394653956539665397653986539965400654016540265403654046540565406654076540865409654106541165412654136541465415654166541765418654196542065421654226542365424654256542665427654286542965430654316543265433654346543565436654376543865439654406544165442654436544465445654466544765448654496545065451654526545365454654556545665457654586545965460654616546265463654646546565466654676546865469654706547165472654736547465475654766547765478654796548065481654826548365484654856548665487654886548965490654916549265493654946549565496654976549865499655006550165502655036550465505655066550765508655096551065511655126551365514655156551665517655186551965520655216552265523655246552565526655276552865529655306553165532655336553465535655366553765538655396554065541655426554365544655456554665547655486554965550655516555265553655546555565556655576555865559655606556165562655636556465565655666556765568655696557065571655726557365574655756557665577655786557965580655816558265583655846558565586655876558865589655906559165592655936559465595655966559765598655996560065601656026560365604656056560665607656086560965610656116561265613656146561565616656176561865619656206562165622656236562465625656266562765628656296563065631656326563365634656356563665637656386563965640656416564265643656446564565646656476564865649656506565165652656536565465655656566565765658656596566065661656626566365664656656566665667656686566965670656716567265673656746567565676656776567865679656806568165682656836568465685656866568765688656896569065691656926569365694656956569665697656986569965700657016570265703657046570565706657076570865709657106571165712657136571465715657166571765718657196572065721657226572365724657256572665727657286572965730657316573265733657346573565736657376573865739657406574165742657436574465745657466574765748657496575065751657526575365754657556575665757657586575965760657616576265763657646576565766657676576865769657706577165772657736577465775657766577765778657796578065781657826578365784657856578665787657886578965790657916579265793657946579565796657976579865799658006580165802658036580465805658066580765808658096581065811658126581365814658156581665817658186581965820658216582265823658246582565826658276582865829658306583165832658336583465835658366583765838658396584065841658426584365844658456584665847658486584965850658516585265853658546585565856658576585865859658606586165862658636586465865658666586765868658696587065871658726587365874658756587665877658786587965880658816588265883658846588565886658876588865889658906589165892658936589465895658966589765898658996590065901659026590365904659056590665907659086590965910659116591265913659146591565916659176591865919659206592165922659236592465925659266592765928659296593065931659326593365934659356593665937659386593965940659416594265943659446594565946659476594865949659506595165952659536595465955659566595765958659596596065961659626596365964659656596665967659686596965970659716597265973659746597565976659776597865979659806598165982659836598465985659866598765988659896599065991659926599365994659956599665997659986599966000660016600266003660046600566006660076600866009660106601166012660136601466015660166601766018660196602066021660226602366024660256602666027660286602966030660316603266033660346603566036660376603866039660406604166042660436604466045660466604766048660496605066051660526605366054660556605666057660586605966060660616606266063660646606566066660676606866069660706607166072660736607466075660766607766078660796608066081660826608366084660856608666087660886608966090660916609266093660946609566096660976609866099661006610166102661036610466105661066610766108661096611066111661126611366114661156611666117661186611966120661216612266123661246612566126661276612866129661306613166132661336613466135661366613766138661396614066141661426614366144661456614666147661486614966150661516615266153661546615566156661576615866159661606616166162661636616466165661666616766168661696617066171661726617366174661756617666177661786617966180661816618266183661846618566186661876618866189661906619166192661936619466195661966619766198661996620066201662026620366204662056620666207662086620966210662116621266213662146621566216662176621866219662206622166222662236622466225662266622766228662296623066231662326623366234662356623666237662386623966240662416624266243662446624566246662476624866249662506625166252662536625466255662566625766258662596626066261662626626366264662656626666267662686626966270662716627266273662746627566276662776627866279662806628166282662836628466285662866628766288662896629066291662926629366294662956629666297662986629966300663016630266303663046630566306663076630866309663106631166312663136631466315663166631766318663196632066321663226632366324663256632666327663286632966330663316633266333663346633566336663376633866339663406634166342663436634466345663466634766348663496635066351663526635366354663556635666357663586635966360663616636266363663646636566366663676636866369663706637166372663736637466375663766637766378663796638066381663826638366384663856638666387663886638966390663916639266393663946639566396663976639866399664006640166402664036640466405664066640766408664096641066411664126641366414664156641666417664186641966420664216642266423664246642566426664276642866429664306643166432664336643466435664366643766438664396644066441664426644366444664456644666447664486644966450664516645266453664546645566456664576645866459664606646166462664636646466465664666646766468664696647066471664726647366474664756647666477664786647966480664816648266483664846648566486664876648866489664906649166492664936649466495664966649766498664996650066501665026650366504665056650666507665086650966510665116651266513665146651566516665176651866519665206652166522665236652466525665266652766528665296653066531665326653366534665356653666537665386653966540665416654266543665446654566546665476654866549665506655166552665536655466555665566655766558665596656066561665626656366564665656656666567665686656966570665716657266573665746657566576665776657866579665806658166582665836658466585665866658766588665896659066591665926659366594665956659666597665986659966600666016660266603666046660566606666076660866609666106661166612666136661466615666166661766618666196662066621666226662366624666256662666627666286662966630666316663266633666346663566636666376663866639666406664166642666436664466645666466664766648666496665066651666526665366654666556665666657666586665966660666616666266663666646666566666666676666866669666706667166672666736667466675666766667766678666796668066681666826668366684666856668666687666886668966690666916669266693666946669566696666976669866699667006670166702667036670466705667066670766708667096671066711667126671366714667156671666717667186671966720667216672266723667246672566726667276672866729667306673166732667336673466735667366673766738667396674066741667426674366744667456674666747667486674966750667516675266753667546675566756667576675866759667606676166762667636676466765667666676766768667696677066771667726677366774667756677666777667786677966780667816678266783667846678566786667876678866789667906679166792667936679466795667966679766798667996680066801668026680366804668056680666807668086680966810668116681266813668146681566816668176681866819668206682166822668236682466825668266682766828668296683066831668326683366834668356683666837668386683966840668416684266843668446684566846668476684866849668506685166852668536685466855668566685766858668596686066861668626686366864668656686666867668686686966870668716687266873668746687566876668776687866879668806688166882668836688466885668866688766888668896689066891668926689366894668956689666897668986689966900669016690266903669046690566906669076690866909669106691166912669136691466915669166691766918669196692066921669226692366924669256692666927669286692966930669316693266933669346693566936669376693866939669406694166942669436694466945669466694766948669496695066951669526695366954669556695666957669586695966960669616696266963669646696566966669676696866969669706697166972669736697466975669766697766978669796698066981669826698366984669856698666987669886698966990669916699266993669946699566996669976699866999670006700167002670036700467005670066700767008670096701067011670126701367014670156701667017670186701967020670216702267023670246702567026670276702867029670306703167032670336703467035670366703767038670396704067041670426704367044670456704667047670486704967050670516705267053670546705567056670576705867059670606706167062670636706467065670666706767068670696707067071670726707367074670756707667077670786707967080670816708267083670846708567086670876708867089670906709167092670936709467095670966709767098670996710067101671026710367104671056710667107671086710967110671116711267113671146711567116671176711867119671206712167122671236712467125671266712767128671296713067131671326713367134671356713667137671386713967140671416714267143671446714567146671476714867149671506715167152671536715467155671566715767158671596716067161671626716367164671656716667167671686716967170671716717267173671746717567176671776717867179671806718167182671836718467185671866718767188671896719067191671926719367194671956719667197671986719967200672016720267203672046720567206672076720867209672106721167212672136721467215672166721767218672196722067221672226722367224672256722667227672286722967230672316723267233672346723567236672376723867239672406724167242672436724467245672466724767248672496725067251672526725367254672556725667257672586725967260672616726267263672646726567266672676726867269672706727167272672736727467275672766727767278672796728067281672826728367284672856728667287672886728967290672916729267293672946729567296672976729867299673006730167302673036730467305673066730767308673096731067311673126731367314673156731667317673186731967320673216732267323673246732567326673276732867329673306733167332673336733467335673366733767338673396734067341673426734367344673456734667347673486734967350673516735267353673546735567356673576735867359673606736167362673636736467365673666736767368673696737067371673726737367374673756737667377673786737967380673816738267383673846738567386673876738867389673906739167392673936739467395673966739767398673996740067401674026740367404674056740667407674086740967410674116741267413674146741567416674176741867419674206742167422674236742467425674266742767428674296743067431674326743367434674356743667437674386743967440674416744267443674446744567446674476744867449674506745167452674536745467455674566745767458674596746067461674626746367464674656746667467674686746967470674716747267473674746747567476674776747867479674806748167482674836748467485674866748767488674896749067491674926749367494674956749667497674986749967500675016750267503675046750567506675076750867509675106751167512675136751467515675166751767518675196752067521675226752367524675256752667527675286752967530675316753267533675346753567536675376753867539675406754167542675436754467545675466754767548675496755067551675526755367554675556755667557675586755967560675616756267563675646756567566675676756867569675706757167572675736757467575675766757767578675796758067581675826758367584675856758667587675886758967590675916759267593675946759567596675976759867599676006760167602676036760467605676066760767608676096761067611676126761367614676156761667617676186761967620676216762267623676246762567626676276762867629676306763167632676336763467635676366763767638676396764067641676426764367644676456764667647676486764967650676516765267653676546765567656676576765867659676606766167662676636766467665676666766767668676696767067671676726767367674676756767667677676786767967680676816768267683676846768567686676876768867689676906769167692676936769467695676966769767698676996770067701677026770367704677056770667707677086770967710677116771267713677146771567716677176771867719677206772167722677236772467725677266772767728677296773067731677326773367734677356773667737677386773967740677416774267743677446774567746677476774867749677506775167752677536775467755677566775767758677596776067761677626776367764677656776667767677686776967770677716777267773677746777567776677776777867779677806778167782677836778467785677866778767788677896779067791677926779367794677956779667797677986779967800678016780267803678046780567806678076780867809678106781167812678136781467815678166781767818678196782067821678226782367824678256782667827678286782967830678316783267833678346783567836678376783867839678406784167842678436784467845678466784767848678496785067851678526785367854678556785667857678586785967860678616786267863678646786567866678676786867869678706787167872678736787467875678766787767878678796788067881678826788367884678856788667887678886788967890678916789267893678946789567896678976789867899679006790167902679036790467905679066790767908679096791067911679126791367914679156791667917679186791967920679216792267923679246792567926679276792867929679306793167932679336793467935679366793767938679396794067941679426794367944679456794667947679486794967950679516795267953679546795567956679576795867959679606796167962679636796467965679666796767968679696797067971679726797367974679756797667977679786797967980679816798267983679846798567986679876798867989679906799167992679936799467995679966799767998679996800068001680026800368004680056800668007680086800968010680116801268013680146801568016680176801868019680206802168022680236802468025680266802768028680296803068031680326803368034680356803668037680386803968040680416804268043680446804568046680476804868049680506805168052680536805468055680566805768058680596806068061680626806368064680656806668067680686806968070680716807268073680746807568076680776807868079680806808168082680836808468085680866808768088680896809068091680926809368094680956809668097680986809968100681016810268103681046810568106681076810868109681106811168112681136811468115681166811768118681196812068121681226812368124681256812668127681286812968130681316813268133681346813568136681376813868139681406814168142681436814468145681466814768148681496815068151681526815368154681556815668157681586815968160681616816268163681646816568166681676816868169681706817168172681736817468175681766817768178681796818068181681826818368184681856818668187681886818968190681916819268193681946819568196681976819868199682006820168202682036820468205682066820768208682096821068211682126821368214682156821668217682186821968220682216822268223682246822568226682276822868229682306823168232682336823468235682366823768238682396824068241682426824368244682456824668247682486824968250682516825268253682546825568256682576825868259682606826168262682636826468265682666826768268682696827068271682726827368274682756827668277682786827968280682816828268283682846828568286682876828868289682906829168292682936829468295682966829768298682996830068301683026830368304683056830668307683086830968310683116831268313683146831568316683176831868319683206832168322683236832468325683266832768328683296833068331683326833368334683356833668337683386833968340683416834268343683446834568346683476834868349683506835168352683536835468355683566835768358683596836068361683626836368364683656836668367683686836968370683716837268373683746837568376683776837868379683806838168382683836838468385683866838768388683896839068391683926839368394683956839668397683986839968400684016840268403684046840568406684076840868409684106841168412684136841468415684166841768418684196842068421684226842368424684256842668427684286842968430684316843268433684346843568436684376843868439684406844168442684436844468445684466844768448684496845068451684526845368454684556845668457684586845968460684616846268463684646846568466684676846868469684706847168472684736847468475684766847768478684796848068481684826848368484684856848668487684886848968490684916849268493684946849568496684976849868499685006850168502685036850468505685066850768508685096851068511685126851368514685156851668517685186851968520685216852268523685246852568526685276852868529685306853168532685336853468535685366853768538685396854068541685426854368544685456854668547685486854968550685516855268553685546855568556685576855868559685606856168562685636856468565685666856768568685696857068571685726857368574685756857668577685786857968580685816858268583685846858568586685876858868589685906859168592685936859468595685966859768598685996860068601686026860368604686056860668607686086860968610686116861268613686146861568616686176861868619686206862168622686236862468625686266862768628686296863068631686326863368634686356863668637686386863968640686416864268643686446864568646686476864868649686506865168652686536865468655686566865768658686596866068661686626866368664686656866668667686686866968670686716867268673686746867568676686776867868679686806868168682686836868468685686866868768688686896869068691686926869368694686956869668697686986869968700687016870268703687046870568706687076870868709687106871168712687136871468715687166871768718687196872068721687226872368724687256872668727687286872968730687316873268733687346873568736687376873868739687406874168742687436874468745687466874768748687496875068751687526875368754687556875668757687586875968760687616876268763687646876568766687676876868769687706877168772687736877468775687766877768778687796878068781687826878368784687856878668787687886878968790687916879268793687946879568796687976879868799688006880168802688036880468805688066880768808688096881068811688126881368814688156881668817688186881968820688216882268823688246882568826688276882868829688306883168832688336883468835688366883768838688396884068841688426884368844688456884668847688486884968850688516885268853688546885568856688576885868859688606886168862688636886468865688666886768868688696887068871688726887368874688756887668877688786887968880688816888268883688846888568886688876888868889688906889168892688936889468895688966889768898688996890068901689026890368904689056890668907689086890968910689116891268913689146891568916689176891868919689206892168922689236892468925689266892768928689296893068931689326893368934689356893668937689386893968940689416894268943689446894568946689476894868949689506895168952689536895468955689566895768958689596896068961689626896368964689656896668967689686896968970689716897268973689746897568976689776897868979689806898168982689836898468985689866898768988689896899068991689926899368994689956899668997689986899969000690016900269003690046900569006690076900869009690106901169012690136901469015690166901769018690196902069021690226902369024690256902669027690286902969030690316903269033690346903569036690376903869039690406904169042690436904469045690466904769048690496905069051690526905369054690556905669057690586905969060690616906269063690646906569066690676906869069690706907169072690736907469075690766907769078690796908069081690826908369084690856908669087690886908969090690916909269093690946909569096690976909869099691006910169102691036910469105691066910769108691096911069111691126911369114691156911669117691186911969120691216912269123691246912569126691276912869129691306913169132691336913469135691366913769138691396914069141691426914369144691456914669147691486914969150691516915269153691546915569156691576915869159691606916169162691636916469165691666916769168691696917069171691726917369174691756917669177691786917969180691816918269183691846918569186691876918869189691906919169192691936919469195691966919769198691996920069201692026920369204692056920669207692086920969210692116921269213692146921569216692176921869219692206922169222692236922469225692266922769228692296923069231692326923369234692356923669237692386923969240692416924269243692446924569246692476924869249692506925169252692536925469255692566925769258692596926069261692626926369264692656926669267692686926969270692716927269273692746927569276692776927869279692806928169282692836928469285692866928769288692896929069291692926929369294692956929669297692986929969300693016930269303693046930569306693076930869309693106931169312693136931469315693166931769318693196932069321693226932369324693256932669327693286932969330693316933269333693346933569336693376933869339693406934169342693436934469345693466934769348693496935069351693526935369354693556935669357693586935969360693616936269363693646936569366693676936869369693706937169372693736937469375693766937769378693796938069381693826938369384693856938669387693886938969390693916939269393693946939569396693976939869399694006940169402694036940469405694066940769408694096941069411694126941369414694156941669417694186941969420694216942269423694246942569426694276942869429694306943169432694336943469435694366943769438694396944069441694426944369444694456944669447694486944969450694516945269453694546945569456694576945869459694606946169462694636946469465694666946769468694696947069471694726947369474694756947669477694786947969480694816948269483694846948569486694876948869489694906949169492694936949469495694966949769498694996950069501695026950369504695056950669507695086950969510695116951269513695146951569516695176951869519695206952169522695236952469525695266952769528695296953069531695326953369534695356953669537695386953969540695416954269543695446954569546695476954869549695506955169552695536955469555695566955769558695596956069561695626956369564695656956669567695686956969570695716957269573695746957569576695776957869579695806958169582695836958469585695866958769588695896959069591695926959369594695956959669597695986959969600696016960269603696046960569606696076960869609696106961169612696136961469615696166961769618696196962069621696226962369624696256962669627696286962969630696316963269633696346963569636696376963869639696406964169642696436964469645696466964769648696496965069651696526965369654696556965669657696586965969660696616966269663696646966569666696676966869669696706967169672696736967469675696766967769678696796968069681696826968369684696856968669687696886968969690696916969269693696946969569696696976969869699697006970169702697036970469705697066970769708697096971069711697126971369714697156971669717697186971969720697216972269723697246972569726697276972869729697306973169732697336973469735697366973769738697396974069741697426974369744697456974669747697486974969750697516975269753697546975569756697576975869759697606976169762697636976469765697666976769768697696977069771697726977369774697756977669777697786977969780697816978269783697846978569786697876978869789697906979169792697936979469795697966979769798697996980069801698026980369804698056980669807698086980969810698116981269813698146981569816698176981869819698206982169822698236982469825698266982769828698296983069831698326983369834698356983669837698386983969840698416984269843698446984569846698476984869849698506985169852698536985469855698566985769858698596986069861698626986369864698656986669867698686986969870698716987269873698746987569876698776987869879698806988169882698836988469885698866988769888698896989069891698926989369894698956989669897698986989969900699016990269903699046990569906699076990869909699106991169912699136991469915699166991769918699196992069921699226992369924699256992669927699286992969930699316993269933699346993569936699376993869939699406994169942699436994469945699466994769948699496995069951699526995369954699556995669957699586995969960699616996269963699646996569966699676996869969699706997169972699736997469975699766997769978699796998069981699826998369984699856998669987699886998969990699916999269993699946999569996699976999869999700007000170002700037000470005700067000770008700097001070011700127001370014700157001670017700187001970020700217002270023700247002570026700277002870029700307003170032700337003470035700367003770038700397004070041700427004370044700457004670047700487004970050700517005270053700547005570056700577005870059700607006170062700637006470065700667006770068700697007070071700727007370074700757007670077700787007970080700817008270083700847008570086700877008870089700907009170092700937009470095700967009770098700997010070101701027010370104701057010670107701087010970110701117011270113701147011570116701177011870119701207012170122701237012470125701267012770128701297013070131701327013370134701357013670137701387013970140701417014270143701447014570146701477014870149701507015170152701537015470155701567015770158701597016070161701627016370164701657016670167701687016970170701717017270173701747017570176701777017870179701807018170182701837018470185701867018770188701897019070191701927019370194701957019670197701987019970200702017020270203702047020570206702077020870209702107021170212702137021470215702167021770218702197022070221702227022370224702257022670227702287022970230702317023270233702347023570236702377023870239702407024170242702437024470245702467024770248702497025070251702527025370254702557025670257702587025970260702617026270263702647026570266702677026870269702707027170272702737027470275702767027770278702797028070281702827028370284702857028670287702887028970290702917029270293702947029570296702977029870299703007030170302703037030470305703067030770308703097031070311703127031370314703157031670317703187031970320703217032270323703247032570326703277032870329703307033170332703337033470335703367033770338703397034070341703427034370344703457034670347703487034970350703517035270353703547035570356703577035870359703607036170362703637036470365703667036770368703697037070371703727037370374703757037670377703787037970380703817038270383703847038570386703877038870389703907039170392703937039470395703967039770398703997040070401704027040370404704057040670407704087040970410704117041270413704147041570416704177041870419704207042170422704237042470425704267042770428704297043070431704327043370434704357043670437704387043970440704417044270443704447044570446704477044870449704507045170452704537045470455704567045770458704597046070461704627046370464704657046670467704687046970470704717047270473704747047570476704777047870479704807048170482704837048470485704867048770488704897049070491704927049370494704957049670497704987049970500705017050270503705047050570506705077050870509705107051170512705137051470515705167051770518705197052070521705227052370524705257052670527705287052970530705317053270533705347053570536705377053870539705407054170542705437054470545705467054770548705497055070551705527055370554705557055670557705587055970560705617056270563705647056570566705677056870569705707057170572705737057470575705767057770578705797058070581705827058370584705857058670587705887058970590705917059270593705947059570596705977059870599706007060170602706037060470605706067060770608706097061070611706127061370614706157061670617706187061970620706217062270623706247062570626706277062870629706307063170632706337063470635706367063770638706397064070641706427064370644706457064670647706487064970650706517065270653706547065570656706577065870659706607066170662706637066470665706667066770668706697067070671706727067370674706757067670677706787067970680706817068270683706847068570686706877068870689706907069170692706937069470695706967069770698706997070070701707027070370704707057070670707707087070970710707117071270713707147071570716707177071870719707207072170722707237072470725707267072770728707297073070731707327073370734707357073670737707387073970740707417074270743707447074570746707477074870749707507075170752707537075470755707567075770758707597076070761707627076370764707657076670767707687076970770707717077270773707747077570776707777077870779707807078170782707837078470785707867078770788707897079070791707927079370794707957079670797707987079970800708017080270803708047080570806708077080870809708107081170812708137081470815708167081770818708197082070821708227082370824708257082670827708287082970830708317083270833708347083570836708377083870839708407084170842708437084470845708467084770848708497085070851708527085370854708557085670857708587085970860708617086270863708647086570866708677086870869708707087170872708737087470875708767087770878708797088070881708827088370884708857088670887708887088970890708917089270893708947089570896708977089870899709007090170902709037090470905709067090770908709097091070911709127091370914709157091670917709187091970920709217092270923709247092570926709277092870929709307093170932709337093470935709367093770938709397094070941709427094370944709457094670947709487094970950709517095270953709547095570956709577095870959709607096170962709637096470965709667096770968709697097070971709727097370974709757097670977709787097970980709817098270983709847098570986709877098870989709907099170992709937099470995709967099770998709997100071001710027100371004710057100671007710087100971010710117101271013710147101571016710177101871019710207102171022710237102471025710267102771028710297103071031710327103371034710357103671037710387103971040710417104271043710447104571046710477104871049710507105171052710537105471055710567105771058710597106071061710627106371064710657106671067710687106971070710717107271073710747107571076710777107871079710807108171082710837108471085710867108771088710897109071091710927109371094710957109671097710987109971100711017110271103711047110571106711077110871109711107111171112711137111471115711167111771118711197112071121711227112371124711257112671127711287112971130711317113271133711347113571136711377113871139711407114171142711437114471145711467114771148711497115071151711527115371154711557115671157711587115971160711617116271163711647116571166711677116871169711707117171172711737117471175711767117771178711797118071181711827118371184711857118671187711887118971190711917119271193711947119571196711977119871199712007120171202712037120471205712067120771208712097121071211712127121371214712157121671217712187121971220712217122271223712247122571226712277122871229712307123171232712337123471235712367123771238712397124071241712427124371244712457124671247712487124971250712517125271253712547125571256712577125871259712607126171262712637126471265712667126771268712697127071271712727127371274712757127671277712787127971280712817128271283712847128571286712877128871289712907129171292712937129471295712967129771298712997130071301713027130371304713057130671307713087130971310713117131271313713147131571316713177131871319713207132171322713237132471325713267132771328713297133071331713327133371334713357133671337713387133971340713417134271343713447134571346713477134871349713507135171352713537135471355713567135771358713597136071361713627136371364713657136671367713687136971370713717137271373713747137571376713777137871379713807138171382713837138471385713867138771388713897139071391713927139371394713957139671397713987139971400714017140271403714047140571406714077140871409714107141171412714137141471415714167141771418714197142071421714227142371424714257142671427714287142971430714317143271433714347143571436714377143871439714407144171442714437144471445714467144771448714497145071451714527145371454714557145671457714587145971460714617146271463714647146571466714677146871469714707147171472714737147471475714767147771478714797148071481714827148371484714857148671487714887148971490714917149271493714947149571496714977149871499715007150171502715037150471505715067150771508715097151071511715127151371514715157151671517715187151971520715217152271523715247152571526715277152871529715307153171532715337153471535715367153771538715397154071541715427154371544715457154671547715487154971550715517155271553715547155571556715577155871559715607156171562715637156471565715667156771568715697157071571715727157371574715757157671577715787157971580715817158271583715847158571586715877158871589715907159171592715937159471595715967159771598715997160071601716027160371604716057160671607716087160971610716117161271613716147161571616716177161871619716207162171622716237162471625716267162771628716297163071631716327163371634716357163671637716387163971640716417164271643716447164571646716477164871649716507165171652716537165471655716567165771658716597166071661716627166371664716657166671667716687166971670716717167271673716747167571676716777167871679716807168171682716837168471685716867168771688716897169071691716927169371694716957169671697716987169971700717017170271703717047170571706717077170871709717107171171712717137171471715717167171771718717197172071721717227172371724717257172671727717287172971730717317173271733717347173571736717377173871739717407174171742717437174471745717467174771748717497175071751717527175371754717557175671757717587175971760717617176271763717647176571766717677176871769717707177171772717737177471775717767177771778717797178071781717827178371784717857178671787717887178971790717917179271793717947179571796717977179871799718007180171802718037180471805718067180771808718097181071811718127181371814718157181671817718187181971820718217182271823718247182571826718277182871829718307183171832718337183471835718367183771838718397184071841718427184371844718457184671847718487184971850718517185271853718547185571856718577185871859718607186171862718637186471865718667186771868718697187071871718727187371874718757187671877718787187971880718817188271883718847188571886718877188871889718907189171892718937189471895718967189771898718997190071901719027190371904719057190671907719087190971910719117191271913719147191571916719177191871919719207192171922719237192471925719267192771928719297193071931719327193371934719357193671937719387193971940719417194271943719447194571946719477194871949719507195171952719537195471955719567195771958719597196071961719627196371964719657196671967719687196971970719717197271973719747197571976719777197871979719807198171982719837198471985719867198771988719897199071991719927199371994719957199671997719987199972000720017200272003720047200572006720077200872009720107201172012720137201472015720167201772018720197202072021720227202372024720257202672027720287202972030720317203272033720347203572036720377203872039720407204172042720437204472045720467204772048720497205072051720527205372054720557205672057720587205972060720617206272063720647206572066720677206872069720707207172072720737207472075720767207772078720797208072081720827208372084720857208672087720887208972090720917209272093720947209572096720977209872099721007210172102721037210472105721067210772108721097211072111721127211372114721157211672117721187211972120721217212272123721247212572126721277212872129721307213172132721337213472135721367213772138721397214072141721427214372144721457214672147721487214972150721517215272153721547215572156721577215872159721607216172162721637216472165721667216772168721697217072171721727217372174721757217672177721787217972180721817218272183721847218572186721877218872189721907219172192721937219472195721967219772198721997220072201722027220372204722057220672207722087220972210722117221272213722147221572216722177221872219722207222172222722237222472225722267222772228722297223072231722327223372234722357223672237722387223972240722417224272243722447224572246722477224872249722507225172252722537225472255722567225772258722597226072261722627226372264722657226672267722687226972270722717227272273722747227572276722777227872279722807228172282722837228472285722867228772288722897229072291722927229372294722957229672297722987229972300723017230272303723047230572306723077230872309723107231172312723137231472315723167231772318723197232072321723227232372324723257232672327723287232972330723317233272333723347233572336723377233872339723407234172342723437234472345723467234772348723497235072351723527235372354723557235672357723587235972360723617236272363723647236572366723677236872369723707237172372723737237472375723767237772378723797238072381723827238372384723857238672387723887238972390723917239272393723947239572396723977239872399724007240172402724037240472405724067240772408724097241072411724127241372414724157241672417724187241972420724217242272423724247242572426724277242872429724307243172432724337243472435724367243772438724397244072441724427244372444724457244672447724487244972450724517245272453724547245572456724577245872459724607246172462724637246472465724667246772468724697247072471724727247372474724757247672477724787247972480724817248272483724847248572486724877248872489724907249172492724937249472495724967249772498724997250072501725027250372504725057250672507725087250972510725117251272513725147251572516725177251872519725207252172522725237252472525725267252772528725297253072531725327253372534725357253672537725387253972540725417254272543725447254572546725477254872549725507255172552725537255472555725567255772558725597256072561725627256372564725657256672567725687256972570725717257272573725747257572576725777257872579725807258172582725837258472585725867258772588725897259072591725927259372594725957259672597725987259972600726017260272603726047260572606726077260872609726107261172612726137261472615726167261772618726197262072621726227262372624726257262672627726287262972630726317263272633726347263572636726377263872639726407264172642726437264472645726467264772648726497265072651726527265372654726557265672657726587265972660726617266272663726647266572666726677266872669726707267172672726737267472675726767267772678726797268072681726827268372684726857268672687726887268972690726917269272693726947269572696726977269872699727007270172702727037270472705727067270772708727097271072711727127271372714727157271672717727187271972720727217272272723727247272572726727277272872729727307273172732727337273472735727367273772738727397274072741727427274372744727457274672747727487274972750727517275272753727547275572756727577275872759727607276172762727637276472765727667276772768727697277072771727727277372774727757277672777727787277972780727817278272783727847278572786727877278872789727907279172792727937279472795727967279772798727997280072801728027280372804728057280672807728087280972810728117281272813728147281572816728177281872819728207282172822728237282472825728267282772828728297283072831728327283372834728357283672837728387283972840728417284272843728447284572846728477284872849728507285172852728537285472855728567285772858728597286072861728627286372864728657286672867728687286972870728717287272873728747287572876728777287872879728807288172882728837288472885728867288772888728897289072891728927289372894728957289672897728987289972900729017290272903729047290572906729077290872909729107291172912729137291472915729167291772918729197292072921729227292372924729257292672927729287292972930729317293272933729347293572936729377293872939729407294172942729437294472945729467294772948729497295072951729527295372954729557295672957729587295972960729617296272963729647296572966729677296872969729707297172972729737297472975729767297772978729797298072981729827298372984729857298672987729887298972990729917299272993729947299572996729977299872999730007300173002730037300473005730067300773008730097301073011730127301373014730157301673017730187301973020730217302273023730247302573026730277302873029730307303173032730337303473035730367303773038730397304073041730427304373044730457304673047730487304973050730517305273053730547305573056730577305873059730607306173062730637306473065730667306773068730697307073071730727307373074730757307673077730787307973080730817308273083730847308573086730877308873089730907309173092730937309473095730967309773098730997310073101731027310373104731057310673107731087310973110731117311273113731147311573116731177311873119731207312173122731237312473125731267312773128731297313073131731327313373134731357313673137731387313973140731417314273143731447314573146731477314873149731507315173152731537315473155731567315773158731597316073161731627316373164731657316673167731687316973170731717317273173731747317573176731777317873179731807318173182731837318473185731867318773188731897319073191731927319373194731957319673197731987319973200732017320273203732047320573206732077320873209732107321173212732137321473215732167321773218732197322073221732227322373224732257322673227732287322973230732317323273233732347323573236732377323873239732407324173242732437324473245732467324773248732497325073251732527325373254732557325673257732587325973260732617326273263732647326573266732677326873269732707327173272732737327473275732767327773278732797328073281732827328373284732857328673287732887328973290732917329273293732947329573296732977329873299733007330173302733037330473305733067330773308733097331073311733127331373314733157331673317733187331973320733217332273323733247332573326733277332873329733307333173332733337333473335733367333773338733397334073341733427334373344733457334673347733487334973350733517335273353733547335573356733577335873359733607336173362733637336473365733667336773368733697337073371733727337373374733757337673377733787337973380733817338273383733847338573386733877338873389733907339173392733937339473395733967339773398733997340073401734027340373404734057340673407734087340973410734117341273413734147341573416734177341873419734207342173422734237342473425734267342773428734297343073431734327343373434734357343673437734387343973440734417344273443734447344573446734477344873449734507345173452734537345473455734567345773458734597346073461734627346373464734657346673467734687346973470734717347273473734747347573476734777347873479734807348173482734837348473485734867348773488734897349073491734927349373494734957349673497734987349973500735017350273503735047350573506735077350873509735107351173512735137351473515735167351773518735197352073521735227352373524735257352673527735287352973530735317353273533735347353573536735377353873539735407354173542735437354473545735467354773548735497355073551735527355373554735557355673557735587355973560735617356273563735647356573566735677356873569735707357173572735737357473575735767357773578735797358073581735827358373584735857358673587735887358973590735917359273593735947359573596735977359873599736007360173602736037360473605736067360773608736097361073611736127361373614736157361673617736187361973620736217362273623736247362573626736277362873629736307363173632736337363473635736367363773638736397364073641736427364373644736457364673647736487364973650736517365273653736547365573656736577365873659736607366173662736637366473665736667366773668736697367073671736727367373674736757367673677736787367973680736817368273683736847368573686736877368873689736907369173692736937369473695736967369773698736997370073701737027370373704737057370673707737087370973710737117371273713737147371573716737177371873719737207372173722737237372473725737267372773728737297373073731737327373373734737357373673737737387373973740737417374273743737447374573746737477374873749737507375173752737537375473755737567375773758737597376073761737627376373764737657376673767737687376973770737717377273773737747377573776737777377873779737807378173782737837378473785737867378773788737897379073791737927379373794737957379673797737987379973800738017380273803738047380573806738077380873809738107381173812738137381473815738167381773818738197382073821738227382373824738257382673827738287382973830738317383273833738347383573836738377383873839738407384173842738437384473845738467384773848738497385073851738527385373854738557385673857738587385973860738617386273863738647386573866738677386873869738707387173872738737387473875738767387773878738797388073881738827388373884738857388673887738887388973890738917389273893738947389573896738977389873899739007390173902739037390473905739067390773908739097391073911739127391373914739157391673917739187391973920739217392273923739247392573926739277392873929739307393173932739337393473935739367393773938739397394073941739427394373944739457394673947739487394973950739517395273953739547395573956739577395873959739607396173962739637396473965739667396773968739697397073971739727397373974739757397673977739787397973980739817398273983739847398573986739877398873989739907399173992739937399473995739967399773998739997400074001740027400374004740057400674007740087400974010740117401274013740147401574016740177401874019740207402174022740237402474025740267402774028740297403074031740327403374034740357403674037740387403974040740417404274043740447404574046740477404874049740507405174052740537405474055740567405774058740597406074061740627406374064740657406674067740687406974070740717407274073740747407574076740777407874079740807408174082740837408474085740867408774088740897409074091740927409374094740957409674097740987409974100741017410274103741047410574106741077410874109741107411174112741137411474115741167411774118741197412074121741227412374124741257412674127741287412974130741317413274133741347413574136741377413874139741407414174142741437414474145741467414774148741497415074151741527415374154741557415674157741587415974160741617416274163741647416574166741677416874169741707417174172741737417474175741767417774178741797418074181741827418374184741857418674187741887418974190741917419274193741947419574196741977419874199742007420174202742037420474205742067420774208742097421074211742127421374214742157421674217742187421974220742217422274223742247422574226742277422874229742307423174232742337423474235742367423774238742397424074241742427424374244742457424674247742487424974250742517425274253742547425574256742577425874259742607426174262742637426474265742667426774268742697427074271742727427374274742757427674277742787427974280742817428274283742847428574286742877428874289742907429174292742937429474295742967429774298742997430074301743027430374304743057430674307743087430974310743117431274313743147431574316743177431874319743207432174322743237432474325743267432774328743297433074331743327433374334743357433674337743387433974340743417434274343743447434574346743477434874349743507435174352743537435474355743567435774358743597436074361743627436374364743657436674367743687436974370743717437274373743747437574376743777437874379743807438174382743837438474385743867438774388743897439074391743927439374394743957439674397743987439974400744017440274403744047440574406744077440874409744107441174412744137441474415744167441774418744197442074421744227442374424744257442674427744287442974430744317443274433744347443574436744377443874439744407444174442744437444474445744467444774448744497445074451744527445374454744557445674457744587445974460744617446274463744647446574466744677446874469744707447174472744737447474475744767447774478744797448074481744827448374484744857448674487744887448974490744917449274493744947449574496744977449874499745007450174502745037450474505745067450774508745097451074511745127451374514745157451674517745187451974520745217452274523745247452574526745277452874529745307453174532745337453474535745367453774538745397454074541745427454374544745457454674547745487454974550745517455274553745547455574556745577455874559745607456174562745637456474565745667456774568745697457074571745727457374574745757457674577745787457974580745817458274583745847458574586745877458874589745907459174592745937459474595745967459774598745997460074601746027460374604746057460674607746087460974610746117461274613746147461574616746177461874619746207462174622746237462474625746267462774628746297463074631746327463374634746357463674637746387463974640746417464274643746447464574646746477464874649746507465174652746537465474655746567465774658746597466074661746627466374664746657466674667746687466974670746717467274673746747467574676746777467874679746807468174682746837468474685746867468774688746897469074691746927469374694746957469674697746987469974700747017470274703747047470574706747077470874709747107471174712747137471474715747167471774718747197472074721747227472374724747257472674727747287472974730747317473274733747347473574736747377473874739747407474174742747437474474745747467474774748747497475074751747527475374754747557475674757747587475974760747617476274763747647476574766747677476874769747707477174772747737477474775747767477774778747797478074781747827478374784747857478674787747887478974790747917479274793747947479574796747977479874799748007480174802748037480474805748067480774808748097481074811748127481374814748157481674817748187481974820748217482274823748247482574826748277482874829748307483174832748337483474835748367483774838748397484074841748427484374844748457484674847748487484974850748517485274853748547485574856748577485874859748607486174862748637486474865748667486774868748697487074871748727487374874748757487674877748787487974880748817488274883748847488574886748877488874889748907489174892748937489474895748967489774898748997490074901749027490374904749057490674907749087490974910749117491274913749147491574916749177491874919749207492174922749237492474925749267492774928749297493074931749327493374934749357493674937749387493974940749417494274943749447494574946749477494874949749507495174952749537495474955749567495774958749597496074961749627496374964749657496674967749687496974970749717497274973749747497574976749777497874979749807498174982749837498474985749867498774988749897499074991749927499374994749957499674997749987499975000750017500275003750047500575006750077500875009750107501175012750137501475015750167501775018750197502075021750227502375024750257502675027750287502975030750317503275033750347503575036750377503875039750407504175042750437504475045750467504775048750497505075051750527505375054750557505675057750587505975060750617506275063750647506575066750677506875069750707507175072750737507475075750767507775078750797508075081750827508375084750857508675087750887508975090750917509275093750947509575096750977509875099751007510175102751037510475105751067510775108751097511075111751127511375114751157511675117751187511975120751217512275123751247512575126751277512875129751307513175132751337513475135751367513775138751397514075141751427514375144751457514675147751487514975150751517515275153751547515575156751577515875159751607516175162751637516475165751667516775168751697517075171751727517375174751757517675177751787517975180751817518275183751847518575186751877518875189751907519175192751937519475195751967519775198751997520075201752027520375204752057520675207752087520975210752117521275213752147521575216752177521875219752207522175222752237522475225752267522775228752297523075231752327523375234752357523675237752387523975240752417524275243752447524575246752477524875249752507525175252752537525475255752567525775258752597526075261752627526375264752657526675267752687526975270752717527275273752747527575276752777527875279752807528175282752837528475285752867528775288752897529075291752927529375294752957529675297752987529975300753017530275303753047530575306753077530875309753107531175312753137531475315753167531775318753197532075321753227532375324753257532675327753287532975330753317533275333753347533575336753377533875339753407534175342753437534475345753467534775348753497535075351753527535375354753557535675357753587535975360753617536275363753647536575366753677536875369753707537175372753737537475375753767537775378753797538075381753827538375384753857538675387753887538975390753917539275393753947539575396753977539875399754007540175402754037540475405754067540775408754097541075411754127541375414754157541675417754187541975420754217542275423754247542575426754277542875429754307543175432754337543475435754367543775438754397544075441754427544375444754457544675447754487544975450754517545275453754547545575456754577545875459754607546175462754637546475465754667546775468754697547075471754727547375474754757547675477754787547975480754817548275483754847548575486754877548875489754907549175492754937549475495754967549775498754997550075501755027550375504755057550675507755087550975510755117551275513755147551575516755177551875519755207552175522755237552475525755267552775528755297553075531755327553375534755357553675537755387553975540755417554275543755447554575546755477554875549755507555175552755537555475555755567555775558755597556075561755627556375564755657556675567755687556975570755717557275573755747557575576755777557875579755807558175582755837558475585755867558775588755897559075591755927559375594755957559675597755987559975600756017560275603756047560575606756077560875609756107561175612756137561475615756167561775618756197562075621756227562375624756257562675627756287562975630756317563275633756347563575636756377563875639756407564175642756437564475645756467564775648756497565075651756527565375654756557565675657756587565975660756617566275663756647566575666756677566875669756707567175672756737567475675756767567775678756797568075681756827568375684756857568675687756887568975690756917569275693756947569575696756977569875699757007570175702757037570475705757067570775708757097571075711757127571375714757157571675717757187571975720757217572275723757247572575726757277572875729757307573175732757337573475735757367573775738757397574075741757427574375744757457574675747757487574975750757517575275753757547575575756757577575875759757607576175762757637576475765757667576775768757697577075771757727577375774757757577675777757787577975780757817578275783757847578575786757877578875789757907579175792757937579475795757967579775798757997580075801758027580375804758057580675807758087580975810758117581275813758147581575816758177581875819758207582175822758237582475825758267582775828758297583075831758327583375834758357583675837758387583975840758417584275843758447584575846758477584875849758507585175852758537585475855758567585775858758597586075861758627586375864758657586675867758687586975870758717587275873758747587575876758777587875879758807588175882758837588475885758867588775888758897589075891758927589375894758957589675897758987589975900759017590275903759047590575906759077590875909759107591175912759137591475915759167591775918759197592075921759227592375924759257592675927759287592975930759317593275933759347593575936759377593875939759407594175942759437594475945759467594775948759497595075951759527595375954759557595675957759587595975960759617596275963759647596575966759677596875969759707597175972759737597475975759767597775978759797598075981759827598375984759857598675987759887598975990759917599275993759947599575996759977599875999760007600176002760037600476005760067600776008760097601076011760127601376014760157601676017760187601976020760217602276023760247602576026760277602876029760307603176032760337603476035760367603776038760397604076041760427604376044760457604676047760487604976050760517605276053760547605576056760577605876059760607606176062760637606476065760667606776068760697607076071760727607376074760757607676077760787607976080760817608276083760847608576086760877608876089760907609176092760937609476095760967609776098760997610076101761027610376104761057610676107761087610976110761117611276113761147611576116761177611876119761207612176122761237612476125761267612776128761297613076131761327613376134761357613676137761387613976140761417614276143761447614576146761477614876149761507615176152761537615476155761567615776158761597616076161761627616376164761657616676167761687616976170761717617276173761747617576176761777617876179761807618176182761837618476185761867618776188761897619076191761927619376194761957619676197761987619976200762017620276203762047620576206762077620876209762107621176212762137621476215762167621776218762197622076221762227622376224762257622676227762287622976230762317623276233762347623576236762377623876239762407624176242762437624476245762467624776248762497625076251762527625376254762557625676257762587625976260762617626276263762647626576266762677626876269762707627176272762737627476275762767627776278762797628076281762827628376284762857628676287762887628976290762917629276293762947629576296762977629876299763007630176302763037630476305763067630776308763097631076311763127631376314763157631676317763187631976320763217632276323763247632576326763277632876329763307633176332763337633476335763367633776338763397634076341763427634376344763457634676347763487634976350763517635276353763547635576356763577635876359763607636176362763637636476365763667636776368763697637076371763727637376374763757637676377763787637976380763817638276383763847638576386763877638876389763907639176392763937639476395763967639776398763997640076401764027640376404764057640676407764087640976410764117641276413764147641576416764177641876419764207642176422764237642476425764267642776428764297643076431764327643376434764357643676437764387643976440764417644276443764447644576446764477644876449764507645176452764537645476455764567645776458764597646076461764627646376464764657646676467764687646976470764717647276473764747647576476764777647876479764807648176482764837648476485764867648776488764897649076491764927649376494764957649676497764987649976500765017650276503765047650576506765077650876509765107651176512765137651476515765167651776518765197652076521765227652376524765257652676527765287652976530765317653276533765347653576536765377653876539765407654176542765437654476545765467654776548765497655076551765527655376554765557655676557765587655976560765617656276563765647656576566765677656876569765707657176572765737657476575765767657776578765797658076581765827658376584765857658676587765887658976590765917659276593765947659576596765977659876599766007660176602766037660476605766067660776608766097661076611766127661376614766157661676617766187661976620766217662276623766247662576626766277662876629766307663176632766337663476635766367663776638766397664076641766427664376644766457664676647766487664976650766517665276653766547665576656766577665876659766607666176662766637666476665766667666776668766697667076671766727667376674766757667676677766787667976680766817668276683766847668576686766877668876689766907669176692766937669476695766967669776698766997670076701767027670376704767057670676707767087670976710767117671276713767147671576716767177671876719767207672176722767237672476725767267672776728767297673076731767327673376734767357673676737767387673976740767417674276743767447674576746767477674876749767507675176752767537675476755767567675776758767597676076761767627676376764767657676676767767687676976770767717677276773767747677576776767777677876779767807678176782767837678476785767867678776788767897679076791767927679376794767957679676797767987679976800768017680276803768047680576806768077680876809768107681176812768137681476815768167681776818768197682076821768227682376824768257682676827768287682976830768317683276833768347683576836768377683876839768407684176842768437684476845768467684776848768497685076851768527685376854768557685676857768587685976860768617686276863768647686576866768677686876869768707687176872768737687476875768767687776878768797688076881768827688376884768857688676887768887688976890768917689276893768947689576896768977689876899769007690176902769037690476905769067690776908769097691076911769127691376914769157691676917769187691976920769217692276923769247692576926769277692876929769307693176932769337693476935769367693776938769397694076941769427694376944769457694676947769487694976950769517695276953769547695576956769577695876959769607696176962769637696476965769667696776968769697697076971769727697376974769757697676977769787697976980769817698276983769847698576986769877698876989769907699176992769937699476995769967699776998769997700077001770027700377004770057700677007770087700977010770117701277013770147701577016770177701877019770207702177022770237702477025770267702777028770297703077031770327703377034770357703677037770387703977040770417704277043770447704577046770477704877049770507705177052770537705477055770567705777058770597706077061770627706377064770657706677067770687706977070770717707277073770747707577076770777707877079770807708177082770837708477085770867708777088770897709077091770927709377094770957709677097770987709977100771017710277103771047710577106771077710877109771107711177112771137711477115771167711777118771197712077121771227712377124771257712677127771287712977130771317713277133771347713577136771377713877139771407714177142771437714477145771467714777148771497715077151771527715377154771557715677157771587715977160771617716277163771647716577166771677716877169771707717177172771737717477175771767717777178771797718077181771827718377184771857718677187771887718977190771917719277193771947719577196771977719877199772007720177202772037720477205772067720777208772097721077211772127721377214772157721677217772187721977220772217722277223772247722577226772277722877229772307723177232772337723477235772367723777238772397724077241772427724377244772457724677247772487724977250772517725277253772547725577256772577725877259772607726177262772637726477265772667726777268772697727077271772727727377274772757727677277772787727977280772817728277283772847728577286772877728877289772907729177292772937729477295772967729777298772997730077301773027730377304773057730677307773087730977310773117731277313773147731577316773177731877319773207732177322773237732477325773267732777328773297733077331773327733377334773357733677337773387733977340773417734277343773447734577346773477734877349773507735177352773537735477355773567735777358773597736077361773627736377364773657736677367773687736977370773717737277373773747737577376773777737877379773807738177382773837738477385773867738777388773897739077391773927739377394773957739677397773987739977400774017740277403774047740577406774077740877409774107741177412774137741477415774167741777418774197742077421774227742377424774257742677427774287742977430774317743277433774347743577436774377743877439774407744177442774437744477445774467744777448774497745077451774527745377454774557745677457774587745977460774617746277463774647746577466774677746877469774707747177472774737747477475774767747777478774797748077481774827748377484774857748677487774887748977490774917749277493774947749577496774977749877499775007750177502775037750477505775067750777508775097751077511775127751377514775157751677517775187751977520775217752277523775247752577526775277752877529775307753177532775337753477535775367753777538775397754077541775427754377544775457754677547775487754977550775517755277553775547755577556775577755877559775607756177562775637756477565775667756777568775697757077571775727757377574775757757677577775787757977580775817758277583775847758577586775877758877589775907759177592775937759477595775967759777598775997760077601776027760377604776057760677607776087760977610776117761277613776147761577616776177761877619776207762177622776237762477625776267762777628776297763077631776327763377634776357763677637776387763977640776417764277643776447764577646776477764877649776507765177652776537765477655776567765777658776597766077661776627766377664776657766677667776687766977670776717767277673776747767577676776777767877679776807768177682776837768477685776867768777688776897769077691776927769377694776957769677697776987769977700777017770277703777047770577706777077770877709777107771177712777137771477715777167771777718777197772077721777227772377724777257772677727777287772977730777317773277733777347773577736777377773877739777407774177742777437774477745777467774777748777497775077751777527775377754777557775677757777587775977760777617776277763777647776577766777677776877769777707777177772777737777477775777767777777778777797778077781777827778377784777857778677787777887778977790777917779277793777947779577796777977779877799778007780177802778037780477805778067780777808778097781077811778127781377814778157781677817778187781977820778217782277823778247782577826778277782877829778307783177832778337783477835778367783777838778397784077841778427784377844778457784677847778487784977850778517785277853778547785577856778577785877859778607786177862778637786477865778667786777868778697787077871778727787377874778757787677877778787787977880778817788277883778847788577886778877788877889778907789177892778937789477895778967789777898778997790077901779027790377904779057790677907779087790977910779117791277913779147791577916779177791877919779207792177922779237792477925779267792777928779297793077931779327793377934779357793677937779387793977940779417794277943779447794577946779477794877949779507795177952779537795477955779567795777958779597796077961779627796377964779657796677967779687796977970779717797277973779747797577976779777797877979779807798177982779837798477985779867798777988779897799077991779927799377994779957799677997779987799978000780017800278003780047800578006780077800878009780107801178012780137801478015780167801778018780197802078021780227802378024780257802678027780287802978030780317803278033780347803578036780377803878039780407804178042780437804478045780467804778048780497805078051780527805378054780557805678057780587805978060780617806278063780647806578066780677806878069780707807178072780737807478075780767807778078780797808078081780827808378084780857808678087780887808978090780917809278093780947809578096780977809878099781007810178102781037810478105781067810778108781097811078111781127811378114781157811678117781187811978120781217812278123781247812578126781277812878129781307813178132781337813478135781367813778138781397814078141781427814378144781457814678147781487814978150781517815278153781547815578156781577815878159781607816178162781637816478165781667816778168781697817078171781727817378174781757817678177781787817978180781817818278183781847818578186781877818878189781907819178192781937819478195781967819778198781997820078201782027820378204782057820678207782087820978210782117821278213782147821578216782177821878219782207822178222782237822478225782267822778228782297823078231782327823378234782357823678237782387823978240782417824278243782447824578246782477824878249782507825178252782537825478255782567825778258782597826078261782627826378264782657826678267782687826978270782717827278273782747827578276782777827878279782807828178282782837828478285782867828778288782897829078291782927829378294782957829678297782987829978300783017830278303783047830578306783077830878309783107831178312783137831478315783167831778318783197832078321783227832378324783257832678327783287832978330783317833278333783347833578336783377833878339783407834178342783437834478345783467834778348783497835078351783527835378354783557835678357783587835978360783617836278363783647836578366783677836878369783707837178372783737837478375783767837778378783797838078381783827838378384783857838678387783887838978390783917839278393783947839578396783977839878399784007840178402784037840478405784067840778408784097841078411784127841378414784157841678417784187841978420784217842278423784247842578426784277842878429784307843178432784337843478435784367843778438784397844078441784427844378444784457844678447784487844978450784517845278453784547845578456784577845878459784607846178462784637846478465784667846778468784697847078471784727847378474784757847678477784787847978480784817848278483784847848578486784877848878489784907849178492784937849478495784967849778498784997850078501785027850378504785057850678507785087850978510785117851278513785147851578516785177851878519785207852178522785237852478525785267852778528785297853078531785327853378534785357853678537785387853978540785417854278543785447854578546785477854878549785507855178552785537855478555785567855778558785597856078561785627856378564785657856678567785687856978570785717857278573785747857578576785777857878579785807858178582785837858478585785867858778588785897859078591785927859378594785957859678597785987859978600786017860278603786047860578606786077860878609786107861178612786137861478615786167861778618786197862078621786227862378624786257862678627786287862978630786317863278633786347863578636786377863878639786407864178642786437864478645786467864778648786497865078651786527865378654786557865678657786587865978660786617866278663786647866578666786677866878669786707867178672786737867478675786767867778678786797868078681786827868378684786857868678687786887868978690786917869278693786947869578696786977869878699787007870178702787037870478705787067870778708787097871078711787127871378714787157871678717787187871978720787217872278723787247872578726787277872878729787307873178732787337873478735787367873778738787397874078741787427874378744787457874678747787487874978750787517875278753787547875578756787577875878759787607876178762787637876478765787667876778768787697877078771787727877378774787757877678777787787877978780787817878278783787847878578786787877878878789787907879178792787937879478795787967879778798787997880078801788027880378804788057880678807788087880978810788117881278813788147881578816788177881878819788207882178822788237882478825788267882778828788297883078831788327883378834788357883678837788387883978840788417884278843788447884578846788477884878849788507885178852788537885478855788567885778858788597886078861788627886378864788657886678867788687886978870788717887278873788747887578876788777887878879788807888178882788837888478885788867888778888788897889078891788927889378894788957889678897788987889978900789017890278903789047890578906789077890878909789107891178912789137891478915789167891778918789197892078921789227892378924789257892678927789287892978930789317893278933789347893578936789377893878939789407894178942789437894478945789467894778948789497895078951789527895378954789557895678957789587895978960789617896278963789647896578966789677896878969789707897178972789737897478975789767897778978789797898078981789827898378984789857898678987789887898978990789917899278993789947899578996789977899878999790007900179002790037900479005790067900779008790097901079011790127901379014790157901679017790187901979020790217902279023790247902579026790277902879029790307903179032790337903479035790367903779038790397904079041790427904379044790457904679047790487904979050790517905279053790547905579056790577905879059790607906179062790637906479065790667906779068790697907079071790727907379074790757907679077790787907979080790817908279083790847908579086790877908879089790907909179092790937909479095790967909779098790997910079101791027910379104791057910679107791087910979110791117911279113791147911579116791177911879119791207912179122791237912479125791267912779128791297913079131791327913379134791357913679137791387913979140791417914279143791447914579146791477914879149791507915179152791537915479155791567915779158791597916079161791627916379164791657916679167791687916979170791717917279173791747917579176791777917879179791807918179182791837918479185791867918779188791897919079191791927919379194791957919679197791987919979200792017920279203792047920579206792077920879209792107921179212792137921479215792167921779218792197922079221792227922379224792257922679227792287922979230792317923279233792347923579236792377923879239792407924179242792437924479245792467924779248792497925079251792527925379254792557925679257792587925979260792617926279263792647926579266792677926879269792707927179272792737927479275792767927779278792797928079281792827928379284792857928679287792887928979290792917929279293792947929579296792977929879299793007930179302793037930479305793067930779308793097931079311793127931379314793157931679317793187931979320793217932279323793247932579326793277932879329793307933179332793337933479335793367933779338793397934079341793427934379344793457934679347793487934979350793517935279353793547935579356793577935879359793607936179362793637936479365793667936779368793697937079371793727937379374793757937679377793787937979380793817938279383793847938579386793877938879389793907939179392793937939479395793967939779398793997940079401794027940379404794057940679407794087940979410794117941279413794147941579416794177941879419794207942179422794237942479425794267942779428794297943079431794327943379434794357943679437794387943979440794417944279443794447944579446794477944879449794507945179452794537945479455794567945779458794597946079461794627946379464794657946679467794687946979470794717947279473794747947579476794777947879479794807948179482794837948479485794867948779488794897949079491794927949379494794957949679497794987949979500795017950279503795047950579506795077950879509795107951179512795137951479515795167951779518795197952079521795227952379524795257952679527795287952979530795317953279533795347953579536795377953879539795407954179542795437954479545795467954779548795497955079551795527955379554795557955679557795587955979560795617956279563795647956579566795677956879569795707957179572795737957479575795767957779578795797958079581795827958379584795857958679587795887958979590795917959279593795947959579596795977959879599796007960179602796037960479605796067960779608796097961079611796127961379614796157961679617796187961979620796217962279623796247962579626796277962879629796307963179632796337963479635796367963779638796397964079641796427964379644796457964679647796487964979650796517965279653796547965579656796577965879659796607966179662796637966479665796667966779668796697967079671796727967379674796757967679677796787967979680796817968279683796847968579686796877968879689796907969179692796937969479695796967969779698796997970079701797027970379704797057970679707797087970979710797117971279713797147971579716797177971879719797207972179722797237972479725797267972779728797297973079731797327973379734797357973679737797387973979740797417974279743797447974579746797477974879749797507975179752797537975479755797567975779758797597976079761797627976379764797657976679767797687976979770797717977279773797747977579776797777977879779797807978179782797837978479785797867978779788797897979079791797927979379794797957979679797797987979979800798017980279803798047980579806798077980879809798107981179812798137981479815798167981779818798197982079821798227982379824798257982679827798287982979830798317983279833798347983579836798377983879839798407984179842798437984479845798467984779848798497985079851798527985379854798557985679857798587985979860798617986279863798647986579866798677986879869798707987179872798737987479875798767987779878798797988079881798827988379884798857988679887798887988979890798917989279893798947989579896798977989879899799007990179902799037990479905799067990779908799097991079911799127991379914799157991679917799187991979920799217992279923799247992579926799277992879929799307993179932799337993479935799367993779938799397994079941799427994379944799457994679947799487994979950799517995279953799547995579956799577995879959799607996179962799637996479965799667996779968799697997079971799727997379974799757997679977799787997979980799817998279983799847998579986799877998879989799907999179992799937999479995799967999779998799998000080001800028000380004800058000680007800088000980010800118001280013800148001580016800178001880019800208002180022800238002480025800268002780028800298003080031800328003380034800358003680037800388003980040800418004280043800448004580046800478004880049800508005180052800538005480055800568005780058800598006080061800628006380064800658006680067800688006980070800718007280073800748007580076800778007880079800808008180082800838008480085800868008780088800898009080091800928009380094800958009680097800988009980100801018010280103801048010580106801078010880109801108011180112801138011480115801168011780118801198012080121801228012380124801258012680127801288012980130801318013280133801348013580136801378013880139801408014180142801438014480145801468014780148801498015080151801528015380154801558015680157801588015980160801618016280163801648016580166801678016880169801708017180172801738017480175801768017780178801798018080181801828018380184801858018680187801888018980190801918019280193801948019580196801978019880199802008020180202802038020480205802068020780208802098021080211802128021380214802158021680217802188021980220802218022280223802248022580226802278022880229802308023180232802338023480235802368023780238802398024080241802428024380244802458024680247802488024980250802518025280253802548025580256802578025880259802608026180262802638026480265802668026780268802698027080271802728027380274802758027680277802788027980280802818028280283802848028580286802878028880289802908029180292802938029480295802968029780298802998030080301803028030380304803058030680307803088030980310803118031280313803148031580316803178031880319803208032180322803238032480325803268032780328803298033080331803328033380334803358033680337803388033980340803418034280343803448034580346803478034880349803508035180352803538035480355803568035780358803598036080361803628036380364803658036680367803688036980370803718037280373803748037580376803778037880379803808038180382803838038480385803868038780388803898039080391803928039380394803958039680397803988039980400804018040280403804048040580406804078040880409804108041180412804138041480415804168041780418804198042080421804228042380424804258042680427804288042980430804318043280433804348043580436804378043880439804408044180442804438044480445804468044780448804498045080451804528045380454804558045680457804588045980460804618046280463804648046580466804678046880469804708047180472804738047480475804768047780478804798048080481804828048380484804858048680487804888048980490804918049280493804948049580496804978049880499805008050180502805038050480505805068050780508805098051080511805128051380514805158051680517805188051980520805218052280523805248052580526805278052880529805308053180532805338053480535805368053780538805398054080541805428054380544805458054680547805488054980550805518055280553805548055580556805578055880559805608056180562805638056480565805668056780568805698057080571805728057380574805758057680577805788057980580805818058280583805848058580586805878058880589805908059180592805938059480595805968059780598805998060080601806028060380604806058060680607806088060980610806118061280613806148061580616806178061880619806208062180622806238062480625806268062780628806298063080631806328063380634806358063680637806388063980640806418064280643806448064580646806478064880649806508065180652806538065480655806568065780658806598066080661806628066380664806658066680667806688066980670806718067280673806748067580676806778067880679806808068180682806838068480685806868068780688806898069080691806928069380694806958069680697806988069980700807018070280703807048070580706807078070880709807108071180712807138071480715807168071780718807198072080721807228072380724807258072680727807288072980730807318073280733807348073580736807378073880739807408074180742807438074480745807468074780748807498075080751807528075380754807558075680757807588075980760807618076280763807648076580766807678076880769807708077180772807738077480775807768077780778807798078080781807828078380784807858078680787807888078980790807918079280793807948079580796807978079880799808008080180802808038080480805808068080780808808098081080811808128081380814808158081680817808188081980820808218082280823808248082580826808278082880829808308083180832808338083480835808368083780838808398084080841808428084380844808458084680847808488084980850808518085280853808548085580856808578085880859808608086180862808638086480865808668086780868808698087080871808728087380874808758087680877808788087980880808818088280883808848088580886808878088880889808908089180892808938089480895808968089780898808998090080901809028090380904809058090680907809088090980910809118091280913809148091580916809178091880919809208092180922809238092480925809268092780928809298093080931809328093380934809358093680937809388093980940809418094280943809448094580946809478094880949809508095180952809538095480955809568095780958809598096080961809628096380964809658096680967809688096980970809718097280973809748097580976809778097880979809808098180982809838098480985809868098780988809898099080991809928099380994809958099680997809988099981000810018100281003810048100581006810078100881009810108101181012810138101481015810168101781018810198102081021810228102381024810258102681027810288102981030810318103281033810348103581036810378103881039810408104181042810438104481045810468104781048810498105081051810528105381054810558105681057810588105981060810618106281063810648106581066810678106881069810708107181072810738107481075810768107781078810798108081081810828108381084810858108681087810888108981090810918109281093810948109581096810978109881099811008110181102811038110481105811068110781108811098111081111811128111381114811158111681117811188111981120811218112281123811248112581126811278112881129811308113181132811338113481135811368113781138811398114081141811428114381144811458114681147811488114981150811518115281153811548115581156811578115881159811608116181162811638116481165811668116781168811698117081171811728117381174811758117681177811788117981180811818118281183811848118581186811878118881189811908119181192811938119481195811968119781198811998120081201812028120381204812058120681207812088120981210812118121281213812148121581216812178121881219812208122181222812238122481225812268122781228812298123081231812328123381234812358123681237812388123981240812418124281243812448124581246812478124881249812508125181252812538125481255812568125781258812598126081261812628126381264812658126681267812688126981270812718127281273812748127581276812778127881279812808128181282812838128481285812868128781288812898129081291812928129381294812958129681297812988129981300813018130281303813048130581306813078130881309813108131181312813138131481315813168131781318813198132081321813228132381324813258132681327813288132981330813318133281333813348133581336813378133881339813408134181342813438134481345813468134781348813498135081351813528135381354813558135681357813588135981360813618136281363813648136581366813678136881369813708137181372813738137481375813768137781378813798138081381813828138381384813858138681387813888138981390813918139281393813948139581396813978139881399814008140181402814038140481405814068140781408814098141081411814128141381414814158141681417814188141981420814218142281423814248142581426814278142881429814308143181432814338143481435814368143781438814398144081441814428144381444814458144681447814488144981450814518145281453814548145581456814578145881459814608146181462814638146481465814668146781468814698147081471814728147381474814758147681477814788147981480814818148281483814848148581486814878148881489814908149181492814938149481495814968149781498814998150081501815028150381504815058150681507815088150981510815118151281513815148151581516815178151881519815208152181522815238152481525815268152781528815298153081531815328153381534815358153681537815388153981540815418154281543815448154581546815478154881549815508155181552815538155481555815568155781558815598156081561815628156381564815658156681567815688156981570815718157281573815748157581576815778157881579815808158181582815838158481585815868158781588815898159081591815928159381594815958159681597815988159981600816018160281603816048160581606816078160881609816108161181612816138161481615816168161781618816198162081621816228162381624816258162681627816288162981630816318163281633816348163581636816378163881639816408164181642816438164481645816468164781648816498165081651816528165381654816558165681657816588165981660816618166281663816648166581666816678166881669816708167181672816738167481675816768167781678816798168081681816828168381684816858168681687816888168981690816918169281693816948169581696816978169881699817008170181702817038170481705817068170781708817098171081711817128171381714817158171681717817188171981720817218172281723817248172581726817278172881729817308173181732817338173481735817368173781738817398174081741817428174381744817458174681747817488174981750817518175281753817548175581756817578175881759817608176181762817638176481765817668176781768817698177081771817728177381774817758177681777817788177981780817818178281783817848178581786817878178881789817908179181792817938179481795817968179781798817998180081801818028180381804818058180681807818088180981810818118181281813818148181581816818178181881819818208182181822818238182481825818268182781828818298183081831818328183381834818358183681837818388183981840818418184281843818448184581846818478184881849818508185181852818538185481855818568185781858818598186081861818628186381864818658186681867818688186981870818718187281873818748187581876818778187881879818808188181882818838188481885818868188781888818898189081891818928189381894818958189681897818988189981900819018190281903819048190581906819078190881909819108191181912819138191481915819168191781918819198192081921819228192381924819258192681927819288192981930819318193281933819348193581936819378193881939819408194181942819438194481945819468194781948819498195081951819528195381954819558195681957819588195981960819618196281963819648196581966819678196881969819708197181972819738197481975819768197781978819798198081981819828198381984819858198681987819888198981990819918199281993819948199581996819978199881999820008200182002820038200482005820068200782008820098201082011820128201382014820158201682017820188201982020820218202282023820248202582026820278202882029820308203182032820338203482035820368203782038820398204082041820428204382044820458204682047820488204982050820518205282053820548205582056820578205882059820608206182062820638206482065820668206782068820698207082071820728207382074820758207682077820788207982080820818208282083820848208582086820878208882089820908209182092820938209482095820968209782098820998210082101821028210382104821058210682107821088210982110821118211282113821148211582116821178211882119821208212182122821238212482125821268212782128821298213082131821328213382134821358213682137821388213982140821418214282143821448214582146821478214882149821508215182152821538215482155821568215782158821598216082161821628216382164821658216682167821688216982170821718217282173821748217582176821778217882179821808218182182821838218482185821868218782188821898219082191821928219382194821958219682197821988219982200822018220282203822048220582206822078220882209822108221182212822138221482215822168221782218822198222082221822228222382224822258222682227822288222982230822318223282233822348223582236822378223882239822408224182242822438224482245822468224782248822498225082251822528225382254822558225682257822588225982260822618226282263822648226582266822678226882269822708227182272822738227482275822768227782278822798228082281822828228382284822858228682287822888228982290822918229282293822948229582296822978229882299823008230182302823038230482305823068230782308823098231082311823128231382314823158231682317823188231982320823218232282323823248232582326823278232882329823308233182332823338233482335823368233782338823398234082341823428234382344823458234682347823488234982350823518235282353823548235582356823578235882359823608236182362823638236482365823668236782368823698237082371823728237382374823758237682377823788237982380823818238282383823848238582386823878238882389823908239182392823938239482395823968239782398823998240082401824028240382404824058240682407824088240982410824118241282413824148241582416824178241882419824208242182422824238242482425824268242782428824298243082431824328243382434824358243682437824388243982440824418244282443824448244582446824478244882449824508245182452824538245482455824568245782458824598246082461824628246382464824658246682467824688246982470824718247282473824748247582476824778247882479824808248182482824838248482485824868248782488824898249082491824928249382494824958249682497824988249982500825018250282503825048250582506825078250882509825108251182512825138251482515825168251782518825198252082521825228252382524825258252682527825288252982530825318253282533825348253582536825378253882539825408254182542825438254482545825468254782548825498255082551825528255382554825558255682557825588255982560825618256282563825648256582566825678256882569825708257182572825738257482575825768257782578825798258082581825828258382584825858258682587825888258982590825918259282593825948259582596825978259882599826008260182602826038260482605826068260782608826098261082611826128261382614826158261682617826188261982620826218262282623826248262582626826278262882629826308263182632826338263482635826368263782638826398264082641826428264382644826458264682647826488264982650826518265282653826548265582656826578265882659826608266182662826638266482665826668266782668826698267082671826728267382674826758267682677826788267982680826818268282683826848268582686826878268882689826908269182692826938269482695826968269782698826998270082701827028270382704827058270682707827088270982710827118271282713827148271582716827178271882719827208272182722827238272482725827268272782728827298273082731827328273382734827358273682737827388273982740827418274282743827448274582746827478274882749827508275182752827538275482755827568275782758827598276082761827628276382764827658276682767827688276982770827718277282773827748277582776827778277882779827808278182782827838278482785827868278782788827898279082791827928279382794827958279682797827988279982800828018280282803828048280582806828078280882809828108281182812828138281482815828168281782818828198282082821828228282382824828258282682827828288282982830828318283282833828348283582836828378283882839828408284182842828438284482845828468284782848828498285082851828528285382854828558285682857828588285982860828618286282863828648286582866828678286882869828708287182872828738287482875828768287782878828798288082881828828288382884828858288682887828888288982890828918289282893828948289582896828978289882899829008290182902829038290482905829068290782908829098291082911829128291382914829158291682917829188291982920829218292282923829248292582926829278292882929829308293182932829338293482935829368293782938829398294082941829428294382944829458294682947829488294982950829518295282953829548295582956829578295882959829608296182962829638296482965829668296782968829698297082971829728297382974829758297682977829788297982980829818298282983829848298582986829878298882989829908299182992829938299482995829968299782998829998300083001830028300383004830058300683007830088300983010830118301283013830148301583016830178301883019830208302183022830238302483025830268302783028830298303083031830328303383034830358303683037830388303983040830418304283043830448304583046830478304883049830508305183052830538305483055830568305783058830598306083061830628306383064830658306683067830688306983070830718307283073830748307583076830778307883079830808308183082830838308483085830868308783088830898309083091830928309383094830958309683097830988309983100831018310283103831048310583106831078310883109831108311183112831138311483115831168311783118831198312083121831228312383124831258312683127831288312983130831318313283133831348313583136831378313883139831408314183142831438314483145831468314783148831498315083151831528315383154831558315683157831588315983160831618316283163831648316583166831678316883169831708317183172831738317483175831768317783178831798318083181831828318383184831858318683187831888318983190831918319283193831948319583196831978319883199832008320183202832038320483205832068320783208832098321083211832128321383214832158321683217832188321983220832218322283223832248322583226832278322883229832308323183232832338323483235832368323783238832398324083241832428324383244832458324683247832488324983250832518325283253832548325583256832578325883259832608326183262832638326483265832668326783268832698327083271832728327383274832758327683277832788327983280832818328283283832848328583286832878328883289832908329183292832938329483295832968329783298832998330083301833028330383304833058330683307833088330983310833118331283313833148331583316833178331883319833208332183322833238332483325833268332783328833298333083331833328333383334833358333683337833388333983340833418334283343833448334583346833478334883349833508335183352833538335483355833568335783358833598336083361833628336383364833658336683367833688336983370833718337283373833748337583376833778337883379833808338183382833838338483385833868338783388833898339083391833928339383394833958339683397833988339983400834018340283403834048340583406834078340883409834108341183412834138341483415834168341783418834198342083421834228342383424834258342683427834288342983430834318343283433834348343583436834378343883439834408344183442834438344483445834468344783448834498345083451834528345383454834558345683457834588345983460834618346283463834648346583466834678346883469834708347183472834738347483475834768347783478834798348083481834828348383484834858348683487834888348983490834918349283493834948349583496834978349883499835008350183502835038350483505835068350783508835098351083511835128351383514835158351683517835188351983520835218352283523835248352583526835278352883529835308353183532835338353483535835368353783538835398354083541835428354383544835458354683547835488354983550835518355283553835548355583556835578355883559835608356183562835638356483565835668356783568835698357083571835728357383574835758357683577835788357983580835818358283583835848358583586835878358883589835908359183592835938359483595835968359783598835998360083601836028360383604836058360683607836088360983610836118361283613836148361583616836178361883619836208362183622836238362483625836268362783628836298363083631836328363383634836358363683637836388363983640836418364283643836448364583646836478364883649836508365183652836538365483655836568365783658836598366083661836628366383664836658366683667836688366983670836718367283673836748367583676836778367883679836808368183682836838368483685836868368783688836898369083691836928369383694836958369683697836988369983700837018370283703837048370583706837078370883709837108371183712837138371483715837168371783718837198372083721837228372383724837258372683727837288372983730837318373283733837348373583736837378373883739837408374183742837438374483745837468374783748837498375083751837528375383754837558375683757837588375983760837618376283763837648376583766837678376883769837708377183772837738377483775837768377783778837798378083781837828378383784837858378683787837888378983790837918379283793837948379583796837978379883799838008380183802838038380483805838068380783808838098381083811838128381383814838158381683817838188381983820838218382283823838248382583826838278382883829838308383183832838338383483835838368383783838838398384083841838428384383844838458384683847838488384983850838518385283853838548385583856838578385883859838608386183862838638386483865838668386783868838698387083871838728387383874838758387683877838788387983880838818388283883838848388583886838878388883889838908389183892838938389483895838968389783898838998390083901839028390383904839058390683907839088390983910839118391283913839148391583916839178391883919839208392183922839238392483925839268392783928839298393083931839328393383934839358393683937839388393983940839418394283943839448394583946839478394883949839508395183952839538395483955839568395783958839598396083961839628396383964839658396683967839688396983970839718397283973839748397583976839778397883979839808398183982839838398483985839868398783988839898399083991839928399383994839958399683997839988399984000840018400284003840048400584006840078400884009840108401184012840138401484015840168401784018840198402084021840228402384024840258402684027840288402984030840318403284033840348403584036840378403884039840408404184042840438404484045840468404784048840498405084051840528405384054840558405684057840588405984060840618406284063840648406584066840678406884069840708407184072840738407484075840768407784078840798408084081840828408384084840858408684087840888408984090840918409284093840948409584096840978409884099841008410184102841038410484105841068410784108841098411084111841128411384114841158411684117841188411984120841218412284123841248412584126841278412884129841308413184132841338413484135841368413784138841398414084141841428414384144841458414684147841488414984150841518415284153841548415584156841578415884159841608416184162841638416484165841668416784168841698417084171841728417384174841758417684177841788417984180841818418284183841848418584186841878418884189841908419184192841938419484195841968419784198841998420084201842028420384204842058420684207842088420984210842118421284213842148421584216842178421884219842208422184222842238422484225842268422784228842298423084231842328423384234842358423684237842388423984240842418424284243842448424584246842478424884249842508425184252842538425484255842568425784258842598426084261842628426384264842658426684267842688426984270842718427284273842748427584276842778427884279842808428184282842838428484285842868428784288842898429084291842928429384294842958429684297842988429984300843018430284303843048430584306843078430884309843108431184312843138431484315843168431784318843198432084321843228432384324843258432684327843288432984330843318433284333843348433584336843378433884339843408434184342843438434484345843468434784348843498435084351843528435384354843558435684357843588435984360843618436284363843648436584366843678436884369843708437184372843738437484375843768437784378843798438084381843828438384384843858438684387843888438984390843918439284393843948439584396843978439884399844008440184402844038440484405844068440784408844098441084411844128441384414844158441684417844188441984420844218442284423844248442584426844278442884429844308443184432844338443484435844368443784438844398444084441844428444384444844458444684447844488444984450844518445284453844548445584456844578445884459844608446184462844638446484465844668446784468844698447084471844728447384474844758447684477844788447984480844818448284483844848448584486844878448884489844908449184492844938449484495844968449784498844998450084501845028450384504845058450684507845088450984510845118451284513845148451584516845178451884519845208452184522845238452484525845268452784528845298453084531845328453384534845358453684537845388453984540845418454284543845448454584546845478454884549845508455184552845538455484555845568455784558845598456084561845628456384564845658456684567845688456984570845718457284573845748457584576845778457884579845808458184582845838458484585845868458784588845898459084591845928459384594845958459684597845988459984600846018460284603846048460584606846078460884609846108461184612846138461484615846168461784618846198462084621846228462384624846258462684627846288462984630846318463284633846348463584636846378463884639846408464184642846438464484645846468464784648846498465084651846528465384654846558465684657846588465984660846618466284663846648466584666846678466884669846708467184672846738467484675846768467784678846798468084681846828468384684846858468684687846888468984690846918469284693846948469584696846978469884699847008470184702847038470484705847068470784708847098471084711847128471384714847158471684717847188471984720847218472284723847248472584726847278472884729847308473184732847338473484735847368473784738847398474084741847428474384744847458474684747847488474984750847518475284753847548475584756847578475884759847608476184762847638476484765847668476784768847698477084771847728477384774847758477684777847788477984780847818478284783847848478584786847878478884789847908479184792847938479484795847968479784798847998480084801848028480384804848058480684807848088480984810848118481284813848148481584816848178481884819848208482184822848238482484825848268482784828848298483084831848328483384834848358483684837848388483984840848418484284843848448484584846848478484884849848508485184852848538485484855848568485784858848598486084861848628486384864848658486684867848688486984870848718487284873848748487584876848778487884879848808488184882848838488484885848868488784888848898489084891848928489384894848958489684897848988489984900849018490284903849048490584906849078490884909849108491184912849138491484915849168491784918849198492084921849228492384924849258492684927849288492984930849318493284933849348493584936849378493884939849408494184942849438494484945849468494784948849498495084951849528495384954849558495684957849588495984960849618496284963849648496584966849678496884969849708497184972849738497484975849768497784978849798498084981849828498384984849858498684987849888498984990849918499284993849948499584996849978499884999850008500185002850038500485005850068500785008850098501085011850128501385014850158501685017850188501985020850218502285023850248502585026850278502885029850308503185032850338503485035850368503785038850398504085041850428504385044850458504685047850488504985050850518505285053850548505585056850578505885059850608506185062850638506485065850668506785068850698507085071850728507385074850758507685077850788507985080850818508285083850848508585086850878508885089850908509185092850938509485095850968509785098850998510085101851028510385104851058510685107851088510985110851118511285113851148511585116851178511885119851208512185122851238512485125851268512785128851298513085131851328513385134851358513685137851388513985140851418514285143851448514585146851478514885149851508515185152851538515485155851568515785158851598516085161851628516385164851658516685167851688516985170851718517285173851748517585176851778517885179851808518185182851838518485185851868518785188851898519085191851928519385194851958519685197851988519985200852018520285203852048520585206852078520885209852108521185212852138521485215852168521785218852198522085221852228522385224852258522685227852288522985230852318523285233852348523585236852378523885239852408524185242852438524485245852468524785248852498525085251852528525385254852558525685257852588525985260852618526285263852648526585266852678526885269852708527185272852738527485275852768527785278852798528085281852828528385284852858528685287852888528985290852918529285293852948529585296852978529885299853008530185302853038530485305853068530785308853098531085311853128531385314853158531685317853188531985320853218532285323853248532585326853278532885329853308533185332853338533485335853368533785338853398534085341853428534385344853458534685347853488534985350853518535285353853548535585356853578535885359853608536185362853638536485365853668536785368853698537085371853728537385374853758537685377853788537985380853818538285383853848538585386853878538885389853908539185392853938539485395853968539785398853998540085401854028540385404854058540685407854088540985410854118541285413854148541585416854178541885419854208542185422854238542485425854268542785428854298543085431854328543385434854358543685437854388543985440854418544285443854448544585446854478544885449854508545185452854538545485455854568545785458854598546085461854628546385464854658546685467854688546985470854718547285473854748547585476854778547885479854808548185482854838548485485854868548785488854898549085491854928549385494854958549685497854988549985500855018550285503855048550585506855078550885509855108551185512855138551485515855168551785518855198552085521855228552385524855258552685527855288552985530855318553285533855348553585536855378553885539855408554185542855438554485545855468554785548855498555085551855528555385554855558555685557855588555985560855618556285563855648556585566855678556885569855708557185572855738557485575855768557785578855798558085581855828558385584855858558685587855888558985590855918559285593855948559585596855978559885599856008560185602856038560485605856068560785608856098561085611856128561385614856158561685617856188561985620856218562285623856248562585626856278562885629856308563185632856338563485635856368563785638856398564085641856428564385644856458564685647856488564985650856518565285653856548565585656856578565885659856608566185662856638566485665856668566785668856698567085671856728567385674856758567685677856788567985680856818568285683856848568585686856878568885689856908569185692856938569485695856968569785698856998570085701857028570385704857058570685707857088570985710857118571285713857148571585716857178571885719857208572185722857238572485725857268572785728857298573085731857328573385734857358573685737857388573985740857418574285743857448574585746857478574885749857508575185752857538575485755857568575785758857598576085761857628576385764857658576685767857688576985770857718577285773857748577585776857778577885779857808578185782857838578485785857868578785788857898579085791857928579385794857958579685797857988579985800858018580285803858048580585806858078580885809858108581185812858138581485815858168581785818858198582085821858228582385824858258582685827858288582985830858318583285833858348583585836858378583885839858408584185842858438584485845858468584785848858498585085851858528585385854858558585685857858588585985860858618586285863858648586585866858678586885869858708587185872858738587485875858768587785878858798588085881858828588385884858858588685887858888588985890858918589285893858948589585896858978589885899859008590185902859038590485905859068590785908859098591085911859128591385914859158591685917859188591985920859218592285923859248592585926859278592885929859308593185932859338593485935859368593785938859398594085941859428594385944859458594685947859488594985950859518595285953859548595585956859578595885959859608596185962859638596485965859668596785968859698597085971859728597385974859758597685977859788597985980859818598285983859848598585986859878598885989859908599185992859938599485995859968599785998859998600086001860028600386004860058600686007860088600986010860118601286013860148601586016860178601886019860208602186022860238602486025860268602786028860298603086031860328603386034860358603686037860388603986040860418604286043860448604586046860478604886049860508605186052860538605486055860568605786058860598606086061860628606386064860658606686067860688606986070860718607286073860748607586076860778607886079860808608186082860838608486085860868608786088860898609086091860928609386094860958609686097860988609986100861018610286103861048610586106861078610886109861108611186112861138611486115861168611786118861198612086121861228612386124861258612686127861288612986130861318613286133861348613586136861378613886139861408614186142861438614486145861468614786148861498615086151861528615386154861558615686157861588615986160861618616286163861648616586166861678616886169861708617186172861738617486175861768617786178861798618086181861828618386184861858618686187861888618986190861918619286193861948619586196861978619886199862008620186202862038620486205862068620786208862098621086211862128621386214862158621686217862188621986220862218622286223862248622586226862278622886229862308623186232862338623486235862368623786238862398624086241862428624386244862458624686247862488624986250862518625286253862548625586256862578625886259862608626186262862638626486265862668626786268862698627086271862728627386274862758627686277862788627986280862818628286283862848628586286862878628886289862908629186292862938629486295862968629786298862998630086301863028630386304863058630686307863088630986310863118631286313863148631586316863178631886319863208632186322863238632486325863268632786328863298633086331863328633386334863358633686337863388633986340863418634286343863448634586346863478634886349863508635186352863538635486355863568635786358863598636086361863628636386364863658636686367863688636986370863718637286373863748637586376863778637886379863808638186382863838638486385863868638786388863898639086391863928639386394863958639686397863988639986400864018640286403864048640586406864078640886409864108641186412864138641486415864168641786418864198642086421864228642386424864258642686427864288642986430864318643286433864348643586436864378643886439864408644186442864438644486445864468644786448864498645086451864528645386454864558645686457864588645986460864618646286463864648646586466864678646886469864708647186472864738647486475864768647786478864798648086481864828648386484864858648686487864888648986490864918649286493864948649586496864978649886499865008650186502865038650486505865068650786508865098651086511865128651386514865158651686517865188651986520865218652286523865248652586526865278652886529865308653186532865338653486535865368653786538865398654086541865428654386544865458654686547865488654986550865518655286553865548655586556865578655886559865608656186562865638656486565865668656786568865698657086571865728657386574865758657686577865788657986580865818658286583865848658586586865878658886589865908659186592865938659486595865968659786598865998660086601866028660386604866058660686607866088660986610866118661286613866148661586616866178661886619866208662186622866238662486625866268662786628866298663086631866328663386634866358663686637866388663986640866418664286643866448664586646866478664886649866508665186652866538665486655866568665786658866598666086661866628666386664866658666686667866688666986670866718667286673866748667586676866778667886679866808668186682866838668486685866868668786688866898669086691866928669386694866958669686697866988669986700867018670286703867048670586706867078670886709867108671186712867138671486715867168671786718867198672086721867228672386724867258672686727867288672986730867318673286733867348673586736867378673886739867408674186742867438674486745867468674786748867498675086751867528675386754867558675686757867588675986760867618676286763867648676586766867678676886769867708677186772867738677486775867768677786778867798678086781867828678386784867858678686787867888678986790867918679286793867948679586796867978679886799868008680186802868038680486805868068680786808868098681086811868128681386814868158681686817868188681986820868218682286823868248682586826868278682886829868308683186832868338683486835868368683786838868398684086841868428684386844868458684686847868488684986850868518685286853868548685586856868578685886859868608686186862868638686486865868668686786868868698687086871868728687386874868758687686877868788687986880868818688286883868848688586886868878688886889868908689186892868938689486895868968689786898868998690086901869028690386904869058690686907869088690986910869118691286913869148691586916869178691886919869208692186922869238692486925869268692786928869298693086931869328693386934869358693686937869388693986940869418694286943869448694586946869478694886949869508695186952869538695486955869568695786958869598696086961869628696386964869658696686967869688696986970869718697286973869748697586976869778697886979869808698186982869838698486985869868698786988869898699086991869928699386994869958699686997869988699987000870018700287003870048700587006870078700887009870108701187012870138701487015870168701787018870198702087021870228702387024870258702687027870288702987030870318703287033870348703587036870378703887039870408704187042870438704487045870468704787048870498705087051870528705387054870558705687057870588705987060870618706287063870648706587066870678706887069870708707187072870738707487075870768707787078870798708087081870828708387084870858708687087870888708987090870918709287093870948709587096870978709887099871008710187102871038710487105871068710787108871098711087111871128711387114871158711687117871188711987120871218712287123871248712587126871278712887129871308713187132871338713487135871368713787138871398714087141871428714387144871458714687147871488714987150871518715287153871548715587156871578715887159871608716187162871638716487165871668716787168871698717087171871728717387174871758717687177871788717987180871818718287183871848718587186871878718887189871908719187192871938719487195871968719787198871998720087201872028720387204872058720687207872088720987210872118721287213872148721587216872178721887219872208722187222872238722487225872268722787228872298723087231872328723387234872358723687237872388723987240872418724287243872448724587246872478724887249872508725187252872538725487255872568725787258872598726087261872628726387264872658726687267872688726987270872718727287273872748727587276872778727887279872808728187282872838728487285872868728787288872898729087291872928729387294872958729687297872988729987300873018730287303873048730587306873078730887309873108731187312873138731487315873168731787318873198732087321873228732387324873258732687327873288732987330873318733287333873348733587336873378733887339873408734187342873438734487345873468734787348873498735087351873528735387354873558735687357873588735987360873618736287363873648736587366873678736887369873708737187372873738737487375873768737787378873798738087381873828738387384873858738687387873888738987390873918739287393873948739587396873978739887399874008740187402874038740487405874068740787408874098741087411874128741387414874158741687417874188741987420874218742287423874248742587426874278742887429874308743187432874338743487435874368743787438874398744087441874428744387444874458744687447874488744987450874518745287453874548745587456874578745887459874608746187462874638746487465874668746787468874698747087471874728747387474874758747687477874788747987480874818748287483874848748587486874878748887489874908749187492874938749487495874968749787498874998750087501875028750387504875058750687507875088750987510875118751287513875148751587516875178751887519875208752187522875238752487525875268752787528875298753087531875328753387534875358753687537875388753987540875418754287543875448754587546875478754887549875508755187552875538755487555875568755787558875598756087561875628756387564875658756687567875688756987570875718757287573875748757587576875778757887579875808758187582875838758487585875868758787588875898759087591875928759387594875958759687597875988759987600876018760287603876048760587606876078760887609876108761187612876138761487615876168761787618876198762087621876228762387624876258762687627876288762987630876318763287633876348763587636876378763887639876408764187642876438764487645876468764787648876498765087651876528765387654876558765687657876588765987660876618766287663876648766587666876678766887669876708767187672876738767487675876768767787678876798768087681876828768387684876858768687687876888768987690876918769287693876948769587696876978769887699877008770187702877038770487705877068770787708877098771087711877128771387714877158771687717877188771987720877218772287723877248772587726877278772887729877308773187732877338773487735877368773787738877398774087741877428774387744877458774687747877488774987750877518775287753877548775587756877578775887759877608776187762877638776487765877668776787768877698777087771877728777387774877758777687777877788777987780877818778287783877848778587786877878778887789877908779187792877938779487795877968779787798877998780087801878028780387804878058780687807878088780987810878118781287813878148781587816878178781887819878208782187822878238782487825878268782787828878298783087831878328783387834878358783687837878388783987840878418784287843878448784587846878478784887849878508785187852878538785487855878568785787858878598786087861878628786387864878658786687867878688786987870878718787287873878748787587876878778787887879878808788187882878838788487885878868788787888878898789087891878928789387894878958789687897878988789987900879018790287903879048790587906879078790887909879108791187912879138791487915879168791787918879198792087921879228792387924879258792687927879288792987930879318793287933879348793587936879378793887939879408794187942879438794487945879468794787948879498795087951879528795387954879558795687957879588795987960879618796287963879648796587966879678796887969879708797187972879738797487975879768797787978879798798087981879828798387984879858798687987879888798987990879918799287993879948799587996879978799887999880008800188002880038800488005880068800788008880098801088011880128801388014880158801688017880188801988020880218802288023880248802588026880278802888029880308803188032880338803488035880368803788038880398804088041880428804388044880458804688047880488804988050880518805288053880548805588056880578805888059880608806188062880638806488065880668806788068880698807088071880728807388074880758807688077880788807988080880818808288083880848808588086880878808888089880908809188092880938809488095880968809788098880998810088101881028810388104881058810688107881088810988110881118811288113881148811588116881178811888119881208812188122881238812488125881268812788128881298813088131881328813388134881358813688137881388813988140881418814288143881448814588146881478814888149881508815188152881538815488155881568815788158881598816088161881628816388164881658816688167881688816988170881718817288173881748817588176881778817888179881808818188182881838818488185881868818788188881898819088191881928819388194881958819688197881988819988200882018820288203882048820588206882078820888209882108821188212882138821488215882168821788218882198822088221882228822388224882258822688227882288822988230882318823288233882348823588236882378823888239882408824188242882438824488245882468824788248882498825088251882528825388254882558825688257882588825988260882618826288263882648826588266882678826888269882708827188272882738827488275882768827788278882798828088281882828828388284882858828688287882888828988290882918829288293882948829588296882978829888299883008830188302883038830488305883068830788308883098831088311883128831388314883158831688317883188831988320883218832288323883248832588326883278832888329883308833188332883338833488335883368833788338883398834088341883428834388344883458834688347883488834988350883518835288353883548835588356883578835888359883608836188362883638836488365883668836788368883698837088371883728837388374883758837688377883788837988380883818838288383883848838588386883878838888389883908839188392883938839488395883968839788398883998840088401884028840388404884058840688407884088840988410884118841288413884148841588416884178841888419884208842188422884238842488425884268842788428884298843088431884328843388434884358843688437884388843988440884418844288443884448844588446884478844888449884508845188452884538845488455884568845788458884598846088461884628846388464884658846688467884688846988470884718847288473884748847588476884778847888479884808848188482884838848488485884868848788488884898849088491884928849388494884958849688497884988849988500885018850288503885048850588506885078850888509885108851188512885138851488515885168851788518885198852088521885228852388524885258852688527885288852988530885318853288533885348853588536885378853888539885408854188542885438854488545885468854788548885498855088551885528855388554885558855688557885588855988560885618856288563885648856588566885678856888569885708857188572885738857488575885768857788578885798858088581885828858388584885858858688587885888858988590885918859288593885948859588596885978859888599886008860188602886038860488605886068860788608886098861088611886128861388614886158861688617886188861988620886218862288623886248862588626886278862888629886308863188632886338863488635886368863788638886398864088641886428864388644886458864688647886488864988650886518865288653886548865588656886578865888659886608866188662886638866488665886668866788668886698867088671886728867388674886758867688677886788867988680886818868288683886848868588686886878868888689886908869188692886938869488695886968869788698886998870088701887028870388704887058870688707887088870988710887118871288713887148871588716887178871888719887208872188722887238872488725887268872788728887298873088731887328873388734887358873688737887388873988740887418874288743887448874588746887478874888749887508875188752887538875488755887568875788758887598876088761887628876388764887658876688767887688876988770887718877288773887748877588776887778877888779887808878188782887838878488785887868878788788887898879088791887928879388794887958879688797887988879988800888018880288803888048880588806888078880888809888108881188812888138881488815888168881788818888198882088821888228882388824888258882688827888288882988830888318883288833888348883588836888378883888839888408884188842888438884488845888468884788848888498885088851888528885388854888558885688857888588885988860888618886288863888648886588866888678886888869888708887188872888738887488875888768887788878888798888088881888828888388884888858888688887888888888988890888918889288893888948889588896888978889888899889008890188902889038890488905889068890788908889098891088911889128891388914889158891688917889188891988920889218892288923889248892588926889278892888929889308893188932889338893488935889368893788938889398894088941889428894388944889458894688947889488894988950889518895288953889548895588956889578895888959889608896188962889638896488965889668896788968889698897088971889728897388974889758897688977889788897988980889818898288983889848898588986889878898888989889908899188992889938899488995889968899788998889998900089001890028900389004890058900689007890088900989010890118901289013890148901589016890178901889019890208902189022890238902489025890268902789028890298903089031890328903389034890358903689037890388903989040890418904289043890448904589046890478904889049890508905189052890538905489055890568905789058890598906089061890628906389064890658906689067890688906989070890718907289073890748907589076890778907889079890808908189082890838908489085890868908789088890898909089091890928909389094890958909689097890988909989100891018910289103891048910589106891078910889109891108911189112891138911489115891168911789118891198912089121891228912389124891258912689127891288912989130891318913289133891348913589136891378913889139891408914189142891438914489145891468914789148891498915089151891528915389154891558915689157891588915989160891618916289163891648916589166891678916889169891708917189172891738917489175891768917789178891798918089181891828918389184891858918689187891888918989190891918919289193891948919589196891978919889199892008920189202892038920489205892068920789208892098921089211892128921389214892158921689217892188921989220892218922289223892248922589226892278922889229892308923189232892338923489235892368923789238892398924089241892428924389244892458924689247892488924989250892518925289253892548925589256892578925889259892608926189262892638926489265892668926789268892698927089271892728927389274892758927689277892788927989280892818928289283892848928589286892878928889289892908929189292892938929489295892968929789298892998930089301893028930389304893058930689307893088930989310893118931289313893148931589316893178931889319893208932189322893238932489325893268932789328893298933089331893328933389334893358933689337893388933989340893418934289343893448934589346893478934889349893508935189352893538935489355893568935789358893598936089361893628936389364893658936689367893688936989370893718937289373893748937589376893778937889379893808938189382893838938489385893868938789388893898939089391893928939389394893958939689397893988939989400894018940289403894048940589406894078940889409894108941189412894138941489415894168941789418894198942089421894228942389424894258942689427894288942989430894318943289433894348943589436894378943889439894408944189442894438944489445894468944789448894498945089451894528945389454894558945689457894588945989460894618946289463894648946589466894678946889469894708947189472894738947489475894768947789478894798948089481894828948389484894858948689487894888948989490894918949289493894948949589496894978949889499895008950189502895038950489505895068950789508895098951089511895128951389514895158951689517895188951989520895218952289523895248952589526895278952889529895308953189532895338953489535895368953789538895398954089541895428954389544895458954689547895488954989550895518955289553895548955589556895578955889559895608956189562895638956489565895668956789568895698957089571895728957389574895758957689577895788957989580895818958289583895848958589586895878958889589895908959189592895938959489595895968959789598895998960089601896028960389604896058960689607896088960989610896118961289613896148961589616896178961889619896208962189622896238962489625896268962789628896298963089631896328963389634896358963689637896388963989640896418964289643896448964589646896478964889649896508965189652896538965489655896568965789658896598966089661896628966389664896658966689667896688966989670896718967289673896748967589676896778967889679896808968189682896838968489685896868968789688896898969089691896928969389694896958969689697896988969989700897018970289703897048970589706897078970889709897108971189712897138971489715897168971789718897198972089721897228972389724897258972689727897288972989730897318973289733897348973589736897378973889739897408974189742897438974489745897468974789748897498975089751897528975389754897558975689757897588975989760897618976289763897648976589766897678976889769897708977189772897738977489775897768977789778897798978089781897828978389784897858978689787897888978989790897918979289793897948979589796897978979889799898008980189802898038980489805898068980789808898098981089811898128981389814898158981689817898188981989820898218982289823898248982589826898278982889829898308983189832898338983489835898368983789838898398984089841898428984389844898458984689847898488984989850898518985289853898548985589856898578985889859898608986189862898638986489865898668986789868898698987089871898728987389874898758987689877898788987989880898818988289883898848988589886898878988889889898908989189892898938989489895898968989789898898998990089901899028990389904899058990689907899088990989910899118991289913899148991589916899178991889919899208992189922899238992489925899268992789928899298993089931899328993389934899358993689937899388993989940899418994289943899448994589946899478994889949899508995189952899538995489955899568995789958899598996089961899628996389964899658996689967899688996989970899718997289973899748997589976899778997889979899808998189982899838998489985899868998789988899898999089991899928999389994899958999689997899988999990000900019000290003900049000590006900079000890009900109001190012900139001490015900169001790018900199002090021900229002390024900259002690027900289002990030900319003290033900349003590036900379003890039900409004190042900439004490045900469004790048900499005090051900529005390054900559005690057900589005990060900619006290063900649006590066900679006890069900709007190072900739007490075900769007790078900799008090081900829008390084900859008690087900889008990090900919009290093900949009590096900979009890099901009010190102901039010490105901069010790108901099011090111901129011390114901159011690117901189011990120901219012290123901249012590126901279012890129901309013190132901339013490135901369013790138901399014090141901429014390144901459014690147901489014990150901519015290153901549015590156901579015890159901609016190162901639016490165901669016790168901699017090171901729017390174901759017690177901789017990180901819018290183901849018590186901879018890189901909019190192901939019490195901969019790198901999020090201902029020390204902059020690207902089020990210902119021290213902149021590216902179021890219902209022190222902239022490225902269022790228902299023090231902329023390234902359023690237902389023990240902419024290243902449024590246902479024890249902509025190252902539025490255902569025790258902599026090261902629026390264902659026690267902689026990270902719027290273902749027590276902779027890279902809028190282902839028490285902869028790288902899029090291902929029390294902959029690297902989029990300903019030290303903049030590306903079030890309903109031190312903139031490315903169031790318903199032090321903229032390324903259032690327903289032990330903319033290333903349033590336903379033890339903409034190342903439034490345903469034790348903499035090351903529035390354903559035690357903589035990360903619036290363903649036590366903679036890369903709037190372903739037490375903769037790378903799038090381903829038390384903859038690387903889038990390903919039290393903949039590396903979039890399904009040190402904039040490405904069040790408904099041090411904129041390414904159041690417904189041990420904219042290423904249042590426904279042890429904309043190432904339043490435904369043790438904399044090441904429044390444904459044690447904489044990450904519045290453904549045590456904579045890459904609046190462904639046490465904669046790468904699047090471904729047390474904759047690477904789047990480904819048290483904849048590486904879048890489904909049190492904939049490495904969049790498904999050090501905029050390504905059050690507905089050990510905119051290513905149051590516905179051890519905209052190522905239052490525905269052790528905299053090531905329053390534905359053690537905389053990540905419054290543905449054590546905479054890549905509055190552905539055490555905569055790558905599056090561905629056390564905659056690567905689056990570905719057290573905749057590576905779057890579905809058190582905839058490585905869058790588905899059090591905929059390594905959059690597905989059990600906019060290603906049060590606906079060890609906109061190612906139061490615906169061790618906199062090621906229062390624906259062690627906289062990630906319063290633906349063590636906379063890639906409064190642906439064490645906469064790648906499065090651906529065390654906559065690657906589065990660906619066290663906649066590666906679066890669906709067190672906739067490675906769067790678906799068090681906829068390684906859068690687906889068990690906919069290693906949069590696906979069890699907009070190702907039070490705907069070790708907099071090711907129071390714907159071690717907189071990720907219072290723907249072590726907279072890729907309073190732907339073490735907369073790738907399074090741907429074390744907459074690747907489074990750907519075290753907549075590756907579075890759907609076190762907639076490765907669076790768907699077090771907729077390774907759077690777907789077990780907819078290783907849078590786907879078890789907909079190792907939079490795907969079790798907999080090801908029080390804908059080690807908089080990810908119081290813908149081590816908179081890819908209082190822908239082490825908269082790828908299083090831908329083390834908359083690837908389083990840908419084290843908449084590846908479084890849908509085190852908539085490855908569085790858908599086090861908629086390864908659086690867908689086990870908719087290873908749087590876908779087890879908809088190882908839088490885908869088790888908899089090891908929089390894908959089690897908989089990900909019090290903909049090590906909079090890909909109091190912909139091490915909169091790918909199092090921909229092390924909259092690927909289092990930909319093290933909349093590936909379093890939909409094190942909439094490945909469094790948909499095090951909529095390954909559095690957909589095990960909619096290963909649096590966909679096890969909709097190972909739097490975909769097790978909799098090981909829098390984909859098690987909889098990990909919099290993909949099590996909979099890999910009100191002910039100491005910069100791008910099101091011910129101391014910159101691017910189101991020910219102291023910249102591026910279102891029910309103191032910339103491035910369103791038910399104091041910429104391044910459104691047910489104991050910519105291053910549105591056910579105891059910609106191062910639106491065910669106791068910699107091071910729107391074910759107691077910789107991080910819108291083910849108591086910879108891089910909109191092910939109491095910969109791098910999110091101911029110391104911059110691107911089110991110911119111291113911149111591116911179111891119911209112191122911239112491125911269112791128911299113091131911329113391134911359113691137911389113991140911419114291143911449114591146911479114891149911509115191152911539115491155911569115791158911599116091161911629116391164911659116691167911689116991170911719117291173911749117591176911779117891179911809118191182911839118491185911869118791188911899119091191911929119391194911959119691197911989119991200912019120291203912049120591206912079120891209912109121191212912139121491215912169121791218912199122091221912229122391224912259122691227912289122991230912319123291233912349123591236912379123891239912409124191242912439124491245912469124791248912499125091251912529125391254912559125691257912589125991260912619126291263912649126591266912679126891269912709127191272912739127491275912769127791278912799128091281912829128391284912859128691287912889128991290912919129291293912949129591296912979129891299913009130191302913039130491305913069130791308913099131091311913129131391314913159131691317913189131991320913219132291323913249132591326913279132891329913309133191332913339133491335913369133791338913399134091341913429134391344913459134691347913489134991350913519135291353913549135591356913579135891359913609136191362913639136491365913669136791368913699137091371913729137391374913759137691377913789137991380913819138291383913849138591386913879138891389913909139191392913939139491395913969139791398913999140091401914029140391404914059140691407914089140991410914119141291413914149141591416914179141891419914209142191422914239142491425914269142791428914299143091431914329143391434914359143691437914389143991440914419144291443914449144591446914479144891449914509145191452914539145491455914569145791458914599146091461914629146391464914659146691467914689146991470914719147291473914749147591476914779147891479914809148191482914839148491485914869148791488914899149091491914929149391494914959149691497914989149991500915019150291503915049150591506915079150891509915109151191512915139151491515915169151791518915199152091521915229152391524915259152691527915289152991530915319153291533915349153591536915379153891539915409154191542915439154491545915469154791548915499155091551915529155391554915559155691557915589155991560915619156291563915649156591566915679156891569915709157191572915739157491575915769157791578915799158091581915829158391584915859158691587915889158991590915919159291593915949159591596915979159891599916009160191602916039160491605916069160791608916099161091611916129161391614916159161691617916189161991620916219162291623916249162591626916279162891629916309163191632916339163491635916369163791638916399164091641916429164391644916459164691647916489164991650916519165291653916549165591656916579165891659916609166191662916639166491665916669166791668916699167091671916729167391674916759167691677916789167991680916819168291683916849168591686916879168891689916909169191692916939169491695916969169791698916999170091701917029170391704917059170691707917089170991710917119171291713917149171591716917179171891719917209172191722917239172491725917269172791728917299173091731917329173391734917359173691737917389173991740917419174291743917449174591746917479174891749917509175191752917539175491755917569175791758917599176091761917629176391764917659176691767917689176991770917719177291773917749177591776917779177891779917809178191782917839178491785917869178791788917899179091791917929179391794917959179691797917989179991800918019180291803918049180591806918079180891809918109181191812918139181491815918169181791818918199182091821918229182391824918259182691827918289182991830918319183291833918349183591836918379183891839918409184191842918439184491845918469184791848918499185091851918529185391854918559185691857918589185991860918619186291863918649186591866918679186891869918709187191872918739187491875918769187791878918799188091881918829188391884918859188691887918889188991890918919189291893918949189591896918979189891899919009190191902919039190491905919069190791908919099191091911919129191391914919159191691917919189191991920919219192291923919249192591926919279192891929919309193191932919339193491935919369193791938919399194091941919429194391944919459194691947919489194991950919519195291953919549195591956919579195891959919609196191962919639196491965919669196791968919699197091971919729197391974919759197691977919789197991980919819198291983919849198591986919879198891989919909199191992919939199491995919969199791998919999200092001920029200392004920059200692007920089200992010920119201292013920149201592016920179201892019920209202192022920239202492025920269202792028920299203092031920329203392034920359203692037920389203992040920419204292043920449204592046920479204892049920509205192052920539205492055920569205792058920599206092061920629206392064920659206692067920689206992070920719207292073920749207592076920779207892079920809208192082920839208492085920869208792088920899209092091920929209392094920959209692097920989209992100921019210292103921049210592106921079210892109921109211192112921139211492115921169211792118921199212092121921229212392124921259212692127921289212992130921319213292133921349213592136921379213892139921409214192142921439214492145921469214792148921499215092151921529215392154921559215692157921589215992160921619216292163921649216592166921679216892169921709217192172921739217492175921769217792178921799218092181921829218392184921859218692187921889218992190921919219292193921949219592196921979219892199922009220192202922039220492205922069220792208922099221092211922129221392214922159221692217922189221992220922219222292223922249222592226922279222892229922309223192232922339223492235922369223792238922399224092241922429224392244922459224692247922489224992250922519225292253922549225592256922579225892259922609226192262922639226492265922669226792268922699227092271922729227392274922759227692277922789227992280922819228292283922849228592286922879228892289922909229192292922939229492295922969229792298922999230092301923029230392304923059230692307923089230992310923119231292313923149231592316923179231892319923209232192322923239232492325923269232792328923299233092331923329233392334923359233692337923389233992340923419234292343923449234592346923479234892349923509235192352923539235492355923569235792358923599236092361923629236392364923659236692367923689236992370923719237292373923749237592376923779237892379923809238192382923839238492385923869238792388923899239092391923929239392394923959239692397923989239992400924019240292403924049240592406924079240892409924109241192412924139241492415924169241792418924199242092421924229242392424924259242692427924289242992430924319243292433924349243592436924379243892439924409244192442924439244492445924469244792448924499245092451924529245392454924559245692457924589245992460924619246292463924649246592466924679246892469924709247192472924739247492475924769247792478924799248092481924829248392484924859248692487924889248992490924919249292493924949249592496924979249892499925009250192502925039250492505925069250792508925099251092511925129251392514925159251692517925189251992520925219252292523925249252592526925279252892529925309253192532925339253492535925369253792538925399254092541925429254392544925459254692547925489254992550925519255292553925549255592556925579255892559925609256192562925639256492565925669256792568925699257092571925729257392574925759257692577925789257992580925819258292583925849258592586925879258892589925909259192592925939259492595925969259792598925999260092601926029260392604926059260692607926089260992610926119261292613926149261592616926179261892619926209262192622926239262492625926269262792628926299263092631926329263392634926359263692637926389263992640926419264292643926449264592646926479264892649926509265192652926539265492655926569265792658926599266092661926629266392664926659266692667926689266992670926719267292673926749267592676926779267892679926809268192682926839268492685926869268792688926899269092691926929269392694926959269692697926989269992700927019270292703927049270592706927079270892709927109271192712927139271492715927169271792718927199272092721927229272392724927259272692727927289272992730927319273292733927349273592736927379273892739927409274192742927439274492745927469274792748927499275092751927529275392754927559275692757927589275992760927619276292763927649276592766927679276892769927709277192772927739277492775927769277792778927799278092781927829278392784927859278692787927889278992790927919279292793927949279592796927979279892799928009280192802928039280492805928069280792808928099281092811928129281392814928159281692817928189281992820928219282292823928249282592826928279282892829928309283192832928339283492835928369283792838928399284092841928429284392844928459284692847928489284992850928519285292853928549285592856928579285892859928609286192862928639286492865928669286792868928699287092871928729287392874928759287692877928789287992880928819288292883928849288592886928879288892889928909289192892928939289492895928969289792898928999290092901929029290392904929059290692907929089290992910929119291292913929149291592916929179291892919929209292192922929239292492925929269292792928929299293092931929329293392934929359293692937929389293992940929419294292943929449294592946929479294892949929509295192952929539295492955929569295792958929599296092961929629296392964929659296692967929689296992970929719297292973929749297592976929779297892979929809298192982929839298492985929869298792988929899299092991929929299392994929959299692997929989299993000930019300293003930049300593006930079300893009930109301193012930139301493015930169301793018930199302093021930229302393024930259302693027930289302993030930319303293033930349303593036930379303893039930409304193042930439304493045930469304793048930499305093051930529305393054930559305693057930589305993060930619306293063930649306593066930679306893069930709307193072930739307493075930769307793078930799308093081930829308393084930859308693087930889308993090930919309293093930949309593096930979309893099931009310193102931039310493105931069310793108931099311093111931129311393114931159311693117931189311993120931219312293123931249312593126931279312893129931309313193132931339313493135931369313793138931399314093141931429314393144931459314693147931489314993150931519315293153931549315593156931579315893159931609316193162931639316493165931669316793168931699317093171931729317393174931759317693177931789317993180931819318293183931849318593186931879318893189931909319193192931939319493195931969319793198931999320093201932029320393204932059320693207932089320993210932119321293213932149321593216932179321893219932209322193222932239322493225932269322793228932299323093231932329323393234932359323693237932389323993240932419324293243932449324593246932479324893249932509325193252932539325493255932569325793258932599326093261932629326393264932659326693267932689326993270932719327293273932749327593276932779327893279932809328193282932839328493285932869328793288932899329093291932929329393294932959329693297932989329993300933019330293303933049330593306933079330893309933109331193312933139331493315933169331793318933199332093321933229332393324933259332693327933289332993330933319333293333933349333593336933379333893339933409334193342933439334493345933469334793348933499335093351933529335393354933559335693357933589335993360933619336293363933649336593366933679336893369933709337193372933739337493375933769337793378933799338093381933829338393384933859338693387933889338993390933919339293393933949339593396933979339893399934009340193402934039340493405934069340793408934099341093411934129341393414934159341693417934189341993420934219342293423934249342593426934279342893429934309343193432934339343493435934369343793438934399344093441934429344393444934459344693447934489344993450934519345293453934549345593456934579345893459934609346193462934639346493465934669346793468934699347093471934729347393474934759347693477934789347993480934819348293483934849348593486934879348893489934909349193492934939349493495934969349793498934999350093501935029350393504935059350693507935089350993510935119351293513935149351593516935179351893519935209352193522935239352493525935269352793528935299353093531935329353393534935359353693537935389353993540935419354293543935449354593546935479354893549935509355193552935539355493555935569355793558935599356093561935629356393564935659356693567935689356993570935719357293573935749357593576935779357893579935809358193582935839358493585935869358793588935899359093591935929359393594935959359693597935989359993600936019360293603936049360593606936079360893609936109361193612936139361493615936169361793618936199362093621936229362393624936259362693627936289362993630936319363293633936349363593636936379363893639936409364193642936439364493645936469364793648936499365093651936529365393654936559365693657936589365993660936619366293663936649366593666936679366893669936709367193672936739367493675936769367793678936799368093681936829368393684936859368693687936889368993690936919369293693936949369593696936979369893699937009370193702937039370493705937069370793708937099371093711937129371393714937159371693717937189371993720937219372293723937249372593726937279372893729937309373193732937339373493735937369373793738937399374093741937429374393744937459374693747937489374993750937519375293753937549375593756937579375893759937609376193762937639376493765937669376793768937699377093771937729377393774937759377693777937789377993780937819378293783937849378593786937879378893789937909379193792937939379493795937969379793798937999380093801938029380393804938059380693807938089380993810938119381293813938149381593816938179381893819938209382193822938239382493825938269382793828938299383093831938329383393834938359383693837938389383993840938419384293843938449384593846938479384893849938509385193852938539385493855938569385793858938599386093861938629386393864938659386693867938689386993870938719387293873938749387593876938779387893879938809388193882938839388493885938869388793888938899389093891938929389393894938959389693897938989389993900939019390293903939049390593906939079390893909939109391193912939139391493915939169391793918939199392093921939229392393924939259392693927939289392993930939319393293933939349393593936939379393893939939409394193942939439394493945939469394793948939499395093951939529395393954939559395693957939589395993960939619396293963939649396593966939679396893969939709397193972939739397493975939769397793978939799398093981939829398393984939859398693987939889398993990939919399293993939949399593996939979399893999940009400194002940039400494005940069400794008940099401094011940129401394014940159401694017940189401994020940219402294023940249402594026940279402894029940309403194032940339403494035940369403794038940399404094041940429404394044940459404694047940489404994050940519405294053940549405594056940579405894059940609406194062940639406494065940669406794068940699407094071940729407394074940759407694077940789407994080940819408294083940849408594086940879408894089940909409194092940939409494095940969409794098940999410094101941029410394104941059410694107941089410994110941119411294113941149411594116941179411894119941209412194122941239412494125941269412794128941299413094131941329413394134941359413694137941389413994140941419414294143941449414594146941479414894149941509415194152941539415494155941569415794158941599416094161941629416394164941659416694167941689416994170941719417294173941749417594176941779417894179941809418194182941839418494185941869418794188941899419094191941929419394194941959419694197941989419994200942019420294203942049420594206942079420894209942109421194212942139421494215942169421794218942199422094221942229422394224942259422694227942289422994230942319423294233942349423594236942379423894239942409424194242942439424494245942469424794248942499425094251942529425394254942559425694257942589425994260942619426294263942649426594266942679426894269942709427194272942739427494275942769427794278942799428094281942829428394284942859428694287942889428994290942919429294293942949429594296942979429894299943009430194302943039430494305943069430794308943099431094311943129431394314943159431694317943189431994320943219432294323943249432594326943279432894329943309433194332943339433494335943369433794338943399434094341943429434394344943459434694347943489434994350943519435294353943549435594356943579435894359943609436194362943639436494365943669436794368943699437094371943729437394374943759437694377943789437994380943819438294383943849438594386943879438894389943909439194392943939439494395943969439794398943999440094401944029440394404944059440694407944089440994410944119441294413944149441594416944179441894419944209442194422944239442494425944269442794428944299443094431944329443394434944359443694437944389443994440944419444294443944449444594446944479444894449944509445194452944539445494455944569445794458944599446094461944629446394464944659446694467944689446994470944719447294473944749447594476944779447894479944809448194482944839448494485944869448794488944899449094491944929449394494944959449694497944989449994500945019450294503945049450594506945079450894509945109451194512945139451494515945169451794518945199452094521945229452394524945259452694527945289452994530945319453294533945349453594536945379453894539945409454194542945439454494545945469454794548945499455094551945529455394554945559455694557945589455994560945619456294563945649456594566945679456894569945709457194572945739457494575945769457794578945799458094581945829458394584945859458694587945889458994590945919459294593945949459594596945979459894599946009460194602946039460494605946069460794608946099461094611946129461394614946159461694617946189461994620946219462294623946249462594626946279462894629946309463194632946339463494635946369463794638946399464094641946429464394644946459464694647946489464994650946519465294653946549465594656946579465894659946609466194662946639466494665946669466794668946699467094671946729467394674946759467694677946789467994680946819468294683946849468594686946879468894689946909469194692946939469494695946969469794698946999470094701947029470394704947059470694707947089470994710947119471294713947149471594716947179471894719947209472194722947239472494725947269472794728947299473094731947329473394734947359473694737947389473994740947419474294743947449474594746947479474894749947509475194752947539475494755947569475794758947599476094761947629476394764947659476694767947689476994770947719477294773947749477594776947779477894779947809478194782947839478494785947869478794788947899479094791947929479394794947959479694797947989479994800948019480294803948049480594806948079480894809948109481194812948139481494815948169481794818948199482094821948229482394824948259482694827948289482994830948319483294833948349483594836948379483894839948409484194842948439484494845948469484794848948499485094851948529485394854948559485694857948589485994860948619486294863948649486594866948679486894869948709487194872948739487494875948769487794878948799488094881948829488394884948859488694887948889488994890948919489294893948949489594896948979489894899949009490194902949039490494905949069490794908949099491094911949129491394914949159491694917949189491994920949219492294923949249492594926949279492894929949309493194932949339493494935949369493794938949399494094941949429494394944949459494694947949489494994950949519495294953949549495594956949579495894959949609496194962949639496494965949669496794968949699497094971949729497394974949759497694977949789497994980949819498294983949849498594986949879498894989949909499194992949939499494995949969499794998949999500095001950029500395004950059500695007950089500995010950119501295013950149501595016950179501895019950209502195022950239502495025950269502795028950299503095031950329503395034950359503695037950389503995040950419504295043950449504595046950479504895049950509505195052950539505495055950569505795058950599506095061950629506395064950659506695067950689506995070950719507295073950749507595076950779507895079950809508195082950839508495085950869508795088950899509095091950929509395094950959509695097950989509995100951019510295103951049510595106951079510895109951109511195112951139511495115951169511795118951199512095121951229512395124951259512695127951289512995130951319513295133951349513595136951379513895139951409514195142951439514495145951469514795148951499515095151951529515395154951559515695157951589515995160951619516295163951649516595166951679516895169951709517195172951739517495175951769517795178951799518095181951829518395184951859518695187951889518995190951919519295193951949519595196951979519895199952009520195202952039520495205952069520795208952099521095211952129521395214952159521695217952189521995220952219522295223952249522595226952279522895229952309523195232952339523495235952369523795238952399524095241952429524395244952459524695247952489524995250952519525295253952549525595256952579525895259952609526195262952639526495265952669526795268952699527095271952729527395274952759527695277952789527995280952819528295283952849528595286952879528895289952909529195292952939529495295952969529795298952999530095301953029530395304953059530695307953089530995310953119531295313953149531595316953179531895319953209532195322953239532495325953269532795328953299533095331953329533395334953359533695337953389533995340953419534295343953449534595346953479534895349953509535195352953539535495355953569535795358953599536095361953629536395364953659536695367953689536995370953719537295373953749537595376953779537895379953809538195382953839538495385953869538795388953899539095391953929539395394953959539695397953989539995400954019540295403954049540595406954079540895409954109541195412954139541495415954169541795418954199542095421954229542395424954259542695427954289542995430954319543295433954349543595436954379543895439954409544195442954439544495445954469544795448954499545095451954529545395454954559545695457954589545995460954619546295463954649546595466954679546895469954709547195472954739547495475954769547795478954799548095481954829548395484954859548695487954889548995490954919549295493954949549595496954979549895499955009550195502955039550495505955069550795508955099551095511955129551395514955159551695517955189551995520955219552295523955249552595526955279552895529955309553195532955339553495535955369553795538955399554095541955429554395544955459554695547955489554995550955519555295553955549555595556955579555895559955609556195562955639556495565955669556795568955699557095571955729557395574955759557695577955789557995580955819558295583955849558595586955879558895589955909559195592955939559495595955969559795598955999560095601956029560395604956059560695607956089560995610956119561295613956149561595616956179561895619956209562195622956239562495625956269562795628956299563095631956329563395634956359563695637956389563995640956419564295643956449564595646956479564895649956509565195652956539565495655956569565795658956599566095661956629566395664956659566695667956689566995670956719567295673956749567595676956779567895679956809568195682956839568495685956869568795688956899569095691956929569395694956959569695697956989569995700957019570295703957049570595706957079570895709957109571195712957139571495715957169571795718957199572095721957229572395724957259572695727957289572995730957319573295733957349573595736957379573895739957409574195742957439574495745957469574795748957499575095751957529575395754957559575695757957589575995760957619576295763957649576595766957679576895769957709577195772957739577495775957769577795778957799578095781957829578395784957859578695787957889578995790957919579295793957949579595796957979579895799958009580195802958039580495805958069580795808958099581095811958129581395814958159581695817958189581995820958219582295823958249582595826958279582895829958309583195832958339583495835958369583795838958399584095841958429584395844958459584695847958489584995850958519585295853958549585595856958579585895859958609586195862958639586495865958669586795868958699587095871958729587395874958759587695877958789587995880958819588295883958849588595886958879588895889958909589195892958939589495895958969589795898958999590095901959029590395904959059590695907959089590995910959119591295913959149591595916959179591895919959209592195922959239592495925959269592795928959299593095931959329593395934959359593695937959389593995940959419594295943959449594595946959479594895949959509595195952959539595495955959569595795958959599596095961959629596395964959659596695967959689596995970959719597295973959749597595976959779597895979959809598195982959839598495985959869598795988959899599095991959929599395994959959599695997959989599996000960019600296003960049600596006960079600896009960109601196012960139601496015960169601796018960199602096021960229602396024960259602696027960289602996030960319603296033960349603596036960379603896039960409604196042960439604496045960469604796048960499605096051960529605396054960559605696057960589605996060960619606296063960649606596066960679606896069960709607196072960739607496075960769607796078960799608096081960829608396084960859608696087960889608996090960919609296093960949609596096960979609896099961009610196102961039610496105961069610796108961099611096111961129611396114961159611696117961189611996120961219612296123961249612596126961279612896129961309613196132961339613496135961369613796138961399614096141961429614396144961459614696147961489614996150961519615296153961549615596156961579615896159961609616196162961639616496165961669616796168961699617096171961729617396174961759617696177961789617996180961819618296183961849618596186961879618896189961909619196192961939619496195961969619796198961999620096201962029620396204962059620696207962089620996210962119621296213962149621596216962179621896219962209622196222962239622496225962269622796228962299623096231962329623396234962359623696237962389623996240962419624296243962449624596246962479624896249962509625196252962539625496255962569625796258962599626096261962629626396264962659626696267962689626996270962719627296273962749627596276962779627896279962809628196282962839628496285962869628796288962899629096291962929629396294962959629696297962989629996300963019630296303963049630596306963079630896309963109631196312963139631496315963169631796318963199632096321963229632396324963259632696327963289632996330963319633296333963349633596336963379633896339963409634196342963439634496345963469634796348963499635096351963529635396354963559635696357963589635996360963619636296363963649636596366963679636896369963709637196372963739637496375963769637796378963799638096381963829638396384963859638696387963889638996390963919639296393963949639596396963979639896399964009640196402964039640496405964069640796408964099641096411964129641396414964159641696417964189641996420964219642296423964249642596426964279642896429964309643196432964339643496435964369643796438964399644096441964429644396444964459644696447964489644996450964519645296453964549645596456964579645896459964609646196462964639646496465964669646796468964699647096471964729647396474964759647696477964789647996480964819648296483964849648596486964879648896489964909649196492964939649496495964969649796498964999650096501965029650396504965059650696507965089650996510965119651296513965149651596516965179651896519965209652196522965239652496525965269652796528965299653096531965329653396534965359653696537965389653996540965419654296543965449654596546965479654896549965509655196552965539655496555965569655796558965599656096561965629656396564965659656696567965689656996570965719657296573965749657596576965779657896579965809658196582965839658496585965869658796588965899659096591965929659396594965959659696597965989659996600966019660296603966049660596606966079660896609966109661196612966139661496615966169661796618966199662096621966229662396624966259662696627966289662996630966319663296633966349663596636966379663896639966409664196642966439664496645966469664796648966499665096651966529665396654966559665696657966589665996660966619666296663966649666596666966679666896669966709667196672966739667496675966769667796678966799668096681966829668396684966859668696687966889668996690966919669296693966949669596696966979669896699967009670196702967039670496705967069670796708967099671096711967129671396714967159671696717967189671996720967219672296723967249672596726967279672896729967309673196732967339673496735967369673796738967399674096741967429674396744967459674696747967489674996750967519675296753967549675596756967579675896759967609676196762967639676496765967669676796768967699677096771967729677396774967759677696777967789677996780967819678296783967849678596786967879678896789967909679196792967939679496795967969679796798967999680096801968029680396804968059680696807968089680996810968119681296813968149681596816968179681896819968209682196822968239682496825968269682796828968299683096831968329683396834968359683696837968389683996840968419684296843968449684596846968479684896849968509685196852968539685496855968569685796858968599686096861968629686396864968659686696867968689686996870968719687296873968749687596876968779687896879968809688196882968839688496885968869688796888968899689096891968929689396894968959689696897968989689996900969019690296903969049690596906969079690896909969109691196912969139691496915969169691796918969199692096921969229692396924969259692696927969289692996930969319693296933969349693596936969379693896939969409694196942969439694496945969469694796948969499695096951969529695396954969559695696957969589695996960969619696296963969649696596966969679696896969969709697196972969739697496975969769697796978969799698096981969829698396984969859698696987969889698996990969919699296993969949699596996969979699896999970009700197002970039700497005970069700797008970099701097011970129701397014970159701697017970189701997020970219702297023970249702597026970279702897029970309703197032970339703497035970369703797038970399704097041970429704397044970459704697047970489704997050970519705297053970549705597056970579705897059970609706197062970639706497065970669706797068970699707097071970729707397074970759707697077970789707997080970819708297083970849708597086970879708897089970909709197092970939709497095970969709797098970999710097101971029710397104971059710697107971089710997110971119711297113971149711597116971179711897119971209712197122971239712497125971269712797128971299713097131971329713397134971359713697137971389713997140971419714297143971449714597146971479714897149971509715197152971539715497155971569715797158971599716097161971629716397164971659716697167971689716997170971719717297173971749717597176971779717897179971809718197182971839718497185971869718797188971899719097191971929719397194971959719697197971989719997200972019720297203972049720597206972079720897209972109721197212972139721497215972169721797218972199722097221972229722397224972259722697227972289722997230972319723297233972349723597236972379723897239972409724197242972439724497245972469724797248972499725097251972529725397254972559725697257972589725997260972619726297263972649726597266972679726897269972709727197272972739727497275972769727797278972799728097281972829728397284972859728697287972889728997290972919729297293972949729597296972979729897299973009730197302973039730497305973069730797308973099731097311973129731397314973159731697317973189731997320973219732297323973249732597326973279732897329973309733197332973339733497335973369733797338973399734097341973429734397344973459734697347973489734997350973519735297353973549735597356973579735897359973609736197362973639736497365973669736797368973699737097371973729737397374973759737697377973789737997380973819738297383973849738597386973879738897389973909739197392973939739497395973969739797398973999740097401974029740397404974059740697407974089740997410974119741297413974149741597416974179741897419974209742197422974239742497425974269742797428974299743097431974329743397434974359743697437974389743997440974419744297443974449744597446974479744897449974509745197452974539745497455974569745797458974599746097461974629746397464974659746697467974689746997470974719747297473974749747597476974779747897479974809748197482974839748497485974869748797488974899749097491974929749397494974959749697497974989749997500975019750297503975049750597506975079750897509975109751197512975139751497515975169751797518975199752097521975229752397524975259752697527975289752997530975319753297533975349753597536975379753897539975409754197542975439754497545975469754797548975499755097551975529755397554975559755697557975589755997560975619756297563975649756597566975679756897569975709757197572975739757497575975769757797578975799758097581975829758397584975859758697587975889758997590975919759297593975949759597596975979759897599976009760197602976039760497605976069760797608976099761097611976129761397614976159761697617976189761997620976219762297623976249762597626976279762897629976309763197632976339763497635976369763797638976399764097641976429764397644976459764697647976489764997650976519765297653976549765597656976579765897659976609766197662976639766497665976669766797668976699767097671976729767397674976759767697677976789767997680976819768297683976849768597686976879768897689976909769197692976939769497695976969769797698976999770097701977029770397704977059770697707977089770997710977119771297713977149771597716977179771897719977209772197722977239772497725977269772797728977299773097731977329773397734977359773697737977389773997740977419774297743977449774597746977479774897749977509775197752977539775497755977569775797758977599776097761977629776397764977659776697767977689776997770977719777297773977749777597776977779777897779977809778197782977839778497785977869778797788977899779097791977929779397794977959779697797977989779997800978019780297803978049780597806978079780897809978109781197812978139781497815978169781797818978199782097821978229782397824978259782697827978289782997830978319783297833978349783597836978379783897839978409784197842978439784497845978469784797848978499785097851978529785397854978559785697857978589785997860978619786297863978649786597866978679786897869978709787197872978739787497875978769787797878978799788097881978829788397884978859788697887978889788997890978919789297893978949789597896978979789897899979009790197902979039790497905979069790797908979099791097911979129791397914979159791697917979189791997920979219792297923979249792597926979279792897929979309793197932979339793497935979369793797938979399794097941979429794397944979459794697947979489794997950979519795297953979549795597956979579795897959979609796197962979639796497965979669796797968979699797097971979729797397974979759797697977979789797997980979819798297983979849798597986979879798897989979909799197992979939799497995979969799797998979999800098001980029800398004980059800698007980089800998010980119801298013980149801598016980179801898019980209802198022980239802498025980269802798028980299803098031980329803398034980359803698037980389803998040980419804298043980449804598046980479804898049980509805198052980539805498055980569805798058980599806098061980629806398064980659806698067980689806998070980719807298073980749807598076980779807898079980809808198082980839808498085980869808798088980899809098091980929809398094980959809698097980989809998100981019810298103981049810598106981079810898109981109811198112981139811498115981169811798118981199812098121981229812398124981259812698127981289812998130981319813298133981349813598136981379813898139981409814198142981439814498145981469814798148981499815098151981529815398154981559815698157981589815998160981619816298163981649816598166981679816898169981709817198172981739817498175981769817798178981799818098181981829818398184981859818698187981889818998190981919819298193981949819598196981979819898199982009820198202982039820498205982069820798208982099821098211982129821398214982159821698217982189821998220982219822298223982249822598226982279822898229982309823198232982339823498235982369823798238982399824098241982429824398244982459824698247982489824998250982519825298253982549825598256982579825898259982609826198262982639826498265982669826798268982699827098271982729827398274982759827698277982789827998280982819828298283982849828598286982879828898289982909829198292982939829498295982969829798298982999830098301983029830398304983059830698307983089830998310983119831298313983149831598316983179831898319983209832198322983239832498325983269832798328983299833098331983329833398334983359833698337983389833998340983419834298343983449834598346983479834898349983509835198352983539835498355983569835798358983599836098361983629836398364983659836698367983689836998370983719837298373983749837598376983779837898379983809838198382983839838498385983869838798388983899839098391983929839398394983959839698397983989839998400984019840298403984049840598406984079840898409984109841198412984139841498415984169841798418984199842098421984229842398424984259842698427984289842998430984319843298433984349843598436984379843898439984409844198442984439844498445984469844798448984499845098451984529845398454984559845698457984589845998460984619846298463984649846598466984679846898469984709847198472984739847498475984769847798478984799848098481984829848398484984859848698487984889848998490984919849298493984949849598496984979849898499985009850198502985039850498505985069850798508985099851098511985129851398514985159851698517985189851998520985219852298523985249852598526985279852898529985309853198532985339853498535985369853798538985399854098541985429854398544985459854698547985489854998550985519855298553985549855598556985579855898559985609856198562985639856498565985669856798568985699857098571985729857398574985759857698577985789857998580985819858298583985849858598586985879858898589985909859198592985939859498595985969859798598985999860098601986029860398604986059860698607986089860998610986119861298613986149861598616986179861898619986209862198622986239862498625986269862798628986299863098631986329863398634986359863698637986389863998640986419864298643986449864598646986479864898649986509865198652986539865498655986569865798658986599866098661986629866398664986659866698667986689866998670986719867298673986749867598676986779867898679986809868198682986839868498685986869868798688986899869098691986929869398694986959869698697986989869998700987019870298703987049870598706987079870898709987109871198712987139871498715987169871798718987199872098721987229872398724987259872698727987289872998730987319873298733987349873598736987379873898739987409874198742987439874498745987469874798748987499875098751987529875398754987559875698757987589875998760987619876298763987649876598766987679876898769987709877198772987739877498775987769877798778987799878098781987829878398784987859878698787987889878998790987919879298793987949879598796987979879898799988009880198802988039880498805988069880798808988099881098811988129881398814988159881698817988189881998820988219882298823988249882598826988279882898829988309883198832988339883498835988369883798838988399884098841988429884398844988459884698847988489884998850988519885298853988549885598856988579885898859988609886198862988639886498865988669886798868988699887098871988729887398874988759887698877988789887998880988819888298883988849888598886988879888898889988909889198892988939889498895988969889798898988999890098901989029890398904989059890698907989089890998910989119891298913989149891598916989179891898919989209892198922989239892498925989269892798928989299893098931989329893398934989359893698937989389893998940989419894298943989449894598946989479894898949989509895198952989539895498955989569895798958989599896098961989629896398964989659896698967989689896998970989719897298973989749897598976989779897898979989809898198982989839898498985989869898798988989899899098991989929899398994989959899698997989989899999000990019900299003990049900599006990079900899009990109901199012990139901499015990169901799018990199902099021990229902399024990259902699027990289902999030990319903299033990349903599036990379903899039990409904199042990439904499045990469904799048990499905099051990529905399054990559905699057990589905999060990619906299063990649906599066990679906899069990709907199072990739907499075990769907799078990799908099081990829908399084990859908699087990889908999090990919909299093990949909599096990979909899099991009910199102991039910499105991069910799108991099911099111991129911399114991159911699117991189911999120991219912299123991249912599126991279912899129991309913199132991339913499135991369913799138991399914099141991429914399144991459914699147991489914999150991519915299153991549915599156991579915899159991609916199162991639916499165991669916799168991699917099171991729917399174991759917699177991789917999180991819918299183991849918599186991879918899189991909919199192991939919499195991969919799198991999920099201992029920399204992059920699207992089920999210992119921299213992149921599216992179921899219992209922199222992239922499225992269922799228992299923099231992329923399234992359923699237992389923999240992419924299243992449924599246992479924899249992509925199252992539925499255992569925799258992599926099261992629926399264992659926699267992689926999270992719927299273992749927599276992779927899279992809928199282992839928499285992869928799288992899929099291992929929399294992959929699297992989929999300993019930299303993049930599306993079930899309993109931199312993139931499315993169931799318993199932099321993229932399324993259932699327993289932999330993319933299333993349933599336993379933899339993409934199342993439934499345993469934799348993499935099351993529935399354993559935699357993589935999360993619936299363993649936599366993679936899369993709937199372993739937499375993769937799378993799938099381993829938399384993859938699387993889938999390993919939299393993949939599396993979939899399994009940199402994039940499405994069940799408994099941099411994129941399414994159941699417994189941999420994219942299423994249942599426994279942899429994309943199432994339943499435994369943799438994399944099441994429944399444994459944699447994489944999450994519945299453994549945599456994579945899459994609946199462994639946499465994669946799468994699947099471994729947399474994759947699477994789947999480994819948299483994849948599486994879948899489994909949199492994939949499495994969949799498994999950099501995029950399504995059950699507995089950999510995119951299513995149951599516995179951899519995209952199522995239952499525995269952799528995299953099531995329953399534995359953699537995389953999540995419954299543995449954599546995479954899549995509955199552995539955499555995569955799558995599956099561995629956399564995659956699567995689956999570995719957299573995749957599576995779957899579995809958199582995839958499585995869958799588995899959099591995929959399594995959959699597995989959999600996019960299603996049960599606996079960899609996109961199612996139961499615996169961799618996199962099621996229962399624996259962699627996289962999630996319963299633996349963599636996379963899639996409964199642996439964499645996469964799648996499965099651996529965399654996559965699657996589965999660996619966299663996649966599666996679966899669996709967199672996739967499675996769967799678996799968099681996829968399684996859968699687996889968999690996919969299693996949969599696996979969899699997009970199702997039970499705997069970799708997099971099711997129971399714997159971699717997189971999720997219972299723997249972599726997279972899729997309973199732997339973499735997369973799738997399974099741997429974399744997459974699747997489974999750997519975299753997549975599756997579975899759997609976199762997639976499765997669976799768997699977099771997729977399774997759977699777997789977999780997819978299783997849978599786997879978899789997909979199792997939979499795997969979799798997999980099801998029980399804998059980699807998089980999810998119981299813998149981599816998179981899819998209982199822998239982499825998269982799828998299983099831998329983399834998359983699837998389983999840998419984299843998449984599846998479984899849998509985199852998539985499855998569985799858998599986099861998629986399864998659986699867998689986999870998719987299873998749987599876998779987899879998809988199882998839988499885998869988799888998899989099891998929989399894998959989699897998989989999900999019990299903999049990599906999079990899909999109991199912999139991499915999169991799918999199992099921999229992399924999259992699927999289992999930999319993299933999349993599936999379993899939999409994199942999439994499945999469994799948999499995099951999529995399954999559995699957999589995999960999619996299963999649996599966999679996899969999709997199972999739997499975999769997799978999799998099981999829998399984999859998699987999889998999990999919999299993999949999599996999979999899999100000100001100002100003100004100005100006100007100008100009100010100011100012100013100014100015100016100017100018100019100020100021100022100023100024100025100026100027100028100029100030100031100032100033100034100035100036100037100038100039100040100041100042100043100044100045100046100047100048100049100050100051100052100053100054100055100056100057100058100059100060100061100062100063100064100065100066100067100068100069100070100071100072100073100074100075100076100077100078100079100080100081100082100083100084100085100086100087100088100089100090100091100092100093100094100095100096100097100098100099100100100101100102100103100104100105100106100107100108100109100110100111100112100113100114100115100116100117100118100119100120100121100122100123100124100125100126100127100128100129100130100131100132100133100134100135100136100137100138100139100140100141100142100143100144100145100146100147100148100149100150100151100152100153100154100155100156100157100158100159100160100161100162100163100164100165100166100167100168100169100170100171100172100173100174100175100176100177100178100179100180100181100182100183100184100185100186100187100188100189100190100191100192100193100194100195100196100197100198100199100200100201100202100203100204100205100206100207100208100209100210100211100212100213100214100215100216100217100218100219100220100221100222100223100224100225100226100227100228100229100230100231100232100233100234100235100236100237100238100239100240100241100242100243100244100245100246100247100248100249100250100251100252100253100254100255100256100257100258100259100260100261100262100263100264100265100266100267100268100269100270100271100272100273100274100275100276100277100278100279100280100281100282100283100284100285100286100287100288100289100290100291100292100293100294100295100296100297100298100299100300100301100302100303100304100305100306100307100308100309100310100311100312100313100314100315100316100317100318100319100320100321100322100323100324100325100326100327100328100329100330100331100332100333100334100335100336100337100338100339100340100341100342100343100344100345100346100347100348100349100350100351100352100353100354100355100356100357100358100359100360100361100362100363100364100365100366100367100368100369100370100371100372100373100374100375100376100377100378100379100380100381100382100383100384100385100386100387100388100389100390100391100392100393100394100395100396100397100398100399100400100401100402100403100404100405100406100407100408100409100410100411100412100413100414100415100416100417100418100419100420100421100422100423100424100425100426100427100428100429100430100431100432100433100434100435100436100437100438100439100440100441100442100443100444100445100446100447100448100449100450100451100452100453100454100455100456100457100458100459100460100461100462100463100464100465100466100467100468100469100470100471100472100473100474100475100476100477100478100479100480100481100482100483100484100485100486100487100488100489100490100491100492100493100494100495100496100497100498100499100500100501100502100503100504100505100506100507100508100509100510100511100512100513100514100515100516100517100518100519100520100521100522100523100524100525100526100527100528100529100530100531100532100533100534100535100536100537100538100539100540100541100542100543100544100545100546100547100548100549100550100551100552100553100554100555100556100557100558100559100560100561100562100563100564100565100566100567100568100569100570100571100572100573100574100575100576100577100578100579100580100581100582100583100584100585100586100587100588100589100590100591100592100593100594100595100596100597100598100599100600100601100602100603100604100605100606100607100608100609100610100611100612100613100614100615100616100617100618100619100620100621100622100623100624100625100626100627100628100629100630100631100632100633100634100635100636100637100638100639100640100641100642100643100644100645100646100647100648100649100650100651100652100653100654100655100656100657100658100659100660100661100662100663100664100665100666100667100668100669100670100671100672100673100674100675100676100677100678100679100680100681100682100683100684100685100686100687100688100689100690100691100692100693100694100695100696100697100698100699100700100701100702100703100704100705100706100707100708100709100710100711100712100713100714100715100716100717100718100719100720100721100722100723100724100725100726100727100728100729100730100731100732100733100734100735100736100737100738100739100740100741100742100743100744100745100746100747100748100749100750100751100752100753100754100755100756100757100758100759100760100761100762100763100764100765100766100767100768100769100770100771100772100773100774100775100776100777100778100779100780100781100782100783100784100785100786100787100788100789100790100791100792100793100794100795100796100797100798100799100800100801100802100803100804100805100806100807100808100809100810100811100812100813100814100815100816100817100818100819100820100821100822100823100824100825100826100827100828100829100830100831100832100833100834100835100836100837100838100839100840100841100842100843100844100845100846100847100848100849100850100851100852100853100854100855100856100857100858100859100860100861100862100863100864100865100866100867100868100869100870100871100872100873100874100875100876100877100878100879100880100881100882100883100884100885100886100887100888100889100890100891100892100893100894100895100896100897100898100899100900100901100902100903100904100905100906100907100908100909100910100911100912100913100914100915100916100917100918100919100920100921100922100923100924100925100926100927100928100929100930100931100932100933100934100935100936100937100938100939100940100941100942100943100944100945100946100947100948100949100950100951100952100953100954100955100956100957100958100959100960100961100962100963100964100965100966100967100968100969100970100971100972100973100974100975100976100977100978100979100980100981100982100983100984100985100986100987100988100989100990100991100992100993100994100995100996100997100998100999101000101001101002101003101004101005101006101007101008101009101010101011101012101013101014101015101016101017101018101019101020101021101022101023101024101025101026101027101028101029101030101031101032101033101034101035101036101037101038101039101040101041101042101043101044101045101046101047101048101049101050101051101052101053101054101055101056101057101058101059101060101061101062101063101064101065101066101067101068101069101070101071101072101073101074101075101076101077101078101079101080101081101082101083101084101085101086101087101088101089101090101091101092101093101094101095101096101097101098101099101100101101101102101103101104101105101106101107101108101109101110101111101112101113101114101115101116101117101118101119101120101121101122101123101124101125101126101127101128101129101130101131101132101133101134101135101136101137101138101139101140101141101142101143101144101145101146101147101148101149101150101151101152101153101154101155101156101157101158101159101160101161101162101163101164101165101166101167101168101169101170101171101172101173101174101175101176101177101178101179101180101181101182101183101184101185101186101187101188101189101190101191101192101193101194101195101196101197101198101199101200101201101202101203101204101205101206101207101208101209101210101211101212101213101214101215101216101217101218101219101220101221101222101223101224101225101226101227101228101229101230101231101232101233101234101235101236101237101238101239101240101241101242101243101244101245101246101247101248101249101250101251101252101253101254101255101256101257101258101259101260101261101262101263101264101265101266101267101268101269101270101271101272101273101274101275101276101277101278101279101280101281101282101283101284101285101286101287101288101289101290101291101292101293101294101295101296101297101298101299101300101301101302101303101304101305101306101307101308101309101310101311101312101313101314101315101316101317101318101319101320101321101322101323101324101325101326101327101328101329101330101331101332101333101334101335101336101337101338101339101340101341101342101343101344101345101346101347101348101349101350101351101352101353101354101355101356101357101358101359101360101361101362101363101364101365101366101367101368101369101370101371101372101373101374101375101376101377101378101379101380101381101382101383101384101385101386101387101388101389101390101391101392101393101394101395101396101397101398101399101400101401101402101403101404101405101406101407101408101409101410101411101412101413101414101415101416101417101418101419101420101421101422101423101424101425101426101427101428101429101430101431101432101433101434101435101436101437101438101439101440101441101442101443101444101445101446101447101448101449101450101451101452101453101454101455101456101457101458101459101460101461101462101463101464101465101466101467101468101469101470101471101472101473101474101475101476101477101478101479101480101481101482101483101484101485101486101487101488101489101490101491101492101493101494101495101496101497101498101499101500101501101502101503101504101505101506101507101508101509101510 | /*! * DevExtreme* Version: 15.1.4* Build date: Jun 22, 2015** Copyright (c) 2012 - 2015 Developer Express Inc. ALL RIGHTS RESERVED* EULA: https://www.devexpress.com/Support/EULAs/DevExtreme.xml*/"use strict";if (!window.DevExpress) {    /*! Module core, file devexpress.js */    (function($, global, undefined) {        global.DevExpress = global.DevExpress || {};        $.extend(global.DevExpress, {            VERSION: "15.1.4",            abstract: function() {                throw global.DevExpress.Error("E0001");            },            stringFormat: function() {                var s = arguments[0],                    replaceDollarCount,                    reg,                    argument;                for (var i = 0; i < arguments.length - 1; i++) {                    reg = new RegExp("\\{" + i + "\\}", "gm");                    argument = arguments[i + 1];                    if ($.type(argument) === "string" && argument.indexOf("$") >= 0) {                        replaceDollarCount = "$".replace("$", "$$").length;                        argument = argument.replace("$", replaceDollarCount === 1 ? "$$$$" : "$$")                    }                    s = s.replace(reg, argument)                }                return s            },            parseUrl: function() {                var a = document.createElement("a"),                    props = ["protocol", "hostname", "port", "pathname", "search", "hash"];                var normalizePath = function(value) {                        if (value.charAt(0) !== "/")                            value = "/" + value;                        return value                    };                return function(url) {                        a.href = url;                        var result = {};                        $.each(props, function() {                            result[this] = a[this]                        });                        result.pathname = normalizePath(result.pathname);                        return result                    }            }(),            processHardwareBackButton: function() {                this.hardwareBackButton.fire()            },            hardwareBackButton: $.Callbacks(),            viewPort: function() {                var $current;                return function(element) {                        if (!arguments.length)                            return $current;                        var $element = $(element);                        var isNewViewportFound = !!$element.length;                        var prevViewPort = this.viewPort();                        $current = isNewViewportFound ? $element : $("body");                        this.viewPortChanged.fire(isNewViewportFound ? this.viewPort() : $(), prevViewPort)                    }            }(),            viewPortChanged: $.Callbacks(),            hideTopOverlayCallback: function() {                var callbacks = [];                return {                        add: function(callback) {                            var indexOfCallback = $.inArray(callback, callbacks);                            if (indexOfCallback === -1)                                callbacks.push(callback)                        },                        remove: function(callback) {                            var indexOfCallback = $.inArray(callback, callbacks);                            if (indexOfCallback !== -1)                                callbacks.splice(indexOfCallback, 1)                        },                        fire: function() {                            var callback = callbacks.pop(),                                result = !!callback;                            if (result)                                callback();                            return result                        },                        hasCallback: function() {                            return callbacks.length > 0                        },                        reset: function() {                            callbacks = []                        }                    }            }(),            compareVersions: function(x, y, maxLevel) {                function normalizeArg(value) {                    if (typeof value === "string")                        return value.split(".");                    if (typeof value === "number")                        return [value];                    return value                }                x = normalizeArg(x);                y = normalizeArg(y);                var length = Math.max(x.length, y.length);                if (isFinite(maxLevel))                    length = Math.min(length, maxLevel);                for (var i = 0; i < length; i++) {                    var xItem = parseInt(x[i] || 0, 10),                        yItem = parseInt(y[i] || 0, 10);                    if (xItem < yItem)                        return -1;                    if (xItem > yItem)                        return 1                }                return 0            },            rtlEnabled: false        });        $(function() {            DevExpress.viewPort(".dx-viewport")        })    })(jQuery, this);    /*! Module core, file errors.js */    (function($, DX) {        var ERROR_MESSAGES = {                E0001: "Method is not implemented",                E0002: "Member name collision: {0}",                E0003: "A class must be instantiated using the 'new' keyword",                E0004: "The NAME property of the component is not specified",                E0005: "Unknown device",                E0006: "Unknown endpoint key is requested",                E0007: "'Invalidate' method is called outside the update transaction",                E0008: "Type of the option name is not appropriate to create an action",                E0009: "Component '{0}' has not been initialized for an element",                E0010: "Animation configuration with the '{0}' type requires '{1}' configuration as {2}",                E0011: "Unknown animation type '{0}'",                E0012: "jQuery version is too old. Please upgrade jQuery to 1.10.0 or later",                E0013: "KnockoutJS version is too old. Please upgrade KnockoutJS to 2.3.0 or later",                E0014: "The 'release' method shouldn't be called for an unlocked Lock object",                E0015: "Queued task returned an unexpected result",                E0017: "Event namespace is not defined",                E0018: "DevExpress.ui.dxPopup widget is required",                E0020: "Template engine '{0}' is not supported",                E0021: "Unknown theme is set: {0}",                E0022: "LINK[rel=dx-theme] tags must go before DevExpress included scripts",                E0023: "Template name is not specified",                E0100: "Unknown validation type is detected",                E0101: "Misconfigured range validation rule is detected",                E0102: "Misconfigured comparison validation rule is detected",                E0110: "Unknown validation group is detected",                E0120: "Adapter for a dxValidator component cannot be configured",                W0000: "'{0}' is deprecated in {1}. {2}",                W0001: "{0} - '{1}' option is deprecated in {2}. {3}",                W0002: "{0} - '{1}' method is deprecated in {2}. {3}",                W0003: "{0} - '{1}' property is deprecated in {2}. {3}",                W0004: "Timeout for theme loading is over: {0}",                W0005: "'{0}' event is deprecated in {1}. {2}"            };        var ERROR_URL = "http://js.devexpress.com/error/" + DX.VERSION.split(".").slice(0, 2).join("_") + "/";        var combineMessage = function(args) {                var id = args[0];                args = args.slice(1);                return formatMessage(id, formatDetails(id, args))            };        var formatDetails = function(id, args) {                args = [DX.ERROR_MESSAGES[id]].concat(args);                return DX.stringFormat.apply(this, args).replace(/\.*\s*?$/, '')            };        var formatMessage = function(id, details) {                return DX.stringFormat.apply(this, ["{0} - {1}. See:\n{2}", id, details, ERROR_URL + id])            };        var makeError = function(args) {                var id,                    details,                    message;                id = args[0];                args = args.slice(1);                details = formatDetails(id, args);                message = formatMessage(id, details);                return $.extend(new Error(message), {                        __id: id,                        __details: details                    })            };        $.extend(DX, {            Error: function() {                return makeError($.makeArray(arguments))            },            log: function(id) {                var method = "log",                    logger = DX.utils.logger;                if (/^E\d+$/.test(id))                    method = "error";                else if (/^W\d+$/.test(id))                    method = "warn";                logger[method](method === "log" ? id : combineMessage($.makeArray(arguments)))            },            ERROR_MESSAGES: ERROR_MESSAGES        })    })(jQuery, DevExpress);    /*! Module core, file class.js */    (function($, global, DX, undefined) {        DX.Class = function() {            var wrapOverridden = function(baseProto, methodName, method) {                    return function() {                            var prevCallBase = this.callBase;                            this.callBase = baseProto[methodName];                            try {                                return method.apply(this, arguments)                            }                            finally {                                this.callBase = prevCallBase                            }                        }                };            var clonePrototype = function(obj) {                    var func = function(){};                    func.prototype = obj.prototype;                    return new func                };            var classImpl = function(){};            var redefine = function(members) {                    var that = this;                    if (!members)                        return that;                    var memberNames = $.map(members, function(_, k) {                            return k                        });                    $.each(["toString", "toLocaleString", "valueOf"], function() {                        if (members[this])                            memberNames.push(this)                    });                    $.each(memberNames, function() {                        var overridden = $.isFunction(that.prototype[this]) && $.isFunction(members[this]);                        that.prototype[this] = overridden ? wrapOverridden(that.parent.prototype, this, members[this]) : members[this]                    });                    return that                };            var include = function() {                    var classObj = this;                    $.each(arguments, function() {                        if (this.ctor)                            classObj._includedCtors.push(this.ctor);                        if (this.postCtor)                            classObj._includedPostCtors.push(this.postCtor);                        for (var name in this) {                            if (name === "ctor" || name === "postCtor")                                continue;                            if (name in classObj.prototype)                                throw DX.Error("E0002", name);                            classObj.prototype[name] = this[name]                        }                    });                    return classObj                };            var subclassOf = function(parentClass) {                    if (this.parent === parentClass)                        return true;                    if (!this.parent || !this.parent.subclassOf)                        return false;                    return this.parent.subclassOf(parentClass)                };            classImpl.inherit = function(members) {                var inheritor = function() {                        if (!this || this === global || typeof this.constructor !== "function")                            throw DX.Error("E0003");                        var instance = this,                            ctor = instance.ctor;                        $.each(instance.constructor._includedCtors, function() {                            this.call(instance)                        });                        if (ctor)                            ctor.apply(instance, arguments);                        $.each(instance.constructor._includedPostCtors, function() {                            this.call(instance)                        })                    };                inheritor.prototype = clonePrototype(this);                inheritor.inherit = this.inherit;                inheritor.redefine = redefine;                inheritor.include = include;                inheritor.subclassOf = subclassOf;                inheritor.parent = this;                inheritor._includedCtors = this._includedCtors ? this._includedCtors.slice(0) : [];                inheritor._includedPostCtors = this._includedPostCtors ? this._includedPostCtors.slice(0) : [];                inheritor.prototype.constructor = inheritor;                inheritor.redefine(members);                return inheritor            };            return classImpl        }()    })(jQuery, this, DevExpress);    /*! Module core, file queue.js */    (function($, global, undefined) {        var DX = global.DevExpress;        function createQueue(discardPendingTasks) {            var _tasks = [],                _busy = false;            function exec() {                while (_tasks.length) {                    _busy = true;                    var task = _tasks.shift(),                        result = task();                    if (result === undefined)                        continue;                    if (result.then) {                        $.when(result).always(exec);                        return                    }                    throw DX.Error("E0015");                }                _busy = false            }            function add(task, removeTaskCallback) {                if (!discardPendingTasks)                    _tasks.push(task);                else {                    if (_tasks[0] && removeTaskCallback)                        removeTaskCallback(_tasks[0]);                    _tasks = [task]                }                if (!_busy)                    exec()            }            function busy() {                return _busy            }            return {                    add: add,                    busy: busy                }        }        $.extend(global.DevExpress, {            createQueue: createQueue,            enqueue: createQueue().add        })    })(jQuery, this);    /*! Module core, file inflector.js */    (function($, DX, undefined) {        var _normalize = function(text) {                if (text === undefined || text === null)                    return "";                return String(text)            };        var _ucfirst = function(text) {                return _normalize(text).charAt(0).toUpperCase() + text.substr(1)            };        var _chop = function(text) {                return _normalize(text).replace(/([a-z\d])([A-Z])/g, "$1 $2").split(/[\s_-]+/)            };        var dasherize = function(text) {                return $.map(_chop(text), function(p) {                        return p.toLowerCase()                    }).join("-")            };        var underscore = function(text) {                return dasherize(text).replace(/-/g, "_")            };        var camelize = function(text, upperFirst) {                return $.map(_chop(text), function(p, i) {                        p = p.toLowerCase();                        if (upperFirst || i > 0)                            p = _ucfirst(p);                        return p                    }).join("")            };        var humanize = function(text) {                return _ucfirst(dasherize(text).replace(/-/g, " "))            };        var titleize = function(text) {                return $.map(_chop(text), function(p) {                        return _ucfirst(p.toLowerCase())                    }).join(" ")            };        DX.inflector = {            dasherize: dasherize,            camelize: camelize,            humanize: humanize,            titleize: titleize,            underscore: underscore        }    })(jQuery, DevExpress);    /*! Module core, file eventsMixin.js */    (function($, DX, undefined) {        var EventsMixin = {                ctor: function() {                    this._events = {}                },                fireEvent: function(eventName, eventArgs) {                    var callbacks = this._events[eventName];                    if (callbacks)                        callbacks.fireWith(this, eventArgs);                    return this                },                on: function(eventName, eventHandler) {                    if ($.isPlainObject(eventName))                        $.each(eventName, $.proxy(function(e, h) {                            this.on(e, h)                        }, this));                    else {                        var callbacks = this._events[eventName],                            addFn;                        if (!callbacks) {                            callbacks = $.Callbacks();                            this._events[eventName] = callbacks                        }                        addFn = callbacks.originalAdd || callbacks.add;                        addFn.call(callbacks, eventHandler)                    }                    return this                },                off: function(eventName, eventHandler) {                    var callbacks = this._events[eventName];                    if (callbacks)                        if ($.isFunction(eventHandler))                            callbacks.remove(eventHandler);                        else                            callbacks.empty();                    return this                },                _disposeEvents: function() {                    $.each(this._events, function() {                        this.empty()                    })                },                _callbacksToEvents: function(className, eventNames) {                    var that = this;                    $.each(eventNames, function(_, eventName) {                        var callbacksProperty = that[eventName],                            originalAdd;                        if (callbacksProperty !== undefined) {                            originalAdd = callbacksProperty.add;                            callbacksProperty.originalAdd = originalAdd;                            callbacksProperty.add = function() {                                DX.log("W0003", className, eventName, "14.2", "Use the '" + eventName + "' event instead");                                return originalAdd.apply(that, arguments)                            };                            that._events[eventName] = callbacksProperty                        }                    })                }            };        $.extend(DX, {EventsMixin: EventsMixin})    })(jQuery, DevExpress);    /*! Module core, file jquery.js */    (function($, DX) {        if (DX.compareVersions($.fn.jquery, [1, 10]) < 0)            throw DX.Error("E0012");    })(jQuery, DevExpress);    /*! Module core, file jquery.selectors.js */    (function($) {        var focusable = function(element, tabIndex) {                var nodeName = element.nodeName.toLowerCase(),                    isTabIndexNotNaN = !isNaN(tabIndex),                    isVisible = visible(element),                    isDisabled = element.disabled,                    isDefaultFocus = /^(input|select|textarea|button|object)$/.test(nodeName),                    isHyperlink = nodeName === "a",                    isFocusable = true;                if (isDefaultFocus)                    isFocusable = !isDisabled;                else if (isHyperlink)                    isFocusable = element.href || isTabIndexNotNaN;                else                    isFocusable = isTabIndexNotNaN;                return isVisible ? isFocusable : false            };        var visible = function(element) {                var $element = $(element);                return $element.is(":visible") && $element.css("visibility") !== "hidden" && $element.parents().css("visibility") !== "hidden"            };        $.extend(jQuery.expr[':'], {            "dx-focusable": function(element) {                return focusable(element, $.attr(element, "tabindex"))            },            "dx-tabbable": function(element) {                var tabIndex = $.attr(element, "tabindex");                return (isNaN(tabIndex) || tabIndex >= 0) && focusable(element, tabIndex)            }        })    })(jQuery);    /*! Module core, file utils.common.js */    (function($, DX, undefined) {        var isDefined = function(object) {                return object !== null && object !== undefined            };        var isString = function(object) {                return $.type(object) === 'string'            };        var isNumber = function(object) {                return typeof object === "number" && isFinite(object) || $.isNumeric(object)            };        var isObject = function(object) {                return $.type(object) === 'object'            };        var isArray = function(object) {                return $.type(object) === 'array'            };        var isDate = function(object) {                return $.type(object) === 'date'            };        var isFunction = function(object) {                return $.type(object) === 'function'            };        var isExponential = function(value) {                return isNumber(value) && value.toString().indexOf('e') !== -1            };        var ensureDefined = function(value, defaultValue) {                return isDefined(value) ? value : defaultValue            };        var getImageSourceType = function(source) {                if (!isDefined(source))                    return false;                if (/^fa fa-|^fa-.* fa/.test(source))                    return "faIcon";                else if (/^ion-.*|ion.*ion-.*/.test(source))                    return "ionIcon";                else if (/^glyphicon glyphicon-|^glyphicon-.* glyphicon/.test(source))                    return "glyphIcon";                else if (/data:.*base64|\.|\//.test(source))                    return "image";                else if (/^[\w-_]+$/.test(source))                    return "dxIcon";                else                    return false            };        var getImageContainer = function(source) {                var imageType = getImageSourceType(source),                    ICON_CLASS = "dx-icon";                switch (imageType) {                    case"image":                        return $("<img>", {src: source}).addClass(ICON_CLASS);                    case"faIcon":                    case"glyphIcon":                        return $("<i>", {"class": ICON_CLASS + " " + source});                    case"ionIcon":                        var result = $("<i>", {"class": ICON_CLASS + " " + source});                        if (!result.hasClass("ion") && !result.hasClass("ionicons"))                            result.addClass("ion");                        return result;                    case"dxIcon":                        return $("<i>", {"class": ICON_CLASS + " " + ICON_CLASS + "-" + source});                    default:                        return null                }            };        var extendFromObject = function(target, source, overrideExistingValues) {                target = target || {};                for (var prop in source)                    if (source.hasOwnProperty(prop)) {                        var value = source[prop];                        if (!(prop in target) || overrideExistingValues)                            target[prop] = value                    }                return target            };        var clone = function() {                function Clone(){}                return function(obj) {                        Clone.prototype = obj;                        return new Clone                    }            }();        var executeAsync = function(action, context) {                var deferred = $.Deferred(),                    normalizedContext = context || this,                    timerId,                    task = {                        promise: deferred.promise(),                        abort: function() {                            clearTimeout(timerId);                            deferred.rejectWith(normalizedContext)                        }                    },                    callback = function() {                        var result = action.call(normalizedContext);                        if (result && result.done && $.isFunction(result.done))                            result.done(function() {                                deferred.resolveWith(normalizedContext)                            });                        else                            deferred.resolveWith(normalizedContext)                    };                timerId = (arguments[2] || setTimeout)(callback, 0);                return task            };        var findBestMatches = function(targetFilter, items, mapFn) {                var bestMatches = [],                    maxMatchCount = 0;                $.each(items, function(index, itemSrc) {                    var matchCount = 0,                        item = mapFn ? mapFn(itemSrc) : itemSrc;                    $.each(targetFilter, function(paramName) {                        var value = item[paramName];                        if (value === undefined)                            return;                        if (value === targetFilter[paramName]) {                            matchCount++;                            return                        }                        matchCount = -1;                        return false                    });                    if (matchCount < maxMatchCount)                        return;                    if (matchCount > maxMatchCount) {                        bestMatches.length = 0;                        maxMatchCount = matchCount                    }                    bestMatches.push(itemSrc)                });                return bestMatches            };        var preg_quote = function(str) {                return (str + "").replace(/([\+\*\?\\\.\[\^\]\$\(\)\{\}\><\|\=\!\:])/g, "\\$1")            };        var replaceAll = function(text, searchToken, replacementToken) {                return text.replace(new RegExp("(" + preg_quote(searchToken) + ")", "gi"), replacementToken)            };        var splitPair = function(raw) {                switch (typeof raw) {                    case"string":                        return raw.split(/\s+/, 2);                    case"object":                        return [raw.x || raw.h, raw.y || raw.v];                    case"number":                        return [raw];                    default:                        return raw                }            };        var stringPairToObject = function(raw) {                var pair = splitPair(raw),                    h = parseInt(pair && pair[0], 10),                    v = parseInt(pair && pair[1], 10);                if (!isFinite(h))                    h = 0;                if (!isFinite(v))                    v = h;                return {                        h: h,                        v: v                    }            };        var orderEach = function(map, func) {                var keys = [],                    key,                    i;                for (key in map)                    keys.push(key);                keys.sort(function(x, y) {                    var isNumberX = DX.utils.isNumber(x),                        isNumberY = DX.utils.isNumber(y);                    if (isNumberX && isNumberY)                        return x - y;                    if (isNumberX && !isNumberY)                        return -1;                    if (!isNumberX && isNumberY)                        return 1;                    if (x < y)                        return -1;                    if (x > y)                        return 1;                    return 0                });                for (i = 0; i < keys.length; i++) {                    key = keys[i];                    func(key, map[key])                }            };        function icontains(elem, text) {            var result = false;            $.each($(elem).contents(), function(index, content) {                if (content.nodeType === 3 && (content.textContent || content.nodeValue || "").toLowerCase().indexOf((text || "").toLowerCase()) > -1) {                    result = true;                    return false                }            });            return result        }        $.expr[":"].dxicontains = $.expr.createPseudo(function(text) {            return function(elem) {                    return icontains(elem, text)                }        });        function deepExtendArraySafe(target, changes) {            var prevValue,                newValue;            for (var name in changes) {                prevValue = target[name];                newValue = changes[name];                if (target === newValue)                    continue;                if ($.isPlainObject(newValue) && !(newValue instanceof $.Event))                    target[name] = deepExtendArraySafe($.isPlainObject(prevValue) ? prevValue : {}, newValue);                else if (newValue !== undefined)                    target[name] = newValue            }            return target        }        function unwrapObservable(value) {            if (DX.support.hasKo)                return ko.utils.unwrapObservable(value);            return value        }        function normalizeIndexes(items, indexParameterName, currentItem, needIndexCallback) {            var indexedItems = {},                parameterIndex = 0;            $.each(items, function(index, item) {                index = item[indexParameterName];                if (isDefined(index)) {                    indexedItems[index] = indexedItems[index] || [];                    if (item === currentItem)                        indexedItems[index].unshift(item);                    else                        indexedItems[index].push(item);                    delete item[indexParameterName]                }            });            orderEach(indexedItems, function(index, items) {                $.each(items, function() {                    if (index >= 0)                        this[indexParameterName] = parameterIndex++                })            });            $.each(items, function() {                if (!isDefined(this[indexParameterName]) && (!needIndexCallback || needIndexCallback(this)))                    this[indexParameterName] = parameterIndex++            });            return parameterIndex        }        DX.utils = {            isDefined: isDefined,            isString: isString,            isNumber: isNumber,            isObject: isObject,            isArray: isArray,            isDate: isDate,            isFunction: isFunction,            isExponential: isExponential,            ensureDefined: ensureDefined,            extendFromObject: extendFromObject,            clone: clone,            executeAsync: executeAsync,            stringFormat: DX.stringFormat,            findBestMatches: findBestMatches,            replaceAll: replaceAll,            deepExtendArraySafe: deepExtendArraySafe,            splitPair: splitPair,            stringPairToObject: stringPairToObject,            normalizeIndexes: normalizeIndexes,            orderEach: orderEach,            unwrapObservable: unwrapObservable,            getImageSourceType: getImageSourceType,            getImageContainer: getImageContainer        }    })(jQuery, DevExpress);    /*! Module core, file utils.console.js */    (function($, DX, undefined) {        var logger = function() {                var console = window.console;                function info(text) {                    if (!console || !$.isFunction(console.info))                        return;                    console.info(text)                }                function warn(text) {                    if (!console || !$.isFunction(console.warn))                        return;                    console.warn(text)                }                function error(text) {                    if (!console || !$.isFunction(console.error))                        return;                    console.error(text)                }                return {                        info: info,                        warn: warn,                        error: error                    }            }();        var debug = function() {                function assert(condition, message) {                    if (!condition)                        throw new Error(message);                }                function assertParam(parameter, message) {                    assert(parameter !== null && parameter !== undefined, message)                }                return {                        assert: assert,                        assertParam: assertParam                    }            }();        $.extend(DX.utils, {            logger: logger,            debug: debug        })    })(jQuery, DevExpress);    /*! Module core, file utils.math.js */    (function($, DX, undefined) {        var PI = Math.PI,            LN10 = Math.LN10;        var cos = Math.cos,            sin = Math.sin,            abs = Math.abs,            log = Math.log,            floor = Math.floor,            ceil = Math.ceil,            max = Math.max,            isNaN = window.isNaN,            Number = window.Number,            NaN = window.NaN;        var isNumber = DX.utils.isNumber,            isExponential = DX.utils.isExponential;        var getPrecision = function(value) {                var stringFraction,                    stringValue = value.toString(),                    pointIndex = stringValue.indexOf('.'),                    startIndex,                    precision;                if (isExponential(value)) {                    precision = getDecimalOrder(value);                    if (precision < 0)                        return Math.abs(precision);                    else                        return 0                }                if (pointIndex !== -1) {                    startIndex = pointIndex + 1;                    stringFraction = stringValue.substring(startIndex, startIndex + 20);                    return stringFraction.length                }                return 0            };        var getLog = function(value, base) {                if (!value)                    return NaN;                return Math.log(value) / Math.log(base)            };        var raiseTo = function(power, base) {                return Math.pow(base, power)            };        var sign = function(value) {                if (value === 0)                    return 0;                return value / abs(value)            };        var normalizeAngle = function(angle) {                return (angle % 360 + 360) % 360            };        var convertAngleToRendererSpace = function(angle) {                return 90 - angle            };        var degreesToRadians = function(value) {                return PI * value / 180            };        var getCosAndSin = function(angle) {                var angleInRadians = degreesToRadians(angle);                return {                        cos: cos(angleInRadians),                        sin: sin(angleInRadians)                    }            };        var DECIMAL_ORDER_THRESHOLD = 1E-14;        var getDistance = function(x1, y1, x2, y2) {                var diffX = x2 - x1,                    diffY = y2 - y1;                return Math.sqrt(diffY * diffY + diffX * diffX)            };        var getDecimalOrder = function(number) {                var n = abs(number),                    cn;                if (!isNaN(n)) {                    if (n > 0) {                        n = log(n) / LN10;                        cn = ceil(n);                        return cn - n < DECIMAL_ORDER_THRESHOLD ? cn : floor(n)                    }                    return 0                }                return NaN            };        var getAppropriateFormat = function(start, end, count) {                var order = max(getDecimalOrder(start), getDecimalOrder(end)),                    precision = -getDecimalOrder(abs(end - start) / count),                    format;                if (!isNaN(order) && !isNaN(precision)) {                    if (abs(order) <= 4) {                        format = 'fixedPoint';                        precision < 0 && (precision = 0);                        precision > 4 && (precision = 4)                    }                    else {                        format = 'exponential';                        precision += order - 1;                        precision > 3 && (precision = 3)                    }                    return {                            format: format,                            precision: precision                        }                }                return null            };        var getFraction = function(value) {                var valueString,                    dotIndex;                if (isNumber(value)) {                    valueString = value.toString();                    dotIndex = valueString.indexOf('.');                    if (dotIndex >= 0)                        if (isExponential(value))                            return valueString.substr(dotIndex + 1, valueString.indexOf('e') - dotIndex - 1);                        else {                            valueString = value.toFixed(20);                            return valueString.substr(dotIndex + 1, valueString.length - dotIndex + 1)                        }                }                return ''            };        var getSignificantDigitPosition = function(value) {                var fraction = getFraction(value),                    i;                if (fraction)                    for (i = 0; i < fraction.length; i++)                        if (fraction.charAt(i) !== '0')                            return i + 1;                return 0            };        var adjustValue = function(value) {                var fraction = getFraction(value),                    nextValue,                    i;                if (fraction)                    for (i = 1; i <= fraction.length; i++) {                        nextValue = roundValue(value, i);                        if (nextValue !== 0 && fraction[i - 2] && fraction[i - 1] && fraction[i - 2] === fraction[i - 1])                            return nextValue                    }                return value            };        var roundValue = function(value, precision) {                if (precision > 20)                    precision = 20;                if (isNumber(value))                    if (isExponential(value))                        return Number(value.toExponential(precision));                    else                        return Number(value.toFixed(precision))            };        var applyPrecisionByMinDelta = function(min, delta, value) {                var minPrecision = getPrecision(min),                    deltaPrecision = getPrecision(delta);                return roundValue(value, minPrecision < deltaPrecision ? deltaPrecision : minPrecision)            };        var fitIntoRange = function(value, minValue, maxValue) {                return Math.min(Math.max(value, minValue), maxValue)            };        var getPower = function(value) {                return value.toExponential().split("e")[1]            };        $.extend(DX.utils, {            getLog: getLog,            raiseTo: raiseTo,            sign: sign,            normalizeAngle: normalizeAngle,            convertAngleToRendererSpace: convertAngleToRendererSpace,            degreesToRadians: degreesToRadians,            getCosAndSin: getCosAndSin,            getDecimalOrder: getDecimalOrder,            getAppropriateFormat: getAppropriateFormat,            getDistance: getDistance,            getFraction: getFraction,            adjustValue: adjustValue,            roundValue: roundValue,            applyPrecisionByMinDelta: applyPrecisionByMinDelta,            getSignificantDigitPosition: getSignificantDigitPosition,            getPower: getPower,            fitIntoRange: fitIntoRange        });        DX.utils.getPrecision = getPrecision    })(jQuery, DevExpress);    /*! Module core, file utils.date.js */    (function($, DX, undefined) {        var isObject = DX.utils.isObject,            isString = DX.utils.isString,            isDate = DX.utils.isDate,            isDefined = DX.utils.isDefined;        var dateUnitIntervals = ['millisecond', 'second', 'minute', 'hour', 'day', 'week', 'month', 'quarter', 'year'];        var addSubValues = function(value1, value2, isSub) {                return value1 + (isSub ? -1 : 1) * value2            };        var toMilliseconds = function(value) {                switch (value) {                    case'millisecond':                        return 1;                    case'second':                        return toMilliseconds('millisecond') * 1000;                    case'minute':                        return toMilliseconds('second') * 60;                    case'hour':                        return toMilliseconds('minute') * 60;                    case'day':                        return toMilliseconds('hour') * 24;                    case'week':                        return toMilliseconds('day') * 7;                    case'month':                        return toMilliseconds('day') * 30;                    case'quarter':                        return toMilliseconds('month') * 3;                    case'year':                        return toMilliseconds('day') * 365;                    default:                        return 0                }            };        var convertMillisecondsToDateUnits = function(value) {                var i,                    dateUnitCount,                    dateUnitInterval,                    dateUnitIntervals = ['millisecond', 'second', 'minute', 'hour', 'day', 'month', 'year'],                    result = {};                for (i = dateUnitIntervals.length - 1; i >= 0; i--) {                    dateUnitInterval = dateUnitIntervals[i];                    dateUnitCount = Math.floor(value / toMilliseconds(dateUnitInterval));                    if (dateUnitCount > 0) {                        result[dateUnitInterval + 's'] = dateUnitCount;                        value -= convertDateUnitToMilliseconds(dateUnitInterval, dateUnitCount)                    }                }                return result            };        var dateToMilliseconds = function(tickInterval) {                var milliseconds = 0;                if (isObject(tickInterval))                    $.each(tickInterval, function(key, value) {                        milliseconds += convertDateUnitToMilliseconds(key.substr(0, key.length - 1), value)                    });                if (isString(tickInterval))                    milliseconds = convertDateUnitToMilliseconds(tickInterval, 1);                return milliseconds            };        var convertDateUnitToMilliseconds = function(dateUnit, count) {                return toMilliseconds(dateUnit) * count            };        var getDateUnitInterval = function(tickInterval) {                var maxInterval = -1,                    i;                if (isString(tickInterval))                    return tickInterval;                if (isObject(tickInterval)) {                    $.each(tickInterval, function(key, value) {                        for (i = 0; i < dateUnitIntervals.length; i++)                            if (value && (key === dateUnitIntervals[i] + 's' || key === dateUnitIntervals[i]) && maxInterval < i)                                maxInterval = i                    });                    return dateUnitIntervals[maxInterval]                }                return ''            };        var correctDateWithUnitBeginning = function(date, dateInterval, withCorrection) {                var oldDate = new Date(date.getTime()),                    dayMonth,                    firstQuarterMonth,                    dateUnitInterval = getDateUnitInterval(dateInterval);                switch (dateUnitInterval) {                    case'second':                        date.setMilliseconds(0);                        break;                    case'minute':                        date.setSeconds(0, 0);                        break;                    case'hour':                        date.setMinutes(0, 0, 0);                        break;                    case'year':                        date.setMonth(0);                    case'month':                        date.setDate(1);                    case'day':                        date.setHours(0, 0, 0, 0);                        break;                    case'week':                        dayMonth = date.getDate();                        if (date.getDay() !== 0)                            dayMonth += 7 - date.getDay();                        date.setDate(dayMonth);                        date.setHours(0, 0, 0, 0);                        break;                    case'quarter':                        firstQuarterMonth = DX.formatHelper.getFirstQuarterMonth(date.getMonth());                        if (date.getMonth() !== firstQuarterMonth)                            date.setMonth(firstQuarterMonth);                        date.setDate(1);                        date.setHours(0, 0, 0, 0);                        break                }                if (withCorrection && dateUnitInterval !== "hour" && dateUnitInterval !== "minute" && dateUnitInterval !== "second")                    fixTimezoneGap(oldDate, date)            };        var getDatesDifferences = function(date1, date2) {                var differences,                    counter = 0;                differences = {                    year: date1.getFullYear() !== date2.getFullYear(),                    month: date1.getMonth() !== date2.getMonth(),                    day: date1.getDate() !== date2.getDate(),                    hour: date1.getHours() !== date2.getHours(),                    minute: date1.getMinutes() !== date2.getMinutes(),                    second: date1.getSeconds() !== date2.getSeconds()                };                $.each(differences, function(key, value) {                    if (value)                        counter++                });                differences.count = counter;                return differences            };        var addInterval = function(value, interval, isNegative) {                var result = null,                    intervalObject;                if (isDate(value)) {                    intervalObject = isString(interval) ? getDateIntervalByString(interval.toLowerCase()) : interval;                    result = new Date(value.getTime());                    if (intervalObject.years)                        result.setFullYear(addSubValues(result.getFullYear(), intervalObject.years, isNegative));                    if (intervalObject.quarters)                        result.setMonth(addSubValues(result.getMonth(), 3 * intervalObject.quarters, isNegative));                    if (intervalObject.months)                        result.setMonth(addSubValues(result.getMonth(), intervalObject.months, isNegative));                    if (intervalObject.weeks)                        result.setDate(addSubValues(result.getDate(), 7 * intervalObject.weeks, isNegative));                    if (intervalObject.days)                        result.setDate(addSubValues(result.getDate(), intervalObject.days, isNegative));                    if (intervalObject.hours)                        result.setHours(addSubValues(result.getHours(), intervalObject.hours, isNegative));                    if (intervalObject.minutes)                        result.setMinutes(addSubValues(result.getMinutes(), intervalObject.minutes, isNegative));                    if (intervalObject.seconds)                        result.setSeconds(addSubValues(result.getSeconds(), intervalObject.seconds, isNegative));                    if (intervalObject.milliseconds)                        result.setMilliseconds(addSubValues(value.getMilliseconds(), intervalObject.milliseconds, isNegative))                }                else                    result = addSubValues(value, interval, isNegative);                return result            };        var getFirstDateView = function(typeView, date) {                if (!isDefined(date))                    return;                if (typeView === "month")                    return getFirstMonthDate(date);                if (typeView === "year")                    return new Date(date.getFullYear(), 0, 1);                if (typeView === "decade")                    return new Date(getFirstYearInDecade(date), 0, 1);                if (typeView === "century")                    return new Date(getFirstDecadeInCentury(date), 0, 1)            };        var getLastDateView = function(typeView, date) {                if (typeView === "month")                    return new Date(date.getFullYear(), date.getMonth(), getLastDayOfMonth(date));                if (typeView === "year")                    return new Date(date.getFullYear(), 11, 1);                if (typeView === "decade")                    return new Date(getFirstYearInDecade(date) + 9, 0, 1);                if (typeView === "century")                    return new Date(getFirstDecadeInCentury(date) + 90, 0, 1)            };        var sameView = function(view, date1, date2) {                return DX.utils[DX.inflector.camelize("same " + view)](date1, date2)            };        var getViewUp = function(typeView) {                switch (typeView) {                    case"month":                        return "year";                    case"year":                        return "decade";                    case"decade":                        return "century";                    default:                        break                }            };        var getViewDown = function(typeView) {                switch (typeView) {                    case"century":                        return "decade";                    case"decade":                        return "year";                    case"year":                        return "month";                    default:                        break                }            };        var getDifferenceInMonth = function(typeView) {                var difference = 1;                if (typeView === "year")                    difference = 12;                if (typeView === "decade")                    difference = 12 * 10;                if (typeView === "century")                    difference = 12 * 100;                return difference            };        var getDifferenceInMonthForCells = function(typeView) {                var difference = 1;                if (typeView === "decade")                    difference = 12;                if (typeView === "century")                    difference = 12 * 10;                return difference            };        var getDateIntervalByString = function(intervalString) {                var result = {};                switch (intervalString) {                    case'year':                        result.years = 1;                        break;                    case'month':                        result.months = 1;                        break;                    case'quarter':                        result.months = 3;                        break;                    case'week':                        result.days = 7;                        break;                    case'day':                        result.days = 1;                        break;                    case'hour':                        result.hours = 1;                        break;                    case'minute':                        result.minutes = 1;                        break;                    case'second':                        result.seconds = 1;                        break;                    case'millisecond':                        result.milliseconds = 1;                        break                }                return result            };        var sameMonthAndYear = function(date1, date2) {                return date1 && date2 && date1.getFullYear() === date2.getFullYear() && date1.getMonth() === date2.getMonth()            };        var sameYear = function(date1, date2) {                return date1 && date2 && date1.getFullYear() === date2.getFullYear()            };        var sameDecade = function(date1, date2) {                if (!isDefined(date1) || !isDefined(date2))                    return;                var startDecadeDate1 = date1.getFullYear() - date1.getFullYear() % 10,                    startDecadeDate2 = date2.getFullYear() - date2.getFullYear() % 10;                return date1 && date2 && startDecadeDate1 === startDecadeDate2            };        var sameCentury = function(date1, date2) {                if (!isDefined(date1) || !isDefined(date2))                    return;                var startCenturyDate1 = date1.getFullYear() - date1.getFullYear() % 100,                    startCenturyDate2 = date2.getFullYear() - date2.getFullYear() % 100;                return date1 && date2 && startCenturyDate1 === startCenturyDate2            };        var getFirstDecadeInCentury = function(date) {                return date && date.getFullYear() - date.getFullYear() % 100            };        var getFirstYearInDecade = function(date) {                return date && date.getFullYear() - date.getFullYear() % 10            };        var getShortDate = function(date) {                return Globalize.format(date, "yyyy/M/d")            };        var getLastDayOfMonth = function(date) {                date = new Date(date.getFullYear(), date.getMonth() + 1, 0);                return date.getDate()            };        var getFirstMonthDate = function(date) {                if (!isDefined(date))                    return;                var newDate = new Date(date.getFullYear(), date.getMonth(), 1);                return newDate            };        var getLastMonthDate = function(date) {                if (!isDefined(date))                    return;                var newDate = new Date(date.getFullYear(), date.getMonth() + 1, 0);                return newDate            };        var getFirstWeekDate = function(date, firstDayOfWeek) {                firstDayOfWeek = firstDayOfWeek || Globalize.culture().calendar.firstDay;                var delta = (date.getDay() - firstDayOfWeek + 7) % 7;                var result = new Date(date);                result.setDate(date.getDate() - delta);                return result            };        var dateInRange = function(date, min, max) {                return normalizeDate(date, min, max) === date            };        var normalizeDate = function(date, min, max) {                var normalizedDate = date;                if (isDefined(min) && date < min)                    normalizedDate = min;                if (isDefined(max) && date > max)                    normalizedDate = max;                return normalizedDate            };        var fixTimezoneGap = function(oldDate, newDate) {                if (!DX.utils.isDefined(oldDate))                    return;                var diff = newDate.getHours() - oldDate.getHours(),                    sign,                    trial;                if (diff === 0)                    return;                sign = diff === 1 || diff === -23 ? -1 : 1,                trial = new Date(newDate.getTime() + sign * 3600000);                if (sign > 0 || trial.getDate() === newDate.getDate())                    newDate.setTime(trial.getTime())            };        var makeDate = function(date) {                if (!(date instanceof Date))                    date = new Date(date);                return date            };        $.extend(DX.utils, {            dateUnitIntervals: dateUnitIntervals,            convertMillisecondsToDateUnits: convertMillisecondsToDateUnits,            dateToMilliseconds: dateToMilliseconds,            convertDateUnitToMilliseconds: convertDateUnitToMilliseconds,            getDateUnitInterval: getDateUnitInterval,            getDatesDifferences: getDatesDifferences,            correctDateWithUnitBeginning: correctDateWithUnitBeginning,            addInterval: addInterval,            getDateIntervalByString: getDateIntervalByString,            sameMonthAndYear: sameMonthAndYear,            sameMonth: sameMonthAndYear,            sameYear: sameYear,            sameDecade: sameDecade,            sameCentury: sameCentury,            sameView: sameView,            getDifferenceInMonth: getDifferenceInMonth,            getDifferenceInMonthForCells: getDifferenceInMonthForCells,            getFirstYearInDecade: getFirstYearInDecade,            getFirstDecadeInCentury: getFirstDecadeInCentury,            getShortDate: getShortDate,            getFirstDateView: getFirstDateView,            getLastDateView: getLastDateView,            getViewDown: getViewDown,            getViewUp: getViewUp,            getLastMonthDate: getLastMonthDate,            getFirstMonthDate: getFirstMonthDate,            getFirstWeekDate: getFirstWeekDate,            getLastDayOfMonth: getLastDayOfMonth,            dateInRange: dateInRange,            normalizeDate: normalizeDate,            fixTimezoneGap: fixTimezoneGap,            makeDate: makeDate        })    })(jQuery, DevExpress);    /*! Module core, file utils.recurrence.js */    (function($, DX, undefined) {        var utils = DX.utils;        var intervalMap = {                secondly: "seconds",                minutely: "minutes",                hourly: "hours",                daily: "days",                weekly: "weeks",                monthly: "months",                yearly: "years"            };        var dateSetterMap = {                bysecond: function(date, value) {                    date.setSeconds(value)                },                byminute: function(date, value) {                    date.setMinutes(value)                },                byhour: function(date, value) {                    date.setHours(value)                },                bymonth: function(date, value) {                    date.setMonth(value)                },                bymonthday: function(date, value) {                    date.setDate(value)                },                byday: function(date, dayOfWeek) {                    date.setDate(date.getDate() - date.getDay() + dayOfWeek)                }            };        var dateGetterMap = {                bysecond: "getSeconds",                byminute: "getMinutes",                byhour: "getHours",                bymonth: "getMonth",                bymonthday: "getDate",                byday: "getDay"            };        var dateInRecurrenceRange = function(recurrenceString, currentDate, viewStartDate, viewEndDate) {                var result = [];                if (recurrenceString)                    result = getDatesByRecurrence(recurrenceString, currentDate, viewStartDate, viewEndDate);                return !!result.length            };        var normalizeInterval = function(freq, interval) {                var intervalObject = {},                    intervalField = intervalMap[freq.toLowerCase()];                intervalObject[intervalField] = interval;                return intervalObject            };        var getDatesByRecurrence = function(recurrenceString, recurrenceStartDate, viewStartDate, viewEndDate) {                if (!recurrenceString)                    return [];                var result = [],                    recurrenceRule = getRecurrenceRule(recurrenceString);                if (!recurrenceRule.freq)                    return result;                recurrenceRule.interval = normalizeInterval(recurrenceRule.freq, recurrenceRule.interval);                viewEndDate = utils.normalizeDate(viewEndDate, viewStartDate, recurrenceRule.until);                var recurrenceCounter = 0,                    dateCounter = 0,                    dateRules = splitDateRules(recurrenceRule),                    ruleDates = getDatesByRules(dateRules, recurrenceStartDate),                    currentDate = ruleDates[0],                    firstDate = new Date(recurrenceStartDate);                utils.correctDateWithUnitBeginning(firstDate, recurrenceRule.interval);                var firstDateInterval = getDatePartDiffs(recurrenceStartDate, firstDate);                while (currentDate <= viewEndDate && recurrenceRule.count !== recurrenceCounter) {                    if (checkDateByRule(currentDate, dateRules)) {                        if (currentDate >= viewStartDate) {                            viewStartDate = new Date(currentDate);                            viewStartDate.setMilliseconds(viewStartDate.getMilliseconds() + 1);                            result.push(new Date(currentDate))                        }                        recurrenceCounter++                    }                    dateCounter++;                    currentDate = ruleDates[dateCounter % ruleDates.length];                    if (dateCounter / ruleDates.length >= 1) {                        dateCounter = 0;                        firstDate = utils.addInterval(firstDate, recurrenceRule.interval);                        ruleDates = getDatesByRules(dateRules, utils.addInterval(firstDate, firstDateInterval));                        currentDate = ruleDates[0]                    }                }                return result            };        var getDatePartDiffs = function(date1, date2) {                return {                        years: date1.getFullYear() - date2.getFullYear(),                        months: date1.getMonth() - date2.getMonth(),                        days: date1.getDate() - date2.getDate(),                        hours: date1.getHours() - date2.getHours(),                        minutes: date1.getMinutes() - date2.getMinutes(),                        seconds: date1.getSeconds() - date2.getSeconds()                    }            };        var getRecurrenceRule = function(recurrence) {                if (!recurrence)                    return {};                var ruleObject = {},                    ruleStrings = recurrence.split(";");                for (var i = 0, len = ruleStrings.length; i < len; i++) {                    var rule = ruleStrings[i].split("="),                        ruleName = rule[0].toLowerCase(),                        ruleValue = rule[1];                    ruleObject[ruleName] = ruleValue                }                return normalizeRRule(ruleObject)            };        var normalizeRRule = function(rule) {                var count = parseInt(rule.count);                if (!isNaN(count))                    rule.count = count;                var interval = parseInt(rule.interval);                rule.interval = isNaN(interval) ? 1 : interval;                if (rule.freq && rule.until)                    rule.until = getDateByAsciiString(rule.until);                return rule            };        var getDateByAsciiString = function(string) {                var date = Globalize.parseDate(string, "yyyyMMddThhmmss");                if (!date)                    date = Globalize.parseDate(string, "yyyyMMdd");                return date            };        var getAsciiStringByDate = function(date) {                return date.getFullYear() + ('0' + (date.getMonth() + 1)).slice(-2) + ('0' + date.getDate()).slice(-2)            };        var splitDateRules = function(rule) {                var result = [];                for (var field in dateSetterMap) {                    if (!rule[field])                        continue;                    var ruleFieldValues = rule[field].split(","),                        ruleArray = getDateRuleArray(field, ruleFieldValues);                    result = result.length ? extendObjectArray(ruleArray, result) : ruleArray                }                return result            };        var getDateRuleArray = function(field, values) {                var result = [];                for (var i = 0, length = values.length; i < length; i++) {                    var dateRule = {};                    dateRule[field] = handleRuleFieldValue(field, values[i]);                    result.push(dateRule)                }                return result            };        var days = {                SU: 0,                MO: 1,                TU: 2,                WE: 3,                TH: 4,                FR: 5,                SA: 6            };        var handleRuleFieldValue = function(field, value) {                var result = parseInt(value);                if (field === "bymonth")                    result -= 1;                if (field === "byday")                    result = days[value];                return result            };        var extendObjectArray = function(firstArray, secondArray) {                var result = [];                for (var i = 0, firstArrayLength = firstArray.length; i < firstArrayLength; i++)                    for (var j = 0, secondArrayLength = secondArray.length; j < secondArrayLength; j++)                        result.push($.extend({}, firstArray[i], secondArray[j]));                return result            };        var getDatesByRules = function(dateRules, startDate) {                var updatedDate = new Date(startDate),                    result = [];                for (var i = 0, len = dateRules.length; i < len; i++) {                    var current = dateRules[i];                    for (var field in current)                        dateSetterMap[field](updatedDate, current[field]);                    result.push(new Date(updatedDate))                }                if (!result.length)                    result.push(updatedDate);                return result            };        var checkDateByRule = function(date, rules) {                var result = false;                for (var i = 0; i < rules.length; i++) {                    var current = rules[i],                        currentRuleResult = true;                    for (var field in current)                        if (current[field] !== date[dateGetterMap[field]]())                            currentRuleResult = false;                    result = result || currentRuleResult                }                return result || !rules.length            };        var getRecurrenceString = function(object) {                if (!object || !object.freq)                    return;                var result = "";                for (var field in object) {                    if (field === "interval" && object[field] < 2)                        continue;                    result += field + "=" + object[field] + ";"                }                result = result.substring(0, result.length - 1);                return result.toUpperCase()            };        $.extend(DX.utils, {            getRecurrenceString: getRecurrenceString,            getRecurrenceRule: getRecurrenceRule,            getAsciiStringByDate: getAsciiStringByDate,            getDatesByRecurrence: getDatesByRecurrence,            dateInRecurrenceRange: dateInRecurrenceRange        })    })(jQuery, DevExpress);    /*! Module core, file utils.dom.js */    (function($, DX, undefined) {        var windowResizeCallbacks = function() {                var prevSize,                    callbacks = $.Callbacks(),                    jqWindow = $(window),                    resizeEventHandlerAttached = false,                    originalCallbacksAdd = callbacks.add,                    originalCallbacksRemove = callbacks.remove;                var formatSize = function() {                        return [jqWindow.width(), jqWindow.height()].join()                    };                var handleResize = function() {                        var now = formatSize();                        if (now === prevSize)                            return;                        prevSize = now;                        setTimeout(callbacks.fire)                    };                prevSize = formatSize();                callbacks.add = function() {                    var result = originalCallbacksAdd.apply(callbacks, arguments);                    if (!resizeEventHandlerAttached && callbacks.has()) {                        jqWindow.on("resize", handleResize);                        resizeEventHandlerAttached = true                    }                    return result                };                callbacks.remove = function() {                    var result = originalCallbacksRemove.apply(callbacks, arguments);                    if (!callbacks.has() && resizeEventHandlerAttached) {                        jqWindow.off("resize", handleResize);                        resizeEventHandlerAttached = false                    }                    return result                };                return callbacks            }();        var resetActiveElement = function() {                var activeElement = document.activeElement;                if (activeElement && activeElement !== document.body && activeElement.blur)                    activeElement.blur()            };        var createMarkupFromString = function(str) {                var tempElement = $("<div />");                if (window.WinJS)                    WinJS.Utilities.setInnerHTMLUnsafe(tempElement.get(0), str);                else                    tempElement.append(str);                return tempElement.contents()            };        var initMobileViewport = function(options) {                options = $.extend({}, options);                var device = DX.devices.current();                var realDevice = DX.devices.real();                var allowZoom = options.allowZoom,                    allowPan = options.allowPan,                    allowSelection = "allowSelection" in options ? options.allowSelection : device.platform === "generic";                var metaSelector = "meta[name=viewport]";                if (!$(metaSelector).length)                    $("<meta />").attr("name", "viewport").appendTo("head");                var metaVerbs = ["width=device-width"],                    msTouchVerbs = [];                if (allowZoom)                    msTouchVerbs.push("pinch-zoom");                else                    metaVerbs.push("initial-scale=1.0", "maximum-scale=1.0, user-scalable=no");                if (allowPan)                    msTouchVerbs.push("pan-x", "pan-y");                if (!allowPan && !allowZoom)                    $("html, body").css({                        "-ms-content-zooming": "none",                        "-ms-user-select": "none",                        overflow: "hidden"                    });                else                    $("html").css("-ms-overflow-style", "-ms-autohiding-scrollbar");                if (!allowSelection && DX.support.supportProp("user-select"))                    $(".dx-viewport").css(DX.support.styleProp("user-select"), "none");                $(metaSelector).attr("content", metaVerbs.join());                $("html").css("-ms-touch-action", msTouchVerbs.join(" ") || "none");                if (DX.support.touch)                    $(document).off(".dxInitMobileViewport").on("dxpointermove.dxInitMobileViewport", function(e) {                        var count = e.pointers.length,                            isTouchEvent = e.pointerType === "touch",                            zoomDisabled = !allowZoom && count > 1,                            panDisabled = !allowPan && count === 1 && !e.isScrollingEvent;                        if (isTouchEvent && (zoomDisabled || panDisabled))                            e.preventDefault()                    });                realDevice = DX.devices.real();                if (realDevice.ios) {                    var isPhoneGap = document.location.protocol === "file:";                    if (!isPhoneGap)                        windowResizeCallbacks.add(function() {                            var windowWidth = $(window).width();                            $("body").width(windowWidth)                        })                }                if (realDevice.android)                    windowResizeCallbacks.add(function() {                        document.activeElement.scrollIntoViewIfNeeded()                    })            };        var triggerVisibilityChangeEvent = function(eventName) {                var VISIBILITY_CHANGE_SELECTOR = ".dx-visibility-change-handler";                return function(element) {                        var $element = $(element || "body");                        var $changeHandlers = $element.find(VISIBILITY_CHANGE_SELECTOR).add($element.filter(VISIBILITY_CHANGE_SELECTOR));                        $changeHandlers.each(function() {                            $(this).triggerHandler(eventName)                        })                    }            };        var uniqueId = function() {                var counter = 0;                return function(prefix) {                        return (prefix || "") + counter++                    }            }();        DX.dataOptionsAttributeName = "data-options";        var getElementOptions = function(element) {                var optionsString = $(element).attr(DX.dataOptionsAttributeName),                    result;                if ($.trim(optionsString).charAt(0) !== "{")                    optionsString = "{" + optionsString + "}";                try {                    result = new Function("return " + optionsString)()                }                catch(ex) {                    throw DX.Error("E3018", ex, optionsString);                }                return result            };        var createComponents = function(elements, componentTypes) {                var result = [],                    selector = "[" + DX.dataOptionsAttributeName + "]";                elements.find(selector).addBack(selector).each(function(index, element) {                    var $element = $(element),                        options = getElementOptions(element);                    for (var componentName in options)                        if (!componentTypes || $.inArray(componentName, componentTypes) > -1)                            if ($element[componentName]) {                                $element[componentName](options[componentName]);                                result.push($element[componentName]("instance"))                            }                });                return result            };        var normalizeTemplateElement = function(element) {                var $element = DX.utils.isDefined(element) && (element.nodeType || element.jquery) ? $(element) : $("<div>").html(element).contents();                if ($element.length === 1 && $element.is("script"))                    $element = normalizeTemplateElement(element.html());                return $element            };        var clearSelection = function() {                if (window.getSelection) {                    if (window.getSelection().empty)                        window.getSelection().empty();                    else if (window.getSelection().removeAllRanges)                        window.getSelection().removeAllRanges()                }                else if (document.selection)                    document.selection.empty()            };        var closestCommonParent = function(startTarget, endTarget) {                var $startParents = $(startTarget).parents().addBack(),                    $endParents = $(endTarget).parents().addBack(),                    startingParent = Math.min($startParents.length, $endParents.length) - 1;                for (var i = startingParent; i >= 0; i--)                    if ($startParents.eq(i).is($endParents.eq(i)))                        return $startParents.get(i)            };        var toggleAttr = function($target, attr, value) {                value ? $target.attr(attr, value) : $target.removeAttr(attr)            };        var clipboardText = function(event, text) {                var clipboard = event.originalEvent && event.originalEvent.clipboardData || window.clipboardData;                if (arguments.length === 1)                    return clipboard && clipboard.getData("Text");                clipboard && clipboard.setData("Text", text)            };        $.extend(DX.utils, {            windowResizeCallbacks: windowResizeCallbacks,            resetActiveElement: resetActiveElement,            createMarkupFromString: createMarkupFromString,            triggerShownEvent: triggerVisibilityChangeEvent("dxshown"),            triggerHidingEvent: triggerVisibilityChangeEvent("dxhiding"),            initMobileViewport: initMobileViewport,            getElementOptions: getElementOptions,            createComponents: createComponents,            normalizeTemplateElement: normalizeTemplateElement,            clearSelection: clearSelection,            uniqueId: uniqueId,            closestCommonParent: closestCommonParent,            clipboardText: clipboardText,            toggleAttr: toggleAttr        })    })(jQuery, DevExpress);    /*! Module core, file utils.caret.js */    (function($, DX, undefined) {        var getCaret = function(input) {                if (isObsoleteBrowser(input))                    return getCaretForObsoleteBrowser(input);                return {                        start: input.selectionStart,                        end: input.selectionEnd                    }            };        var setCaret = function(input, position) {                if (isObsoleteBrowser(input)) {                    setCaretForObsoleteBrowser(input, position);                    return                }                if (!$.contains(document, input))                    return;                input.selectionStart = position.start;                input.selectionEnd = position.end            };        var isObsoleteBrowser = function(input) {                return !input.setSelectionRange            };        var getCaretForObsoleteBrowser = function(input) {                var range = document.selection.createRange();                var rangeCopy = range.duplicate();                range.move('character', -input.value.length);                range.setEndPoint('EndToStart', rangeCopy);                return {                        start: range.text.length,                        end: range.text.length + rangeCopy.text.length                    }            };        var setCaretForObsoleteBrowser = function(input, position) {                var range = input.createTextRange();                range.collapse(true);                range.moveStart("character", position.start);                range.moveEnd("character", position.end - position.start);                range.select()            };        var caret = function(input, position) {                input = $(input).get(0);                if (!DX.utils.isDefined(position))                    return getCaret(input);                setCaret(input, position)            };        $.extend(DX.utils, {caret: caret})    })(jQuery, DevExpress);    /*! Module core, file utils.graphics.js */    (function($, DX, undefined) {        var _utils = DX.utils,            isFunction = _utils.isFunction,            _inArray = $.inArray,            isDefined = _utils.isDefined;        var processSeriesTemplate = function(seriesTemplate, items) {                var customizeSeries = isFunction(seriesTemplate.customizeSeries) ? seriesTemplate.customizeSeries : $.noop,                    nameField = seriesTemplate.nameField || 'series',                    generatedSeries = {},                    seriesOrder = [],                    series;                for (var i = 0, length = items.length; i < length; i++) {                    var data = items[i];                    if (nameField in data) {                        series = generatedSeries[data[nameField]];                        if (!series) {                            series = generatedSeries[data[nameField]] = {                                name: data[nameField],                                data: []                            };                            seriesOrder.push(series.name)                        }                        series.data.push(data)                    }                }                return $.map(seriesOrder, function(orderedName) {                        var group = generatedSeries[orderedName],                            seriesOptions = customizeSeries.call(null, group.name);                        return $.extend(group, seriesOptions)                    })            };        var getCategoriesInfo = function(categories, startValue, endValue) {                if (!(categories && categories.length > 0))                    return {};                startValue = isDefined(startValue) ? startValue : categories[0];                endValue = isDefined(endValue) ? endValue : categories[categories.length - 1];                var categoriesValue = $.map(categories, function(category) {                        return category && category.valueOf()                    }),                    visibleCategories = [],                    indexStartValue = isDefined(startValue) ? _inArray(startValue.valueOf(), categoriesValue) : 0,                    indexEndValue = isDefined(endValue) ? _inArray(endValue.valueOf(), categoriesValue) : categories.length - 1,                    swapBuf,                    hasVisibleCategories,                    inverted = false,                    visibleCategoriesLen;                indexStartValue < 0 && (indexStartValue = 0);                indexEndValue < 0 && (indexEndValue = categories.length - 1);                if (indexEndValue < indexStartValue) {                    swapBuf = indexEndValue;                    indexEndValue = indexStartValue;                    indexStartValue = swapBuf;                    inverted = true                }                visibleCategories = categories.slice(indexStartValue, indexEndValue + 1);                visibleCategoriesLen = visibleCategories.length;                hasVisibleCategories = visibleCategoriesLen > 0;                return {                        categories: hasVisibleCategories ? visibleCategories : null,                        start: hasVisibleCategories ? visibleCategories[inverted ? visibleCategoriesLen - 1 : 0] : null,                        end: hasVisibleCategories ? visibleCategories[inverted ? 0 : visibleCategoriesLen - 1] : null,                        inverted: inverted                    }            };        $.extend(_utils, {            processSeriesTemplate: processSeriesTemplate,            getCategoriesInfo: getCategoriesInfo        })    })(jQuery, DevExpress);    /*! Module core, file utils.arrays.js */    (function($, DX, undefined) {        var isEmptyArray = function(entity) {                return $.isArray(entity) && !entity.length            };        var wrapToArray = function(entity) {                return $.isArray(entity) ? entity : [entity]            };        var removeDublicates = function(from, what) {                if (!$.isArray(from) || from.length === 0)                    return [];                if (!$.isArray(what) || what.length === 0)                    return from.slice();                var result = [];                $.each(from, function(_, value) {                    var bIndex = $.inArray(value, what);                    if (bIndex === -1)                        result.push(value)                });                return result            };        $.extend(DX.utils, {            isEmptyArray: isEmptyArray,            wrapToArray: wrapToArray,            removeDublicates: removeDublicates        })    })(jQuery, DevExpress);    /*! Module core, file devices.js */    (function($, DX, undefined) {        var KNOWN_UA_TABLE = {                iPhone: "iPhone",                iPhone5: "iPhone",                iPhone6: "iPhone",                iPhone6plus: "iPhone",                iPad: "iPad",                iPadMini: "iPad Mini",                androidPhone: "Android Mobile",                androidTablet: "Android",                win8: "MSAppHost",                win8Phone: "Windows Phone 8",                msSurface: "MSIE ARM Tablet PC",                desktop: "desktop"            };        var DEFAULT_DEVICE = {                deviceType: "",                platform: "",                version: [],                phone: false,                tablet: false,                android: false,                ios: false,                win8: false,                generic: false,                grade: "A",                mac: false            };        $.extend(DEFAULT_DEVICE, {            platform: "generic",            deviceType: "desktop",            generic: true        });        var uaParsers = {                win8: function(userAgent) {                    var isPhone = /windows phone/i.test(userAgent) || userAgent.match(/WPDesktop/),                        isTablet = !isPhone && /arm(.*)trident/i.test(userAgent),                        isDesktop = !isPhone && !isTablet && /msapphost/i.test(userAgent);                    if (!(isPhone || isTablet || isDesktop))                        return;                    var matches = userAgent.match(/windows phone (\d+).(\d+)/i) || userAgent.match(/windows nt (\d+).(\d+)/i),                        version = matches ? [parseInt(matches[1], 10), parseInt(matches[2], 10)] : [];                    return {                            deviceType: isPhone ? "phone" : isTablet ? "tablet" : "desktop",                            platform: "win8",                            version: version,                            grade: "A"                        }                },                ios: function(userAgent) {                    if (!/ip(hone|od|ad)/i.test(userAgent))                        return;                    var isPhone = /ip(hone|od)/i.test(userAgent),                        matches = userAgent.match(/os (\d+)_(\d+)_?(\d+)?/i),                        version = matches ? [parseInt(matches[1], 10), parseInt(matches[2], 10), parseInt(matches[3] || 0, 10)] : [],                        isIPhone4 = window.screen.height === 960 / 2,                        grade = isIPhone4 ? "B" : "A";                    return {                            deviceType: isPhone ? "phone" : "tablet",                            platform: "ios",                            version: version,                            grade: grade                        }                },                android: function(userAgent) {                    if (!/android|htc_|silk/i.test(userAgent))                        return;                    var isPhone = /mobile/i.test(userAgent),                        matches = userAgent.match(/android (\d+)\.(\d+)\.?(\d+)?/i),                        version = matches ? [parseInt(matches[1], 10), parseInt(matches[2], 10), parseInt(matches[3] || 0, 10)] : [],                        worseThan4_4 = version.length > 1 && (version[0] < 4 || version[0] === 4 && version[1] < 4),                        grade = worseThan4_4 ? "B" : "A";                    return {                            deviceType: isPhone ? "phone" : "tablet",                            platform: "android",                            version: version,                            grade: grade                        }                }            };        DX.Devices = DX.Class.inherit({            ctor: function(options) {                this._window = options && options.window || window;                this._realDevice = this._getDevice();                this._currentDevice = undefined;                this._currentOrientation = undefined;                this.orientationChanged = $.Callbacks();                this._callbacksToEvents("Devices", ["orientationChanged"]);                this._recalculateOrientation();                DX.utils.windowResizeCallbacks.add($.proxy(this._recalculateOrientation, this))            },            current: function(deviceOrName) {                if (deviceOrName) {                    this._currentDevice = this._getDevice(deviceOrName);                    this._forced = true;                    DX.ui.themes.init({_autoInit: true})                }                else {                    if (!this._currentDevice) {                        deviceOrName = undefined;                        try {                            deviceOrName = this._getDeviceOrNameFromWindowScope()                        }                        catch(e) {                            deviceOrName = this._getDeviceNameFromSessionStorage()                        }                        finally {                            if (!deviceOrName)                                deviceOrName = this._getDeviceNameFromSessionStorage();                            if (deviceOrName)                                this._forced = true                        }                        this._currentDevice = this._getDevice(deviceOrName)                    }                    return this._currentDevice                }            },            real: function() {                var forceDevice = arguments[0];                if ($.isPlainObject(forceDevice)) {                    $.extend(this._realDevice, forceDevice);                    return                }                return $.extend({}, this._realDevice)            },            orientation: function() {                return this._currentOrientation            },            isForced: function() {                return this._forced            },            isRippleEmulator: function() {                return !!this._window.tinyHippos            },            _getCssClasses: function(device) {                var result = [];                var realDevice = this._realDevice;                device = device || this.current();                if (device.deviceType) {                    result.push("dx-device-" + device.deviceType);                    if (device.deviceType !== "desktop")                        result.push("dx-device-mobile")                }                result.push("dx-device-" + realDevice.platform);                if (realDevice.version && realDevice.version.length)                    result.push("dx-device-" + realDevice.platform + "-" + realDevice.version[0]);                if (DX.devices.isSimulator())                    result.push("dx-simulator");                if (DX.rtlEnabled)                    result.push("dx-rtl");                return result            },            attachCssClasses: function(element, device) {                this._deviceClasses = this._getCssClasses(device).join(" ");                $(element).addClass(this._deviceClasses)            },            detachCssClasses: function(element) {                $(element).removeClass(this._deviceClasses)            },            isSimulator: function() {                try {                    return this._isSimulator || this._window.top !== this._window.self && this._window.top["dx-force-device"] || this.isRippleEmulator()                }                catch(e) {                    return false                }            },            forceSimulator: function() {                this._isSimulator = true            },            _getDevice: function(deviceName) {                if (deviceName === "genericPhone")                    deviceName = {                        deviceType: "phone",                        platform: "generic",                        generic: true                    };                if ($.isPlainObject(deviceName))                    return this._fromConfig(deviceName);                else {                    var ua;                    if (deviceName) {                        ua = KNOWN_UA_TABLE[deviceName];                        if (!ua)                            throw DX.Error("E0005");                    }                    else                        ua = navigator.userAgent;                    return this._fromUA(ua)                }            },            _getDeviceOrNameFromWindowScope: function() {                var result;                if (this._window.top["dx-force-device-object"] || this._window.top["dx-force-device"])                    result = this._window.top["dx-force-device-object"] || this._window.top["dx-force-device"];                return result            },            _getDeviceNameFromSessionStorage: function() {                var sessionStorage;                try {                    sessionStorage = this._window.sessionStorage                }                catch(e) {}                if (!sessionStorage)                    return;                var deviceOrName = sessionStorage.getItem("dx-force-device");                try {                    return $.parseJSON(deviceOrName)                }                catch(ex) {                    return deviceOrName                }            },            _fromConfig: function(config) {                var shortcuts = {                        phone: config.deviceType === "phone",                        tablet: config.deviceType === "tablet",                        android: config.platform === "android",                        ios: config.platform === "ios",                        win8: config.platform === "win8",                        generic: config.platform === "generic"                    };                return $.extend({}, DEFAULT_DEVICE, this._currentDevice, shortcuts, config)            },            _fromUA: function(ua) {                var config;                $.each(uaParsers, function(platform, parser) {                    config = parser(ua);                    return !config                });                if (config)                    return this._fromConfig(config);                var isMac = /(mac os)/.test(ua.toLowerCase()),                    deviceWithOS = DEFAULT_DEVICE;                deviceWithOS.mac = isMac;                return deviceWithOS            },            _changeOrientation: function() {                var $window = $(this._window),                    orientation = $window.height() > $window.width() ? "portrait" : "landscape";                if (this._currentOrientation === orientation)                    return;                this._currentOrientation = orientation;                this.orientationChanged.fire({orientation: orientation})            },            _recalculateOrientation: function() {                var windowWidth = $(this._window).width();                if (this._currentWidth === windowWidth)                    return;                this._currentWidth = windowWidth;                this._changeOrientation()            }        }).include(DX.EventsMixin);        DX.devices = new DX.Devices;        DX.viewPortChanged.add(function(viewPort, prevViewport) {            DX.devices.detachCssClasses(prevViewport);            DX.devices.attachCssClasses(viewPort)        })    })(jQuery, DevExpress);    /*! Module core, file browser.js */    (function($, DX, global, undefined) {        var webkitRegExp = /(webkit)[ \/]([\w.]+)/,            operaRegExp = /(opera)(?:.*version)?[ \/]([\w.]+)/,            ieRegExp = /(msie) (\d{1,2}\.\d)/,            ie11RegExp = /(trident).*rv:(\d{1,2}\.\d)/,            mozillaRegExp = /(mozilla)(?:.*? rv:([\w.]+))?/;        var ua = navigator.userAgent.toLowerCase();        var browser = function() {                var result = {},                    matches = webkitRegExp.exec(ua) || operaRegExp.exec(ua) || ieRegExp.exec(ua) || ie11RegExp.exec(ua) || ua.indexOf("compatible") < 0 && mozillaRegExp.exec(ua) || [],                    browserName = matches[1],                    browserVersion = matches[2];                if (browserName === "trident")                    browserName = "msie";                if (browserName) {                    result[browserName] = true;                    result.version = browserVersion                }                return result            }();        DX.browser = browser    })(jQuery, DevExpress, this);    /*! Module core, file support.js */    (function($, DX, window) {        var jsPrefixes = ["", "Webkit", "Moz", "O", "Ms"],            cssPrefixes = {                "": "",                Webkit: "-webkit-",                Moz: "-moz-",                O: "-o-",                ms: "-ms-"            },            styles = document.createElement("dx").style;        var transitionEndEventNames = {                webkitTransition: 'webkitTransitionEnd',                MozTransition: 'transitionend',                OTransition: 'oTransitionEnd',                msTransition: 'MsTransitionEnd',                transition: 'transitionend'            };        var forEachPrefixes = function(prop, callBack) {                prop = DX.inflector.camelize(prop, true);                var result;                for (var i = 0, cssPrefixesCount = jsPrefixes.length; i < cssPrefixesCount; i++) {                    var jsPrefix = jsPrefixes[i];                    var prefixedProp = jsPrefix + prop;                    var lowerPrefixedProp = DX.inflector.camelize(prefixedProp);                    result = callBack(lowerPrefixedProp, jsPrefix);                    if (result === undefined)                        result = callBack(prefixedProp, jsPrefix);                    if (result !== undefined)                        break                }                return result            };        var styleProp = function(prop) {                return forEachPrefixes(prop, function(specific) {                        if (specific in styles)                            return specific                    })            };        var stylePropPrefix = function(prop) {                return forEachPrefixes(prop, function(specific, jsPrefix) {                        if (specific in styles)                            return cssPrefixes[jsPrefix]                    })            };        var supportProp = function(prop) {                return !!styleProp(prop)            };        var isNativeScrollingSupported = function() {                var realDevice = DX.devices.real(),                    realPlatform = realDevice.platform,                    realVersion = realDevice.version,                    isObsoleteAndroid = realVersion && realVersion[0] < 4 && realPlatform === "android",                    isNativeScrollDevice = !isObsoleteAndroid && $.inArray(realPlatform, ["ios", "android", "win8"]) > -1 || realDevice.mac;                return isNativeScrollDevice            };        DX.support = {            touchEvents: "ontouchstart" in window,            touch: "ontouchstart" in window || !!window.navigator.msMaxTouchPoints,            pointer: window.navigator.pointerEnabled || window.navigator.msPointerEnabled,            transform: supportProp("transform"),            transition: supportProp("transition"),            transitionEndEventName: transitionEndEventNames[styleProp("transition")],            animation: supportProp("animation"),            nativeScrolling: isNativeScrollingSupported(),            winJS: "WinJS" in window,            styleProp: styleProp,            stylePropPrefix: stylePropPrefix,            supportProp: supportProp,            hasKo: !!window.ko,            hasNg: !window.ko && !!window.angular,            inputType: function(type) {                if (type === "text")                    return true;                var input = document.createElement("input");                try {                    input.setAttribute("type", type);                    input.value = "wrongValue";                    return !input.value                }                catch(e) {                    return false                }            }        }    })(jQuery, DevExpress, this);    /*! Module core, file position.js */    (function($, DX, undefined) {        var horzRe = /left|right/,            vertRe = /top|bottom/,            collisionRe = /fit|flip|none/;        var normalizeAlign = function(raw) {                var result = {                        h: "center",                        v: "center"                    };                var pair = DX.utils.splitPair(raw);                if (pair)                    $.each(pair, function() {                        var w = String(this).toLowerCase();                        if (horzRe.test(w))                            result.h = w;                        else if (vertRe.test(w))                            result.v = w                    });                return result            };        var normalizeOffset = function(raw) {                return DX.utils.stringPairToObject(raw)            };        var normalizeCollision = function(raw) {                var pair = DX.utils.splitPair(raw),                    h = String(pair && pair[0]).toLowerCase(),                    v = String(pair && pair[1]).toLowerCase();                if (!collisionRe.test(h))                    h = "none";                if (!collisionRe.test(v))                    v = h;                return {                        h: h,                        v: v                    }            };        var getAlignFactor = function(align) {                switch (align) {                    case"center":                        return 0.5;                    case"right":                    case"bottom":                        return 1;                    default:                        return 0                }            };        var inverseAlign = function(align) {                switch (align) {                    case"left":                        return "right";                    case"right":                        return "left";                    case"top":                        return "bottom";                    case"bottom":                        return "top";                    default:                        return align                }            };        var calculateOversize = function(data, bounds) {                var oversize = 0;                if (data.myLocation < bounds.min)                    oversize += bounds.min - data.myLocation;                if (data.myLocation > bounds.max)                    oversize += data.myLocation - bounds.max;                return oversize            };        var initMyLocation = function(data) {                data.myLocation = data.atLocation + getAlignFactor(data.atAlign) * data.atSize - getAlignFactor(data.myAlign) * data.mySize + data.offset            };        var decolliders = {                fit: function(data, bounds) {                    var result = false;                    if (data.myLocation > bounds.max) {                        data.myLocation = bounds.max;                        result = true                    }                    if (data.myLocation < bounds.min) {                        data.myLocation = bounds.min;                        result = true                    }                    return result                },                flip: function(data, bounds) {                    if (data.myAlign === "center" && data.atAlign === "center")                        return false;                    if (data.myLocation < bounds.min || data.myLocation > bounds.max) {                        var inverseData = $.extend({}, data, {                                myAlign: inverseAlign(data.myAlign),                                atAlign: inverseAlign(data.atAlign),                                offset: -data.offset                            });                        initMyLocation(inverseData);                        inverseData.oversize = calculateOversize(inverseData, bounds);                        if (inverseData.myLocation >= bounds.min && inverseData.myLocation <= bounds.max || inverseData.myLocation > data.myLocation || inverseData.oversize < data.oversize) {                            data.myLocation = inverseData.myLocation;                            data.oversize = inverseData.oversize;                            return true                        }                    }                    return false                }            };        var scrollbarWidth;        var defaultPositionResult = {                h: {                    location: 0,                    flip: false,                    fit: false,                    oversize: 0                },                v: {                    location: 0,                    flip: false,                    fit: false,                    oversize: 0                }            };        var calculatePosition = function(what, options) {                var $what = $(what),                    currentOffset = $what.offset(),                    result = $.extend(true, {}, defaultPositionResult, {                        h: {location: currentOffset.left},                        v: {location: currentOffset.top}                    });                if (!options)                    return result;                var my = normalizeAlign(options.my),                    at = normalizeAlign(options.at),                    of = options.of || window,                    offset = normalizeOffset(options.offset),                    collision = normalizeCollision(options.collision),                    boundary = options.boundary,                    boundaryOffset = normalizeOffset(options.boundaryOffset);                var h = {                        mySize: $what.outerWidth(),                        myAlign: my.h,                        atAlign: at.h,                        offset: offset.h,                        collision: collision.h,                        boundaryOffset: boundaryOffset.h                    };                var v = {                        mySize: $what.outerHeight(),                        myAlign: my.v,                        atAlign: at.v,                        offset: offset.v,                        collision: collision.v,                        boundaryOffset: boundaryOffset.v                    };                if (of.preventDefault) {                    h.atLocation = of.pageX;                    v.atLocation = of.pageY;                    h.atSize = 0;                    v.atSize = 0                }                else {                    of = $(of);                    if ($.isWindow(of[0])) {                        h.atLocation = of.scrollLeft();                        v.atLocation = of.scrollTop();                        h.atSize = of.width();                        v.atSize = of.height()                    }                    else if (of[0].nodeType === 9) {                        h.atLocation = 0;                        v.atLocation = 0;                        h.atSize = of.width();                        v.atSize = of.height()                    }                    else {                        var o = of.offset();                        h.atLocation = o.left;                        v.atLocation = o.top;                        h.atSize = of.outerWidth();                        v.atSize = of.outerHeight()                    }                }                initMyLocation(h);                initMyLocation(v);                var bounds = function() {                        var win = $(window),                            windowWidth = win.width(),                            windowHeight = win.height(),                            left = win.scrollLeft(),                            top = win.scrollTop(),                            hScrollbar = document.width > document.documentElement.clientWidth,                            vScrollbar = document.height > document.documentElement.clientHeight,                            hZoomLevel = DX.support.touch ? document.documentElement.clientWidth / (vScrollbar ? windowWidth - scrollbarWidth : windowWidth) : 1,                            vZoomLevel = DX.support.touch ? document.documentElement.clientHeight / (hScrollbar ? windowHeight - scrollbarWidth : windowHeight) : 1;                        if (scrollbarWidth === undefined)                            scrollbarWidth = calculateScrollbarWidth();                        var boundaryWidth = windowWidth,                            boundaryHeight = windowHeight;                        if (boundary) {                            var $boundary = $(boundary),                                boundaryPosition = $boundary.offset();                            left = boundaryPosition.left;                            top = boundaryPosition.top;                            boundaryWidth = $boundary.width();                            boundaryHeight = $boundary.height()                        }                        return {                                h: {                                    min: left + h.boundaryOffset,                                    max: left + boundaryWidth / hZoomLevel - h.mySize - h.boundaryOffset                                },                                v: {                                    min: top + v.boundaryOffset,                                    max: top + boundaryHeight / vZoomLevel - v.mySize - v.boundaryOffset                                }                            }                    }();                h.oversize = calculateOversize(h, bounds.h);                v.oversize = calculateOversize(v, bounds.v);                if (decolliders[h.collision])                    result.h[h.collision] = decolliders[h.collision](h, bounds.h);                if (decolliders[v.collision])                    result.v[v.collision] = decolliders[v.collision](v, bounds.v);                var preciser = function(number) {                        return options.precise ? number : Math.round(number)                    };                $.extend(true, result, {                    h: {                        location: preciser(h.myLocation),                        oversize: preciser(h.oversize)                    },                    v: {                        location: preciser(v.myLocation),                        oversize: preciser(v.oversize)                    },                    precise: options.precise                });                return result            };        var position = function(what, options) {                var $what = $(what);                if (!options)                    return $what.offset();                DX.translator.resetPosition($what);                var offset = $what.offset(),                    targetPosition = options.h && options.v ? options : calculatePosition($what, options);                var preciser = function(number) {                        return options.precise ? number : Math.round(number)                    };                DX.translator.move($what, {                    left: targetPosition.h.location - preciser(offset.left),                    top: targetPosition.v.location - preciser(offset.top)                });                return targetPosition            };        $.extend(DX, {            calculatePosition: calculatePosition,            position: position        });        $.extend(DX.position, {            inverseAlign: inverseAlign,            normalizeAlign: normalizeAlign        });        var calculateScrollbarWidth = function() {                var $scrollDiv = $("<div>").css({                        width: 100,                        height: 100,                        overflow: "scroll",                        position: "absolute",                        top: -9999                    }).appendTo($("body")),                    result = $scrollDiv.get(0).offsetWidth - $scrollDiv.get(0).clientWidth;                $scrollDiv.remove();                return result            }    })(jQuery, DevExpress);    /*! Module core, file action.js */    (function($, DX, undefined) {        var actionExecutors = {};        var registerExecutor = function(name, executor) {                if ($.isPlainObject(name)) {                    $.each(name, registerExecutor);                    return                }                actionExecutors[name] = executor            };        var unregisterExecutor = function() {                var args = $.makeArray(arguments);                $.each(args, function() {                    delete actionExecutors[this]                })            };        registerExecutor({            func: {execute: function(e) {                    if ($.isFunction(e.action)) {                        e.result = e.action.apply(e.context, e.args);                        e.handled = true                    }                }},            url: {execute: function(e) {                    if (typeof e.action === "string" && e.action.charAt(0) !== "#")                        document.location = e.action                }},            hash: {execute: function(e) {                    if (typeof e.action === "string" && e.action.charAt(0) === "#")                        document.location.hash = e.action                }}        });        var Action = DX.Class.inherit({                ctor: function(action, config) {                    config = config || {};                    this._action = action || $.noop;                    this._context = config.context || window;                    this._beforeExecute = config.beforeExecute || $.noop;                    this._afterExecute = config.afterExecute || $.noop;                    this._component = config.component;                    this._excludeValidators = config.excludeValidators;                    this._validatingTargetName = config.validatingTargetName                },                execute: function() {                    var e = {                            action: this._action,                            args: Array.prototype.slice.call(arguments),                            context: this._context,                            component: this._component,                            validatingTargetName: this._validatingTargetName,                            cancel: false,                            handled: false                        };                    if (!this._validateAction(e))                        return;                    this._beforeExecute.call(this._context, e);                    if (e.cancel)                        return;                    var result = this._executeAction(e);                    this._afterExecute.call(this._context, e);                    return result                },                _validateAction: function(e) {                    var excludeValidators = this._excludeValidators;                    $.each(actionExecutors, function(name, executor) {                        if (excludeValidators && $.inArray(name, excludeValidators) > -1)                            return;                        if (executor.validate)                            executor.validate(e);                        if (e.cancel)                            return false                    });                    return !e.cancel                },                _executeAction: function(e) {                    var result;                    $.each(actionExecutors, function(index, executor) {                        if (executor.execute)                            executor.execute(e);                        if (e.handled) {                            result = e.result;                            return false                        }                    });                    return result                }            });        $.extend(DX, {            registerActionExecutor: registerExecutor,            unregisterActionExecutor: unregisterExecutor,            Action: Action        });        DX.__internals = {actionExecutors: actionExecutors}    })(jQuery, DevExpress);    /*! Module core, file translator.js */    (function($, DX, undefined) {        var support = DX.support,            TRANSLATOR_DATA_KEY = "dxTranslator",            TRANSFORM_MATRIX_REGEX = /matrix(3d)?\((.+?)\)/,            TRANSLATE_REGEX = /translate(?:3d)?\((.+?)\)/;        var locate = function($element) {                var translate = support.transform ? getTranslate($element) : getTranslateFallback($element);                return {                        left: translate.x,                        top: translate.y                    }            };        var move = function($element, position) {                if (!support.transform) {                    $element.css(position);                    return                }                var translate = getTranslate($element),                    left = position.left,                    top = position.top;                if (left !== undefined)                    translate.x = left || 0;                if (top !== undefined)                    translate.y = top || 0;                $element.css({transform: getTranslateCss(translate)});                if (isPersentValue(left) || isPersentValue(top))                    clearCache($element)            };        var isPersentValue = function(value) {                return $.type(value) === "string" && value[value.length - 1] === "%"            };        var getTranslateFallback = function($element) {                var result;                try {                    var originalTop = $element.css("top"),                        originalLeft = $element.css("left");                    var position = $element.position();                    $element.css({                        transform: "none",                        top: 0,                        left: 0                    });                    clearCache($element);                    var finalPosition = $element.position();                    result = {                        x: position.left - finalPosition.left || parseInt(originalLeft) || 0,                        y: position.top - finalPosition.top || parseInt(originalTop) || 0                    };                    $element.css({                        top: originalTop,                        left: originalLeft                    })                }                catch(e) {                    result = {                        x: 0,                        y: 0                    }                }                return result            };        var getTranslate = function($element) {                var result = $element.data(TRANSLATOR_DATA_KEY);                if (!result) {                    var transformValue = $element.css("transform") || getTranslateCss({                            x: 0,                            y: 0                        }),                        matrix = transformValue.match(TRANSFORM_MATRIX_REGEX),                        is3D = matrix && matrix[1];                    if (matrix) {                        matrix = matrix[2].split(",");                        if (is3D === "3d")                            matrix = matrix.slice(12, 15);                        else {                            matrix.push(0);                            matrix = matrix.slice(4, 7)                        }                    }                    else                        matrix = [0, 0, 0];                    result = {                        x: parseFloat(matrix[0]),                        y: parseFloat(matrix[1]),                        z: parseFloat(matrix[2])                    };                    cacheTranslate($element, result)                }                return result            };        var cacheTranslate = function($element, translate) {                $element.data(TRANSLATOR_DATA_KEY, translate)            };        var clearCache = function($element) {                $element.removeData(TRANSLATOR_DATA_KEY)            };        var resetPosition = function($element) {                $element.css({                    left: 0,                    top: 0,                    transform: "none"                });                clearCache($element)            };        var parseTranslate = function(translateString) {                var result = translateString.match(TRANSLATE_REGEX);                if (!result || !result[1])                    return;                result = result[1].split(",");                result = {                    x: parseFloat(result[0]),                    y: parseFloat(result[1]),                    z: parseFloat(result[2])                };                return result            };        var getTranslateCss = function(translate) {                translate.x = translate.x || 0;                translate.y = translate.y || 0;                var xValueString = isPersentValue(translate.x) ? translate.x : translate.x + "px";                var yValueString = isPersentValue(translate.y) ? translate.y : translate.y + "px";                return "translate(" + xValueString + ", " + yValueString + ")"            };        DX.translator = {            move: move,            locate: locate,            clearCache: clearCache,            parseTranslate: parseTranslate,            getTranslate: getTranslate,            getTranslateCss: getTranslateCss,            resetPosition: resetPosition        }    })(jQuery, DevExpress);    /*! Module core, file animationFrame.js */    (function($, DX, undefined) {        var FRAME_ANIMATION_STEP_TIME = 1000 / 60,            requestAnimationFrame = function(callback) {                return this.setTimeout(callback, FRAME_ANIMATION_STEP_TIME)            },            cancelAnimationFrame = function(requestID) {                this.clearTimeout(requestID)            },            nativeRequestAnimationFrame = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame,            nativeCancelAnimationFrame = window.cancelAnimationFrame || window.webkitCancelAnimationFrame || window.mozCancelAnimationFrame || window.oCancelAnimationFrame || window.msCancelAnimationFrame;        if (nativeRequestAnimationFrame && nativeCancelAnimationFrame) {            requestAnimationFrame = nativeRequestAnimationFrame;            cancelAnimationFrame = nativeCancelAnimationFrame        }        if (nativeRequestAnimationFrame && !nativeCancelAnimationFrame) {            var cancelledRequests = {};            requestAnimationFrame = function(callback) {                var requestId = nativeRequestAnimationFrame.call(window, function() {                        try {                            if (requestId in cancelledRequests)                                return;                            callback.apply(this, arguments)                        }                        finally {                            delete cancelledRequests[requestId]                        }                    });                return requestId            };            cancelAnimationFrame = function(requestId) {                cancelledRequests[requestId] = true            }        }        requestAnimationFrame = $.proxy(requestAnimationFrame, window);        cancelAnimationFrame = $.proxy(cancelAnimationFrame, window);        $.extend(DX, {            requestAnimationFrame: requestAnimationFrame,            cancelAnimationFrame: cancelAnimationFrame        })    })(jQuery, DevExpress);    /*! Module core, file animator.js */    (function($, DX, undefined) {        DX.Animator = DX.Class.inherit({            ctor: function() {                this._finished = true;                this._stopped = false;                this._proxiedStepCore = $.proxy(this._stepCore, this)            },            start: function() {                this._stopped = false;                this._finished = false;                this._stepCore()            },            stop: function() {                this._stopped = true;                DX.cancelAnimationFrame(this._stepAnimationFrame)            },            _stepCore: function() {                if (this._isStopped()) {                    this._stop();                    return                }                if (this._isFinished()) {                    this._finished = true;                    this._complete();                    return                }                this._step();                this._stepAnimationFrame = DX.requestAnimationFrame.call(window, this._proxiedStepCore)            },            _step: DX.abstract,            _isFinished: $.noop,            _stop: $.noop,            _complete: $.noop,            _isStopped: function() {                return this._stopped            },            inProgress: function() {                return !(this._stopped || this._finished)            }        })    })(jQuery, DevExpress);    /*! Module core, file fx.js */    (function($, DX, undefined) {        var translator = DX.translator,            support = DX.support,            transitionEndEventName = support.transitionEndEventName + ".dxFX",            removeEventName = "dxremove.dxFX";        var CSS_TRANSITION_EASING_REGEX = /cubic-bezier\((\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\)/,            RELATIVE_VALUE_REGEX = /^([+-])=(.*)/i,            ANIM_DATA_KEY = "dxAnimData",            ANIM_QUEUE_KEY = "dxAnimQueue",            TRANSFORM_PROP = "transform";        var TransitionAnimationStrategy = {                initAnimation: function($element, config) {                    $element.css({transitionProperty: "none"});                    if (typeof config.from === "string")                        $element.addClass(config.from);                    else                        setProps($element, config.from)                },                animate: function($element, config) {                    var that = this,                        deferred = $.Deferred(),                        cleanupWhen = config.cleanupWhen;                    config.transitionAnimation = {finish: function() {                            that._finishTransition($element, config);                            if (cleanupWhen)                                $.when(deferred, cleanupWhen).always(function() {                                    that._cleanup($element, config)                                });                            else                                that._cleanup($element, config);                            deferred.resolveWith($element, [config, $element])                        }};                    this._startAnimation($element, config);                    this._completeAnimationCallback($element, config).done(function() {                        config.transitionAnimation.finish()                    });                    if (!config.duration)                        config.transitionAnimation.finish();                    return deferred.promise()                },                _completeAnimationCallback: function($element, config) {                    var startTime = $.now() + config.delay,                        deferred = $.Deferred(),                        transitionEndFired = $.Deferred(),                        simulatedTransitionEndFired = $.Deferred(),                        simulatedEndEventTimer,                        waitForJSCompleteTimer;                    config.transitionAnimation.cleanup = function() {                        clearTimeout(simulatedEndEventTimer);                        clearTimeout(waitForJSCompleteTimer)                    };                    $element.one(transitionEndEventName, function() {                        if ($.now() - startTime >= config.duration)                            transitionEndFired.reject()                    }).off(removeEventName).on(removeEventName, function() {                        config.transitionAnimation.cleanup()                    });                    waitForJSCompleteTimer = setTimeout(function() {                        simulatedEndEventTimer = setTimeout(function() {                            simulatedTransitionEndFired.reject()                        }, config.duration + config.delay + DX.fx._simulatedTransitionEndDelay);                        $.when(transitionEndFired, simulatedTransitionEndFired).fail($.proxy(function() {                            deferred.resolve()                        }, this))                    });                    return deferred.promise()                },                _startAnimation: function($element, config) {                    $element.css("transform");                    $element.css({                        transitionProperty: "all",                        transitionDelay: config.delay + "ms",                        transitionDuration: config.duration + "ms",                        transitionTimingFunction: config.easing                    });                    if (typeof config.to === "string")                        $element.addClass(config.to);                    else if (config.to)                        setProps($element, config.to)                },                _finishTransition: function($element, config) {                    $element.css("transition", "none")                },                _cleanup: function($element, config) {                    $element.off(transitionEndEventName);                    config.transitionAnimation.cleanup();                    if (typeof config.from === "string") {                        $element.removeClass(config.from);                        $element.removeClass(config.to)                    }                },                stop: function($element, config, jumpToEnd) {                    if (!config)                        return;                    if (jumpToEnd)                        config.transitionAnimation.finish();                    else {                        if ($.isPlainObject(config.to))                            $.each(config.to, function(key) {                                $element.css(key, $element.css(key))                            });                        this._finishTransition($element, config);                        this._cleanup($element, config)                    }                }            };        var FrameAnimationStrategy = {                initAnimation: function($element, config) {                    setProps($element, config.from)                },                animate: function($element, config) {                    var deferred = $.Deferred(),                        that = this;                    if (!config)                        return deferred.reject().promise();                    $.each(config.to, function(prop) {                        if (config.from[prop] === undefined)                            config.from[prop] = that._normalizeValue($element.css(prop))                    });                    if (config.to[TRANSFORM_PROP]) {                        config.from[TRANSFORM_PROP] = that._parseTransform(config.from[TRANSFORM_PROP]);                        config.to[TRANSFORM_PROP] = that._parseTransform(config.to[TRANSFORM_PROP])                    }                    config.frameAnimation = {                        to: config.to,                        from: config.from,                        currentValue: config.from,                        easing: convertTransitionTimingFuncToJQueryEasing(config.easing),                        duration: config.duration,                        startTime: (new Date).valueOf(),                        finish: function() {                            this.currentValue = this.to;                            this.draw();                            deferred.resolve()                        },                        draw: function() {                            var currentValue = $.extend({}, this.currentValue);                            if (currentValue[TRANSFORM_PROP])                                currentValue[TRANSFORM_PROP] = $.map(currentValue[TRANSFORM_PROP], function(value, prop) {                                    if (prop === "translate")                                        return translator.getTranslateCss(value);                                    else if (prop === "scale")                                        return "scale(" + value + ")";                                    else if (prop.substr(0, prop.length - 1) === "rotate")                                        return prop + "(" + value + "deg)"                                }).join(" ");                            $element.css(currentValue)                        }                    };                    if (config.delay) {                        config.frameAnimation.startTime += config.delay;                        config.frameAnimation.delayTimeout = setTimeout(function() {                            that._animationStep($element, config)                        }, config.delay)                    }                    else                        that._animationStep($element, config);                    return deferred.promise()                },                _parseTransform: function(transformString) {                    var result = {};                    $.each(transformString.match(/(\w|\d)+\([^\)]*\)\s*/g), function(i, part) {                        var translateData = translator.parseTranslate(part),                            scaleData = part.match(/scale\((.+?)\)/),                            rotateData = part.match(/(rotate.)\((.+)deg\)/);                        if (translateData)                            result.translate = translateData;                        if (scaleData && scaleData[1])                            result.scale = parseFloat(scaleData[1]);                        if (rotateData && rotateData[1])                            result[rotateData[1]] = parseFloat(rotateData[2])                    });                    return result                },                stop: function($element, config, jumpToEnd) {                    var frameAnimation = config && config.frameAnimation;                    if (!frameAnimation)                        return;                    clearTimeout(frameAnimation.delayTimeout);                    if (jumpToEnd)                        frameAnimation.finish();                    delete config.frameAnimation                },                _animationStep: function($element, config) {                    var frameAnimation = config && config.frameAnimation;                    if (!frameAnimation)                        return;                    var now = (new Date).valueOf();                    if (now >= frameAnimation.startTime + frameAnimation.duration) {                        frameAnimation.finish();                        return                    }                    frameAnimation.currentValue = this._calcStepValue(frameAnimation, now - frameAnimation.startTime);                    frameAnimation.draw();                    DX.requestAnimationFrame($.proxy(function() {                        this._animationStep($element, config)                    }, this))                },                _calcStepValue: function(frameAnimation, currentDuration) {                    var calcValueRecursively = function(from, to) {                            var result = $.isArray(to) ? [] : {};                            var calcEasedValue = function(propName) {                                    var x = currentDuration / frameAnimation.duration,                                        t = currentDuration,                                        b = 1 * from[propName],                                        c = to[propName] - from[propName],                                        d = frameAnimation.duration;                                    return $.easing[frameAnimation.easing](x, t, b, c, d)                                };                            $.each(to, function(propName, endPropValue) {                                if (typeof endPropValue === "string" && parseFloat(endPropValue, 10) === false)                                    return true;                                result[propName] = typeof endPropValue === "object" ? calcValueRecursively(from[propName], endPropValue) : calcEasedValue(propName)                            });                            return result                        };                    return calcValueRecursively(frameAnimation.from, frameAnimation.to)                },                _normalizeValue: function(value) {                    var numericValue = parseFloat(value, 10);                    if (numericValue === false)                        return value;                    return numericValue                }            };        var FallbackToNoAnimationStrategy = {                initAnimation: function($element, config){},                animate: function($element, config) {                    return $.Deferred().resolve().promise()                }            };        var animationStrategies = {                transition: support.transition ? TransitionAnimationStrategy : FrameAnimationStrategy,                frame: FrameAnimationStrategy,                noAnimation: FallbackToNoAnimationStrategy            };        var getAnimationStrategy = function(config) {                config = config || {};                var strategy = config.strategy || "transition";                if (config.type === "css" && !support.transition)                    strategy = "noAnimation";                return animationStrategies[strategy]            };        var TransitionTimingFuncMap = {                linear: "cubic-bezier(0, 0, 1, 1)",                ease: "cubic-bezier(0.25, 0.1, 0.25, 1)",                "ease-in": "cubic-bezier(0.42, 0, 1, 1)",                "ease-out": "cubic-bezier(0, 0, 0.58, 1)",                "ease-in-out": "cubic-bezier(0.42, 0, 0.58, 1)"            };        var convertTransitionTimingFuncToJQueryEasing = function(cssTransitionEasing) {                cssTransitionEasing = TransitionTimingFuncMap[cssTransitionEasing] || cssTransitionEasing;                var bezCoeffs = cssTransitionEasing.match(CSS_TRANSITION_EASING_REGEX);                if (!bezCoeffs)                    return "linear";                bezCoeffs = bezCoeffs.slice(1, 5);                $.each(bezCoeffs, function(index, value) {                    bezCoeffs[index] = parseFloat(value)                });                var easingName = "cubicbezier_" + bezCoeffs.join("_").replace(/\./g, "p");                if (!$.isFunction($.easing[easingName])) {                    var polynomBezier = function(x1, y1, x2, y2) {                            var Cx = 3 * x1,                                Bx = 3 * (x2 - x1) - Cx,                                Ax = 1 - Cx - Bx,                                Cy = 3 * y1,                                By = 3 * (y2 - y1) - Cy,                                Ay = 1 - Cy - By;                            var bezierX = function(t) {                                    return t * (Cx + t * (Bx + t * Ax))                                };                            var bezierY = function(t) {                                    return t * (Cy + t * (By + t * Ay))                                };                            var findXfor = function(t) {                                    var x = t,                                        i = 0,                                        z;                                    while (i < 14) {                                        z = bezierX(x) - t;                                        if (Math.abs(z) < 1e-3)                                            break;                                        x = x - z / derivativeX(x);                                        i++                                    }                                    return x                                };                            var derivativeX = function(t) {                                    return Cx + t * (2 * Bx + t * 3 * Ax)                                };                            return function(t) {                                    return bezierY(findXfor(t))                                }                        };                    $.easing[easingName] = function(x, t, b, c, d) {                        return c * polynomBezier(bezCoeffs[0], bezCoeffs[1], bezCoeffs[2], bezCoeffs[3])(t / d) + b                    }                }                return easingName            };        var baseConfigValidator = function(config, animationType, validate, typeMessage) {                $.each(["from", "to"], function() {                    if (!validate(config[this]))                        throw DX.Error("E0010", animationType, this, typeMessage);                })            };        var isObjectConfigValidator = function(config, animationType) {                return baseConfigValidator(config, animationType, function(target) {                        return $.isPlainObject(target)                    }, "a plain object")            };        var isStringConfigValidator = function(config, animationType) {                return baseConfigValidator(config, animationType, function(target) {                        return typeof target === "string"                    }, "a string")            };        var CustomAnimationConfigurator = {setup: function($element, config){}};        var CssAnimationConfigurator = {                validateConfig: function(config) {                    isStringConfigValidator(config, "css")                },                setup: function($element, config){}            };        var positionAliases = {                top: {                    my: "bottom center",                    at: "top center"                },                bottom: {                    my: "top center",                    at: "bottom center"                },                right: {                    my: "left center",                    at: "right center"                },                left: {                    my: "right center",                    at: "left center"                }            };        var SlideAnimationConfigurator = {                validateConfig: function(config) {                    isObjectConfigValidator(config, "slide")                },                setup: function($element, config) {                    var location = translator.locate($element);                    if (config.type !== "slide") {                        var positioningConfig = config.type === "slideIn" ? config.from : config.to;                        positioningConfig.position = $.extend({of: window}, positionAliases[config.direction]);                        setupPosition($element, positioningConfig)                    }                    this._setUpConfig(location, config.from);                    this._setUpConfig(location, config.to);                    translator.clearCache($element);                    if (!support.transform && $element.css("position") === "static")                        $element.css("position", "relative")                },                _setUpConfig: function(location, config) {                    config.left = "left" in config ? config.left : "+=0";                    config.top = "top" in config ? config.top : "+=0";                    this._initNewPosition(location, config)                },                _initNewPosition: function(location, config) {                    var position = {                            left: config.left,                            top: config.top                        };                    delete config.left;                    delete config.top;                    var relativeValue = this._getRelativeValue(position.left);                    if (relativeValue !== undefined)                        position.left = relativeValue + location.left;                    else                        config.left = 0;                    relativeValue = this._getRelativeValue(position.top);                    if (relativeValue !== undefined)                        position.top = relativeValue + location.top;                    else                        config.top = 0;                    var translate = {                            x: 0,                            y: 0                        };                    if (support.transform)                        translate = {                            x: position.left,                            y: position.top                        };                    else {                        config.left = position.left;                        config.top = position.top                    }                    config[TRANSFORM_PROP] = translator.getTranslateCss(translate)                },                _getRelativeValue: function(value) {                    var relativeValue;                    if (typeof value === "string" && (relativeValue = RELATIVE_VALUE_REGEX.exec(value)))                        return parseInt(relativeValue[1] + "1") * relativeValue[2]                }            };        var FadeAnimationConfigurator = {setup: function($element, config) {                    var from = config.from,                        fromOpacity = $.isPlainObject(from) ? config.skipElementInitialStyles ? 0 : $element.css("opacity") : String(from),                        toOpacity;                    switch (config.type) {                        case"fadeIn":                            toOpacity = 1;                            break;                        case"fadeOut":                            toOpacity = 0;                            break;                        default:                            toOpacity = String(config.to)                    }                    config.from = {                        visibility: "visible",                        opacity: fromOpacity                    };                    config.to = {opacity: toOpacity}                }};        var PopAnimationConfigurator = {                validateConfig: function(config) {                    isObjectConfigValidator(config, "pop")                },                setup: function($element, config) {                    var from = config.from,                        to = config.to,                        fromOpacity = "opacity" in from ? from.opacity : $element.css("opacity"),                        toOpacity = "opacity" in to ? to.opacity : 1,                        fromScale = "scale" in from ? from.scale : 0,                        toScale = "scale" in to ? to.scale : 1;                    config.from = {opacity: fromOpacity};                    var translate = translator.getTranslate($element);                    config.from[TRANSFORM_PROP] = this._getCssTransform(translate, fromScale);                    config.to = {opacity: toOpacity};                    config.to[TRANSFORM_PROP] = this._getCssTransform(translate, toScale)                },                _getCssTransform: function(translate, scale) {                    return translator.getTranslateCss(translate) + "scale(" + scale + ")"                }            };        var animationConfigurators = {                custom: CustomAnimationConfigurator,                slide: SlideAnimationConfigurator,                slideIn: SlideAnimationConfigurator,                slideOut: SlideAnimationConfigurator,                fade: FadeAnimationConfigurator,                fadeIn: FadeAnimationConfigurator,                fadeOut: FadeAnimationConfigurator,                pop: PopAnimationConfigurator,                css: CssAnimationConfigurator            };        var getAnimationConfigurator = function(config) {                var result = animationConfigurators[config.type];                if (!result)                    throw DX.Error("E0011", config.type);                return result            };        var defaultJSConfig = {                type: "custom",                from: {},                to: {},                duration: 400,                start: $.noop,                complete: $.noop,                easing: "ease",                delay: 0            },            defaultCssConfig = {                duration: 400,                easing: "ease",                delay: 0            };        var setupAnimationOnElement = function() {                var animation = this,                    $element = animation.$element,                    config = animation.config;                setupPosition($element, config.from);                setupPosition($element, config.to);                animation.configurator.setup($element, config);                $element.data(ANIM_DATA_KEY, animation);                if (DX.fx.off)                    config.duration = 0;                animation.strategy.initAnimation($element, config);                if (config.start)                    config.start.apply(this, [$element, config])            };        var startAnimationOnElement = function() {                var animation = this,                    $element = animation.$element,                    config = animation.config;                return animation.strategy.animate($element, config).done(function() {                        $element.removeData(ANIM_DATA_KEY);                        if (config.complete)                            config.complete.apply(this, [$element, config]);                        animation.deferred.resolveWith(this, [$element, config])                    })            };        var createAnimation = function($element, initialConfig) {                var defaultConfig = initialConfig.type === "css" ? defaultCssConfig : defaultJSConfig,                    config = $.extend(true, {}, defaultConfig, initialConfig),                    configurator = getAnimationConfigurator(config),                    strategy = getAnimationStrategy(config),                    animation = {                        $element: $element,                        config: config,                        configurator: configurator,                        strategy: strategy,                        setup: setupAnimationOnElement,                        start: startAnimationOnElement,                        deferred: $.Deferred()                    };                if ($.isFunction(configurator.validateConfig))                    configurator.validateConfig(config);                return animation            };        var animate = function(element, config) {                var $element = $(element);                if (!$element.length)                    return $.Deferred().resolve().promise();                var animation = createAnimation($element, config);                pushInAnimationQueue($element, animation);                return animation.deferred.promise()            };        var pushInAnimationQueue = function($element, animation) {                var queueData = getAnimQueueData($element);                writeAnimQueueData($element, queueData);                queueData.push(animation);                if (!isAnimating($element))                    shiftFromAnimationQueue($element, queueData)            };        var getAnimQueueData = function($element) {                return $element.data(ANIM_QUEUE_KEY) || []            };        var writeAnimQueueData = function($element, queueData) {                $element.data(ANIM_QUEUE_KEY, queueData)            };        var destroyAnimQueueData = function($element) {                $element.removeData(ANIM_QUEUE_KEY)            };        var isAnimating = function($element) {                return !!$element.data(ANIM_DATA_KEY)            };        var shiftFromAnimationQueue = function($element, queueData) {                queueData = getAnimQueueData($element);                if (!queueData.length)                    return;                var animation = queueData.shift();                if (queueData.length === 0)                    destroyAnimQueueData($element);                executeAnimation(animation).done(function() {                    shiftFromAnimationQueue($element)                })            };        var executeAnimation = function(animation) {                animation.setup();                return animation.start()            };        var setupPosition = function($element, config) {                if (!config || !config.position)                    return;                var position = DX.calculatePosition($element, config.position),                    offset = $element.offset(),                    currentPosition = $element.position();                $.extend(config, {                    left: position.h.location - offset.left + currentPosition.left,                    top: position.v.location - offset.top + currentPosition.top                });                delete config.position            };        var setProps = function($element, props) {                $.each(props, function(key, value) {                    $element.css(key, value)                })            };        var stop = function(element, jumpToEnd) {                var $element = $(element),                    queueData = getAnimQueueData($element);                $.each(queueData, function(_, animation) {                    animation.config.duration = 0                });                if (!isAnimating($element))                    shiftFromAnimationQueue($element, queueData);                var animation = $element.data(ANIM_DATA_KEY);                if (animation)                    animation.strategy.stop($element, animation.config, jumpToEnd);                $element.removeData(ANIM_DATA_KEY);                destroyAnimQueueData($element)            };        DX.fx = {            off: false,            animationTypes: animationConfigurators,            animate: animate,            createAnimation: createAnimation,            isAnimating: isAnimating,            stop: stop,            _simulatedTransitionEndDelay: 100        };        DX.fx.__internals = {convertTransitionTimingFuncToJQueryEasing: convertTransitionTimingFuncToJQueryEasing}    })(jQuery, DevExpress);    /*! Module core, file dxProxyUrlFormatter.js */    (function($, DX, undefined) {        var location = window.location,            DXPROXY_HOST = "dxproxy.devexpress.com:8000",            IS_DXPROXY_ORIGIN = location.host === DXPROXY_HOST,            urlMapping = {};        var extractProxyAppId = function() {                return location.pathname.split("/")[1]            };        var urlFormatter = {                isProxyUsed: function() {                    return IS_DXPROXY_ORIGIN                },                formatProxyUrl: function(localUrl) {                    var urlData = DX.parseUrl(localUrl);                    if (!/^(localhost$|127\.)/i.test(urlData.hostname))                        return localUrl;                    var proxyUrlPart = DXPROXY_HOST + "/" + extractProxyAppId() + "_" + urlData.port;                    urlMapping[proxyUrlPart] = urlData.hostname + ":" + urlData.port;                    var resultUrl = "http://" + proxyUrlPart + urlData.pathname + urlData.search;                    return resultUrl                },                formatLocalUrl: function(proxyUrl) {                    if (proxyUrl.indexOf(DXPROXY_HOST) < 0)                        return proxyUrl;                    var resultUrl = proxyUrl;                    for (var proxyUrlPart in urlMapping)                        if (urlMapping.hasOwnProperty(proxyUrlPart))                            if (proxyUrl.indexOf(proxyUrlPart) >= 0) {                                resultUrl = proxyUrl.replace(proxyUrlPart, urlMapping[proxyUrlPart]);                                break                            }                    return resultUrl                }            };        DX._proxyUrlFormatter = urlFormatter    })(jQuery, DevExpress);    /*! Module core, file endpointSelector.js */    (function($, DX, undefined) {        var location = window.location,            IS_WINJS_ORIGIN = location.protocol === "ms-appx:",            IS_LOCAL_ORIGIN = isLocalHostName(location.hostname);        function isLocalHostName(url) {            return /^(localhost$|127\.)/i.test(url)        }        var EndpointSelector = DX.EndpointSelector = function(config) {                this.config = config            };        EndpointSelector.prototype = {urlFor: function(key) {                var bag = this.config[key];                if (!bag)                    throw DX.Error("E0006");                if (DX._proxyUrlFormatter.isProxyUsed())                    return DX._proxyUrlFormatter.formatProxyUrl(bag.local);                if (bag.production)                    if (IS_WINJS_ORIGIN && !Debug.debuggerEnabled || !IS_WINJS_ORIGIN && !IS_LOCAL_ORIGIN)                        return bag.production;                return bag.local            }}    })(jQuery, DevExpress);    /*! Module core, file formatHelper.js */    (function($, DX, undefined) {        var utils = DX.utils;        DX.NumericFormat = {            currency: 'C',            fixedpoint: 'N',            exponential: '',            percent: 'P',            decimal: 'D'        };        DX.LargeNumberFormatPostfixes = {            1: 'K',            2: 'M',            3: 'B',            4: 'T'        };        var MAX_LARGE_NUMBER_POWER = 4,            DECIMAL_BASE = 10;        DX.LargeNumberFormatPowers = {            largenumber: 'auto',            thousands: 1,            millions: 2,            billions: 3,            trillions: 4        };        DX.DateTimeFormat = {            longdate: 'D',            longtime: 'T',            monthandday: 'M',            monthandyear: 'Y',            quarterandyear: 'qq',            shortdate: 'd',            shorttime: 't',            millisecond: 'fff',            second: 'T',            minute: 't',            hour: 't',            day: 'dd',            week: 'dd',            month: 'MMMM',            quarter: 'qq',            year: 'yyyy',            longdatelongtime: 'D',            shortdateshorttime: 'd',            shortyear: 'yy'        };        DX.formatHelper = {            defaultQuarterFormat: 'Q{0}',            romanDigits: ['I', 'II', 'III', 'IV'],            _addFormatSeparator: function(format1, format2) {                var separator = ' ';                if (format2)                    return format1 + separator + format2;                return format1            },            _getDateTimeFormatPattern: function(dateTimeFormat) {                return Globalize.findClosestCulture().calendar.patterns[DX.DateTimeFormat[dateTimeFormat.toLowerCase()]]            },            _isDateFormatContains: function(format) {                var result = false;                $.each(DX.DateTimeFormat, function(key) {                    result = key === format.toLowerCase();                    return !result                });                return result            },            getQuarter: function(month) {                return Math.floor(month / 3)            },            getFirstQuarterMonth: function(month) {                return this.getQuarter(month) * 3            },            _getQuarterString: function(date, format) {                var quarter = this.getQuarter(date.getMonth());                switch (format) {                    case'q':                        return this.romanDigits[quarter];                    case'qq':                        return utils.stringFormat(this.defaultQuarterFormat, this.romanDigits[quarter]);                    case'Q':                        return (quarter + 1).toString();                    case'QQ':                        return utils.stringFormat(this.defaultQuarterFormat, (quarter + 1).toString())                }                return ''            },            _formatCustomString: function(value, format) {                var regExp = /qq|q|QQ|Q/g,                    quarterFormat,                    result = '',                    index = 0;                regExp.lastIndex = 0;                while (index < format.length) {                    quarterFormat = regExp.exec(format);                    if (!quarterFormat || quarterFormat.index > index)                        result += Globalize.format(value, format.substring(index, quarterFormat ? quarterFormat.index : format.length));                    if (quarterFormat) {                        result += this._getQuarterString(value, quarterFormat[0]);                        index = quarterFormat.index + quarterFormat[0].length                    }                    else                        index = format.length                }                return result            },            _parseNumberFormatString: function(format) {                var formatList,                    formatObject = {};                if (!format || typeof format !== 'string')                    return;                formatList = format.toLowerCase().split(' ');                $.each(formatList, function(index, value) {                    if (value in DX.NumericFormat)                        formatObject.formatType = value;                    else if (value in DX.LargeNumberFormatPowers)                        formatObject.power = DX.LargeNumberFormatPowers[value]                });                if (formatObject.power && !formatObject.formatType)                    formatObject.formatType = 'fixedpoint';                if (formatObject.formatType)                    return formatObject            },            _calculateNumberPower: function(value, base, minPower, maxPower) {                var number = Math.abs(value);                var power = 0;                if (number > 1)                    while (number && number >= base && (maxPower === undefined || power < maxPower)) {                        power++;                        number = number / base                    }                else if (number > 0 && number < 1)                    while (number < 1 && (minPower === undefined || power > minPower)) {                        power--;                        number = number * base                    }                return power            },            _getNumberByPower: function(number, power, base) {                var result = number;                while (power > 0) {                    result = result / base;                    power--                }                while (power < 0) {                    result = result * base;                    power++                }                return result            },            _formatNumber: function(value, formatObject, precision) {                var powerPostfix;                if (formatObject.power === 'auto')                    formatObject.power = this._calculateNumberPower(value, 1000, 0, MAX_LARGE_NUMBER_POWER);                if (formatObject.power)                    value = this._getNumberByPower(value, formatObject.power, 1000);                powerPostfix = DX.LargeNumberFormatPostfixes[formatObject.power] || '';                return this._formatNumberCore(value, formatObject.formatType, precision) + powerPostfix            },            _formatNumberExponential: function(value, precision) {                var power = this._calculateNumberPower(value, DECIMAL_BASE),                    number = this._getNumberByPower(value, power, DECIMAL_BASE),                    powString;                precision = precision === undefined ? 1 : precision;                if (number.toFixed(precision || 0) >= DECIMAL_BASE) {                    power++;                    number = number / DECIMAL_BASE                }                powString = (power >= 0 ? '+' : '') + power.toString();                return this._formatNumberCore(number, 'fixedpoint', precision) + 'E' + powString            },            _formatNumberCore: function(value, format, precision) {                if (format === 'exponential')                    return this._formatNumberExponential(value, precision);                else                    return Globalize.format(value, DX.NumericFormat[format] + (utils.isNumber(precision) ? precision : 0))            },            _formatDate: function(date, format) {                var resultFormat = DX.DateTimeFormat[format.toLowerCase()];                format = format.toLowerCase();                if (format === 'quarterandyear')                    resultFormat = this._getQuarterString(date, resultFormat) + ' yyyy';                if (format === 'quarter')                    return this._getQuarterString(date, resultFormat);                if (format === 'longdatelongtime')                    return this._formatDate(date, 'longdate') + ' ' + this._formatDate(date, 'longtime');                if (format === 'shortdateshorttime')                    return this._formatDate(date, 'shortDate') + ' ' + this._formatDate(date, 'shortTime');                return Globalize.format(date, resultFormat)            },            format: function(value, format, precision) {                if ($.isPlainObject(format) && format.format)                    if (format.dateType)                        return this._formatDateEx(value, format);                    else if (utils.isNumber(value) && isFinite(value))                        return this._formatNumberEx(value, format);                return this._format(value, format, precision)            },            _format: function(value, format, precision) {                var numberFormatObject;                if (!utils.isString(format) || format === '' || !utils.isNumber(value) && !utils.isDate(value))                    return utils.isDefined(value) ? value.toString() : '';                numberFormatObject = this._parseNumberFormatString(format);                if (utils.isNumber(value) && numberFormatObject)                    return this._formatNumber(value, numberFormatObject, precision);                if (utils.isDate(value) && this._isDateFormatContains(format))                    return this._formatDate(value, format);                if (!numberFormatObject && !this._isDateFormatContains(format))                    return this._formatCustomString(value, format)            },            _formatNumberEx: function(value, formatInfo) {                var that = this,                    numericFormatType = DX.NumericFormat[formatInfo.format.toLowerCase()],                    numberFormat = Globalize.culture().numberFormat,                    currencyFormat = formatInfo.currencyCulture && Globalize.cultures[formatInfo.currencyCulture] ? Globalize.cultures[formatInfo.currencyCulture].numberFormat.currency : numberFormat.currency,                    percentFormat = numberFormat.percent,                    formatSettings = that._getUnitFormatSettings(value, formatInfo),                    unit = formatSettings.unit,                    precision = formatSettings.precision,                    showTrailingZeros = formatSettings.showTrailingZeros,                    includeGroupSeparator = formatSettings.includeGroupSeparator,                    groupSymbol = numberFormat[","],                    floatingSymbol = numberFormat["."],                    number,                    isNegative,                    pattern,                    currentFormat,                    regexParts = /n|\$|-|%/g,                    result = "";                if (!utils.isDefined(value))                    return '';                value = that._applyUnitToValue(value, unit);                number = Math.abs(value);                isNegative = value < 0;                switch (numericFormatType) {                    case DX.NumericFormat.decimal:                        pattern = "n";                        number = Math[isNegative ? "ceil" : "floor"](number);                        if (precision > 0) {                            var str = "" + number;                            for (var i = str.length; i < precision; i += 1)                                str = "0" + str;                            number = str                        }                        if (isNegative)                            number = "-" + number;                        break;                    case DX.NumericFormat.fixedpoint:                        currentFormat = numberFormat;                    case DX.NumericFormat.currency:                        currentFormat = currentFormat || currencyFormat;                    case DX.NumericFormat.percent:                        currentFormat = currentFormat || percentFormat;                        pattern = isNegative ? currentFormat.pattern[0] : currentFormat.pattern[1] || "n";                        number = Globalize.format(number * (numericFormatType === DX.NumericFormat.percent ? 100 : 1), "N" + precision);                        if (!showTrailingZeros)                            number = that._excludeTrailingZeros(number, floatingSymbol);                        if (!includeGroupSeparator)                            number = number.replace(new RegExp('\\' + groupSymbol, 'g'), '');                        break;                    case DX.NumericFormat.exponential:                        return that._formatNumberExponential(value, precision);                    default:                        throw"Illegal numeric format: '" + numericFormatType + "'";                }                for (; ; ) {                    var lastIndex = regexParts.lastIndex,                        matches = regexParts.exec(pattern);                    result += pattern.slice(lastIndex, matches ? matches.index : pattern.length);                    if (matches)                        switch (matches[0]) {                            case"-":                                if (/[1-9]/.test(number))                                    result += numberFormat["-"];                                break;                            case"$":                                result += currencyFormat.symbol;                                break;                            case"%":                                result += percentFormat.symbol;                                break;                            case"n":                                result += number + unit;                                break                        }                    else                        break                }                return (formatInfo.plus && value > 0 ? "+" : '') + result            },            _excludeTrailingZeros: function(strValue, floatingSymbol) {                var floatingIndex = strValue.indexOf(floatingSymbol),                    stopIndex,                    i;                if (floatingIndex < 0)                    return strValue;                stopIndex = strValue.length;                for (i = stopIndex - 1; i >= floatingIndex && (strValue[i] === '0' || i === floatingIndex); i--)                    stopIndex--;                return strValue.substring(0, stopIndex)            },            _getUnitFormatSettings: function(value, formatInfo) {                var unit = formatInfo.unit || '',                    precision = formatInfo.precision || 0,                    includeGroupSeparator = formatInfo.includeGroupSeparator || false,                    showTrailingZeros = formatInfo.showTrailingZeros === undefined ? true : formatInfo.showTrailingZeros,                    significantDigits = formatInfo.significantDigits || 1,                    absValue;                if (unit.toLowerCase() === 'auto') {                    showTrailingZeros = false;                    absValue = Math.abs(value);                    if (significantDigits < 1)                        significantDigits = 1;                    if (absValue >= 1000000000) {                        unit = 'B';                        absValue /= 1000000000                    }                    else if (absValue >= 1000000) {                        unit = 'M';                        absValue /= 1000000                    }                    else if (absValue >= 1000) {                        unit = 'K';                        absValue /= 1000                    }                    else                        unit = '';                    if (absValue === 0)                        precision = 0;                    else if (absValue < 1) {                        precision = significantDigits;                        var smallValue = Math.pow(10, -significantDigits);                        while (absValue < smallValue) {                            smallValue /= 10;                            precision++                        }                    }                    else if (absValue >= 100)                        precision = significantDigits - 3;                    else if (absValue >= 10)                        precision = significantDigits - 2;                    else                        precision = significantDigits - 1                }                if (precision < 0)                    precision = 0;                return {                        unit: unit,                        precision: precision,                        showTrailingZeros: showTrailingZeros,                        includeGroupSeparator: includeGroupSeparator                    }            },            _applyUnitToValue: function(value, unit) {                if (unit === 'B')                    return value.toFixed(1) / 1000000000;                if (unit === 'M')                    return value / 1000000;                if (unit === 'K')                    return value / 1000;                return value            },            _formatDateEx: function(value, formatInfo) {                var that = this,                    format = formatInfo.format,                    dateType = formatInfo.dateType,                    calendar = Globalize.culture().calendars.standard,                    time,                    index,                    dateStr;                format = format.toLowerCase();                if (!utils.isDefined(value))                    return '';                if (dateType !== 'num' || format === 'dayofweek')                    switch (format) {                        case'monthyear':                            return that._formatDate(value, 'monthandyear');                        case'quarteryear':                            return that._getQuarterString(value, 'QQ') + ' ' + value.getFullYear();                        case'daymonthyear':                            return that._formatDate(value, dateType + 'Date');                        case'datehour':                            time = new Date(value.getTime());                            time.setMinutes(0);                            dateStr = dateType === 'timeOnly' ? '' : that._formatDate(value, dateType + 'Date');                            return dateType === 'timeOnly' ? that._formatDate(time, 'shorttime') : dateStr + ' ' + that._formatDate(time, 'shorttime');                        case'datehourminute':                            dateStr = dateType === 'timeOnly' ? '' : that._formatDate(value, dateType + 'Date');                            return dateType === 'timeOnly' ? that._formatDate(value, 'shorttime') : dateStr + ' ' + that._formatDate(value, 'shorttime');                        case'datehourminutesecond':                            dateStr = dateType === 'timeOnly' ? '' : that._formatDate(value, dateType + 'Date');                            return dateType === 'timeOnly' ? that._formatDate(value, 'longtime') : dateStr + ' ' + that._formatDate(value, 'longtime');                        case'year':                            dateStr = value.toString();                            return dateType === 'abbr' ? dateStr.slice(2, 4) : dateStr;                        case'dateyear':                            return dateType === 'abbr' ? that._formatDate(value, 'shortyear') : that._formatDate(value, 'year');                        case'quarter':                            return utils.stringFormat(that.defaultQuarterFormat, value.toString());                        case'month':                            index = value - 1;                            return dateType === 'abbr' ? calendar.months.namesAbbr[index] : calendar.months.names[index];                        case'hour':                            if (dateType === 'long') {                                time = new Date;                                time.setHours(value);                                time.setMinutes(0);                                return that._formatDate(time, 'shorttime')                            }                            return value.toString();                        case'dayofweek':                            index = utils.isString(value) ? $.inArray(value, ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']) : value;                            if (dateType !== 'num')                                return dateType === 'abbr' ? calendar.days.namesAbbr[index] : calendar.days.names[index];                            return ((index - calendar.firstDay + 1 + 7) % 8).toString();                        default:                            return value.toString()                    }                else                    return value.toString()            },            getTimeFormat: function(showSecond) {                if (showSecond)                    return this._getDateTimeFormatPattern('longtime');                return this._getDateTimeFormatPattern('shorttime')            },            getDateFormatByDifferences: function(dateDifferences) {                var resultFormat = '';                if (dateDifferences.millisecond)                    resultFormat = DX.DateTimeFormat.millisecond;                if (dateDifferences.hour || dateDifferences.minute || dateDifferences.second)                    resultFormat = this._addFormatSeparator(this.getTimeFormat(dateDifferences.second), resultFormat);                if (dateDifferences.year && dateDifferences.month && dateDifferences.day)                    return this._addFormatSeparator(this._getDateTimeFormatPattern('shortdate'), resultFormat);                if (dateDifferences.year && dateDifferences.month)                    return DX.DateTimeFormat['monthandyear'];                if (dateDifferences.year)                    return DX.DateTimeFormat['year'];                if (dateDifferences.month && dateDifferences.day)                    return this._addFormatSeparator(this._getDateTimeFormatPattern('monthandday'), resultFormat);                if (dateDifferences.month)                    return DX.DateTimeFormat['month'];                if (dateDifferences.day)                    return this._addFormatSeparator('dddd, dd', resultFormat);                return resultFormat            },            getDateFormatByTicks: function(ticks) {                var resultFormat,                    maxDif,                    currentDif,                    i;                if (ticks.length > 1) {                    maxDif = utils.getDatesDifferences(ticks[0], ticks[1]);                    for (i = 1; i < ticks.length - 1; i++) {                        currentDif = utils.getDatesDifferences(ticks[i], ticks[i + 1]);                        if (maxDif.count < currentDif.count)                            maxDif = currentDif                    }                }                else                    maxDif = {                        year: true,                        month: true,                        day: true,                        hour: ticks[0].getHours() > 0,                        minute: ticks[0].getMinutes() > 0,                        second: ticks[0].getSeconds() > 0                    };                resultFormat = this.getDateFormatByDifferences(maxDif);                return resultFormat            },            getDateFormatByTickInterval: function(startValue, endValue, tickInterval) {                var resultFormat,                    dateDifferences,                    dateUnitInterval,                    dateDifferencesConverter = {                        quarter: 'month',                        week: 'day'                    },                    correctDateDifferences = function(dateDifferences, tickInterval, value) {                        switch (tickInterval) {                            case'year':                                dateDifferences.month = value;                            case'quarter':                            case'month':                                dateDifferences.day = value;                            case'week':                            case'day':                                dateDifferences.hour = value;                            case'hour':                                dateDifferences.minute = value;                            case'minute':                                dateDifferences.second = value;                            case'second':                                dateDifferences.millisecond = value                        }                    },                    correctDifferencesByMaxDate = function(differences, minDate, maxDate) {                        if (!maxDate.getMilliseconds() && maxDate.getSeconds()) {                            if (maxDate.getSeconds() - minDate.getSeconds() === 1) {                                differences.millisecond = true;                                differences.second = false                            }                        }                        else if (!maxDate.getSeconds() && maxDate.getMinutes()) {                            if (maxDate.getMinutes() - minDate.getMinutes() === 1) {                                differences.second = true;                                differences.minute = false                            }                        }                        else if (!maxDate.getMinutes() && maxDate.getHours()) {                            if (maxDate.getHours() - minDate.getHours() === 1) {                                differences.minute = true;                                differences.hour = false                            }                        }                        else if (!maxDate.getHours() && maxDate.getDate() > 1) {                            if (maxDate.getDate() - minDate.getDate() === 1) {                                differences.hour = true;                                differences.day = false                            }                        }                        else if (maxDate.getDate() === 1 && maxDate.getMonth()) {                            if (maxDate.getMonth() - minDate.getMonth() === 1) {                                differences.day = true;                                differences.month = false                            }                        }                        else if (!maxDate.getMonth() && maxDate.getFullYear())                            if (maxDate.getFullYear() - minDate.getFullYear() === 1) {                                differences.month = true;                                differences.year = false                            }                    };                tickInterval = utils.isString(tickInterval) ? tickInterval.toLowerCase() : tickInterval;                dateDifferences = utils.getDatesDifferences(startValue, endValue);                if (startValue !== endValue)                    correctDifferencesByMaxDate(dateDifferences, startValue > endValue ? endValue : startValue, startValue > endValue ? startValue : endValue);                dateUnitInterval = utils.getDateUnitInterval(dateDifferences);                correctDateDifferences(dateDifferences, dateUnitInterval, true);                dateUnitInterval = utils.getDateUnitInterval(tickInterval || 'second');                correctDateDifferences(dateDifferences, dateUnitInterval, false);                dateDifferences[dateDifferencesConverter[dateUnitInterval] || dateUnitInterval] = true;                resultFormat = this.getDateFormatByDifferences(dateDifferences);                return resultFormat            }        }    })(jQuery, DevExpress);    /*! Module core, file color.js */    (function(DX, undefined) {        var standardColorNames = {                aliceblue: 'f0f8ff',                antiquewhite: 'faebd7',                aqua: '00ffff',                aquamarine: '7fffd4',                azure: 'f0ffff',                beige: 'f5f5dc',                bisque: 'ffe4c4',                black: '000000',                blanchedalmond: 'ffebcd',                blue: '0000ff',                blueviolet: '8a2be2',                brown: 'a52a2a',                burlywood: 'deb887',                cadetblue: '5f9ea0',                chartreuse: '7fff00',                chocolate: 'd2691e',                coral: 'ff7f50',                cornflowerblue: '6495ed',                cornsilk: 'fff8dc',                crimson: 'dc143c',                cyan: '00ffff',                darkblue: '00008b',                darkcyan: '008b8b',                darkgoldenrod: 'b8860b',                darkgray: 'a9a9a9',                darkgreen: '006400',                darkkhaki: 'bdb76b',                darkmagenta: '8b008b',                darkolivegreen: '556b2f',                darkorange: 'ff8c00',                darkorchid: '9932cc',                darkred: '8b0000',                darksalmon: 'e9967a',                darkseagreen: '8fbc8f',                darkslateblue: '483d8b',                darkslategray: '2f4f4f',                darkturquoise: '00ced1',                darkviolet: '9400d3',                deeppink: 'ff1493',                deepskyblue: '00bfff',                dimgray: '696969',                dodgerblue: '1e90ff',                feldspar: 'd19275',                firebrick: 'b22222',                floralwhite: 'fffaf0',                forestgreen: '228b22',                fuchsia: 'ff00ff',                gainsboro: 'dcdcdc',                ghostwhite: 'f8f8ff',                gold: 'ffd700',                goldenrod: 'daa520',                gray: '808080',                green: '008000',                greenyellow: 'adff2f',                honeydew: 'f0fff0',                hotpink: 'ff69b4',                indianred: 'cd5c5c',                indigo: '4b0082',                ivory: 'fffff0',                khaki: 'f0e68c',                lavender: 'e6e6fa',                lavenderblush: 'fff0f5',                lawngreen: '7cfc00',                lemonchiffon: 'fffacd',                lightblue: 'add8e6',                lightcoral: 'f08080',                lightcyan: 'e0ffff',                lightgoldenrodyellow: 'fafad2',                lightgrey: 'd3d3d3',                lightgreen: '90ee90',                lightpink: 'ffb6c1',                lightsalmon: 'ffa07a',                lightseagreen: '20b2aa',                lightskyblue: '87cefa',                lightslateblue: '8470ff',                lightslategray: '778899',                lightsteelblue: 'b0c4de',                lightyellow: 'ffffe0',                lime: '00ff00',                limegreen: '32cd32',                linen: 'faf0e6',                magenta: 'ff00ff',                maroon: '800000',                mediumaquamarine: '66cdaa',                mediumblue: '0000cd',                mediumorchid: 'ba55d3',                mediumpurple: '9370d8',                mediumseagreen: '3cb371',                mediumslateblue: '7b68ee',                mediumspringgreen: '00fa9a',                mediumturquoise: '48d1cc',                mediumvioletred: 'c71585',                midnightblue: '191970',                mintcream: 'f5fffa',                mistyrose: 'ffe4e1',                moccasin: 'ffe4b5',                navajowhite: 'ffdead',                navy: '000080',                oldlace: 'fdf5e6',                olive: '808000',                olivedrab: '6b8e23',                orange: 'ffa500',                orangered: 'ff4500',                orchid: 'da70d6',                palegoldenrod: 'eee8aa',                palegreen: '98fb98',                paleturquoise: 'afeeee',                palevioletred: 'd87093',                papayawhip: 'ffefd5',                peachpuff: 'ffdab9',                peru: 'cd853f',                pink: 'ffc0cb',                plum: 'dda0dd',                powderblue: 'b0e0e6',                purple: '800080',                red: 'ff0000',                rosybrown: 'bc8f8f',                royalblue: '4169e1',                saddlebrown: '8b4513',                salmon: 'fa8072',                sandybrown: 'f4a460',                seagreen: '2e8b57',                seashell: 'fff5ee',                sienna: 'a0522d',                silver: 'c0c0c0',                skyblue: '87ceeb',                slateblue: '6a5acd',                slategray: '708090',                snow: 'fffafa',                springgreen: '00ff7f',                steelblue: '4682b4',                tan: 'd2b48c',                teal: '008080',                thistle: 'd8bfd8',                tomato: 'ff6347',                turquoise: '40e0d0',                violet: 'ee82ee',                violetred: 'd02090',                wheat: 'f5deb3',                white: 'ffffff',                whitesmoke: 'f5f5f5',                yellow: 'ffff00',                yellowgreen: '9acd32'            };        var standardColorTypes = [{                    re: /^rgb\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)$/,                    process: function(colorString) {                        return [parseInt(colorString[1], 10), parseInt(colorString[2], 10), parseInt(colorString[3], 10)]                    }                }, {                    re: /^rgba\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3}),\s*(\d*\.*\d+)\)$/,                    process: function(colorString) {                        return [parseInt(colorString[1], 10), parseInt(colorString[2], 10), parseInt(colorString[3], 10), parseFloat(colorString[4])]                    }                }, {                    re: /^#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})$/,                    process: function(colorString) {                        return [parseInt(colorString[1], 16), parseInt(colorString[2], 16), parseInt(colorString[3], 16)]                    }                }, {                    re: /^#([a-f0-9]{1})([a-f0-9]{1})([a-f0-9]{1})$/,                    process: function(colorString) {                        return [parseInt(colorString[1] + colorString[1], 16), parseInt(colorString[2] + colorString[2], 16), parseInt(colorString[3] + colorString[3], 16)]                    }                }, {                    re: /^hsv\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)$/,                    process: function(colorString) {                        var h = parseInt(colorString[1], 10),                            s = parseInt(colorString[2], 10),                            v = parseInt(colorString[3], 10),                            rgb = hsvToRgb(h, s, v);                        return [rgb[0], rgb[1], rgb[2], 1, [h, s, v]]                    }                }, {                    re: /^hsl\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)$/,                    process: function(colorString) {                        var h = parseInt(colorString[1], 10),                            s = parseInt(colorString[2], 10),                            l = parseInt(colorString[3], 10),                            rgb = hslToRgb(h, s, l);                        return [rgb[0], rgb[1], rgb[2], 1, null, [h, s, l]]                    }                }];        function Color(value) {            this.baseColor = value;            var color;            if (value) {                color = String(value).toLowerCase().replace(/ /g, '');                color = standardColorNames[color] ? '#' + standardColorNames[color] : color;                color = parseColor(color)            }            if (!color)                this.colorIsInvalid = true;            color = color || {};            this.r = normalize(color[0]);            this.g = normalize(color[1]);            this.b = normalize(color[2]);            this.a = normalize(color[3], 1, 1);            if (color[4])                this.hsv = {                    h: color[4][0],                    s: color[4][1],                    v: color[4][2]                };            else                this.hsv = toHsvFromRgb(this.r, this.g, this.b);            if (color[5])                this.hsl = {                    h: color[5][0],                    s: color[5][1],                    l: color[5][2]                };            else                this.hsl = toHslFromRgb(this.r, this.g, this.b)        }        function parseColor(color) {            if (color === "transparent")                return [0, 0, 0, 0];            var i = 0,                ii = standardColorTypes.length,                str;            for (; i < ii; ++i) {                str = standardColorTypes[i].re.exec(color);                if (str)                    return standardColorTypes[i].process(str)            }            return null        }        function normalize(colorComponent, def, max) {            def = def || 0;            max = max || 255;            return colorComponent < 0 || isNaN(colorComponent) ? def : colorComponent > max ? max : colorComponent        }        function toHexFromRgb(r, g, b) {            return '#' + (0X01000000 | r << 16 | g << 8 | b).toString(16).slice(1)        }        function toHsvFromRgb(r, g, b) {            var max = Math.max(r, g, b),                min = Math.min(r, g, b),                delta = max - min,                H,                S,                V;            V = max;            S = max === 0 ? 0 : 1 - min / max;            if (max === min)                H = 0;            else                switch (max) {                    case r:                        H = 60 * ((g - b) / delta);                        if (g < b)                            H = H + 360;                        break;                    case g:                        H = 60 * ((b - r) / delta) + 120;                        break;                    case b:                        H = 60 * ((r - g) / delta) + 240;                        break                }            S *= 100;            V *= 100 / 255;            return {                    h: Math.round(H),                    s: Math.round(S),                    v: Math.round(V)                }        }        function hsvToRgb(h, s, v) {            var Vdec,                Vinc,                Vmin,                Hi,                a,                r,                g,                b;            Hi = Math.floor(h / 60);            Vmin = (100 - s) * v / 100;            a = (v - Vmin) * (h % 60 / 60);            Vinc = Vmin + a;            Vdec = v - a;            switch (Hi) {                case 0:                    r = v;                    g = Vinc;                    b = Vmin;                    break;                case 1:                    r = Vdec;                    g = v;                    b = Vmin;                    break;                case 2:                    r = Vmin;                    g = v;                    b = Vinc;                    break;                case 3:                    r = Vmin;                    g = Vdec;                    b = v;                    break;                case 4:                    r = Vinc;                    g = Vmin;                    b = v;                    break;                case 5:                    r = v;                    g = Vmin;                    b = Vdec;                    break            }            return [Math.round(r * 2.55), Math.round(g * 2.55), Math.round(b * 2.55)]        }        function calculateHue(r, g, b, delta) {            var max = Math.max(r, g, b);            switch (max) {                case r:                    return (g - b) / delta + (g < b ? 6 : 0);                case g:                    return (b - r) / delta + 2;                case b:                    return (r - g) / delta + 4            }        }        function toHslFromRgb(r, g, b) {            r = convertTo01Bounds(r, 255);            g = convertTo01Bounds(g, 255);            b = convertTo01Bounds(b, 255);            var max = Math.max(r, g, b),                min = Math.min(r, g, b),                maxMinSumm = max + min,                h,                s,                l = maxMinSumm / 2;            if (max === min)                h = s = 0;            else {                var delta = max - min;                if (l > 0.5)                    s = delta / (2 - maxMinSumm);                else                    s = delta / maxMinSumm;                h = calculateHue(r, g, b, delta);                h /= 6            }            return {                    h: _round(h * 360),                    s: _round(s * 100),                    l: _round(l * 100)                }        }        function makeTc(colorPart, h) {            var Tc = h;            if (colorPart === "r")                Tc = h + 1 / 3;            if (colorPart === "b")                Tc = h - 1 / 3;            return Tc        }        function modifyTc(Tc) {            if (Tc < 0)                Tc += 1;            if (Tc > 1)                Tc -= 1;            return Tc        }        function hueToRgb(p, q, Tc) {            Tc = modifyTc(Tc);            if (Tc < 1 / 6)                return p + (q - p) * 6 * Tc;            if (Tc < 1 / 2)                return q;            if (Tc < 2 / 3)                return p + (q - p) * (2 / 3 - Tc) * 6;            return p        }        function hslToRgb(h, s, l) {            var r,                g,                b;            h = convertTo01Bounds(h, 360),            s = convertTo01Bounds(s, 100),            l = convertTo01Bounds(l, 100);            if (s === 0)                r = g = b = l;            else {                var q = l < 0.5 ? l * (1 + s) : l + s - l * s,                    p = 2 * l - q;                r = hueToRgb(p, q, makeTc("r", h));                g = hueToRgb(p, q, makeTc("g", h));                b = hueToRgb(p, q, makeTc("b", h))            }            return [_round(r * 255), _round(g * 255), _round(b * 255)]        }        function convertTo01Bounds(n, max) {            n = Math.min(max, Math.max(0, parseFloat(n)));            if (Math.abs(n - max) < 0.000001)                return 1;            return n % max / parseFloat(max)        }        function isIntegerBtwMinAndMax(number, min, max) {            min = min || 0;            max = max || 255;            if (number % 1 !== 0 || number < min || number > max || typeof number !== 'number' || isNaN(number))                return false;            return true        }        var _round = Math.round;        Color.prototype = {            constructor: Color,            highlight: function(step) {                step = step || 10;                return this.alter(step).toHex()            },            darken: function(step) {                step = step || 10;                return this.alter(-step).toHex()            },            alter: function(step) {                var result = new Color;                result.r = normalize(this.r + step);                result.g = normalize(this.g + step);                result.b = normalize(this.b + step);                return result            },            blend: function(blendColor, opacity) {                var other = blendColor instanceof Color ? blendColor : new Color(blendColor),                    result = new Color;                result.r = normalize(_round(this.r * (1 - opacity) + other.r * opacity));                result.g = normalize(_round(this.g * (1 - opacity) + other.g * opacity));                result.b = normalize(_round(this.b * (1 - opacity) + other.b * opacity));                return result            },            toHex: function() {                return toHexFromRgb(this.r, this.g, this.b)            },            getPureColor: function() {                var rgb = hsvToRgb(this.hsv.h, 100, 100);                return new Color("rgb(" + rgb.join(",") + ")")            },            isValidHex: function(hex) {                return /(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(hex)            },            isValidRGB: function(r, g, b) {                if (!isIntegerBtwMinAndMax(r) || !isIntegerBtwMinAndMax(g) || !isIntegerBtwMinAndMax(b))                    return false;                return true            },            isValidAlpha: function(a) {                if (isNaN(a) || a < 0 || a > 1 || typeof a !== 'number')                    return false;                return true            },            colorIsInvalid: false        };        DX.Color = Color    })(DevExpress);    /*! Module core, file localization.js */    (function($, DX, undefined) {        Globalize.localize = function(key, cultureSelector) {            var neutral = (cultureSelector || this.cultureSelector || "").substring(0, 2);            return this.findClosestCulture(cultureSelector).messages[key] || this.findClosestCulture(neutral).messages[key] || this.cultures["default"].messages[key]        };        var localization = function() {                var newMessages = {};                return {                        setup: function(localizablePrefix) {                            this.localizeString = function(text) {                                var regex = new RegExp("(^|[^a-zA-Z_0-9" + localizablePrefix + "-]+)(" + localizablePrefix + "{1,2})([a-zA-Z_0-9-]+)", "g"),                                    escapeString = localizablePrefix + localizablePrefix;                                return text.replace(regex, function(str, prefix, escape, localizationKey) {                                        var result = prefix + localizablePrefix + localizationKey;                                        if (escape !== escapeString)                                            if (Globalize.cultures["default"].messages[localizationKey])                                                result = prefix + Globalize.localize(localizationKey);                                            else                                                newMessages[localizationKey] = DX.inflector.humanize(localizationKey);                                        return result                                    })                            }                        },                        localizeNode: function(node) {                            var that = this;                            $(node).each(function(index, nodeItem) {                                if (!nodeItem.nodeType)                                    return;                                if (nodeItem.nodeType === 3)                                    nodeItem.nodeValue = that.localizeString(nodeItem.nodeValue);                                else if (!$(nodeItem).is("iframe")) {                                    $.each(nodeItem.attributes || [], function(index, attr) {                                        if (typeof attr.value === "string") {                                            var localizedValue = that.localizeString(attr.value);                                            if (attr.value !== localizedValue)                                                attr.value = localizedValue                                        }                                    });                                    $(nodeItem).contents().each(function(index, node) {                                        that.localizeNode(node)                                    })                                }                            })                        },                        getDictionary: function(onlyNew) {                            if (onlyNew)                                return newMessages;                            return $.extend({}, newMessages, Globalize.cultures["default"].messages)                        }                    }            }();        localization.setup("@");        DX.localization = localization    })(jQuery, DevExpress);    /*! Module core, file core.en.js */    Globalize.addCultureInfo("default", {messages: {            Yes: "Yes",            No: "No",            Cancel: "Cancel",            Clear: "Clear",            Done: "Done",            Loading: "Loading...",            Select: "Select...",            Search: "Search",            Back: "Back",            OK: "OK",            "dxCollectionWidget-noDataText": "No data to display",            "validation-required": "Required",            "validation-required-formatted": "{0} is required",            "validation-numeric": "Value must be a number",            "validation-numeric-formatted": "{0} must be a number",            "validation-range": "Value is out of range",            "validation-range-formatted": "{0} is out of range",            "validation-stringLength": "The length of the value is not correct",            "validation-stringLength-formatted": "The length of {0} is not correct",            "validation-custom": "Value is invalid",            "validation-custom-formatted": "{0} is invalid",            "validation-compare": "Values do not match",            "validation-compare-formatted": "{0} does not match",            "validation-pattern": "Value does not match pattern",            "validation-pattern-formatted": "{0} does not match pattern",            "validation-email": "Email is invalid",            "validation-email-formatted": "{0} is invalid",            "validation-mask": "Value is invalid"        }});    /*! Module core, file widgets-base.en.js */    Globalize.addCultureInfo("default", {messages: {            "dxLookup-searchPlaceholder": "Minimum character number: {0}",            "dxList-pullingDownText": "Pull down to refresh...",            "dxList-pulledDownText": "Release to refresh...",            "dxList-refreshingText": "Refreshing...",            "dxList-pageLoadingText": "Loading...",            "dxList-nextButtonText": "More",            "dxList-selectAll": "Select All",            "dxListEditDecorator-delete": "Delete",            "dxListEditDecorator-more": "More",            "dxScrollView-pullingDownText": "Pull down to refresh...",            "dxScrollView-pulledDownText": "Release to refresh...",            "dxScrollView-refreshingText": "Refreshing...",            "dxScrollView-reachBottomText": "Loading...",            "dxDateBox-simulatedDataPickerTitleTime": "Select time",            "dxDateBox-simulatedDataPickerTitleDate": "Select date",            "dxDateBox-simulatedDataPickerTitleDateTime": "Select date and time",            "dxDateBox-validation-datetime": "Value must be a date or time",            "dxFileUploader-selectFile": "Select file",            "dxFileUploader-dropFile": "or Drop file here",            "dxFileUploader-bytes": "bytes",            "dxFileUploader-kb": "kb",            "dxFileUploader-Mb": "Mb",            "dxFileUploader-Gb": "Gb",            "dxFileUploader-upload": "Upload",            "dxFileUploader-uploaded": "Uploaded",            "dxFileUploader-readyToUpload": "Ready to upload",            "dxFileUploader-uploadFailedMessage": "Upload failed",            "dxRangeSlider-ariaFrom": "From {0}",            "dxRangeSlider-ariaTill": "Till {0}",            "dxSwitch-onText": "ON",            "dxSwitch-offText": "OFF"        }});    /*! Module core, file widgets-mobile.en.js */    /*! Module core, file widgets-web.en.js */    Globalize.addCultureInfo("default", {messages: {            "dxDataGrid-columnChooserTitle": "Column Chooser",            "dxDataGrid-columnChooserEmptyText": "Drag a column here to hide it",            "dxDataGrid-groupContinuesMessage": "Continues on the next page",            "dxDataGrid-groupContinuedMessage": "Continued from the previous page",            "dxDataGrid-editingEditRow": "Edit",            "dxDataGrid-editingSaveRowChanges": "Save",            "dxDataGrid-editingCancelRowChanges": "Cancel",            "dxDataGrid-editingDeleteRow": "Delete",            "dxDataGrid-editingUndeleteRow": "Undelete",            "dxDataGrid-editingConfirmDeleteMessage": "Are you sure you want to delete this record?",            "dxDataGrid-editingConfirmDeleteTitle": "",            "dxDataGrid-groupPanelEmptyText": "Drag a column header here to group by that column",            "dxDataGrid-noDataText": "No data",            "dxDataGrid-searchPanelPlaceholder": "Search...",            "dxDataGrid-filterRowShowAllText": "(All)",            "dxDataGrid-filterRowResetOperationText": "Reset",            "dxDataGrid-filterRowOperationEquals": "Equals",            "dxDataGrid-filterRowOperationNotEquals": "Does not equal",            "dxDataGrid-filterRowOperationLess": "Less than",            "dxDataGrid-filterRowOperationLessOrEquals": "Less than or equal to",            "dxDataGrid-filterRowOperationGreater": "Greater than",            "dxDataGrid-filterRowOperationGreaterOrEquals": "Greater than or equal to",            "dxDataGrid-filterRowOperationStartsWith": "Starts with",            "dxDataGrid-filterRowOperationContains": "Contains",            "dxDataGrid-filterRowOperationNotContains": "Does not contain",            "dxDataGrid-filterRowOperationEndsWith": "Ends with",            "dxDataGrid-applyFilterText": "Apply filter",            "dxDataGrid-trueText": "true",            "dxDataGrid-falseText": "false",            "dxDataGrid-sortingAscendingText": "Sort Ascending",            "dxDataGrid-sortingDescendingText": "Sort Descending",            "dxDataGrid-sortingClearText": "Clear Sorting",            "dxDataGrid-editingSaveAllChanges": "Save changes",            "dxDataGrid-editingCancelAllChanges": "Discard changes",            "dxDataGrid-editingAddRow": "Add a row",            "dxDataGrid-summaryMin": "Min: {0}",            "dxDataGrid-summaryMinOtherColumn": "Min of {1} is {0}",            "dxDataGrid-summaryMax": "Max: {0}",            "dxDataGrid-summaryMaxOtherColumn": "Max of {1} is {0}",            "dxDataGrid-summaryAvg": "Avg: {0}",            "dxDataGrid-summaryAvgOtherColumn": "Avg of {1} is {0}",            "dxDataGrid-summarySum": "Sum: {0}",            "dxDataGrid-summarySumOtherColumn": "Sum of {1} is {0}",            "dxDataGrid-summaryCount": "Count: {0}",            "dxDataGrid-columnFixingFix": "Fix",            "dxDataGrid-columnFixingUnfix": "Unfix",            "dxDataGrid-columnFixingLeftPosition": "To the left",            "dxDataGrid-columnFixingRightPosition": "To the right",            "dxDataGrid-exportTo": "Export to",            "dxDataGrid-exportToExcel": "Export to Excel file",            "dxDataGrid-excelFormat": "Excel file",            "dxDataGrid-selectedRows": "Selected rows",            "dxDataGrid-headerFilterEmptyValue": "(Blanks)",            "dxDataGrid-headerFilterOK": "OK",            "dxDataGrid-headerFilterCancel": "Cancel",            "dxDataGrid-ariaColumn": "Column",            "dxDataGrid-ariaValue": "Value",            "dxDataGrid-ariaFilterCell": "Filter cell",            "dxDataGrid-ariaCollapse": "Collapse",            "dxDataGrid-ariaExpand": "Expand",            "dxDataGrid-ariaDataGrid": "Data grid",            "dxDataGrid-ariaSearchInGrid": "Search in data grid",            "dxDataGrid-ariaSelectAll": "Select all",            "dxDataGrid-ariaSelectRow": "Select row",            "dxPager-infoText": "Page {0} of {1}",            "dxPivotGrid-grandTotal": "Grand Total",            "dxPivotGrid-total": "{0} Total",            "dxPivotGrid-fieldChooserTitle": "Field Chooser",            "dxPivotGrid-showFieldChooser": "Show Field Chooser",            "dxPivotGrid-expandAll": "Expand All",            "dxPivotGrid-collapseAll": "Collapse All",            "dxPivotGrid-sortColumnBySummary": "Sort \"{0}\" by This Column",            "dxPivotGrid-sortRowBySummary": "Sort \"{0}\" by This Row",            "dxPivotGrid-removeAllSorting": "Remove All Sorting",            "dxPivotGrid-rowFields": "Row Fields",            "dxPivotGrid-columnFields": "Column Fields",            "dxPivotGrid-dataFields": "Data Fields",            "dxPivotGrid-filterFields": "Filter Fields",            "dxPivotGrid-allFields": "All Fields",            "dxScheduler-editorLabelTitle": "Subject",            "dxScheduler-editorLabelStartDate": "Start Date",            "dxScheduler-editorLabelEndDate": "End Date",            "dxScheduler-editorLabelDescription": "Description",            "dxScheduler-editorLabelRecurrence": "Repeat",            "dxScheduler-openAppointment": "Open appointment",            "dxScheduler-recurrenceNever": "Never",            "dxScheduler-recurrenceDaily": "Daily",            "dxScheduler-recurrenceWeekly": "Weekly",            "dxScheduler-recurrenceMonthly": "Monthly",            "dxScheduler-recurrenceYearly": "Yearly",            "dxScheduler-recurrenceEvery": "Every",            "dxScheduler-recurrenceEnd": "End repeat",            "dxScheduler-recurrenceAfter": "After",            "dxScheduler-recurrenceOn": "On",            "dxScheduler-recurrenceRepeatDaily": "day(s)",            "dxScheduler-recurrenceRepeatWeekly": "week(s)",            "dxScheduler-recurrenceRepeatMonthly": "month(s)",            "dxScheduler-recurrenceRepeatYearly": "year(s)",            "dxScheduler-switcherDay": "Day",            "dxScheduler-switcherWeek": "Week",            "dxScheduler-switcherWorkWeek": "Work week",            "dxScheduler-switcherMonth": "Month",            "dxScheduler-recurrenceRepeatOnDate": "on date",            "dxScheduler-recurrenceRepeatCount": "occurrence(s)",            "dxScheduler-allDay": "All day",            "dxCalendar-todayButtonText": "Today",            "dxCalendar-ariaWidgetName": "Calendar",            "dxColorView-ariaRed": "Red",            "dxColorView-ariaGreen": "Green",            "dxColorView-ariaBlue": "Blue",            "dxColorView-ariaAlpha": "Transparency",            "dxColorView-ariaHex": "Color code"        }});    /*! Module core, file validationEngine.js */    (function($, DX, undefined) {        var utils = DX.utils;        var rulesValidators = {                required: {                    validate: function(value, rule) {                        if (!utils.isDefined(value))                            return false;                        if (value === false)                            return false;                        value = String(value);                        if (rule.trim || !utils.isDefined(rule.trim))                            value = $.trim(value);                        return value !== ""                    },                    defaultMessage: function() {                        return Globalize.localize("validation-required")                    },                    defaultFormattedMessage: function() {                        return Globalize.localize("validation-required-formatted")                    }                },                numeric: {                    validate: function(value, rule) {                        if (!rulesValidators.required.validate(value, {}))                            return true;                        if (rule.useCultureSettings && utils.isString(value))                            return !isNaN(Globalize.parseFloat(value));                        else                            return $.isNumeric(value)                    },                    defaultMessage: function() {                        return Globalize.localize("validation-numeric")                    },                    defaultFormattedMessage: function() {                        return Globalize.localize("validation-numeric-formatted")                    }                },                range: {                    validate: function(value, rule) {                        if (!rulesValidators.required.validate(value, {}))                            return true;                        var validNumber = rulesValidators["numeric"].validate(value, rule),                            validValue = utils.isDefined(value),                            number = validNumber ? parseFloat(value) : validValue && value.valueOf(),                            min = rule.min,                            max = rule.max;                        if (!(validNumber || utils.isDate(value)) && !validValue)                            return false;                        if (utils.isDefined(min)) {                            if (utils.isDefined(max))                                return number >= min && number <= max;                            return number >= min                        }                        else if (utils.isDefined(max))                            return number <= max;                        else                            throw DX.Error("E0101");                        return false                    },                    defaultMessage: function() {                        return Globalize.localize("validation-range")                    },                    defaultFormattedMessage: function() {                        return Globalize.localize("validation-range-formatted")                    }                },                stringLength: {                    validate: function(value, rule) {                        value = String(value);                        if (rule.trim || !utils.isDefined(rule.trim))                            value = $.trim(value);                        return rulesValidators.range.validate(value.length, $.extend({}, rule))                    },                    defaultMessage: function() {                        return Globalize.localize("validation-stringLength")                    },                    defaultFormattedMessage: function() {                        return Globalize.localize("validation-stringLength-formatted")                    }                },                custom: {                    validate: function(value, rule) {                        return rule.validationCallback({                                value: value,                                validator: rule.validator,                                rule: rule                            })                    },                    defaultMessage: function() {                        return Globalize.localize("validation-custom")                    },                    defaultFormattedMessage: function() {                        return Globalize.localize("validation-custom-formatted")                    }                },                compare: {                    validate: function(value, rule) {                        if (!rule.comparisonTarget)                            throw DX.Error("E0102");                        $.extend(rule, {reevaluate: true});                        var otherValue = rule.comparisonTarget(),                            type = rule.comparisonType || "==";                        switch (type) {                            case"==":                                return value == otherValue;                            case"!=":                                return value != otherValue;                            case"===":                                return value === otherValue;                            case"!==":                                return value !== otherValue;                            case">":                                return value > otherValue;                            case">=":                                return value >= otherValue;                            case"<":                                return value < otherValue;                            case"<=":                                return value <= otherValue                        }                    },                    defaultMessage: function() {                        return Globalize.localize("validation-compare")                    },                    defaultFormattedMessage: function() {                        return Globalize.localize("validation-compare-formatted")                    }                },                pattern: {                    validate: function(value, rule) {                        if (!rulesValidators.required.validate(value, {}))                            return true;                        var pattern = rule.pattern;                        if (utils.isString(pattern))                            pattern = new RegExp(pattern);                        return pattern.test(value)                    },                    defaultMessage: function() {                        return Globalize.localize("validation-pattern")                    },                    defaultFormattedMessage: function() {                        return Globalize.localize("validation-pattern-formatted")                    }                },                email: {                    validate: function(value, rule) {                        if (!rulesValidators.required.validate(value, {}))                            return true;                        return rulesValidators.pattern.validate(value, $.extend({}, rule, {pattern: /^[\d\w\._\-]+@([\d\w\._\-]+\.)+[\w]+$/i}))                    },                    defaultMessage: function() {                        return Globalize.localize("validation-email")                    },                    defaultFormattedMessage: function() {                        return Globalize.localize("validation-email-formatted")                    }                }            };        var GroupConfig = DX.Class.inherit({                ctor: function(group) {                    this.group = group;                    this.validators = []                },                validate: function() {                    var result = {                            isValid: true,                            brokenRules: [],                            validators: []                        };                    $.each(this.validators, function(_, validator) {                        var validatorResult = validator.validate();                        result.isValid = result.isValid && validatorResult.isValid;                        if (validatorResult.brokenRule)                            result.brokenRules.push(validatorResult.brokenRule);                        result.validators.push(validator)                    });                    this.fireEvent("validated", [{                            validators: result.validators,                            brokenRules: result.brokenRules,                            isValid: result.isValid                        }]);                    return result                },                reset: function() {                    $.each(this.validators, function(_, validator) {                        validator.reset()                    })                }            }).include(DX.EventsMixin);        DX.validationEngine = {            groups: [],            getGroupConfig: function(group) {                var result = $.grep(this.groups, function(config) {                        return config.group === group                    });                if (result.length)                    return result[0]            },            initGroups: function() {                this.groups = [];                this.addGroup()            },            addGroup: function(group) {                var config = this.getGroupConfig(group);                if (!config) {                    config = new GroupConfig(group);                    this.groups.push(config)                }                return config            },            removeGroup: function(group) {                var config = this.getGroupConfig(group),                    index = $.inArray(config, this.groups);                if (index > -1)                    this.groups.splice(index, 1);                return config            },            _setDefaultMessage: function(rule, validator, name) {                if (!utils.isDefined(rule.message))                    if (validator.defaultFormattedMessage && utils.isDefined(name))                        rule.message = validator.defaultFormattedMessage().replace(/\{0\}/, name);                    else                        rule.message = validator.defaultMessage()            },            validate: function validate(value, rules, name) {                var result = {                        name: name,                        value: value,                        brokenRule: null,                        isValid: true,                        validationRules: rules                    },                    that = this;                $.each(rules || [], function(_, rule) {                    var ruleValidator = rulesValidators[rule.type],                        ruleValidationResult;                    if (ruleValidator) {                        if (utils.isDefined(rule.isValid) && rule.value === value && !rule.reevaluate) {                            if (!rule.isValid) {                                result.isValid = false;                                result.brokenRule = rule;                                return false                            }                            return true                        }                        rule.value = value;                        ruleValidationResult = ruleValidator.validate(value, rule);                        rule.isValid = ruleValidationResult;                        if (!ruleValidationResult) {                            result.isValid = false;                            that._setDefaultMessage(rule, ruleValidator, name);                            result.brokenRule = rule                        }                        if (!rule.isValid)                            return false                    }                    else                        throw DX.Error("E0100");                });                return result            },            registerValidatorInGroup: function(group, validator) {                var groupConfig = DX.validationEngine.addGroup(group);                if ($.inArray(validator, groupConfig.validators) < 0)                    groupConfig.validators.push(validator)            },            removeRegistredValidator: function(group, validator) {                var config = DX.validationEngine.getGroupConfig(group),                    validatorsInGroup = config && config.validators;                var index = $.inArray(validator, validatorsInGroup);                if (index > -1)                    validatorsInGroup.splice(index, 1)            },            validateGroup: function(group) {                var groupConfig = DX.validationEngine.getGroupConfig(group);                if (!groupConfig)                    throw DX.Error("E0110");                return groupConfig.validate()            },            resetGroup: function(group) {                var groupConfig = DX.validationEngine.getGroupConfig(group);                if (!groupConfig)                    throw DX.Error("E0110");                return groupConfig.reset()            }        };        DX.validationEngine.initGroups()    })(jQuery, DevExpress);    /*! Module core, file data.errors.js */    (function($, DX) {        $.extend(DX.ERROR_MESSAGES, {            E4000: "[DevExpress.data]: {0}",            E4001: "Unknown aggregating function is detected: '{0}'",            E4002: "Unsupported OData protocol version is used",            E4003: "Unknown filter operation is used: {0}",            E4004: "The thenby() method is called before the sortby() method",            E4005: "Store requires a key expression for this operation",            E4006: "ArrayStore 'data' option must be an array",            E4007: "Compound keys cannot be auto-generated",            E4008: "Attempt to insert an item with the a duplicated key",            E4009: "Data item with specified key value cannot be found",            E4010: "CustomStore does not support creating queries",            E4011: "Custom Store method is not implemented or is not a function: {0}",            E4012: "Custom Store method returns an invalid value: {0}",            E4013: "Local Store requires the 'name' configuration option is specified",            E4014: "Unknown key type is detected: {0}",            E4015: "Unknown entity name or alias is used: {0}",            E4016: "The compileSetter(expr) method is called with 'self' passed as a parameter",            E4017: "Keys cannot be modified"        })    })(jQuery, DevExpress);    /*! Module core, file data.js */    (function($, DX, undefined) {        var bracketsToDots = function(expr) {                return expr.replace(/\[/g, ".").replace(/\]/g, "")            };        var unwrapObservable = DX.utils.unwrapObservable;        var isObservable = function(value) {                return DX.support.hasKo && ko.isObservable(value)            };        var readPropValue = function(obj, propName) {                if (propName === "this")                    return obj;                return obj[propName]            };        var assignPropValue = function(obj, propName, value, options) {                if (propName === "this")                    throw new DX.Error("E4016");                var propValue = obj[propName];                if (options.unwrapObservables && isObservable(propValue))                    propValue(value);                else                    obj[propName] = value            };        var prepareOptions = function(options) {                options = options || {};                options.unwrapObservables = options.unwrapObservables !== undefined ? options.unwrapObservables : true;                return options            };        var unwrap = function(value, options) {                return options.unwrapObservables ? unwrapObservable(value) : value            };        var compileGetter = function(expr) {                if (arguments.length > 1)                    expr = $.makeArray(arguments);                if (!expr || expr === "this")                    return function(obj) {                            return obj                        };                if ($.isFunction(expr))                    return expr;                if ($.isArray(expr))                    return combineGetters(expr);                expr = bracketsToDots(expr);                var path = expr.split(".");                return function(obj, options) {                        options = prepareOptions(options);                        var current = unwrap(obj, options);                        $.each(path, function() {                            if (!current)                                return false;                            var next = unwrap(current[this], options);                            if ($.isFunction(next) && !options.functionsAsIs)                                next = next.call(current);                            current = next                        });                        return current                    }            };        var combineGetters = function(getters) {                var compiledGetters = {};                $.each(getters, function() {                    compiledGetters[this] = compileGetter(this)                });                return function(obj, options) {                        var result = {};                        $.each(compiledGetters, function(name) {                            var value = this(obj, options),                                current,                                path,                                last,                                i;                            if (value === undefined)                                return;                            current = result;                            path = name.split(".");                            last = path.length - 1;                            for (i = 0; i < last; i++)                                current = current[path[i]] = {};                            current[path[i]] = value                        });                        return result                    }            };        var compileSetter = function(expr) {                expr = expr || "this";                expr = bracketsToDots(expr);                var pos = expr.lastIndexOf("."),                    targetGetter = compileGetter(expr.substr(0, pos)),                    targetPropName = expr.substr(1 + pos);                return function(obj, value, options) {                        options = prepareOptions(options);                        var target = targetGetter(obj, {                                functionsAsIs: options.functionsAsIs,                                unwrapObservables: options.unwrapObservables                            }),                            prevTargetValue = readPropValue(target, targetPropName);                        if (!options.functionsAsIs && $.isFunction(prevTargetValue) && !isObservable(prevTargetValue))                            target[targetPropName](value);                        else {                            prevTargetValue = unwrap(prevTargetValue, options);                            if (options.merge && $.isPlainObject(value) && (prevTargetValue === undefined || $.isPlainObject(prevTargetValue)) && !(value instanceof $.Event)) {                                if (!prevTargetValue)                                    assignPropValue(target, targetPropName, {}, options);                                DX.utils.deepExtendArraySafe(unwrap(readPropValue(target, targetPropName), options), value)                            }                            else                                assignPropValue(target, targetPropName, value, options)                        }                    }            };        var normalizeBinaryCriterion = function(crit) {                return [crit[0], crit.length < 3 ? "=" : String(crit[1]).toLowerCase(), crit.length < 2 ? true : crit[crit.length - 1]]            };        var normalizeSortingInfo = function(info) {                if (!$.isArray(info))                    info = [info];                return $.map(info, function(i) {                        return {                                selector: $.isFunction(i) || typeof i === "string" ? i : i.getter || i.field || i.selector,                                desc: !!(i.desc || String(i.dir).charAt(0).toLowerCase() === "d")                            }                    })            };        var Guid = DX.Class.inherit({                ctor: function(value) {                    if (value)                        value = String(value);                    this._value = this._normalize(value || this._generate())                },                _normalize: function(value) {                    value = value.replace(/[^a-f0-9]/ig, "").toLowerCase();                    while (value.length < 32)                        value += "0";                    return [value.substr(0, 8), value.substr(8, 4), value.substr(12, 4), value.substr(16, 4), value.substr(20, 12)].join("-")                },                _generate: function() {                    var value = "";                    for (var i = 0; i < 32; i++)                        value += Math.round(Math.random() * 15).toString(16);                    return value                },                toString: function() {                    return this._value                },                valueOf: function() {                    return this._value                },                toJSON: function() {                    return this._value                }            });        var toComparable = function(value, caseSensitive) {                if (value instanceof Date)                    return value.getTime();                if (value instanceof Guid)                    return value.valueOf();                if (!caseSensitive && typeof value === "string")                    return value.toLowerCase();                return value            };        var keysEqual = function(keyExpr, key1, key2) {                if ($.isArray(keyExpr)) {                    var names = $.map(key1, function(v, k) {                            return k                        }),                        name;                    for (var i = 0; i < names.length; i++) {                        name = names[i];                        if (toComparable(key1[name], true) != toComparable(key2[name], true))                            return false                    }                    return true                }                return toComparable(key1, true) == toComparable(key2, true)            };        var BASE64_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";        var base64_encode = function(input) {                if (!$.isArray(input))                    input = stringToByteArray(String(input));                var result = "";                function getBase64Char(index) {                    return BASE64_CHARS.charAt(index)                }                for (var i = 0; i < input.length; i += 3) {                    var octet1 = input[i],                        octet2 = input[i + 1],                        octet3 = input[i + 2];                    result += $.map([octet1 >> 2, (octet1 & 3) << 4 | octet2 >> 4, isNaN(octet2) ? 64 : (octet2 & 15) << 2 | octet3 >> 6, isNaN(octet3) ? 64 : octet3 & 63], getBase64Char).join("")                }                return result            };        var stringToByteArray = function(str) {                var bytes = [],                    code,                    i;                for (i = 0; i < str.length; i++) {                    code = str.charCodeAt(i);                    if (code < 128)                        bytes.push(code);                    else if (code < 2048)                        bytes.push(192 + (code >> 6), 128 + (code & 63));                    else if (code < 65536)                        bytes.push(224 + (code >> 12), 128 + (code >> 6 & 63), 128 + (code & 63));                    else if (code < 2097152)                        bytes.push(240 + (code >> 18), 128 + (code >> 12 & 63), 128 + (code >> 6 & 63), 128 + (code & 63))                }                return bytes            };        var errorMessageFromXhr = function() {                var textStatusMessages = {                        timeout: "Network connection timeout",                        error: "Unspecified network error",                        parsererror: "Unexpected server response"                    };                var textStatusDetails = {                        timeout: "possible causes: the remote host is not accessible, overloaded or is not included into the domain white-list when being run in the native container",                        error: "if the remote host is located on another domain, make sure it properly supports cross-origin resource sharing (CORS), or use the JSONP approach instead",                        parsererror: "the remote host did not respond with valid JSON data"                    };                var explainTextStatus = function(textStatus) {                        var result = textStatusMessages[textStatus];                        if (!result)                            return textStatus;                        result += " (" + textStatusDetails[textStatus] + ")";                        return result                    };                return function(xhr, textStatus) {                        if (xhr.status < 400)                            return explainTextStatus(textStatus);                        return xhr.statusText                    }            }();        var aggregators = {                count: {                    seed: 0,                    step: function(count) {                        return 1 + count                    }                },                sum: {                    seed: 0,                    step: function(sum, item) {                        return sum + item                    }                },                min: {step: function(min, item) {                        return item < min ? item : min                    }},                max: {step: function(max, item) {                        return item > max ? item : max                    }},                avg: {                    seed: [0, 0],                    step: function(pair, value) {                        return [pair[0] + value, pair[1] + 1]                    },                    finalize: function(pair) {                        return pair[1] ? pair[0] / pair[1] : NaN                    }                }            };        function handleError(error) {            var id = "E4000";            if (error && "__id" in error)                id = error.__id;            DX.log(id, error)        }        function multiLevelSearch(options) {            var itemsGetter = options.itemsGetter,                itemsSetter = options.itemsSetter,                criteria = options.criteria,                data = options.data;            function selector(x) {                var hash,                    items = itemsGetter(x);                if (isNotAnEmptyArray(items)) {                    hash = {};                    itemsSetter(hash, multiLevelSearch({                        data: items,                        criteria: criteria,                        itemsGetter: itemsGetter,                        itemsSetter: itemsSetter                    }));                    return $.extend({}, x, hash)                }                return x            }            function criterion(x) {                return isNotAnEmptyArray(itemsGetter(x))            }            function isNotAnEmptyArray(x) {                return $.isArray(x) && x.length > 0            }            return DX.data.query(data).select(selector).filter([[criterion], "or", criteria]).toArray()        }        var data = DX.data = {                utils: {                    compileGetter: compileGetter,                    compileSetter: compileSetter,                    normalizeBinaryCriterion: normalizeBinaryCriterion,                    normalizeSortingInfo: normalizeSortingInfo,                    toComparable: toComparable,                    keysEqual: keysEqual,                    errorMessageFromXhr: errorMessageFromXhr,                    aggregators: aggregators,                    multiLevelSearch: multiLevelSearch                },                Guid: Guid,                base64_encode: base64_encode,                queryImpl: {},                queryAdapters: {},                query: function() {                    var impl = $.isArray(arguments[0]) ? "array" : "remote";                    return data.queryImpl[impl].apply(this, arguments)                },                errorHandler: null,                _errorHandler: function(error) {                    handleError(error);                    if (data.errorHandler)                        data.errorHandler(error)                }            }    })(jQuery, DevExpress);    /*! Module core, file data.aggregateCalculator.js */    (function($, DX, undefined) {        var data = DX.data,            utils = data.utils;        function isCount(aggregator) {            return aggregator === utils.aggregators.count        }        function normalizeAggregate(aggregate) {            var selector = utils.compileGetter(aggregate.selector),                aggregator = aggregate.aggregator;            if (typeof aggregator === "string") {                aggregator = data.utils.aggregators[aggregator];                if (!aggregator)                    throw DX.Error("E4001", aggregate.aggregator);            }            return {                    selector: selector,                    aggregator: aggregator                }        }        data.AggregateCalculator = DX.Class.inherit({            ctor: function(options) {                this._data = options.data;                this._groupLevel = options.groupLevel || 0;                this._totalAggregates = $.map(options.totalAggregates || [], normalizeAggregate);                this._groupAggregates = $.map(options.groupAggregates || [], normalizeAggregate);                this._totals = []            },            calculate: function() {                if (this._totalAggregates.length)                    this._calculateTotals(0, {items: this._data});                if (this._groupAggregates.length && this._groupLevel > 0)                    this._calculateGroups(0, {items: this._data})            },            totalAggregates: function() {                return this._totals            },            _aggregate: function(data, aggregates, container) {                var i,                    j;                for (i = 0; i < aggregates.length; i++) {                    if (isCount(aggregates[i].aggregator)) {                        container[i] = (container[i] || 0) + data.items.length;                        continue                    }                    for (j = 0; j < data.items.length; j++)                        this._accumulate(i, aggregates[i], container, data.items[j])                }            },            _calculateTotals: function(level, data) {                var i;                if (level === 0)                    this._totals = this._seed(this._totalAggregates);                if (level === this._groupLevel)                    this._aggregate(data, this._totalAggregates, this._totals);                else                    for (i = 0; i < data.items.length; i++)                        this._calculateTotals(level + 1, data.items[i]);                if (level === 0)                    this._totals = this._finalize(this._totalAggregates, this._totals)            },            _calculateGroups: function(level, data, outerAggregates) {                var i,                    innerAggregates;                if (level === this._groupLevel)                    this._aggregate(data, this._groupAggregates, outerAggregates);                else                    for (i = 0; i < data.items.length; i++) {                        innerAggregates = this._seed(this._groupAggregates);                        this._calculateGroups(level + 1, data.items[i], innerAggregates);                        data.items[i].aggregates = this._finalize(this._groupAggregates, innerAggregates);                        if (level > 0) {                            outerAggregates = outerAggregates || this._seed(this._groupAggregates);                            this._calculateGroups(level + 1, data.items[i], outerAggregates)                        }                    }            },            _seed: function(aggregates) {                return $.map(aggregates, function(aggregate) {                        var aggregator = aggregate.aggregator,                            seed = "seed" in aggregator ? aggregator.seed : NaN;                        return $.isArray(seed) ? [seed] : seed                    })            },            _accumulate: function(aggregateIndex, aggregate, results, item) {                var value = aggregate.selector(item),                    aggregator = aggregate.aggregator;                results[aggregateIndex] = results[aggregateIndex] !== results[aggregateIndex] ? value : aggregator.step(results[aggregateIndex], value)            },            _finalize: function(aggregates, results) {                return $.map(aggregates, function(aggregate, index) {                        var fin = aggregate.aggregator.finalize;                        return fin ? fin(results[index]) : results[index]                    })            }        })    })(jQuery, DevExpress);    /*! Module core, file data.query.array.js */    (function($, DX, undefined) {        var Class = DX.Class,            data = DX.data,            queryImpl = data.queryImpl,            compileGetter = data.utils.compileGetter,            toComparable = data.utils.toComparable;        var Iterator = Class.inherit({                toArray: function() {                    var result = [];                    this.reset();                    while (this.next())                        result.push(this.current());                    return result                },                countable: function() {                    return false                }            });        var ArrayIterator = Iterator.inherit({                ctor: function(array) {                    this.array = array;                    this.index = -1                },                next: function() {                    if (this.index + 1 < this.array.length) {                        this.index++;                        return true                    }                    return false                },                current: function() {                    return this.array[this.index]                },                reset: function() {                    this.index = -1                },                toArray: function() {                    return this.array.slice(0)                },                countable: function() {                    return true                },                count: function() {                    return this.array.length                }            });        var WrappedIterator = Iterator.inherit({                ctor: function(iter) {                    this.iter = iter                },                next: function() {                    return this.iter.next()                },                current: function() {                    return this.iter.current()                },                reset: function() {                    return this.iter.reset()                }            });        var MapIterator = WrappedIterator.inherit({                ctor: function(iter, mapper) {                    this.callBase(iter);                    this.index = -1;                    this.mapper = mapper                },                current: function() {                    return this.mapper(this.callBase(), this.index)                },                next: function() {                    var hasNext = this.callBase();                    if (hasNext)                        this.index++;                    return hasNext                }            });        var SortIterator = Iterator.inherit({                ctor: function(iter, getter, desc) {                    if (!(iter instanceof MapIterator))                        iter = new MapIterator(iter, this._wrap);                    this.iter = iter;                    this.rules = [{                            getter: getter,                            desc: desc                        }]                },                thenBy: function(getter, desc) {                    var result = new SortIterator(this.sortedIter || this.iter, getter, desc);                    if (!this.sortedIter)                        result.rules = this.rules.concat(result.rules);                    return result                },                next: function() {                    this._ensureSorted();                    return this.sortedIter.next()                },                current: function() {                    this._ensureSorted();                    return this.sortedIter.current()                },                reset: function() {                    delete this.sortedIter                },                countable: function() {                    return this.sortedIter || this.iter.countable()                },                count: function() {                    if (this.sortedIter)                        return this.sortedIter.count();                    return this.iter.count()                },                _ensureSorted: function() {                    if (this.sortedIter)                        return;                    $.each(this.rules, function() {                        this.getter = compileGetter(this.getter)                    });                    this.sortedIter = new MapIterator(new ArrayIterator(this.iter.toArray().sort($.proxy(this._compare, this))), this._unwrap)                },                _wrap: function(record, index) {                    return {                            index: index,                            value: record                        }                },                _unwrap: function(wrappedItem) {                    return wrappedItem.value                },                _compare: function(x, y) {                    var xIndex = x.index,                        yIndex = y.index;                    x = x.value;                    y = y.value;                    if (x === y)                        return xIndex - yIndex;                    for (var i = 0, rulesCount = this.rules.length; i < rulesCount; i++) {                        var rule = this.rules[i],                            xValue = toComparable(rule.getter(x)),                            yValue = toComparable(rule.getter(y)),                            factor = rule.desc ? -1 : 1;                        if (xValue < yValue)                            return -factor;                        if (xValue > yValue)                            return factor;                        if (xValue !== yValue)                            return !xValue ? -factor : factor                    }                    return xIndex - yIndex                }            });        var compileCriteria = function() {                var compileGroup = function(crit) {                        var operands = [],                            bag = ["return function(d) { return "],                            index = 0,                            pushAnd = false;                        $.each(crit, function() {                            if ($.isArray(this) || $.isFunction(this)) {                                if (pushAnd)                                    bag.push(" && ");                                operands.push(compileCriteria(this));                                bag.push("op[", index, "](d)");                                index++;                                pushAnd = true                            }                            else {                                bag.push(/and|&/i.test(this) ? " && " : " || ");                                pushAnd = false                            }                        });                        bag.push(" }");                        return new Function("op", bag.join(""))(operands)                    };                var toString = function(value) {                        return DX.utils.isDefined(value) ? value.toString() : ''                    };                var compileBinary = function(crit) {                        crit = data.utils.normalizeBinaryCriterion(crit);                        var getter = compileGetter(crit[0]),                            op = crit[1],                            value = crit[2];                        value = toComparable(value);                        switch (op.toLowerCase()) {                            case"=":                                return compileEquals(getter, value);                            case"<>":                                return compileEquals(getter, value, true);                            case">":                                return function(obj) {                                        return toComparable(getter(obj)) > value                                    };                            case"<":                                return function(obj) {                                        return toComparable(getter(obj)) < value                                    };                            case">=":                                return function(obj) {                                        return toComparable(getter(obj)) >= value                                    };                            case"<=":                                return function(obj) {                                        return toComparable(getter(obj)) <= value                                    };                            case"startswith":                                return function(obj) {                                        return toComparable(toString(getter(obj))).indexOf(value) === 0                                    };                            case"endswith":                                return function(obj) {                                        var getterValue = toComparable(toString(getter(obj))),                                            searchValue = toString(value);                                        if (getterValue.length < searchValue.length)                                            return false;                                        return getterValue.lastIndexOf(value) === getterValue.length - value.length                                    };                            case"contains":                                return function(obj) {                                        return toComparable(toString(getter(obj))).indexOf(value) > -1                                    };                            case"notcontains":                                return function(obj) {                                        return toComparable(toString(getter(obj))).indexOf(value) === -1                                    }                        }                        throw DX.Error("E4003", op);                    };                function compileEquals(getter, value, negate) {                    return function(obj) {                            obj = toComparable(getter(obj));                            var result = useStrictComparison(value) ? obj === value : obj == value;                            if (negate)                                result = !result;                            return result                        }                }                function useStrictComparison(value) {                    return value === "" || value === 0 || value === null || value === false || value === undefined                }                return function(crit) {                        if ($.isFunction(crit))                            return crit;                        if ($.isArray(crit[0]))                            return compileGroup(crit);                        return compileBinary(crit)                    }            }();        var FilterIterator = WrappedIterator.inherit({                ctor: function(iter, criteria) {                    this.callBase(iter);                    this.criteria = compileCriteria(criteria)                },                next: function() {                    while (this.iter.next())                        if (this.criteria(this.current()))                            return true;                    return false                }            });        var GroupIterator = Iterator.inherit({                ctor: function(iter, getter) {                    this.iter = iter;                    this.getter = getter                },                next: function() {                    this._ensureGrouped();                    return this.groupedIter.next()                },                current: function() {                    this._ensureGrouped();                    return this.groupedIter.current()                },                reset: function() {                    delete this.groupedIter                },                countable: function() {                    return !!this.groupedIter                },                count: function() {                    return this.groupedIter.count()                },                _ensureGrouped: function() {                    if (this.groupedIter)                        return;                    var hash = {},                        keys = [],                        iter = this.iter,                        getter = compileGetter(this.getter);                    iter.reset();                    while (iter.next()) {                        var current = iter.current(),                            key = getter(current);                        if (key in hash)                            hash[key].push(current);                        else {                            hash[key] = [current];                            keys.push(key)                        }                    }                    this.groupedIter = new ArrayIterator($.map(keys, function(key) {                        return {                                key: key,                                items: hash[key]                            }                    }))                }            });        var SelectIterator = WrappedIterator.inherit({                ctor: function(iter, getter) {                    this.callBase(iter);                    this.getter = compileGetter(getter)                },                current: function() {                    return this.getter(this.callBase())                },                countable: function() {                    return this.iter.countable()                },                count: function() {                    return this.iter.count()                }            });        var SliceIterator = WrappedIterator.inherit({                ctor: function(iter, skip, take) {                    this.callBase(iter);                    this.skip = Math.max(0, skip);                    this.take = Math.max(0, take);                    this.pos = 0                },                next: function() {                    if (this.pos >= this.skip + this.take)                        return false;                    while (this.pos < this.skip && this.iter.next())                        this.pos++;                    this.pos++;                    return this.iter.next()                },                reset: function() {                    this.callBase();                    this.pos = 0                },                countable: function() {                    return this.iter.countable()                },                count: function() {                    return Math.min(this.iter.count() - this.skip, this.take)                }            });        queryImpl.array = function(iter, queryOptions) {            queryOptions = queryOptions || {};            if (!(iter instanceof Iterator))                iter = new ArrayIterator(iter);            var handleError = function(error) {                    var handler = queryOptions.errorHandler;                    if (handler)                        handler(error);                    data._errorHandler(error)                };            var aggregateCore = function(aggregator) {                    var d = $.Deferred().fail(handleError),                        seed,                        step = aggregator.step,                        finalize = aggregator.finalize;                    try {                        iter.reset();                        if ("seed" in aggregator)                            seed = aggregator.seed;                        else                            seed = iter.next() ? iter.current() : NaN;                        var accumulator = seed;                        while (iter.next())                            accumulator = step(accumulator, iter.current());                        d.resolve(finalize ? finalize(accumulator) : accumulator)                    }                    catch(x) {                        d.reject(x)                    }                    return d.promise()                };            var aggregate = function(seed, step, finalize) {                    if (arguments.length < 2)                        return aggregateCore({step: arguments[0]});                    return aggregateCore({                            seed: seed,                            step: step,                            finalize: finalize                        })                };            var standardAggregate = function(name) {                    return aggregateCore(data.utils.aggregators[name])                };            var select = function(getter) {                    if (!$.isFunction(getter) && !$.isArray(getter))                        getter = $.makeArray(arguments);                    return chainQuery(new SelectIterator(iter, getter))                };            var selectProp = function(name) {                    return select(compileGetter(name))                };            var chainQuery = function(iter) {                    return queryImpl.array(iter, queryOptions)                };            return {                    toArray: function() {                        return iter.toArray()                    },                    enumerate: function() {                        var d = $.Deferred().fail(handleError);                        try {                            d.resolve(iter.toArray())                        }                        catch(x) {                            d.reject(x)                        }                        return d.promise()                    },                    sortBy: function(getter, desc) {                        return chainQuery(new SortIterator(iter, getter, desc))                    },                    thenBy: function(getter, desc) {                        if (iter instanceof SortIterator)                            return chainQuery(iter.thenBy(getter, desc));                        throw DX.Error("E4004");                    },                    filter: function(criteria) {                        if (!$.isArray(criteria))                            criteria = $.makeArray(arguments);                        return chainQuery(new FilterIterator(iter, criteria))                    },                    slice: function(skip, take) {                        if (take === undefined)                            take = Number.MAX_VALUE;                        return chainQuery(new SliceIterator(iter, skip, take))                    },                    select: select,                    groupBy: function(getter) {                        return chainQuery(new GroupIterator(iter, getter))                    },                    aggregate: aggregate,                    count: function() {                        if (iter.countable()) {                            var d = $.Deferred().fail(handleError);                            try {                                d.resolve(iter.count())                            }                            catch(x) {                                d.reject(x)                            }                            return d.promise()                        }                        return standardAggregate("count")                    },                    sum: function(getter) {                        if (getter)                            return selectProp(getter).sum();                        return standardAggregate("sum")                    },                    min: function(getter) {                        if (getter)                            return selectProp(getter).min();                        return standardAggregate("min")                    },                    max: function(getter) {                        if (getter)                            return selectProp(getter).max();                        return standardAggregate("max")                    },                    avg: function(getter) {                        if (getter)                            return selectProp(getter).avg();                        return standardAggregate("avg")                    }                }        }    })(jQuery, DevExpress);    /*! Module core, file data.query.remote.js */    (function($, DX, undefined) {        var data = DX.data,            queryImpl = data.queryImpl;        queryImpl.remote = function(url, queryOptions, tasks) {            tasks = tasks || [];            queryOptions = queryOptions || {};            var createTask = function(name, args) {                    return {                            name: name,                            args: args                        }                };            var exec = function(executorTask) {                    var d = $.Deferred(),                        _adapterFactory,                        _adapter,                        _taskQueue,                        _currentTask,                        _mergedSortArgs;                    var rejectWithNotify = function(error) {                            var handler = queryOptions.errorHandler;                            if (handler)                                handler(error);                            data._errorHandler(error);                            d.reject(error)                        };                    function mergeSortTask(task) {                        switch (task.name) {                            case"sortBy":                                _mergedSortArgs = [task.args];                                return true;                            case"thenBy":                                if (!_mergedSortArgs)                                    throw DX.Error("E4004");                                _mergedSortArgs.push(task.args);                                return true                        }                        return false                    }                    function unmergeSortTasks() {                        var head = _taskQueue[0],                            unmergedTasks = [];                        if (head && head.name === "multiSort") {                            _taskQueue.shift();                            $.each(head.args[0], function() {                                unmergedTasks.push(createTask(unmergedTasks.length ? "thenBy" : "sortBy", this))                            })                        }                        _taskQueue = unmergedTasks.concat(_taskQueue)                    }                    try {                        _adapterFactory = queryOptions.adapter || "odata";                        if (!$.isFunction(_adapterFactory))                            _adapterFactory = data.queryAdapters[_adapterFactory];                        _adapter = _adapterFactory(queryOptions);                        _taskQueue = [].concat(tasks).concat(executorTask);                        while (_taskQueue.length) {                            _currentTask = _taskQueue[0];                            if (!mergeSortTask(_currentTask)) {                                if (_mergedSortArgs) {                                    _taskQueue.unshift(createTask("multiSort", [_mergedSortArgs]));                                    _mergedSortArgs = null;                                    continue                                }                                if (String(_currentTask.name) !== "enumerate")                                    if (!_adapter[_currentTask.name] || _adapter[_currentTask.name].apply(_adapter, _currentTask.args) === false)                                        break                            }                            _taskQueue.shift()                        }                        unmergeSortTasks();                        _adapter.exec(url).done(function(result, extra) {                            if (!_taskQueue.length)                                d.resolve(result, extra);                            else {                                var clientChain = queryImpl.array(result, {errorHandler: queryOptions.errorHandler});                                $.each(_taskQueue, function() {                                    clientChain = clientChain[this.name].apply(clientChain, this.args)                                });                                clientChain.done(d.resolve).fail(d.reject)                            }                        }).fail(rejectWithNotify)                    }                    catch(x) {                        rejectWithNotify(x)                    }                    return d.promise()                };            var query = {};            $.each(["sortBy", "thenBy", "filter", "slice", "select", "groupBy"], function() {                var name = String(this);                query[name] = function() {                    return queryImpl.remote(url, queryOptions, tasks.concat(createTask(name, arguments)))                }            });            $.each(["count", "min", "max", "sum", "avg", "aggregate", "enumerate"], function() {                var name = String(this);                query[name] = function() {                    return exec.call(this, createTask(name, arguments))                }            });            return query        }    })(jQuery, DevExpress);    /*! Module core, file data.odata.js */    (function($, DX, undefined) {        var data = DX.data,            utils = DX.utils,            Guid = data.Guid,            isDefined = utils.isDefined;        var DEFAULT_PROTOCOL_VERSION = 2;        var GUID_REGEX = /^(\{{0,1}([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){12}\}{0,1})$/;        var VERBOSE_DATE_REGEX = /^\/Date\((-?\d+)((\+|-)?(\d+)?)\)\/$/;        var ISO8601_DATE_REGEX = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?(Z|[-+]{1}\d{2}(:?)(\d{2})?)?$/;        var JSON_VERBOSE_MIME_TYPE = "application/json;odata=verbose";        function formatISO8601(date, skipZeroTime, skipTimezone) {            var ret = [];            var pad = function(n) {                    if (n < 10)                        return "0".concat(n);                    return String(n)                };            var isZeroTime = function() {                    return date.getHours() + date.getMinutes() + date.getSeconds() + date.getMilliseconds() < 1                };            ret.push(date.getFullYear());            ret.push("-");            ret.push(pad(date.getMonth() + 1));            ret.push("-");            ret.push(pad(date.getDate()));            if (!(skipZeroTime && isZeroTime())) {                ret.push("T");                ret.push(pad(date.getHours()));                ret.push(":");                ret.push(pad(date.getMinutes()));                ret.push(":");                ret.push(pad(date.getSeconds()));                if (date.getMilliseconds()) {                    ret.push(".");                    ret.push(date.getMilliseconds())                }                if (!skipTimezone)                    ret.push("Z")            }            return ret.join("")        }        function parseISO8601(isoString) {            var result = new Date(0);            var chunks = isoString.replace("Z", "").split("T"),                date = /(\d{4})-(\d{2})-(\d{2})/.exec(chunks[0]),                time = /(\d{2}):(\d{2}):(\d{2})\.?(\d{0,7})?/.exec(chunks[1]);            result.setDate(Number(date[3]));            result.setMonth(Number(date[2]) - 1);            result.setFullYear(Number(date[1]));            if ($.isArray(time) && time.length) {                result.setHours(Number(time[1]));                result.setMinutes(Number(time[2]));                result.setSeconds(Number(time[3]));                result.setMilliseconds(Number(String(time[4]).substr(0, 3)) || 0)            }            return result        }        function isAbsoluteUrl(url) {            return /^(?:[a-z]+:)?\/\//i.test(url)        }        function toAbsoluteUrl(basePath, relativePath) {            var part,                baseParts = basePath.split("/"),                relativeParts = relativePath.split("/");            baseParts.pop();            while (relativeParts.length) {                part = relativeParts.shift();                if (part === "..")                    baseParts.pop();                else                    baseParts.push(part)            }            return baseParts.join("/")        }        var ajaxOptionsForRequest = function(protocolVersion, request, requestOptions) {                request = $.extend({                    method: "get",                    url: "",                    params: {},                    payload: null,                    headers: {},                    timeout: 30000                }, request);                requestOptions = requestOptions || {};                var beforeSend = requestOptions.beforeSend;                if (beforeSend)                    beforeSend(request);                var method = (request.method || "get").toLowerCase(),                    isGet = method === "get",                    useJsonp = isGet && requestOptions.jsonp,                    params = $.extend({}, request.params),                    ajaxData = isGet ? params : formatPayload(request.payload),                    qs = !isGet && $.param(params),                    url = request.url,                    contentType = !isGet && JSON_VERBOSE_MIME_TYPE;                if (qs)                    url += (url.indexOf("?") > -1 ? "&" : "?") + qs;                if (useJsonp)                    ajaxData["$format"] = "json";                return {                        url: url,                        data: ajaxData,                        dataType: useJsonp ? "jsonp" : "json",                        jsonp: useJsonp && "$callback",                        type: method,                        timeout: request.timeout,                        headers: request.headers,                        contentType: contentType,                        accepts: {json: [JSON_VERBOSE_MIME_TYPE, "text/plain"].join()},                        xhrFields: {withCredentials: requestOptions.withCredentials}                    };                function formatPayload(payload) {                    return JSON.stringify(payload, function(key, value) {                            if (!(this[key] instanceof Date))                                return value;                            value = formatISO8601(this[key]);                            switch (protocolVersion) {                                case 2:                                    return value.substr(0, value.length - 1);                                case 3:                                case 4:                                    return value;                                default:                                    throw DX.Error("E4002");                            }                        })                }            };        var sendRequest = function(protocolVersion, request, requestOptions) {                var d = $.Deferred();                var options = ajaxOptionsForRequest(protocolVersion, request, requestOptions);                $.ajax(options).always(function(obj, textStatus) {                    var tuplet = interpretJsonFormat(obj, textStatus),                        error = tuplet.error,                        data = tuplet.data,                        nextUrl = tuplet.nextUrl,                        extra;                    if (error)                        d.reject(error);                    else if (requestOptions.countOnly)                        d.resolve(tuplet.count);                    else if (nextUrl) {                        if (!isAbsoluteUrl(nextUrl))                            nextUrl = toAbsoluteUrl(options.url, nextUrl);                        sendRequest(protocolVersion, {url: nextUrl}, requestOptions).fail(d.reject).done(function(nextData) {                            d.resolve(data.concat(nextData))                        })                    }                    else {                        if (isFinite(tuplet.count))                            extra = {totalCount: tuplet.count};                        d.resolve(data, extra)                    }                });                return d.promise()            };        var formatDotNetError = function(errorObj) {                var message,                    currentError = errorObj;                if ("message" in errorObj)                    if (errorObj.message.value)                        message = errorObj.message.value;                    else                        message = errorObj.message;                while (currentError = currentError.innererror || currentError.internalexception) {                    message = currentError.message;                    if (currentError.internalexception && message.indexOf("inner exception") === -1)                        break                }                return message            };        var errorFromResponse = function(obj, textStatus) {                if (textStatus === "nocontent")                    return null;                var httpStatus = 200,                    message = "Unknown error",                    response = obj;                if (textStatus !== "success") {                    httpStatus = obj.status;                    message = data.utils.errorMessageFromXhr(obj, textStatus);                    try {                        response = $.parseJSON(obj.responseText)                    }                    catch(x) {}                }                var errorObj = response && (response.error || response["@odata.error"]);                if (errorObj) {                    message = formatDotNetError(errorObj) || message;                    if (httpStatus === 200)                        httpStatus = 500;                    if (errorObj.code)                        httpStatus = Number(errorObj.code);                    return $.extend(Error(message), {                            httpStatus: httpStatus,                            errorDetails: errorObj                        })                }                else if (httpStatus !== 200)                    return $.extend(Error(message), {httpStatus: httpStatus})            };        var interpretJsonFormat = function(obj, textStatus) {                var error = errorFromResponse(obj, textStatus),                    value;                if (error)                    return {error: error};                if (!$.isPlainObject(obj))                    return {data: obj};                if ("d" in obj && (utils.isArray(obj.d) || utils.isObject(obj.d)))                    value = interpretVerboseJsonFormat(obj, textStatus);                else                    value = interpretLightJsonFormat(obj, textStatus);                transformTypes(value);                return value            };        var interpretVerboseJsonFormat = function(obj) {                var data = obj.d;                if (!isDefined(data))                    return {error: Error("Malformed or unsupported JSON response received")};                data = data;                if (isDefined(data.results))                    data = data.results;                return {                        data: data,                        nextUrl: obj.d.__next,                        count: parseInt(obj.d.__count, 10)                    }            };        var interpretLightJsonFormat = function(obj) {                var data = obj;                if (isDefined(data.value))                    data = data.value;                return {                        data: data,                        nextUrl: obj["@odata.nextLink"],                        count: parseInt(obj["@odata.count"], 10)                    }            };        var EdmLiteral = DX.Class.inherit({                ctor: function(value) {                    this._value = value                },                valueOf: function() {                    return this._value                }            });        var transformTypes = function(obj) {                $.each(obj, function(key, value) {                    if (value !== null && typeof value === "object") {                        if ("results" in value)                            obj[key] = value.results;                        transformTypes(obj[key])                    }                    else if (typeof value === "string")                        if (GUID_REGEX.test(value))                            obj[key] = new Guid(value);                        else if (value.match(VERBOSE_DATE_REGEX)) {                            var date = new Date(Number(RegExp.$1) + RegExp.$2 * 60 * 1000);                            obj[key] = new Date(date.valueOf() + date.getTimezoneOffset() * 60 * 1000)                        }                        else if (ISO8601_DATE_REGEX.test(value))                            obj[key] = new Date(parseISO8601(obj[key]).valueOf())                })            };        var serializeDate = function(date) {                return "datetime'" + formatISO8601(date, true, true) + "'"            };        var serializeString = function(value) {                return "'" + value.replace(/'/g, "''") + "'"            };        var serializePropName = function(propName) {                if (propName instanceof EdmLiteral)                    return propName.valueOf();                return propName.replace(/\./g, "/")            };        var serializeValueV4 = function(value) {                if (value instanceof Date)                    return formatISO8601(value, false, false);                if (value instanceof Guid)                    return value.valueOf();                return serializeValueV2(value)            };        var serializeValueV2 = function(value) {                if (value instanceof Date)                    return serializeDate(value);                if (value instanceof Guid)                    return "guid'" + value + "'";                if (value instanceof EdmLiteral)                    return value.valueOf();                if (typeof value === "string")                    return serializeString(value);                return String(value)            };        var serializeValue = function(value, protocolVersion) {                switch (protocolVersion) {                    case 2:                    case 3:                        return serializeValueV2(value);                    case 4:                        return serializeValueV4(value);                    default:                        throw DX.Error("E4002");                }            };        var serializeKey = function(key, protocolVersion) {                if ($.isPlainObject(key)) {                    var parts = [];                    $.each(key, function(k, v) {                        parts.push(serializePropName(k) + "=" + serializeValue(v, protocolVersion))                    });                    return parts.join()                }                return serializeValue(key, protocolVersion)            };        var keyConverters = {                String: function(value) {                    return value + ""                },                Int32: function(value) {                    return Math.floor(value)                },                Int64: function(value) {                    if (value instanceof EdmLiteral)                        return value;                    return new EdmLiteral(value + "L")                },                Guid: function(value) {                    if (value instanceof Guid)                        return value;                    return new Guid(value)                },                Boolean: function(value) {                    return !!value                },                Single: function(value) {                    if (value instanceof EdmLiteral)                        return value;                    return new EdmLiteral(value + "f")                },                Decimal: function(value) {                    if (value instanceof EdmLiteral)                        return value;                    return new EdmLiteral(value + "m")                }            };        var compileCriteria = function() {                var createBinaryOperationFormatter = function(op) {                        return function(prop, val, bag) {                                bag.push(prop, " ", op, " ", val)                            }                    };                var createStringFuncFormatter = function(op, reverse) {                        return function(prop, val, bag) {                                if (reverse)                                    bag.push(op, "(", val, ",", prop, ")");                                else                                    bag.push(op, "(", prop, ",", val, ")")                            }                    };                var formatters = {                        "=": createBinaryOperationFormatter("eq"),                        "<>": createBinaryOperationFormatter("ne"),                        ">": createBinaryOperationFormatter("gt"),                        ">=": createBinaryOperationFormatter("ge"),                        "<": createBinaryOperationFormatter("lt"),                        "<=": createBinaryOperationFormatter("le"),                        startswith: createStringFuncFormatter("startswith"),                        endswith: createStringFuncFormatter("endswith")                    };                var formattersV2 = $.extend({}, formatters, {                        contains: createStringFuncFormatter("substringof", true),                        notcontains: createStringFuncFormatter("not substringof", true)                    });                var formattersV4 = $.extend({}, formatters, {                        contains: createStringFuncFormatter("contains"),                        notcontains: createStringFuncFormatter("not contains")                    });                var compileBinary = function(criteria, bag, protocolVersion) {                        criteria = data.utils.normalizeBinaryCriterion(criteria);                        var op = criteria[1],                            formatters = protocolVersion === 4 ? formattersV4 : formattersV2,                            formatter = formatters[op.toLowerCase()];                        if (!formatter)                            throw DX.Error("E4003", op);                        formatter(serializePropName(criteria[0]), serializeValue(criteria[2], protocolVersion), bag)                    };                var compileGroup = function(criteria, bag, protocolVersion) {                        var pushAnd = false;                        $.each(criteria, function() {                            if ($.isArray(this)) {                                if (pushAnd)                                    bag.push(" and ");                                bag.push("(");                                compileCore(this, bag, protocolVersion);                                bag.push(")");                                pushAnd = true                            }                            else {                                bag.push(/and|&/i.test(this) ? " and " : " or ");                                pushAnd = false                            }                        })                    };                var compileCore = function(criteria, bag, protocolVersion) {                        if ($.isArray(criteria[0]))                            compileGroup(criteria, bag, protocolVersion);                        else                            compileBinary(criteria, bag, protocolVersion)                    };                return function(criteria, protocolVersion) {                        var bag = [];                        compileCore(criteria, bag, protocolVersion);                        return bag.join("")                    }            }();        var createODataQueryAdapter = function(queryOptions) {                var _sorting = [],                    _criteria = [],                    _select,                    _skip,                    _take,                    _countQuery;                var hasSlice = function() {                        return _skip || _take !== undefined                    };                var hasFunction = function(criterion) {                        for (var i = 0; i < criterion.length; i++) {                            if ($.isFunction(criterion[i]))                                return true;                            if ($.isArray(criterion[i]) && hasFunction(criterion[i]))                                return true                        }                        return false                    };                var generateExpand = function() {                        var hash = {};                        if (queryOptions.expand)                            $.each($.makeArray(queryOptions.expand), function() {                                hash[serializePropName(this)] = 1                            });                        if (_select)                            $.each(_select, function() {                                var path = this.split(".");                                if (path.length < 2)                                    return;                                path.pop();                                hash[serializePropName(path.join("."))] = 1                            });                        return $.map(hash, function(k, v) {                                return v                            }).join() || undefined                    };                var requestData = function() {                        var result = {};                        if (!_countQuery) {                            if (_sorting.length)                                result["$orderby"] = _sorting.join(",");                            if (_skip)                                result["$skip"] = _skip;                            if (_take !== undefined)                                result["$top"] = _take;                            if (_select)                                result["$select"] = serializePropName(_select.join());                            result["$expand"] = generateExpand()                        }                        if (_criteria.length)                            result["$filter"] = compileCriteria(_criteria.length < 2 ? _criteria[0] : _criteria, queryOptions.version);                        if (_countQuery)                            result["$top"] = 0;                        if (queryOptions.requireTotalCount || _countQuery)                            if (queryOptions.version !== 4)                                result["$inlinecount"] = "allpages";                            else                                result["$count"] = "true";                        return result                    };                queryOptions.version = queryOptions.version || DEFAULT_PROTOCOL_VERSION;                return {                        exec: function(url) {                            return sendRequest(queryOptions.version, {                                    url: url,                                    params: $.extend(requestData(), queryOptions && queryOptions.params)                                }, {                                    beforeSend: queryOptions.beforeSend,                                    jsonp: queryOptions.jsonp,                                    withCredentials: queryOptions.withCredentials,                                    countOnly: _countQuery                                })                        },                        multiSort: function(args) {                            var rules;                            if (hasSlice())                                return false;                            for (var i = 0; i < args.length; i++) {                                var getter = args[i][0],                                    desc = !!args[i][1],                                    rule;                                if (typeof getter !== "string")                                    return false;                                rule = serializePropName(getter);                                if (desc)                                    rule += " desc";                                rules = rules || [];                                rules.push(rule)                            }                            _sorting = rules                        },                        slice: function(skipCount, takeCount) {                            if (hasSlice())                                return false;                            _skip = skipCount;                            _take = takeCount                        },                        filter: function(criterion) {                            if (hasSlice() || $.isFunction(criterion))                                return false;                            if (!$.isArray(criterion))                                criterion = $.makeArray(arguments);                            if (hasFunction(criterion))                                return false;                            if (_criteria.length)                                _criteria.push("and");                            _criteria.push(criterion)                        },                        select: function(expr) {                            if (_select || $.isFunction(expr))                                return false;                            if (!$.isArray(expr))                                expr = $.makeArray(arguments);                            _select = expr                        },                        count: function() {                            _countQuery = true                        }                    }            };        $.extend(true, data, {            EdmLiteral: EdmLiteral,            utils: {odata: {                    sendRequest: sendRequest,                    serializePropName: serializePropName,                    serializeValue: serializeValue,                    serializeKey: serializeKey,                    keyConverters: keyConverters                }},            queryAdapters: {odata: createODataQueryAdapter}        });        data.OData__internals = {interpretJsonFormat: interpretJsonFormat}    })(jQuery, DevExpress);    /*! Module core, file data.store.abstract.js */    (function($, DX, undefined) {        var Class = DX.Class,            abstract = DX.abstract,            data = DX.data,            normalizeSortingInfo = data.utils.normalizeSortingInfo;        var STORE_CALLBACK_NAMES = ["loading", "loaded", "modifying", "modified", "inserting", "inserted", "updating", "updated", "removing", "removed"];        function multiLevelGroup(query, groupInfo) {            query = query.groupBy(groupInfo[0].selector);            if (groupInfo.length > 1)                query = query.select(function(g) {                    return $.extend({}, g, {items: multiLevelGroup(data.query(g.items), groupInfo.slice(1)).toArray()})                });            return query        }        data.utils.multiLevelGroup = multiLevelGroup;        function arrangeSortingInfo(groupInfo, sortInfo) {            var filteredGroup = [];            $.each(groupInfo, function(_, group) {                var collision = $.grep(sortInfo, function(sort) {                        return group.selector === sort.selector                    });                if (collision.length < 1)                    filteredGroup.push(group)            });            return filteredGroup.concat(sortInfo)        }        data.utils.arrangeSortingInfo = arrangeSortingInfo;        data.Store = Class.inherit({            ctor: function(options) {                var that = this;                options = options || {};                $.each(STORE_CALLBACK_NAMES, function() {                    var eventName = this;                    var callbacks = that[eventName] = $.Callbacks();                    var originalAdd = callbacks.add;                    callbacks.add = function() {                        DX.log("W0003", "Store", eventName, "14.2", "Use the '" + eventName + "' event instead");                        return originalAdd.apply(eventName, arguments)                    };                    if (eventName in options)                        callbacks.add(options[eventName]);                    var propertyName = "on" + eventName.charAt(0).toUpperCase() + eventName.slice(1);                    if (propertyName in options)                        that.on(eventName, options[propertyName])                });                this._key = options.key;                this._errorHandler = options.errorHandler;                this._useDefaultSearch = true            },            _customLoadOptions: function() {                return null            },            key: function() {                return this._key            },            keyOf: function(obj) {                if (!this._keyGetter)                    this._keyGetter = data.utils.compileGetter(this.key());                return this._keyGetter(obj)            },            _requireKey: function() {                if (!this.key())                    throw DX.Error("E4005");            },            load: function(options) {                var that = this;                options = options || {};                this.fireEvent("loading", [options]);                this.loading.fire(options);                return this._loadImpl(options).done(function(result, extra) {                        that.fireEvent("loaded", [result, options]);                        that.loaded.fire(result, extra)                    })            },            _loadImpl: function(options) {                var filter = options.filter,                    sort = options.sort,                    select = options.select,                    group = options.group,                    skip = options.skip,                    take = options.take,                    q = this.createQuery(options);                if (filter)                    q = q.filter(filter);                if (group)                    group = normalizeSortingInfo(group);                if (sort || group) {                    sort = normalizeSortingInfo(sort || []);                    if (group)                        sort = arrangeSortingInfo(group, sort);                    $.each(sort, function(index) {                        q = q[index ? "thenBy" : "sortBy"](this.selector, this.desc)                    })                }                if (select)                    q = q.select(select);                if (group)                    q = multiLevelGroup(q, group);                if (take || skip)                    q = q.slice(skip || 0, take);                return q.enumerate()            },            createQuery: abstract,            totalCount: function(options) {                return this._addFailHandlers(this._totalCountImpl(options))            },            _totalCountImpl: function(options) {                options = options || {};                var q = this.createQuery(),                    group = options.group,                    filter = options.filter;                if (filter)                    q = q.filter(filter);                if (group) {                    group = normalizeSortingInfo(group);                    q = multiLevelGroup(q, group)                }                return q.count()            },            byKey: function(key, extraOptions) {                return this._addFailHandlers(this._byKeyImpl(key, extraOptions))            },            _byKeyImpl: abstract,            insert: function(values) {                var that = this;                that.fireEvent("modifying");                that.fireEvent("inserting", [values]);                that.modifying.fire();                that.inserting.fire(values);                return that._addFailHandlers(that._insertImpl(values).done(function(callbackValues, callbackKey) {                        that.fireEvent("inserted", [callbackValues, callbackKey]);                        that.fireEvent("modified");                        that.inserted.fire(callbackValues, callbackKey);                        that.modified.fire()                    }))            },            _insertImpl: abstract,            update: function(key, values) {                var that = this;                that.fireEvent("modifying");                that.fireEvent("updating", [key, values]);                that.modifying.fire();                that.updating.fire(key, values);                return that._addFailHandlers(that._updateImpl(key, values).done(function(callbackKey, callbackValues) {                        that.fireEvent("updated", [callbackKey, callbackValues]);                        that.fireEvent("modified");                        that.updated.fire(callbackKey, callbackValues);                        that.modified.fire()                    }))            },            _updateImpl: abstract,            remove: function(key) {                var that = this;                that.fireEvent("modifying");                that.fireEvent("removing", [key]);                that.modifying.fire();                that.removing.fire(key);                return that._addFailHandlers(that._removeImpl(key).done(function(callbackKey) {                        that.fireEvent("removed", [callbackKey]);                        that.fireEvent("modified");                        that.removed.fire(callbackKey);                        that.modified.fire()                    }))            },            _removeImpl: abstract,            _addFailHandlers: function(deferred) {                return deferred.fail(this._errorHandler, data._errorHandler)            }        }).include(DX.EventsMixin)    })(jQuery, DevExpress);    /*! Module core, file data.store.array.js */    (function($, DX, undefined) {        var data = DX.data,            Guid = data.Guid;        var trivialPromise = function() {                var d = $.Deferred();                return d.resolve.apply(d, arguments).promise()            };        var rejectedPromise = function() {                var d = $.Deferred();                return d.reject.apply(d, arguments).promise()            };        data.ArrayStore = data.Store.inherit({            ctor: function(options) {                if ($.isArray(options))                    options = {data: options};                else                    options = options || {};                this.callBase(options);                var initialArray = options.data;                if (initialArray && !$.isArray(initialArray))                    throw DX.Error("E4006");                this._array = initialArray || []            },            createQuery: function() {                return data.query(this._array, {errorHandler: this._errorHandler})            },            _byKeyImpl: function(key) {                var index = this._indexByKey(key);                if (index === -1)                    return rejectedPromise(DX.Error("E4009"));                return trivialPromise(this._array[index])            },            _insertImpl: function(values) {                var keyExpr = this.key(),                    keyValue,                    obj;                if ($.isPlainObject(values))                    obj = $.extend({}, values);                else                    obj = values;                if (keyExpr) {                    keyValue = this.keyOf(obj);                    if (keyValue === undefined || typeof keyValue === "object" && $.isEmptyObject(keyValue)) {                        if ($.isArray(keyExpr))                            throw DX.Error("E4007");                        keyValue = obj[keyExpr] = String(new Guid)                    }                    else if (this._array[this._indexByKey(keyValue)] !== undefined)                        return rejectedPromise(DX.Error("E4008"))                }                else                    keyValue = obj;                this._array.push(obj);                return trivialPromise(values, keyValue)            },            _updateImpl: function(key, values) {                var target,                    index;                if (this.key()) {                    if (this.keyOf(values))                        if (!data.utils.keysEqual(this.key(), key, this.keyOf(values)))                            return rejectedPromise(DX.Error("E4017"));                    index = this._indexByKey(key);                    if (index < 0)                        return rejectedPromise(DX.Error("E4009"));                    target = this._array[index]                }                else                    target = key;                DX.utils.deepExtendArraySafe(target, values);                return trivialPromise(key, values)            },            _removeImpl: function(key) {                var index = this._indexByKey(key);                if (index > -1)                    this._array.splice(index, 1);                return trivialPromise(key)            },            _indexByKey: function(key) {                for (var i = 0, arrayLength = this._array.length; i < arrayLength; i++)                    if (data.utils.keysEqual(this.key(), this.keyOf(this._array[i]), key))                        return i;                return -1            },            clear: function() {                this._array = []            }        })    })(jQuery, DevExpress);    /*! Module core, file data.store.local.js */    (function($, DX, undefined) {        var Class = DX.Class,            abstract = DX.abstract,            data = DX.data;        var LocalStoreBackend = Class.inherit({                ctor: function(store, storeOptions) {                    this._store = store;                    this._dirty = false;                    var immediate = this._immediate = storeOptions.immediate;                    var flushInterval = Math.max(100, storeOptions.flushInterval || 10 * 1000);                    if (!immediate) {                        var saveProxy = $.proxy(this.save, this);                        setInterval(saveProxy, flushInterval);                        $(window).on("beforeunload", saveProxy);                        if (window.cordova)                            document.addEventListener("pause", saveProxy, false)                    }                },                notifyChanged: function() {                    this._dirty = true;                    if (this._immediate)                        this.save()                },                load: function() {                    this._store._array = this._loadImpl();                    this._dirty = false                },                save: function() {                    if (!this._dirty)                        return;                    this._saveImpl(this._store._array);                    this._dirty = false                },                _loadImpl: abstract,                _saveImpl: abstract            });        var DomLocalStoreBackend = LocalStoreBackend.inherit({                ctor: function(store, storeOptions) {                    this.callBase(store, storeOptions);                    var name = storeOptions.name;                    if (!name)                        throw DX.Error("E4013");                    this._key = "dx-data-localStore-" + name                },                _loadImpl: function() {                    var raw = localStorage.getItem(this._key);                    if (raw)                        return JSON.parse(raw);                    return []                },                _saveImpl: function(array) {                    if (!array.length)                        localStorage.removeItem(this._key);                    else                        localStorage.setItem(this._key, JSON.stringify(array))                }            });        var localStoreBackends = {dom: DomLocalStoreBackend};        data.LocalStore = data.ArrayStore.inherit({            ctor: function(options) {                if (typeof options === "string")                    options = {name: options};                else                    options = options || {};                this.callBase(options);                this._backend = new localStoreBackends[options.backend || "dom"](this, options);                this._backend.load()            },            clear: function() {                this.callBase();                this._backend.notifyChanged()            },            _insertImpl: function(values) {                var b = this._backend;                return this.callBase(values).done($.proxy(b.notifyChanged, b))            },            _updateImpl: function(key, values) {                var b = this._backend;                return this.callBase(key, values).done($.proxy(b.notifyChanged, b))            },            _removeImpl: function(key) {                var b = this._backend;                return this.callBase(key).done($.proxy(b.notifyChanged, b))            }        })    })(jQuery, DevExpress);    /*! Module core, file data.store.odata.js */    (function($, DX, undefined) {        var Class = DX.Class,            data = DX.data,            utils = DX.utils,            odataUtils = data.utils.odata;        var DEFAULT_PROTOCOL_VERSION = 2;        var formatFunctionInvocationUrl = function(baseUrl, args) {                return DX.stringFormat("{0}({1})", baseUrl, $.map(args || {}, function(value, key) {                        return DX.stringFormat("{0}={1}", key, value)                    }).join(","))            };        var escapeServiceOperationParams = function(params, version) {                if (!params)                    return params;                var result = {};                $.each(params, function(k, v) {                    result[k] = odataUtils.serializeValue(v, version)                });                return result            };        var convertSimpleKey = function(keyType, keyValue) {                var converter = odataUtils.keyConverters[keyType];                if (!converter)                    throw DX.Error("E4014", keyType);                return converter(keyValue)            };        var SharedMethods = {                _extractServiceOptions: function(options) {                    options = options || {};                    this._url = String(options.url).replace(/\/+$/, "");                    this._beforeSend = options.beforeSend;                    this._jsonp = options.jsonp;                    this._version = options.version || DEFAULT_PROTOCOL_VERSION;                    this._withCredentials = options.withCredentials                },                _sendRequest: function(url, method, params, payload) {                    return odataUtils.sendRequest(this.version(), {                            url: url,                            method: method,                            params: params || {},                            payload: payload                        }, {                            beforeSend: this._beforeSend,                            jsonp: this._jsonp,                            withCredentials: this._withCredentials                        })                },                version: function() {                    return this._version                }            };        var ODataStore = data.Store.inherit({                ctor: function(options) {                    this.callBase(options);                    this._extractServiceOptions(options);                    this._keyType = options.keyType;                    if (this.version() === 2)                        this._updateMethod = "MERGE";                    else                        this._updateMethod = "PATCH"                },                _customLoadOptions: function() {                    return ["expand", "customQueryParams"]                },                _byKeyImpl: function(key, extraOptions) {                    var params = {};                    if (extraOptions)                        if (extraOptions.expand)                            params["$expand"] = $.map($.makeArray(extraOptions.expand), odataUtils.serializePropName).join();                    return this._sendRequest(this._byKeyUrl(key), "GET", params)                },                createQuery: function(loadOptions) {                    var url,                        queryOptions;                    loadOptions = loadOptions || {};                    queryOptions = {                        beforeSend: this._beforeSend,                        errorHandler: this._errorHandler,                        jsonp: this._jsonp,                        version: this._version,                        withCredentials: this._withCredentials,                        expand: loadOptions.expand,                        requireTotalCount: loadOptions.requireTotalCount                    };                    if (utils.isDefined(loadOptions.urlOverride))                        url = loadOptions.urlOverride;                    else                        url = this._url;                    if ("customQueryParams" in loadOptions) {                        var params = escapeServiceOperationParams(loadOptions.customQueryParams, this.version());                        if (this.version() === 4)                            url = formatFunctionInvocationUrl(url, params);                        else                            queryOptions.params = params                    }                    return data.query(url, queryOptions)                },                _insertImpl: function(values) {                    this._requireKey();                    var that = this,                        d = $.Deferred();                    $.when(this._sendRequest(this._url, "POST", null, values)).done(function(serverResponse) {                        d.resolve(values, that.keyOf(serverResponse))                    }).fail(d.reject);                    return d.promise()                },                _updateImpl: function(key, values) {                    var d = $.Deferred();                    $.when(this._sendRequest(this._byKeyUrl(key), this._updateMethod, null, values)).done(function() {                        d.resolve(key, values)                    }).fail(d.reject, d);                    return d.promise()                },                _removeImpl: function(key) {                    var d = $.Deferred();                    $.when(this._sendRequest(this._byKeyUrl(key), "DELETE")).done(function() {                        d.resolve(key)                    }).fail(d.reject, d);                    return d.promise()                },                _byKeyUrl: function(key, useOriginalHost) {                    var keyObj = key,                        keyType = this._keyType,                        baseUrl = useOriginalHost ? DX._proxyUrlFormatter.formatLocalUrl(this._url) : this._url;                    if ($.isPlainObject(keyType)) {                        keyObj = {};                        $.each(keyType, function(subKeyName, subKeyType) {                            keyObj[subKeyName] = convertSimpleKey(subKeyType, key[subKeyName])                        })                    }                    else if (keyType)                        keyObj = convertSimpleKey(keyType, key);                    return baseUrl + "(" + encodeURIComponent(odataUtils.serializeKey(keyObj, this._version)) + ")"                }            }).include(SharedMethods);        var ODataContext = Class.inherit({                ctor: function(options) {                    var that = this;                    that._extractServiceOptions(options);                    that._errorHandler = options.errorHandler;                    $.each(options.entities || [], function(entityAlias, entityOptions) {                        that[entityAlias] = new ODataStore($.extend({}, options, {url: that._url + "/" + encodeURIComponent(entityOptions.name || entityAlias)}, entityOptions))                    })                },                get: function(operationName, params) {                    return this.invoke(operationName, params, "GET")                },                invoke: function(operationName, params, httpMethod) {                    params = params || {};                    httpMethod = (httpMethod || "POST").toLowerCase();                    var d = $.Deferred(),                        url = this._url + "/" + encodeURIComponent(operationName),                        payload;                    if (this.version() === 4)                        if (httpMethod === "get") {                            url = formatFunctionInvocationUrl(url, escapeServiceOperationParams(params, this.version()));                            params = null                        }                        else if (httpMethod === "post") {                            payload = params;                            params = null                        }                    $.when(this._sendRequest(url, httpMethod, escapeServiceOperationParams(params, this.version()), payload)).done(function(r) {                        if ($.isPlainObject(r) && operationName in r)                            r = r[operationName];                        d.resolve(r)                    }).fail([this._errorHandler, data._errorHandler, d.reject]);                    return d.promise()                },                objectLink: function(entityAlias, key) {                    var store = this[entityAlias];                    if (!store)                        throw DX.Error("E4015", entityAlias);                    if (!utils.isDefined(key))                        return null;                    return {__metadata: {uri: store._byKeyUrl(key, true)}}                }            }).include(SharedMethods);        $.extend(data, {            ODataStore: ODataStore,            ODataContext: ODataContext        })    })(jQuery, DevExpress);    /*! Module core, file data.store.custom.js */    (function($, DX, undefined) {        var data = DX.data;        var TOTAL_COUNT = "totalCount",            LOAD = "load",            BY_KEY = "byKey",            INSERT = "insert",            UPDATE = "update",            REMOVE = "remove";        function isPromise(obj) {            return obj && $.isFunction(obj.then)        }        function trivialPromise(value) {            return $.Deferred().resolve(value).promise()        }        function ensureRequiredFuncOption(name, obj) {            if (!$.isFunction(obj))                throw DX.Error("E4011", name);        }        function throwInvalidUserFuncResult(name) {            throw DX.Error("E4012", name);        }        function createUserFuncFailureHandler(pendingDeferred) {            function errorMessageFromXhr(promiseArguments) {                var xhr = promiseArguments[0],                    textStatus = promiseArguments[1];                if (!xhr || !xhr.getResponseHeader)                    return null;                return data.utils.errorMessageFromXhr(xhr, textStatus)            }            return function(arg) {                    var error;                    if (arg instanceof Error)                        error = arg;                    else                        error = new Error(errorMessageFromXhr(arguments) || arg && String(arg) || "Unknown error");                    pendingDeferred.reject(error)                }        }        data.CustomStore = data.Store.inherit({            ctor: function(options) {                options = options || {};                this.callBase(options);                this._useDefaultSearch = false;                this._loadFunc = options[LOAD];                this._totalCountFunc = options[TOTAL_COUNT];                this._byKeyFunc = options[BY_KEY];                this._insertFunc = options[INSERT];                this._updateFunc = options[UPDATE];                this._removeFunc = options[REMOVE]            },            createQuery: function() {                throw DX.Error("E4010");            },            _totalCountImpl: function(options) {                var userFunc = this._totalCountFunc,                    userResult,                    d = $.Deferred();                ensureRequiredFuncOption(TOTAL_COUNT, userFunc);                userResult = userFunc(options);                if (!isPromise(userResult)) {                    userResult = Number(userResult);                    if (!isFinite(userResult))                        throwInvalidUserFuncResult(TOTAL_COUNT);                    userResult = trivialPromise(userResult)                }                userResult.then(function(count) {                    d.resolve(Number(count))                }, createUserFuncFailureHandler(d));                return d.promise()            },            _loadImpl: function(options) {                var userFunc = this._loadFunc,                    userResult,                    d = $.Deferred();                ensureRequiredFuncOption(LOAD, userFunc);                userResult = userFunc(options);                if ($.isArray(userResult))                    userResult = trivialPromise(userResult);                else if (userResult === null || userResult === undefined)                    userResult = trivialPromise([]);                else if (!isPromise(userResult))                    throwInvalidUserFuncResult(LOAD);                userResult.then(function(data, extra) {                    d.resolve(data, extra)                }, createUserFuncFailureHandler(d));                return this._addFailHandlers(d.promise())            },            _byKeyImpl: function(key, extraOptions) {                var userFunc = this._byKeyFunc,                    userResult,                    d = $.Deferred();                ensureRequiredFuncOption(BY_KEY, userFunc);                userResult = userFunc(key, extraOptions);                if (!isPromise(userResult))                    userResult = trivialPromise(userResult);                userResult.then(function(obj) {                    d.resolve(obj)                }, createUserFuncFailureHandler(d));                return d.promise()            },            _insertImpl: function(values) {                var userFunc = this._insertFunc,                    userResult,                    d = $.Deferred();                ensureRequiredFuncOption(INSERT, userFunc);                userResult = userFunc(values);                if (!isPromise(userResult))                    userResult = trivialPromise(userResult);                userResult.then(function(newKey) {                    d.resolve(values, newKey)                }, createUserFuncFailureHandler(d));                return d.promise()            },            _updateImpl: function(key, values) {                var userFunc = this._updateFunc,                    userResult,                    d = $.Deferred();                ensureRequiredFuncOption(UPDATE, userFunc);                userResult = userFunc(key, values);                if (!isPromise(userResult))                    userResult = trivialPromise();                userResult.then(function() {                    d.resolve(key, values)                }, createUserFuncFailureHandler(d));                return d.promise()            },            _removeImpl: function(key) {                var userFunc = this._removeFunc,                    userResult,                    d = $.Deferred();                ensureRequiredFuncOption(REMOVE, userFunc);                userResult = userFunc(key);                if (!isPromise(userResult))                    userResult = trivialPromise();                userResult.then(function() {                    d.resolve(key)                }, createUserFuncFailureHandler(d));                return d.promise()            }        })    })(jQuery, DevExpress);    /*! Module core, file data.dataSource.js */    (function($, DX, undefined) {        var data = DX.data,            CustomStore = data.CustomStore,            Class = DX.Class;        var storeTypeRegistry = {                jaydata: "JayDataStore",                breeze: "BreezeStore",                odata: "ODataStore",                local: "LocalStore",                array: "ArrayStore"            };        var nextLoadOperationId = function() {                var id = -1;                return function() {                        return ++id                    }            }();        var canceledOperationsRegistry = function() {                var registry = {};                return {                        add: function(operationId) {                            registry[operationId] = true                        },                        has: function(operationId) {                            return operationId in registry                        },                        remove: function(operationId) {                            delete registry[operationId]                        }                    }            }();        var ensureIsNotRejected = function(loadOperationId, pendingDeferred) {                if (canceledOperationsRegistry.has(loadOperationId)) {                    canceledOperationsRegistry.remove(loadOperationId);                    pendingDeferred.reject("canceled");                    return false                }                return true            };        function normalizeDataSourceOptions(options) {            var store;            function createCustomStoreFromLoadFunc() {                var storeConfig = {};                $.each(["key", "load", "byKey", "lookup", "totalCount", "insert", "update", "remove"], function() {                    storeConfig[this] = options[this];                    delete options[this]                });                return new CustomStore(storeConfig)            }            function createStoreFromConfig(storeConfig) {                var storeCtor = data[storeTypeRegistry[storeConfig.type]];                delete storeConfig.type;                return new storeCtor(storeConfig)            }            function createCustomStoreFromUrl(url) {                return new CustomStore({load: function() {                            return $.getJSON(url)                        }})            }            if (typeof options === "string")                options = createCustomStoreFromUrl(options);            if (options === undefined)                options = [];            if ($.isArray(options) || options instanceof data.Store)                options = {store: options};            else                options = $.extend({}, options);            if (options.store === undefined)                options.store = [];            store = options.store;            if ("load" in options)                store = createCustomStoreFromLoadFunc();            else if ($.isArray(store))                store = new data.ArrayStore(store);            else if ($.isPlainObject(store))                store = createStoreFromConfig($.extend({}, store));            options.store = store;            return options        }        function normalizeStoreLoadOptionAccessorArguments(originalArguments) {            switch (originalArguments.length) {                case 0:                    return undefined;                case 1:                    return originalArguments[0]            }            return $.makeArray(originalArguments)        }        function generateStoreLoadOptionAccessor(optionName) {            return function() {                    var args = normalizeStoreLoadOptionAccessorArguments(arguments);                    if (args !== undefined)                        this._storeLoadOptions[optionName] = args;                    return this._storeLoadOptions[optionName]                }        }        function mapDataRespectingGrouping(items, mapper, groupInfo) {            function mapRecursive(items, level) {                if (!DX.utils.isArray(items))                    return items;                return level ? mapGroup(items, level) : $.map(items, mapper)            }            function mapGroup(group, level) {                return $.map(group, function(item) {                        var result = {                                key: item.key,                                items: mapRecursive(item.items, level - 1)                            };                        if ("aggregates" in item)                            result.aggregates = item.aggregates;                        return result                    })            }            return mapRecursive(items, groupInfo ? data.utils.normalizeSortingInfo(groupInfo).length : 0)        }        var DataSource = Class.inherit({                ctor: function(options) {                    options = normalizeDataSourceOptions(options);                    this._store = options.store;                    this._storeLoadOptions = this._extractLoadOptions(options);                    this._mapFunc = options.map;                    this._postProcessFunc = options.postProcess;                    this._pageIndex = options.pageIndex !== undefined ? options.pageIndex : 0;                    this._pageSize = options.pageSize !== undefined ? options.pageSize : 20;                    this._items = [];                    this._totalCount = -1;                    this._isLoaded = false;                    this._loadingCount = 0;                    this._loadQueue = this._createLoadQueue();                    this._searchValue = "searchValue" in options ? options.searchValue : null;                    this._searchOperation = options.searchOperation || "contains";                    this._searchExpr = options.searchExpr;                    this._paginate = options.paginate;                    if (this._paginate === undefined)                        this._paginate = !this.group();                    this._isLastPage = !this._paginate;                    this._userData = {};                    $.each(["changed", "loadError", "loadingChanged"], $.proxy(function(_, eventName) {                        var callbacks = this[eventName] = $.Callbacks();                        var originalAdd = callbacks.add;                        callbacks.add = function() {                            DX.log("W0003", "DataSource", eventName, "14.2", "Use the '" + eventName + "' event instead");                            return originalAdd.apply(eventName, arguments)                        }                    }, this));                    $.each(["changed", "loadError", "loadingChanged", "customizeLoadResult", "customizeStoreLoadOptions"], $.proxy(function(_, eventName) {                        var optionName = "on" + eventName[0].toUpperCase() + eventName.slice(1);                        if (options.hasOwnProperty(optionName))                            this.on(eventName, options[optionName])                    }, this))                },                dispose: function() {                    this.changed.empty();                    this.loadError.empty();                    this.loadingChanged.empty();                    this._disposeEvents();                    delete this._store;                    if (this._delayedLoadTask)                        this._delayedLoadTask.abort();                    this._disposed = true                },                _extractLoadOptions: function(options) {                    var result = {},                        names = ["sort", "filter", "select", "group", "requireTotalCount"],                        customNames = this._store._customLoadOptions();                    if (customNames)                        names = names.concat(customNames);                    $.each(names, function() {                        result[this] = options[this]                    });                    return result                },                loadOptions: function() {                    return this._storeLoadOptions                },                items: function() {                    return this._items                },                pageIndex: function(newIndex) {                    if (newIndex !== undefined) {                        this._pageIndex = newIndex;                        this._isLastPage = !this._paginate                    }                    return this._pageIndex                },                paginate: function(value) {                    if (arguments.length < 1)                        return this._paginate;                    value = !!value;                    if (this._paginate !== value) {                        this._paginate = value;                        this.pageIndex(0)                    }                },                pageSize: function(value) {                    if (arguments.length < 1)                        return this._pageSize;                    this._pageSize = value                },                isLastPage: function() {                    return this._isLastPage                },                sort: generateStoreLoadOptionAccessor("sort"),                filter: function() {                    var newFilter = normalizeStoreLoadOptionAccessorArguments(arguments);                    if (newFilter !== undefined) {                        this._storeLoadOptions.filter = newFilter;                        this.pageIndex(0)                    }                    return this._storeLoadOptions.filter                },                group: generateStoreLoadOptionAccessor("group"),                select: generateStoreLoadOptionAccessor("select"),                requireTotalCount: generateStoreLoadOptionAccessor("requireTotalCount"),                searchValue: function(value) {                    if (value !== undefined) {                        this.pageIndex(0);                        this._searchValue = value                    }                    return this._searchValue                },                searchOperation: function(op) {                    if (op !== undefined) {                        this.pageIndex(0);                        this._searchOperation = op                    }                    return this._searchOperation                },                searchExpr: function(expr) {                    var argc = arguments.length;                    if (argc) {                        if (argc > 1)                            expr = $.makeArray(arguments);                        this.pageIndex(0);                        this._searchExpr = expr                    }                    return this._searchExpr                },                store: function() {                    return this._store                },                key: function() {                    return this._store && this._store.key()                },                totalCount: function() {                    return this._totalCount                },                isLoaded: function() {                    return this._isLoaded                },                isLoading: function() {                    return this._loadingCount > 0                },                _createLoadQueue: function() {                    return DX.createQueue()                },                _changeLoadingCount: function(increment) {                    var oldLoading = this.isLoading(),                        newLoading;                    this._loadingCount += increment;                    newLoading = this.isLoading();                    if (oldLoading ^ newLoading) {                        this.fireEvent("loadingChanged", [newLoading]);                        this.loadingChanged.fire(newLoading)                    }                },                _scheduleLoadCallbacks: function(deferred) {                    var that = this;                    that._changeLoadingCount(1);                    deferred.always(function() {                        that._changeLoadingCount(-1)                    })                },                _scheduleChangedCallbacks: function(deferred) {                    var that = this;                    deferred.done(function() {                        that.fireEvent("changed");                        that.changed.fire()                    })                },                loadSingle: function(propName, propValue) {                    var that = this;                    var d = $.Deferred().fail(function() {                            that.fireEvent("loadError", arguments);                            that.loadError.fire.apply(that, arguments)                        }),                        key = this.key(),                        store = this._store,                        loadOptions = this._createStoreLoadOptions();                    function handleSuccess(data) {                        if (data === null || typeof data === "undefined" || $.isArray(data) && data.length < 1)                            d.reject();                        else                            d.resolve(that._transformLoadedData(data)[0])                    }                    if (arguments.length < 2) {                        propValue = propName;                        propName = key                    }                    delete loadOptions.skip;                    delete loadOptions.group;                    delete loadOptions.refresh;                    delete loadOptions.pageIndex;                    delete loadOptions.searchString;                    if (propName === key || store instanceof data.CustomStore)                        store.byKey(propValue, loadOptions).done(handleSuccess).fail(d.reject);                    else {                        loadOptions.take = 1;                        loadOptions.filter = loadOptions.filter ? [loadOptions.filter, [propName, propValue]] : [propName, propValue];                        store.load(loadOptions).done(handleSuccess).fail(d.reject)                    }                    return d.promise()                },                load: function() {                    var that = this,                        d = $.Deferred(),                        loadOptions;                    this._scheduleLoadCallbacks(d);                    this._scheduleChangedCallbacks(d);                    loadOptions = this._createLoadOptions();                    this.fireEvent("customizeStoreLoadOptions", [loadOptions]);                    if (!ensureIsNotRejected(loadOptions.operationId, d))                        return d.promise();                    function errorCallback() {                        if (arguments[0] !== "canceled") {                            that.fireEvent("loadError", arguments);                            that.loadError.fire.apply(that.loadError, arguments)                        }                    }                    function loadTask() {                        if (that._disposed)                            return undefined;                        return that._loadFromStore(loadOptions, d)                    }                    this._loadQueue.add(function() {                        if (typeof loadOptions.delay === "number")                            that._delayedLoadTask = DX.utils.executeAsync(loadTask, loadOptions.delay);                        else                            loadTask();                        return d.promise()                    });                    return d.promise({loadOperationId: loadOptions.operationId}).fail(errorCallback)                },                reload: function() {                    var prop,                        userData = this._userData;                    for (prop in userData)                        if (userData.hasOwnProperty(prop))                            delete userData[prop];                    this._totalCount = -1;                    this._isLoaded = false;                    return this.load()                },                cancel: function(loadOperationId) {                    canceledOperationsRegistry.add(loadOperationId)                },                _addSearchOptions: function(storeLoadOptions) {                    if (this._disposed)                        return;                    if (this.store()._useDefaultSearch)                        this._addSearchFilter(storeLoadOptions);                    else {                        storeLoadOptions.searchOperation = this._searchOperation;                        storeLoadOptions.searchValue = this._searchValue;                        storeLoadOptions.searchExpr = this._searchExpr                    }                },                _createStoreLoadOptions: function() {                    var result = $.extend({}, this._storeLoadOptions);                    this._addSearchOptions(result);                    if (this._paginate)                        if (this._pageSize) {                            result.skip = this._pageIndex * this._pageSize;                            result.take = this._pageSize                        }                    result.userData = this._userData;                    return result                },                _createLoadOptions: function() {                    return {                            operationId: nextLoadOperationId(),                            storeLoadOptions: this._createStoreLoadOptions()                        }                },                _addSearchFilter: function(storeLoadOptions) {                    var value = this._searchValue,                        op = this._searchOperation,                        selector = this._searchExpr,                        searchFilter = [];                    if (!value)                        return;                    if (!selector)                        selector = "this";                    if (!$.isArray(selector))                        selector = [selector];                    $.each(selector, function(i, item) {                        if (searchFilter.length)                            searchFilter.push("or");                        searchFilter.push([item, op, value])                    });                    if (storeLoadOptions.filter)                        storeLoadOptions.filter = [searchFilter, storeLoadOptions.filter];                    else                        storeLoadOptions.filter = searchFilter                },                _loadFromStore: function(loadOptions, pendingDeferred) {                    var that = this;                    function handleSuccess(data, extra) {                        function processResult() {                            var loadResult;                            loadResult = $.extend({                                data: data,                                extra: extra                            }, loadOptions);                            that.fireEvent("customizeLoadResult", [loadResult]);                            if (ensureIsNotRejected(loadOptions.operationId, pendingDeferred))                                that._processStoreLoadResult(loadResult, pendingDeferred)                        }                        if (that._disposed)                            return;                        processResult()                    }                    if (!ensureIsNotRejected(loadOptions.operationId, pendingDeferred))                        return pendingDeferred.promise();                    return this.store().load(loadOptions.storeLoadOptions).done(handleSuccess).fail(pendingDeferred.reject)                },                _processStoreLoadResult: function(loadResult, pendingDeferred) {                    var that = this;                    var data = loadResult.data,                        extra = loadResult.extra,                        storeLoadOptions = loadResult.storeLoadOptions;                    function resolvePendingDeferred() {                        if (!ensureIsNotRejected(loadResult.operationId, pendingDeferred))                            return pendingDeferred;                        that._isLoaded = true;                        that._totalCount = isFinite(extra.totalCount) ? extra.totalCount : -1;                        return pendingDeferred.resolve(data, extra)                    }                    function proceedLoadingTotalCount() {                        that.store().totalCount(storeLoadOptions).done(function(count) {                            extra.totalCount = count;                            resolvePendingDeferred()                        }).fail(function(){})                    }                    if (that._disposed)                        return;                    data = that._transformLoadedData(data);                    if (!$.isPlainObject(extra))                        extra = {};                    that._items = data;                    if (!data.length || !that._paginate || that._pageSize && data.length < that._pageSize)                        that._isLastPage = true;                    if (storeLoadOptions.requireTotalCount && !isFinite(extra.totalCount))                        proceedLoadingTotalCount();                    else                        resolvePendingDeferred()                },                _transformLoadedData: function(data) {                    var result = $.makeArray(data);                    if (this._mapFunc)                        result = mapDataRespectingGrouping(result, this._mapFunc, this.group());                    if (this._postProcessFunc)                        result = this._postProcessFunc(result);                    return result                }            }).include(DX.EventsMixin);        $.extend(true, data, {            DataSource: DataSource,            utils: {                storeTypeRegistry: storeTypeRegistry,                normalizeDataSourceOptions: normalizeDataSourceOptions            }        })    })(jQuery, DevExpress);    /*! Module core, file ko.js */    (function($, DX) {        if (DX.support.hasKo && DX.compareVersions(ko.version, [2, 3]) < 0)            throw DX.Error("E0013");    })(jQuery, DevExpress);    /*! Module core, file ng.js */    (function($, DX, undefined) {        if (!DX.support.hasNg)            return;        DX.ng = {module: window.angular.module("dx", ["ngSanitize"])}    })(jQuery, DevExpress);    /*! Module core, file component.js */    (function($, DX, undefined) {        var utils = DX.utils,            dataUtils = DX.data.utils,            inflector = DX.inflector;        var Component = DX.Class.inherit({                NAME: "Component",                _setDeprecatedOptions: function() {                    this._deprecatedOptions = {}                },                _getDeprecatedOptions: function() {                    return this._deprecatedOptions                },                _setOptionAliases: function() {                    var aliases = this._optionAliases = {};                    $.each(this._getDeprecatedOptions(), function(optionName, info) {                        var optionAlias = info.alias;                        if (optionAlias)                            aliases[optionName] = optionAlias                    })                },                _getOptionAliases: function() {                    return this._optionAliases                },                _getOptionAliasesByName: function(optionName) {                    return $.map(this._getOptionAliases(), function(aliasedOption, aliasName) {                            return optionName === aliasedOption ? aliasName : undefined                        })                },                _setDefaultOptions: function() {                    this.option({                        onInitialized: null,                        onOptionChanged: null,                        onDisposing: null,                        defaultOptionsRules: null                    })                },                _defaultOptionsRules: function() {                    return []                },                _setOptionsByDevice: function(userRules) {                    var rules = this._defaultOptionsRules();                    if (this._customRules)                        rules = rules.concat(this._customRules);                    if ($.isArray(userRules))                        rules = rules.concat(userRules);                    this.option(this._convertRulesToOptions(rules))                },                _convertRulesToOptions: function(rules) {                    var options = {};                    var currentDevice = DX.devices.current();                    var deviceMatch = function(device, filter) {                            filter = $.makeArray(filter);                            return filter.length === 1 && $.isEmptyObject(filter[0]) || utils.findBestMatches(device, filter).length > 0                        };                    $.each(rules, function(index, rule) {                        var deviceFilter = rule.device || {},                            match;                        if ($.isFunction(deviceFilter))                            match = deviceFilter(currentDevice);                        else                            match = deviceMatch(currentDevice, deviceFilter);                        if (match)                            $.extend(options, rule.options)                    });                    return options                },                _isInitialOptionValue: function(name) {                    var isCustomOption = this._customRules && this._convertRulesToOptions(this._customRules).hasOwnProperty(name);                    var isInitialOption = this.option(name) === this._initialOptions[name];                    return !isCustomOption && isInitialOption                },                _setOptionsByReference: function() {                    this._optionsByReference = {}                },                _getOptionsByReference: function() {                    return this._optionsByReference                },                ctor: function(options) {                    if (!this.NAME)                        throw DX.Error("E0004");                    options = options || {};                    this._options = {};                    this._cachedGetters = {};                    this._updateLockCount = 0;                    this._optionChangedCallbacks = options._optionChangedCallbacks || $.Callbacks();                    this._disposingCallbacks = options._disposingCallbacks || $.Callbacks();                    this.optionChanged = $.Callbacks();                    this.disposing = $.Callbacks();                    $.each(["optionChanged", "disposing"], $.proxy(function(_, propertyName) {                        var that = this,                            originalAdd = this[propertyName].add;                        this[propertyName].add = function() {                            DX.log("W0003", that.NAME, propertyName, "14.2", "Use the '" + propertyName + "' event instead");                            return originalAdd.apply(this, arguments)                        }                    }, this));                    this.beginUpdate();                    try {                        this._suppressDeprecatedWarnings();                        this._setOptionsByReference();                        this._setDeprecatedOptions();                        this._setOptionAliases();                        this._setDefaultOptions();                        this._setOptionsByDevice(options.defaultOptionsRules);                        this._resumeDeprecatedWarnings();                        this._initialOptions = $.extend({}, this.option());                        this._initOptions(options)                    }                    finally {                        this.endUpdate()                    }                },                _initOptions: function(options) {                    this.option(options)                },                _optionValuesEqual: function(name, oldValue, newValue) {                    oldValue = dataUtils.toComparable(oldValue, true);                    newValue = dataUtils.toComparable(newValue, true);                    if (oldValue && newValue && oldValue.jquery && newValue.jquery)                        return newValue.is(oldValue);                    var oldValueIsNaN = oldValue !== oldValue,                        newValueIsNaN = newValue !== newValue;                    if (oldValueIsNaN && newValueIsNaN)                        return true;                    if (oldValue === null || typeof oldValue !== "object")                        return oldValue === newValue;                    return false                },                _init: function() {                    this._createOptionChangedAction();                    this._createDisposingAction();                    this.on("optionChanged", function(args) {                        this._optionChangedCallbacks.fireWith(this, [args])                    });                    this.on("disposing", function(args) {                        this._disposingCallbacks.fireWith(this, [args])                    })                },                _createOptionChangedAction: function() {                    this._optionChangedAction = this._createActionByOption("onOptionChanged", {excludeValidators: ["disabled", "readOnly"]})                },                _createDisposingAction: function() {                    this._disposingAction = this._createActionByOption("onDisposing", {excludeValidators: ["disabled", "readOnly"]})                },                _optionChanged: function(args) {                    switch (args.name) {                        case"onInitialized":                            break;                        case"onOptionChanged":                            this._createOptionChangedAction();                            break;                        case"onDisposing":                            this._createDisposingAction();                            break;                        case"defaultOptionsRules":                            break                    }                },                _dispose: function() {                    this.optionChanged.empty();                    this.disposing.fireWith(this).empty();                    this._disposingAction();                    this._disposeEvents();                    this._disposed = true                },                instance: function() {                    return this                },                beginUpdate: function() {                    this._updateLockCount++                },                endUpdate: function() {                    this._updateLockCount--;                    if (!this._updateLockCount)                        if (!this._initializing && !this._initialized) {                            this._initializing = true;                            try {                                this._init()                            }                            finally {                                this._initializing = false;                                this._initialized = true;                                this._createActionByOption("onInitialized")()                            }                        }                },                _logWarningIfDeprecated: function(option) {                    var info = this._getDeprecatedOptions()[option];                    if (info && !this._deprecatedOptionsSuppressed)                        this._logDeprecatedWarning(option, info)                },                _logDeprecatedWarningCount: 0,                _logDeprecatedWarning: function(option, info) {                    var message = info.message || "Use the '" + info.alias + "' option instead";                    DX.log("W0001", this.NAME, option, info.since, message);                    ++this._logDeprecatedWarningCount                },                _suppressDeprecatedWarnings: function() {                    this._deprecatedOptionsSuppressed = true                },                _resumeDeprecatedWarnings: function() {                    this._deprecatedOptionsSuppressed = false                },                _notifyOptionChanged: function(option, value, previousValue) {                    var that = this;                    if (this._initialized)                        $.each(that._getOptionAliasesByName(option).concat([option]), function(index, name) {                            var args = {                                    name: name.split(/[.\[]/)[0],                                    fullName: name,                                    value: value,                                    previousValue: previousValue                                };                            that.optionChanged.fireWith(that, [args.name, value, previousValue]);                            that._optionChangedAction($.extend({}, args));                            if (!that._disposed)                                that._optionChanged(args)                        })                },                initialOption: function(optionName) {                    var options = this._initialOptions;                    return options[optionName]                },                _defaultActionConfig: function() {                    return {                            context: this,                            component: this                        }                },                _defaultActionArgs: function() {                    return {component: this}                },                _createAction: function(actionSource, config) {                    var that = this,                        action = new DX.Action(actionSource, $.extend(config, that._defaultActionConfig()));                    return function(e) {                            if (!arguments.length)                                e = {};                            if (e instanceof $.Event)                                throw Error("Action must be executed with jQuery.Event like action({ jQueryEvent: event })");                            if (!$.isPlainObject(e))                                e = {actionValue: e};                            return action.execute.call(action, $.extend(e, that._defaultActionArgs()))                        }                },                _createActionByOption: function(optionName, config) {                    config = config || {};                    if (typeof optionName !== "string")                        throw DX.Error("E0008");                    var matches = /^on(\w+)/.exec(optionName);                    if (matches) {                        var eventName = inflector.camelize(matches[1]),                            afterExecute = config.afterExecute || $.noop,                            that = this;                        config.afterExecute = function(args) {                            that.fireEvent(eventName, args.args);                            return afterExecute.apply(this, arguments)                        }                    }                    else {                        var optionAlias = this._getOptionAliasesByName(optionName),                            isOptionDeprecated = Boolean(this._getDeprecatedOptions()[optionName]);                        if (isOptionDeprecated) {                            if (optionAlias.length)                                throw Error("The '" + optionName + "' is deprecated and has alias '" + optionAlias + "'");                        }                        else                            throw Error("The '" + optionName + "' option name should start with 'on' prefix");                    }                    this._suppressDeprecatedWarnings();                    var action = this._createAction(this.option(optionName), config);                    this._resumeDeprecatedWarnings();                    return action                },                option: function(options) {                    var that = this,                        name = options,                        value = arguments[1],                        optionAliases = this._getOptionAliases();                    var normalizeOptionName = function(name) {                            if (name) {                                that._logWarningIfDeprecated(name);                                if (optionAliases[name])                                    name = optionAliases[name]                            }                            return name                        };                    var getOptionValue = function(name, unwrapObservables) {                            if (!that._cachedGetters[name])                                that._cachedGetters[name] = dataUtils.compileGetter(name);                            return that._cachedGetters[name](that._options, {                                    functionsAsIs: true,                                    unwrapObservables: unwrapObservables                                })                        };                    if (arguments.length < 2 && $.type(name) !== "object") {                        name = normalizeOptionName(name);                        return getOptionValue(name)                    }                    if (typeof name === "string") {                        options = {};                        options[name] = value                    }                    that.beginUpdate();                    try {                        $.each(options, function(name, value) {                            name = normalizeOptionName(name);                            var prevValue = getOptionValue(name, false);                            if (that._optionValuesEqual(name, prevValue, value))                                return;                            dataUtils.compileSetter(name)(that._options, value, {                                functionsAsIs: true,                                merge: !that._getOptionsByReference()[name],                                unwrapObservables: false                            });                            that._notifyOptionChanged(name, value, prevValue)                        })                    }                    finally {                        that.endUpdate()                    }                }            }).include(DX.EventsMixin);        $.extend(DX, {Component: Component})    })(jQuery, DevExpress);    /*! Module core, file transitionExecutor.js */    (function($, DX) {        var directionPostfixes = {                forward: " dx-forward",                backward: " dx-backward",                none: " dx-no-direction",                undefined: " dx-no-direction"            };        var addToAnimate = function(targetArray, $elements, animationConfig, type) {                $elements.each(function() {                    var resultAnimationConfig = prepareElementAnimationConfig(animationConfig, type);                    if (resultAnimationConfig)                        targetArray.push({                            $element: $(this),                            animationConfig: resultAnimationConfig                        })                })            };        var prepareElementAnimationConfig = function(config, type) {                var result;                if (typeof config === "string") {                    var presetName = config;                    config = DX.animationPresets.getPreset(presetName)                }                if (!config)                    result = undefined;                else if ($.isFunction(config[type]))                    result = config[type];                else {                    var cssClass = "dx-" + type;                    result = $.extend({skipElementInitialStyles: true}, config);                    if (!result.type || result.type === "css") {                        var extraCssClasses = result.extraCssClasses ? " " + result.extraCssClasses : "";                        result.type = "css";                        result.from = result.from || cssClass + extraCssClasses;                        result.to = result.to || cssClass + "-active"                    }                }                return result            };        var setupAnimations = function(items, config) {                var result = [];                $.each(items, function(index, item) {                    var animationConfig = item.animationConfig,                        $element = item.$element,                        animationInstance;                    if ($.isPlainObject(animationConfig)) {                        var fxConfig = getFXConfig(animationConfig, config);                        fxConfig.staggerDelay = fxConfig.staggerDelay || 0;                        fxConfig.delay = index * fxConfig.staggerDelay + fxConfig.delay;                        animationInstance = DX.fx.createAnimation($element, fxConfig)                    }                    else if ($.isFunction(animationConfig))                        animationInstance = animationConfig($element, config);                    animationInstance.setup();                    result.push({                        $element: $element,                        animationInstance: animationInstance                    })                });                return result            };        var startAnimations = function(items) {                for (var i = 0; i < items.length; i++)                    items[i].animationInstance.start()            };        var getFXConfig = function(animation, config) {                var result = animation;                result.cleanupWhen = config.cleanupWhen;                result.delay = result.delay || 0;                if (result.type === "css") {                    var direction = animation.direction || config.direction,                        directionPostfix = directionPostfixes[direction];                    result.from += directionPostfix                }                return result            };        var TransitionExecutor = DevExpress.Class.inherit({                ctor: function() {                    this.toEnterItems = [];                    this.toLeaveItems = [];                    this.reset()                },                reset: function() {                    this.toEnterItems.length = 0;                    this.toLeaveItems.length = 0                },                enter: function($elements, animation) {                    animation = animation || {};                    addToAnimate(this.toEnterItems, $elements, animation, "enter")                },                leave: function($elements, animation) {                    animation = animation || {};                    addToAnimate(this.toLeaveItems, $elements, animation, "leave")                },                start: function(config) {                    config = $.extend({}, config);                    var that = this,                        result;                    if (!this.toEnterItems.length && !this.toLeaveItems.length) {                        that.reset();                        result = $.Deferred().resolve().promise()                    }                    else {                        var animationItems = [],                            animationDeferreds,                            completeDeferred = $.Deferred();                        config.cleanupWhen = completeDeferred.promise();                        animationItems.push.apply(animationItems, setupAnimations(this.toEnterItems, config));                        animationItems.push.apply(animationItems, setupAnimations(this.toLeaveItems, config));                        animationDeferreds = $.map(animationItems, function(item) {                            return item.animationInstance.deferred                        });                        result = $.when.apply($, animationDeferreds).always(function() {                            completeDeferred.resolve();                            that.reset()                        });                        DX.utils.executeAsync(function() {                            startAnimations(animationItems)                        })                    }                    return result                }            });        var optionPrefix = "preset_";        var AnimationPresetCollection = DevExpress.Component.inherit({                ctor: function() {                    this.callBase.apply(this, arguments);                    this._customRules = [];                    this._registeredPresets = [];                    this.resetToDefaults()                },                _setDefaultOptions: function() {                    this.callBase();                    this.option({                        defaultAnimationDuration: 400,                        defaultAnimationDelay: 0,                        defaultStaggerAnimationDuration: 300,                        defaultStaggerAnimationDelay: 40,                        defaultStaggerAnimationStartDelay: 500                    })                },                _defaultOptionsRules: function() {                    return this.callBase().concat([{                                device: function(device) {                                    return device.phone                                },                                options: {                                    defaultStaggerAnimationDuration: 350,                                    defaultStaggerAnimationDelay: 50,                                    defaultStaggerAnimationStartDelay: 0                                }                            }, {                                device: function(device) {                                    return device.android                                },                                options: {defaultAnimationDelay: 100}                            }])                },                _getPresetOptionName: function(animationName) {                    return optionPrefix + animationName                },                resetToDefaults: function() {                    this.clear();                    this.registerDefaultPresets();                    this.applyChanges()                },                clear: function(name) {                    var that = this,                        newRegisteredPresets = [];                    $.each(this._registeredPresets, function(index, preset) {                        if (!name || name === preset.name)                            that.option(that._getPresetOptionName(preset.name), undefined);                        else                            newRegisteredPresets.push(preset)                    });                    this._registeredPresets = newRegisteredPresets;                    this.applyChanges()                },                registerPreset: function(name, config) {                    this._registeredPresets.push({                        name: name,                        config: config                    })                },                applyChanges: function() {                    var that = this;                    this._customRules.length = 0;                    $.each(this._registeredPresets, function(index, preset) {                        var rule = {                                device: preset.config.device,                                options: {}                            };                        rule.options[that._getPresetOptionName(preset.name)] = preset.config.animation;                        that._customRules.push(rule)                    });                    this._setOptionsByDevice()                },                getPreset: function(name) {                    var result = name;                    while (typeof result === "string")                        result = this.option(this._getPresetOptionName(result));                    return result                },                registerDefaultPresets: function() {                    this.registerPreset("fade", {animation: {                            extraCssClasses: "dx-fade-animation",                            delay: this.option("defaultAnimationDelay"),                            duration: this.option("defaultAnimationDuration")                        }});                    this.registerPreset("slide", {animation: {                            extraCssClasses: "dx-slide-animation",                            delay: this.option("defaultAnimationDelay"),                            duration: this.option("defaultAnimationDuration")                        }});                    this.registerPreset("ios7-slide", {animation: {                            extraCssClasses: "dx-ios7-slide-animation",                            delay: this.option("defaultAnimationDelay"),                            duration: this.option("defaultAnimationDuration")                        }});                    this.registerPreset("overflow", {animation: {                            extraCssClasses: "dx-overflow-animation",                            delay: this.option("defaultAnimationDelay"),                            duration: this.option("defaultAnimationDuration")                        }});                    this.registerPreset("ios7-toolbar", {animation: {                            extraCssClasses: "dx-ios7-toolbar-animation",                            delay: this.option("defaultAnimationDelay"),                            duration: this.option("defaultAnimationDuration")                        }});                    this.registerPreset("stagger-fade", {animation: {                            extraCssClasses: "dx-fade-animation",                            staggerDelay: this.option("defaultStaggerAnimationDelay"),                            duration: this.option("defaultStaggerAnimationDuration"),                            delay: this.option("defaultStaggerAnimationStartDelay")                        }});                    this.registerPreset("stagger-slide", {animation: {                            extraCssClasses: "dx-slide-animation",                            staggerDelay: this.option("defaultStaggerAnimationDelay"),                            duration: this.option("defaultStaggerAnimationDuration"),                            delay: this.option("defaultStaggerAnimationStartDelay")                        }});                    this.registerPreset("stagger-fade-slide", {animation: {                            extraCssClasses: "dx-fade-slide-animation",                            staggerDelay: this.option("defaultStaggerAnimationDelay"),                            duration: this.option("defaultStaggerAnimationDuration"),                            delay: this.option("defaultStaggerAnimationStartDelay")                        }});                    this.registerPreset("stagger-drop", {animation: {                            extraCssClasses: "dx-drop-animation",                            staggerDelay: this.option("defaultStaggerAnimationDelay"),                            duration: this.option("defaultStaggerAnimationDuration"),                            delay: this.option("defaultStaggerAnimationStartDelay")                        }});                    this.registerPreset("stagger-fade-drop", {animation: {                            extraCssClasses: "dx-fade-drop-animation",                            staggerDelay: this.option("defaultStaggerAnimationDelay"),                            duration: this.option("defaultStaggerAnimationDuration"),                            delay: this.option("defaultStaggerAnimationStartDelay")                        }});                    this.registerPreset("stagger-3d-drop", {animation: {                            extraCssClasses: "dx-3d-drop-animation",                            staggerDelay: this.option("defaultStaggerAnimationDelay"),                            duration: this.option("defaultStaggerAnimationDuration"),                            delay: this.option("defaultStaggerAnimationStartDelay")                        }});                    this.registerPreset("stagger-fade-zoom", {animation: {                            extraCssClasses: "dx-fade-zoom-animation",                            staggerDelay: this.option("defaultStaggerAnimationDelay"),                            duration: this.option("defaultStaggerAnimationDuration"),                            delay: this.option("defaultStaggerAnimationStartDelay")                        }})                }            });        DX.TransitionExecutor = TransitionExecutor;        DX.AnimationPresetCollection = AnimationPresetCollection;        DX.animationPresets = new AnimationPresetCollection    })(jQuery, DevExpress);    /*! Module core, file DOMComponent.js */    (function($, DX, undefined) {        var windowResizeCallbacks = DX.utils.windowResizeCallbacks;        var RTL_DIRECTION_CLASS = "dx-rtl",            COMPONENT_NAMES_DATA_KEY = "dxComponents",            VISIBILITY_CHANGE_CLASS = "dx-visibility-change-handler",            VISIBILITY_CHANGE_EVENTNAMESPACE = "dxVisibilityChange";        var DOMComponent = DX.Component.inherit({                NAME: "DOMComponent",                _setDefaultOptions: function() {                    this.callBase();                    this.option({                        width: undefined,                        height: undefined,                        rtlEnabled: DX.rtlEnabled                    })                },                ctor: function(element, options) {                    this._$element = $(element);                    this.element().data(this.NAME, this);                    this._attachInstanceToElement(this._$element);                    this.callBase(options)                },                _attachInstanceToElement: $.noop,                _visibilityChanged: DX.abstract,                _dimensionChanged: DX.abstract,                _init: function() {                    this.callBase();                    this._attachWindowResizeCallback()                },                _attachWindowResizeCallback: function() {                    if (this._isDimensionChangeSupported()) {                        var windowResizeCallBack = this._windowResizeCallBack = $.proxy(this._dimensionChanged, this);                        windowResizeCallbacks.add(windowResizeCallBack)                    }                },                _isDimensionChangeSupported: function() {                    return this._dimensionChanged !== DX.abstract                },                _render: function() {                    this._toggleRTLDirection(this.option("rtlEnabled"));                    this._renderVisibilityChange();                    this._renderDimensions()                },                _renderVisibilityChange: function() {                    if (!this._isVisibilityChangeSupported())                        return;                    this.element().addClass(VISIBILITY_CHANGE_CLASS);                    this._attachVisiblityChangeHandlers()                },                _renderDimensions: function() {                    var width = this.option("width"),                        height = this.option("height"),                        $element = this.element();                    $element.outerWidth(width);                    $element.outerHeight(height)                },                _attachVisiblityChangeHandlers: function() {                    var that = this;                    that.element().off("." + VISIBILITY_CHANGE_EVENTNAMESPACE).on("dxhiding." + VISIBILITY_CHANGE_EVENTNAMESPACE, function() {                        that._visibilityChanged(false)                    }).on("dxshown." + VISIBILITY_CHANGE_EVENTNAMESPACE, function() {                        that._visibilityChanged(true)                    })                },                _isVisibilityChangeSupported: function() {                    return this._visibilityChanged !== DX.abstract                },                _clean: $.noop,                _modelByElement: $.noop,                _invalidate: function() {                    if (!this._updateLockCount)                        throw DX.Error("E0007");                    this._requireRefresh = true                },                _refresh: function() {                    this._clean();                    this._render()                },                _dispose: function() {                    this.callBase();                    this._clean();                    this._detachWindowResizeCallback()                },                _detachWindowResizeCallback: function() {                    if (this._isDimensionChangeSupported())                        windowResizeCallbacks.remove(this._windowResizeCallBack)                },                _toggleRTLDirection: function(rtl) {                    this.element().toggleClass(RTL_DIRECTION_CLASS, rtl)                },                _createComponent: function(element, name, config) {                    config = config || {};                    this._extendConfig(config, {rtlEnabled: this.option("rtlEnabled")});                    var $element = $(element)[name](config);                    return $element[name]("instance")                },                _extendConfig: function(config, extendConfig) {                    $.each(extendConfig, function(key, value) {                        config[key] = config.hasOwnProperty(key) ? config[key] : value                    })                },                _defaultActionConfig: function() {                    return $.extend(this.callBase(), {context: this._modelByElement(this.element())})                },                _defaultActionArgs: function() {                    var element = this.element(),                        model = this._modelByElement(this.element());                    return $.extend(this.callBase(), {                            element: element,                            model: model                        })                },                _optionChanged: function(args) {                    switch (args.name) {                        case"width":                        case"height":                            this._renderDimensions();                            break;                        case"rtlEnabled":                            this._invalidate();                            break;                        default:                            this.callBase(args);                            break                    }                },                endUpdate: function() {                    var requireRender = !this._initializing && !this._initialized;                    this.callBase.apply(this, arguments);                    if (!this._updateLockCount)                        if (requireRender)                            this._render();                        else if (this._requireRefresh) {                            this._requireRefresh = false;                            this._refresh()                        }                },                element: function() {                    return this._$element                }            });        var registerComponent = function(name, namespace, componentClass) {                if (!componentClass) {                    componentClass = namespace;                    namespace = DX                }                componentClass.redefine({_attachInstanceToElement: function($element) {                        $element.data(name, this);                        if (!$element.data(COMPONENT_NAMES_DATA_KEY))                            $element.data(COMPONENT_NAMES_DATA_KEY, []);                        $element.data(COMPONENT_NAMES_DATA_KEY).push(name)                    }});                namespace[name] = componentClass;                componentClass.prototype.NAME = name;                componentClass.defaultOptions = function(rule) {                    componentClass.prototype._customRules = componentClass.prototype._customRules || [];                    componentClass.prototype._customRules.push(rule)                };                $.fn[name] = function(options) {                    var isMemberInvoke = typeof options === "string",                        result;                    if (isMemberInvoke) {                        var memberName = options,                            memberArgs = $.makeArray(arguments).slice(1);                        this.each(function() {                            var instance = $(this).data(name);                            if (!instance)                                throw DX.Error("E0009", name);                            var member = instance[memberName],                                memberValue = member.apply(instance, memberArgs);                            if (result === undefined)                                result = memberValue                        })                    }                    else {                        this.each(function() {                            var instance = $(this).data(name);                            if (instance)                                instance.option(options);                            else                                new componentClass(this, options)                        });                        result = this                    }                    return result                }            };        var getComponents = function(element) {                element = $(element);                var names = element.data(COMPONENT_NAMES_DATA_KEY);                if (!names)                    return [];                return $.map(names, function(name) {                        return element.data(name)                    })            };        var disposeComponents = function() {                $.each(getComponents(this), function() {                    this._dispose()                })            };        var originalCleanData = $.cleanData;        $.cleanData = function(element) {            $.each(element, disposeComponents);            return originalCleanData.apply(this, arguments)        };        registerComponent("DOMComponent", DOMComponent);        DX.registerComponent = registerComponent    })(jQuery, DevExpress);    /*! Module core, file ui.js */    (function($, DX, undefined) {        DX.ui = {};        var createValidatorByTargetElement = function(condition) {                return function(e) {                        if (!e.args.length)                            return;                        var args = e.args[0],                            element = args[e.validatingTargetName] || args.element;                        if (element && condition(element))                            e.cancel = true                    }            };        DX.registerActionExecutor({            designMode: {validate: function(e) {                    if (DX.designMode)                        e.cancel = true                }},            disabled: {validate: createValidatorByTargetElement(function($target) {                    return $target.is(".dx-state-disabled, .dx-state-disabled *")                })},            readOnly: {validate: createValidatorByTargetElement(function($target) {                    return $target.is(".dx-state-readonly, .dx-state-readonly *")                })}        })    })(jQuery, DevExpress);    /*! Module core, file ui.templates.js */    (function($, DX, undefined) {        var ui = DX.ui,            triggerShownEvent = DX.utils.triggerShownEvent;        var getWidgetName = function(widgetConstructor) {                return widgetConstructor.prototype.NAME            };        var TemplateProviderBase = DX.Class.inherit({                ctor: function() {                    this.widgetTemplatesCache = {}                },                createTemplate: DX.abstract,                getTemplates: function(widget) {                    return this._getWidgetTemplates(widget.constructor)                },                _getWidgetTemplates: function(widgetConstructor) {                    if (!getWidgetName(widgetConstructor))                        return {};                    return this._getCachedWidgetTemplates(widgetConstructor)                },                _getCachedWidgetTemplates: function(widgetConstructor) {                    var widgetName = getWidgetName(widgetConstructor),                        templatesCache = this.widgetTemplatesCache;                    if (!templatesCache[widgetName])                        templatesCache[widgetName] = $.extend({}, this._getWidgetTemplates(widgetConstructor.parent), this._templatesForWidget(widgetName));                    return templatesCache[widgetName]                },                _templatesForWidget: DX.abstract            });        var TemplateBase = DX.Class.inherit({                ctor: function(element, owner) {                    this._element = $(element);                    this._owner = owner                },                owner: function() {                    return this._owner                },                render: function(data, $container, index) {                    if (data instanceof jQuery) {                        $container = data;                        data = undefined                    }                    if ($container)                        data = this._prepareDataForContainer(data, $container);                    var $result = this._renderCore(data, index, $container);                    if (this._shouldAppend && $container) {                        $container.append($result);                        if ($.contains(document.body, $container.get(0)))                            triggerShownEvent($result)                    }                    return $result                },                source: function() {                    return this._element.clone()                },                _prepareDataForContainer: function(data) {                    return data                },                _renderCore: DX.abstract,                _shouldAppend: true,                dispose: function() {                    this._owner = null                }            });        $.extend(ui, {            TemplateProviderBase: TemplateProviderBase,            TemplateBase: TemplateBase        })    })(jQuery, DevExpress);    /*! Module core, file jquery.templates.js */    (function($, DX, undefined) {        var ui = DX.ui,            utils = DX.utils,            isString = DX.utils.isString,            currentTemplateEngine,            templateEngines = {};        var Template = ui.TemplateBase.inherit({                ctor: function(element, owner) {                    this.callBase(element, owner);                    this._compiledTemplate = currentTemplateEngine.compile(element)                },                _renderCore: function(data) {                    return $("<div>").append(currentTemplateEngine.render(this._compiledTemplate, data)).contents()                }            });        var setTemplateEngine = function(templateEngine) {                if (isString(templateEngine)) {                    currentTemplateEngine = templateEngines[templateEngine];                    if (!currentTemplateEngine)                        throw DX.Error("E0020", templateEngine);                }                else                    currentTemplateEngine = templateEngine            };        var registerTemplateEngine = function(name, templateEngine) {                templateEngines[name] = templateEngine            };        var outerHtml = function(element) {                element = $(element);                if (!element.length || element[0].nodeName.toLowerCase() !== "script")                    element = $("<div>").append(element);                return element.html()            };        registerTemplateEngine("default", {            compile: function(element) {                return DX.utils.normalizeTemplateElement(element)            },            render: function(template, data) {                return template.clone()            }        });        registerTemplateEngine("jquery-tmpl", {            compile: function(element) {                return $("<div>").append(DX.utils.normalizeTemplateElement(element))            },            render: function(template, data) {                return template.tmpl(data)            }        });        registerTemplateEngine("jsrender", {            compile: function(element) {                return $.templates(outerHtml(element))            },            render: function(template, data) {                return template.render(data)            }        });        registerTemplateEngine("mustache", {            compile: function(element) {                return Mustache.compile(outerHtml(element))            },            render: function(template, data) {                return template(data)            }        });        registerTemplateEngine("hogan", {            compile: function(element) {                return Hogan.compile(outerHtml(element))            },            render: function(template, data) {                return template.render(data)            }        });        registerTemplateEngine("underscore", {            compile: function(element) {                return _.template(outerHtml(element))            },            render: function(template, data) {                return template(data)            }        });        registerTemplateEngine("handlebars", {            compile: function(element) {                return Handlebars.compile(outerHtml(element))            },            render: function(template, data) {                return template(data)            }        });        registerTemplateEngine("doT", {            compile: function(element) {                return doT.template(outerHtml(element))            },            render: function(template, data) {                return template(data)            }        });        setTemplateEngine("default");        var DefaultTemplate = ui.TemplateBase.inherit({                ctor: function(render, owner) {                    this.callBase($("<div>"), owner);                    this._render = render                },                _renderCore: function(data, index, container) {                    return DX.utils.normalizeTemplateElement(this._render(data, index, container))                }            });        var TemplateProvider = new(ui.TemplateProviderBase.inherit({                createTemplate: function(element, owner) {                    return new ui.Template(element, owner)                },                _templatesForWidget: function(widgetName) {                    var templateGenerators = TEMPLATE_GENERATORS[widgetName] || {},                        templates = {};                    $.each(templateGenerators, function(name, generator) {                        templates[name] = new ui.DefaultTemplate(function() {                            var $markup = generator.apply(this, arguments);                            if (name !== "itemFrame")                                $markup = $markup.contents();                            return $markup                        }, TemplateProvider)                    });                    return templates                }            }));        var TEMPLATE_GENERATORS = {};        var emptyTemplate = function() {                return $()            };        var ITEM_CONTENT_PLACEHOLDER_CLASS = "dx-item-content-placeholder";        TEMPLATE_GENERATORS.CollectionWidget = {            item: function(itemData) {                var $itemContent = $("<div>");                if ($.isPlainObject(itemData)) {                    if (itemData.text)                        $itemContent.text(itemData.text);                    if (itemData.html)                        $itemContent.html(itemData.html)                }                else                    $itemContent.html(String(itemData));                return $itemContent            },            itemFrame: function(itemData) {                var $itemFrame = $("<div>");                $itemFrame.toggleClass("dx-state-invisible", itemData.visible !== undefined && !itemData.visible);                $itemFrame.toggleClass("dx-state-disabled", !!itemData.disabled);                var $placeholder = $("<div>").addClass(ITEM_CONTENT_PLACEHOLDER_CLASS);                $itemFrame.append($placeholder);                return $itemFrame            }        };        var BUTTON_TEXT_CLASS = "dx-button-text";        TEMPLATE_GENERATORS.dxButton = {content: function(itemData) {                var $itemContent = $("<div>"),                    $iconElement = utils.getImageContainer(itemData.icon),                    $textContainer = itemData.text ? $("<span>").text(itemData.text).addClass(BUTTON_TEXT_CLASS) : undefined;                $itemContent.append($iconElement).append($textContainer);                return $itemContent            }};        var LIST_ITEM_BADGE_CONTAINER_CLASS = "dx-list-item-badge-container",            LIST_ITEM_BADGE_CLASS = "dx-list-item-badge",            BADGE_CLASS = "dx-badge",            LIST_ITEM_CHEVRON_CONTAINER_CLASS = "dx-list-item-chevron-container",            LIST_ITEM_CHEVRON_CLASS = "dx-list-item-chevron";        TEMPLATE_GENERATORS.dxList = {            item: function(itemData) {                var $itemContent = TEMPLATE_GENERATORS.CollectionWidget.item(itemData);                if (itemData.key) {                    var $key = $("<div>").text(itemData.key);                    $key.appendTo($itemContent)                }                return $itemContent            },            itemFrame: function(itemData) {                var $itemFrame = TEMPLATE_GENERATORS.CollectionWidget.itemFrame(itemData);                if (itemData.badge) {                    var $badgeContainer = $("<div>").addClass(LIST_ITEM_BADGE_CONTAINER_CLASS),                        $badge = $("<div>").addClass(LIST_ITEM_BADGE_CLASS).addClass(BADGE_CLASS);                    $badge.text(itemData.badge);                    $badgeContainer.append($badge).appendTo($itemFrame)                }                if (itemData.showChevron) {                    var $chevronContainer = $("<div>").addClass(LIST_ITEM_CHEVRON_CONTAINER_CLASS),                        $chevron = $("<div>").addClass(LIST_ITEM_CHEVRON_CLASS);                    $chevronContainer.append($chevron).appendTo($itemFrame)                }                return $itemFrame            },            group: function(groupData) {                var $groupContent = $("<div>");                if ($.isPlainObject(groupData)) {                    if (groupData.key)                        $groupContent.text(groupData.key)                }                else                    $groupContent.html(String(groupData));                return $groupContent            }        };        TEMPLATE_GENERATORS.dxDropDownMenu = {item: TEMPLATE_GENERATORS.dxList.item};        TEMPLATE_GENERATORS.dxDropDownList = {item: TEMPLATE_GENERATORS.dxList.item};        TEMPLATE_GENERATORS.dxRadioGroup = {item: TEMPLATE_GENERATORS.CollectionWidget.item};        TEMPLATE_GENERATORS.dxScheduler = {item: function(itemData) {                var $itemContent = TEMPLATE_GENERATORS.CollectionWidget.item(itemData);                var $details = $("<div>").addClass("dx-scheduler-appointment-content-details");                if (itemData.startDate)                    $("<strong>").text(Globalize.format(DX.utils.makeDate(itemData.startDate), "t")).appendTo($details);                if (itemData.endDate)                    $("<strong>").text(" - " + Globalize.format(DX.utils.makeDate(itemData.endDate), "t")).appendTo($details);                $details.appendTo($itemContent);                if (itemData.recurrenceRule)                    $("<span>").addClass("dx-scheduler-appointment-recurrence-icon").appendTo($itemContent);                return $itemContent            }};        TEMPLATE_GENERATORS.dxOverlay = {content: emptyTemplate};        TEMPLATE_GENERATORS.dxSlideOutView = {            menu: emptyTemplate,            content: emptyTemplate        };        TEMPLATE_GENERATORS.dxSlideOut = {            menuItem: TEMPLATE_GENERATORS.dxList.item,            menuGroup: TEMPLATE_GENERATORS.dxList.group,            content: emptyTemplate        };        TEMPLATE_GENERATORS.dxAccordion = {            title: function(titleData) {                var $titleContent = $("<div>"),                    icon = titleData.icon,                    iconSrc = titleData.iconSrc,                    $iconElement = utils.getImageContainer(icon || iconSrc);                if ($.isPlainObject(titleData)) {                    if (titleData.title)                        $titleContent.text(titleData.title)                }                else                    $titleContent.html(String(titleData));                $iconElement && $iconElement.prependTo($titleContent);                return $titleContent            },            item: TEMPLATE_GENERATORS.CollectionWidget.item        };        TEMPLATE_GENERATORS.dxActionSheet = {item: function(itemData) {                return $("<div>").append($("<div>").dxButton($.extend({onClick: itemData.click}, itemData)))            }};        TEMPLATE_GENERATORS.dxGallery = {item: function(itemData) {                var $itemContent = $("<div>");                if (itemData.imageSrc)                    $('<img>').attr('src', itemData.imageSrc).appendTo($itemContent);                else                    $('<img>').attr('src', String(itemData)).appendTo($itemContent);                return $itemContent            }};        var DX_MENU_ITEM_CAPTION_CLASS = 'dx-menu-item-text',            DX_MENU_ITEM_POPOUT_CLASS = 'dx-menu-item-popout',            DX_MENU_ITEM_POPOUT_CONTAINER_CLASS = 'dx-menu-item-popout-container';        TEMPLATE_GENERATORS.dxMenuBase = {item: function(itemData) {                var $itemContent = $("<div>"),                    icon = itemData.icon,                    iconSrc = itemData.iconSrc,                    $iconElement = utils.getImageContainer(icon || iconSrc);                $iconElement && $iconElement.appendTo($itemContent);                var $itemCaption;                if ($.isPlainObject(itemData) && itemData.text)                    $itemCaption = $('<span>').addClass(DX_MENU_ITEM_CAPTION_CLASS).text(itemData.text);                else if (!$.isPlainObject(itemData))                    $itemCaption = $('<span>').addClass(DX_MENU_ITEM_CAPTION_CLASS).html(String(itemData));                $itemContent.append($itemCaption);                var $popOutImage,                    $popOutContainer;                if (itemData.items && itemData.items.length > 0) {                    $popOutContainer = $('<span>').addClass(DX_MENU_ITEM_POPOUT_CONTAINER_CLASS).appendTo($itemContent);                    $popOutImage = $('<div>').addClass(DX_MENU_ITEM_POPOUT_CLASS).appendTo($popOutContainer)                }                return $itemContent            }};        var PANORAMA_ITEM_TITLE_CLASS = "dx-panorama-item-title";        TEMPLATE_GENERATORS.dxPanorama = {itemFrame: function(itemData) {                var $itemContent = TEMPLATE_GENERATORS.CollectionWidget.itemFrame(itemData);                if (itemData.title) {                    var $itemHeader = $("<div>").addClass(PANORAMA_ITEM_TITLE_CLASS).text(itemData.title);                    $itemContent.prepend($itemHeader)                }                return $itemContent            }};        TEMPLATE_GENERATORS.dxPivotTabs = {item: function(itemData) {                var $itemContent = $("<div>");                var $itemText;                if ($.isPlainObject(itemData))                    $itemText = $("<span>").text(itemData.title);                else                    $itemText = $("<span>").text(String(itemData));                $itemContent.html($itemText);                return $itemContent            }};        TEMPLATE_GENERATORS.dxPivot = {            title: TEMPLATE_GENERATORS.dxPivotTabs.item,            content: emptyTemplate        };        var TABS_ITEM_TEXT_CLASS = "dx-tab-text";        TEMPLATE_GENERATORS.dxTabs = {            item: function(itemData) {                var $itemContent = TEMPLATE_GENERATORS.CollectionWidget.item(itemData);                if (itemData.html)                    return $itemContent;                var icon = itemData.icon,                    iconSrc = itemData.iconSrc,                    $iconElement = utils.getImageContainer(icon || iconSrc);                if (!itemData.html)                    $itemContent.wrapInner($("<span>").addClass(TABS_ITEM_TEXT_CLASS));                $iconElement && $iconElement.prependTo($itemContent);                return $itemContent            },            itemFrame: function(itemData) {                var $badge = $(),                    $itemFrame = TEMPLATE_GENERATORS.CollectionWidget.itemFrame(itemData);                if (itemData.badge)                    $badge = $("<div>", {"class": "dx-tabs-item-badge dx-badge"}).text(itemData.badge);                $itemFrame.append($badge);                return $itemFrame            }        };        TEMPLATE_GENERATORS.dxTabPanel = {            item: TEMPLATE_GENERATORS.CollectionWidget.item,            title: function(itemData) {                var itemTitleData = itemData;                if ($.isPlainObject(itemData))                    itemTitleData = $.extend({}, itemData, {text: itemData.title});                var $title = TEMPLATE_GENERATORS.dxTabs.item(itemTitleData);                return $title            }        };        var NAVBAR_ITEM_BADGE_CLASS = "dx-navbar-item-badge";        TEMPLATE_GENERATORS.dxNavBar = {itemFrame: function(itemData) {                var $itemFrame = TEMPLATE_GENERATORS.CollectionWidget.itemFrame(itemData);                if (itemData.badge) {                    var $badge = $("<div>").addClass(NAVBAR_ITEM_BADGE_CLASS).addClass(BADGE_CLASS);                    $badge.text(itemData.badge);                    $badge.appendTo($itemFrame)                }                return $itemFrame            }};        TEMPLATE_GENERATORS.dxToolbar = {            item: function(itemData) {                var $itemContent = TEMPLATE_GENERATORS.CollectionWidget.item(itemData);                var widget = itemData.widget;                if (widget) {                    var widgetElement = $("<div>").appendTo($itemContent),                        widgetName = DX.inflector.camelize("dx-" + widget),                        options = itemData.options || {};                    widgetElement[widgetName](options)                }                else if (itemData.text)                    $itemContent.wrapInner("<div>");                return $itemContent            },            menuItem: TEMPLATE_GENERATORS.dxList.item,            actionSheetItem: TEMPLATE_GENERATORS.dxActionSheet.item        };        TEMPLATE_GENERATORS.dxTreeView = {item: function(itemData) {                var $itemContent = $("<div>"),                    icon = itemData.icon,                    iconSrc = itemData.iconSrc,                    $iconElement = utils.getImageContainer(icon || iconSrc);                if (itemData.html)                    $itemContent.html(itemData.html);                else {                    $iconElement && $iconElement.appendTo($itemContent);                    $("<span>").text(itemData.text).appendTo($itemContent)                }                return $itemContent            }};        var popupTitleAndBottom = function(itemData) {                return $("<div>").append($("<div>").dxToolbar({items: itemData}))            };        TEMPLATE_GENERATORS.dxPopup = {            title: popupTitleAndBottom,            bottom: popupTitleAndBottom        };        TEMPLATE_GENERATORS.dxLookup = {            title: TEMPLATE_GENERATORS.dxPopup.title,            group: TEMPLATE_GENERATORS.dxList.group        };        TEMPLATE_GENERATORS.dxTagBox = {tag: function(itemData) {                return $("<div>").append($("<span>").text(itemData))            }};        TEMPLATE_GENERATORS.dxCalendar = {cell: function(itemData) {                return $("<div>").text(itemData.text || String(itemData))            }};        $.extend(ui, {            TemplateProvider: TemplateProvider,            Template: Template,            DefaultTemplate: DefaultTemplate,            setTemplateEngine: setTemplateEngine        })    })(jQuery, DevExpress);    /*! Module core, file ko.components.js */    (function($, DX, undefined) {        if (!DX.support.hasKo)            return;        var ko = window.ko,            ui = DX.ui,            LOCKS_DATA_KEY = "dxKoLocks",            CREATED_WITH_KO_DATA_KEY = "dxKoCreation";        var Locks = function() {                var info = {};                var currentCount = function(lockName) {                        return info[lockName] || 0                    };                return {                        obtain: function(lockName) {                            info[lockName] = currentCount(lockName) + 1                        },                        release: function(lockName) {                            var count = currentCount(lockName);                            if (count < 1)                                throw DX.Error("E0014");                            if (count === 1)                                delete info[lockName];                            else                                info[lockName] = count - 1                        },                        locked: function(lockName) {                            return currentCount(lockName) > 0                        }                    }            };        var editorsBingindHandlers = [];        var registerComponentKoBinding = function(componentName, componentClass) {                if (componentClass.subclassOf(ui.Editor))                    editorsBingindHandlers.push(componentName);                ko.bindingHandlers[componentName] = {init: function(domNode, valueAccessor) {                        var $element = $(domNode),                            optionChangedCallbacks = $.Callbacks(),                            ctorOptions = {                                templateProvider: ui.KoTemplateProvider,                                _optionChangedCallbacks: optionChangedCallbacks                            },                            optionNameToModelMap = {};                        var applyModelValueToOption = function(optionName, modelValue) {                                var component = $element.data(componentName),                                    locks = $element.data(LOCKS_DATA_KEY),                                    optionValue = ko.unwrap(modelValue);                                if (ko.isWriteableObservable(modelValue))                                    optionNameToModelMap[optionName] = modelValue;                                if (component) {                                    if (locks.locked(optionName))                                        return;                                    locks.obtain(optionName);                                    try {                                        component.option(optionName, optionValue)                                    }                                    finally {                                        locks.release(optionName)                                    }                                }                                else                                    ctorOptions[optionName] = optionValue                            };                        var handleOptionChanged = function(args) {                                var optionName = args.fullName,                                    optionValue = args.value;                                if (!(optionName in optionNameToModelMap))                                    return;                                var $element = this._$element,                                    locks = $element.data(LOCKS_DATA_KEY);                                if (locks.locked(optionName))                                    return;                                locks.obtain(optionName);                                try {                                    optionNameToModelMap[optionName](optionValue)                                }                                finally {                                    locks.release(optionName)                                }                            };                        var createComponent = function() {                                optionChangedCallbacks.add(handleOptionChanged);                                $element.data(CREATED_WITH_KO_DATA_KEY, true).data(LOCKS_DATA_KEY, new Locks)[componentName](ctorOptions);                                ctorOptions = null                            };                        var unwrapModelValue = function(option, model) {                                var modelUnwrapped;                                ko.computed(function() {                                    applyModelValueToOption(option, model);                                    modelUnwrapped = ko.unwrap(model)                                }, null, {disposeWhenNodeIsRemoved: domNode});                                if ($.isPlainObject(modelUnwrapped))                                    $.each(modelUnwrapped, function(optionName, modelValue) {                                        unwrapModelValue(option + "." + optionName, modelValue)                                    })                            };                        ko.computed(function() {                            var component = $element.data(componentName);                            if (component)                                component.beginUpdate();                            $.each(ko.unwrap(valueAccessor()), function(optionName, modelValue) {                                unwrapModelValue(optionName, modelValue)                            });                            if (component)                                component.endUpdate();                            else                                createComponent()                        }, null, {disposeWhenNodeIsRemoved: domNode});                        return {controlsDescendantBindings: componentClass.subclassOf(ui.Widget)}                    }};                if (componentName === "dxValidator")                    ko.bindingHandlers["dxValidator"].after = editorsBingindHandlers            };        DX.DOMComponent.redefine({_modelByElement: function(element) {                if (element.length)                    return ko.dataFor(element.get(0))            }});        var originalRegisterComponent = DX.registerComponent;        var registerKoComponent = function(componentName, _, componentClass) {                componentClass = componentClass || _;                originalRegisterComponent.apply(this, arguments);                registerComponentKoBinding(componentName, componentClass)            };        DX.registerComponent = registerKoComponent;        var cleanKoData = function(element, andSelf) {                var cleanNode = function() {                        ko.cleanNode(this)                    };                if (andSelf)                    element.each(cleanNode);                else                    element.find("*").each(cleanNode)            };        var originalEmpty = $.fn.empty;        $.fn.empty = function() {            cleanKoData(this, false);            return originalEmpty.apply(this, arguments)        };        var originalRemove = $.fn.remove;        $.fn.remove = function(selector, keepData) {            if (!keepData) {                var subject = this;                if (selector)                    subject = subject.filter(selector);                cleanKoData(subject, true)            }            return originalRemove.call(this, selector, keepData)        };        var originalHtml = $.fn.html;        $.fn.html = function(value) {            if (typeof value === "string")                cleanKoData(this, false);            return originalHtml.apply(this, arguments)        };        ko.bindingHandlers.dxAction = {update: function(element, valueAccessor, allBindingsAccessor, viewModel) {                var $element = $(element);                var unwrappedValue = ko.utils.unwrapObservable(valueAccessor()),                    actionSource = unwrappedValue,                    actionOptions = {context: element};                if (unwrappedValue.execute) {                    actionSource = unwrappedValue.execute;                    $.extend(actionOptions, unwrappedValue)                }                var action = new DX.Action(actionSource, actionOptions);                $element.off(".dxActionBinding").on("dxclick.dxActionBinding", function(e) {                    action.execute({                        element: $element,                        model: viewModel,                        evaluate: function(expression) {                            var context = viewModel;                            if (expression.length > 0 && expression[0] === "$")                                context = ko.contextFor(element);                            var getter = DX.data.utils.compileGetter(expression);                            return getter(context)                        },                        jQueryEvent: e                    });                    if (!actionOptions.bubbling)                        e.stopPropagation()                })            }};        ko.bindingHandlers.dxControlsDescendantBindings = {init: function(_, valueAccessor) {                return {controlsDescendantBindings: ko.unwrap(valueAccessor())}            }};        var render = function($element, options, viewModel, bindingContext) {                var result = $.Deferred();                $element.removeClass("dx-pending-rendering-manual");                $element.addClass("dx-pending-rendering-active");                if (options.showLoadIndicator && options.showLoadIndicatorImmediately !== true)                    showLoadIndicator($element);                DX.utils.executeAsync(function() {                    renderImpl($element, options, viewModel, bindingContext).done(function() {                        var shownArgs = {element: $element};                        if (options.onShown)                            options.onShown.apply(viewModel, [shownArgs]);                        result.resolve(shownArgs)                    }).fail(function() {                        result.rejectWith(result, arguments)                    })                });                return result.promise()            };        var showLoadIndicator = function($container) {                var $indicator = $('<div/>').dxLoadIndicator({visible: true}).addClass("dx-defered-rendering-load-indicator");                $container.append($indicator)            };        var isElementInViewport = function(element) {                var rect = element.getBoundingClientRect();                return rect.bottom >= 0 && rect.right >= 0 && rect.top <= (window.innerHeight || document.documentElement.clientHeight) && rect.left <= (window.innerWidth || document.documentElement.clientWidth)            };        var renderImpl = function($element, options, viewModel, bindingContext) {                var animatePromise,                    childBindingContext = bindingContext.createChildContext(viewModel),                    renderedArgs = {element: $element};                $element.find(".dx-defered-rendering-load-indicator").remove();                ko.applyBindingsToDescendants(childBindingContext, $element[0]);                options._renderedDeferred.resolve(renderedArgs);                if (options.onRendered)                    options.onRendered.apply(viewModel, [renderedArgs]);                $element.children().removeClass("dx-invisible-while-pending-rendering");                DX.utils.triggerShownEvent($element.children());                $element.removeClass("dx-pending-rendering");                $element.removeClass("dx-pending-rendering-active");                if (options.animation) {                    var transitionExecutor = new DX.TransitionExecutor;                    if (options.staggerItemSelector) {                        $element.find(options.staggerItemSelector).each(function() {                            if (isElementInViewport(this))                                transitionExecutor.enter($(this), options.animation)                        });                        animatePromise = $.when(animatePromise, transitionExecutor.start())                    }                    else {                        transitionExecutor.enter($element, options.animation || "content-rendered");                        animatePromise = transitionExecutor.start()                    }                }                else                    animatePromise = $.Deferred().resolve().promise();                return animatePromise            };        var initElement = function($element, options) {                $element.addClass("dx-defer-rendering dx-pending-rendering dx-loadindicator-container");                $element.data("dx-rendered-promise", options._renderedDeferred.promise());                if (options.hiddenUntilRendered)                    $element.children().addClass("dx-invisible-while-pending-rendering");                if (options.showLoadIndicator && options.showLoadIndicatorImmediately)                    showLoadIndicator($element)            };        var initRender = function($element, options, viewModel, bindingContext) {                var doRender = function() {                        return render($element, options, viewModel, bindingContext)                    };                if (options.renderWhen)                    options.renderWhen.done(doRender);                else {                    $element.data("dx-render-delegate", doRender);                    $element.addClass("dx-pending-rendering-manual")                }            };        ko.bindingHandlers.dxDeferRendering = {init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {                var $element = $(element),                    passedOptions = ko.unwrap(valueAccessor()),                    showLoadIndicatorImmediately = ko.unwrap(passedOptions.showLoadIndicatorImmediately),                    hiddenUntilRendered = ko.unwrap(passedOptions.hiddenUntilRendered),                    options = {                        showLoadIndicator: ko.unwrap(passedOptions.showLoadIndicator) || false,                        showLoadIndicatorImmediately: showLoadIndicatorImmediately !== undefined ? showLoadIndicatorImmediately : true,                        hiddenUntilRendered: hiddenUntilRendered !== undefined ? hiddenUntilRendered : true,                        renderWhen: ko.unwrap(passedOptions.renderWhen),                        animation: ko.unwrap(passedOptions.animation),                        staggerItemSelector: ko.unwrap(passedOptions.staggerItemSelector),                        onRendered: ko.unwrap(passedOptions.onRendered),                        onShown: ko.unwrap(passedOptions.onShown),                        _renderedDeferred: $.Deferred()                    };                initElement($element, options);                initRender($element, options, viewModel, bindingContext);                return {controlsDescendantBindings: true}            }};        ko.bindingHandlers.dxIcon = {            init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {                var options = ko.utils.unwrapObservable(valueAccessor()) || {},                    iconElement = DevExpress.utils.getImageContainer(options);                ko.virtualElements.emptyNode(element);                if (iconElement)                    ko.virtualElements.prepend(element, iconElement.get(0))            },            update: function(element, valueAccessor, allBindings, viewModel, bindingContext) {                var options = ko.utils.unwrapObservable(valueAccessor()) || {},                    iconElement = DevExpress.utils.getImageContainer(options);                ko.virtualElements.emptyNode(element);                if (iconElement)                    ko.virtualElements.prepend(element, iconElement.get(0))            }        };        ko.virtualElements.allowedBindings.dxIcon = true    })(jQuery, DevExpress);    /*! Module core, file ng.components.js */    (function($, DX, undefined) {        if (!DX.support.hasNg)            return;        var ui = DX.ui,            compileSetter = DX.data.utils.compileSetter,            compileGetter = DX.data.utils.compileGetter;        var ITEM_ALIAS_ATTRIBUTE_NAME = "dxItemAlias",            DEFAULT_MODEL_ALIAS = "scopeValue";        var SKIP_APPLY_ACTION_CATEGORIES = ["rendering"];        var phoneJsModule = DX.ng.module;        var safeApply = function(func, scope) {                if (scope.$root.$$phase)                    func(scope);                else                    scope.$apply(function() {                        func(scope)                    })            };        var ComponentBuilder = DX.Class.inherit({                ctor: function(options) {                    this._$element = options.$element;                    this._$templates = options.$templates;                    this._componentClass = options.componentClass;                    this._scope = options.scope;                    this._parse = options.parse;                    this._compile = options.compile;                    this._ngOptions = this._normalizeOptions(options.ngOptions);                    this._itemAlias = options.itemAlias;                    this._componentDisposing = $.Callbacks();                    if (options.ngOptions.data)                        this._initDataScope(options.ngOptions.data)                },                _normalizeOptions: function(options) {                    var result = $.extend({}, options);                    if (options.bindingOptions)                        $.each(options.bindingOptions, function(key, value) {                            if ($.type(value) === 'string')                                result.bindingOptions[key] = {dataPath: value}                        });                    return result                },                initComponentWithBindings: function() {                    this._initComponentBindings();                    this._initComponent(this._scope);                    this._shownEventTimer = setTimeout($.proxy(function() {                        DX.utils.triggerShownEvent(this._$element)                    }, this))                },                _initDataScope: function(data) {                    if (typeof data === "string") {                        var dataStr = data,                            rootScope = this._scope;                        data = rootScope.$eval(data);                        this._scope = rootScope.$new();                        this._synchronizeDataScopes(rootScope, this._scope, data, dataStr)                    }                    $.extend(this._scope, data)                },                _synchronizeDataScopes: function(parentScope, childScope, data, parentPrefix) {                    var that = this;                    $.each(data, function(fieldPath) {                        that._synchronizeScopeField({                            parentScope: parentScope,                            childScope: childScope,                            fieldPath: fieldPath,                            parentPrefix: parentPrefix                        })                    })                },                _initComponent: function(scope) {                    this._component = new this._componentClass(this._$element, this._evalOptions(scope))                },                _initComponentBindings: function() {                    var that = this,                        optionDependencies = {};                    that._disposingCallbacks = $.Callbacks();                    if (that._ngOptions.bindingOptions)                        $.each(that._ngOptions.bindingOptions, function(optionPath, value) {                            var separatorIndex = optionPath.search(/\[|\./),                                optionForSubscribe = separatorIndex > -1 ? optionPath.substring(0, separatorIndex) : optionPath,                                prevWatchMethod,                                clearWatcher,                                valuePath = value.dataPath,                                deepWatch = true,                                forcePlainWatchMethod = false;                            if (value.deep !== undefined)                                forcePlainWatchMethod = deepWatch = !!value.deep;                            if (!optionDependencies[optionForSubscribe])                                optionDependencies[optionForSubscribe] = {};                            optionDependencies[optionForSubscribe][optionPath] = valuePath;                            var watchCallback = function(newValue, oldValue) {                                    if (newValue !== oldValue) {                                        that._component.option(optionPath, newValue);                                        updateWatcher()                                    }                                };                            var updateWatcher = function() {                                    var watchMethod = $.isArray(that._scope.$eval(valuePath)) && !forcePlainWatchMethod ? "$watchCollection" : "$watch";                                    if (prevWatchMethod !== watchMethod) {                                        if (clearWatcher)                                            clearWatcher();                                        clearWatcher = that._scope[watchMethod](valuePath, watchCallback, deepWatch);                                        prevWatchMethod = watchMethod                                    }                                };                            updateWatcher();                            that._disposingCallbacks.add(function() {                                clearWatcher();                                that._componentDisposing.fire()                            })                        });                    that._optionChangedCallbacks = $.Callbacks().add(function(args) {                        var optionName = args.name,                            optionValue = args.value;                        if (that._scope.$root.$$phase === "$digest" || !optionDependencies || !optionDependencies[optionName])                            return;                        safeApply(function(scope) {                            $.each(optionDependencies[optionName], function(optionPath, valuePath) {                                var getter = compileGetter(optionPath);                                var tmpData = {};                                tmpData[optionName] = optionValue;                                that._parse(valuePath).assign(that._scope, getter(tmpData))                            })                        }, that._scope)                    });                    that._disposingCallbacks.add(function() {                        clearTimeout(that._shownEventTimer)                    })                },                _compilerByTemplate: function(template) {                    var that = this,                        scopeItemsPath = this._getScopeItemsPath();                    return function(data, index) {                            var $resultMarkup = $(template).clone(),                                templateScope;                            if (data !== undefined) {                                var dataIsScope = data.$id;                                templateScope = dataIsScope ? data : that._createScopeWithData(data);                                $resultMarkup.on("$destroy", function() {                                    var destroyAlreadyCalled = !templateScope.$parent;                                    if (destroyAlreadyCalled)                                        return;                                    templateScope.$destroy()                                })                            }                            else                                templateScope = that._scope;                            if (scopeItemsPath)                                that._synchronizeScopes(templateScope, scopeItemsPath, index);                            safeApply(that._compile($resultMarkup), templateScope);                            return $resultMarkup                        }                },                _getScopeItemsPath: function() {                    if (this._componentClass.subclassOf(ui.CollectionWidget) && this._ngOptions.bindingOptions && this._ngOptions.bindingOptions.items)                        return this._ngOptions.bindingOptions.items.dataPath                },                _createScopeWithData: function(data) {                    var newScope = this._scope.$new(true);                    data = this._enshureDataIsPlainObject(data);                    $.extend(newScope, data);                    return newScope                },                _synchronizeScopes: function(itemScope, parentPrefix, itemIndex) {                    var that = this,                        item = compileGetter(parentPrefix + "[" + itemIndex + "]")(this._scope);                    item = that._enshureDataIsPlainObject(item);                    $.each(item, function(itemPath) {                        that._synchronizeScopeField({                            parentScope: that._scope,                            childScope: itemScope,                            fieldPath: itemPath,                            parentPrefix: parentPrefix,                            itemIndex: itemIndex                        })                    })                },                _synchronizeScopeField: function(args) {                    var parentScope = args.parentScope,                        childScope = args.childScope,                        fieldPath = args.fieldPath,                        parentPrefix = args.parentPrefix,                        itemIndex = args.itemIndex;                    var innerPathSuffix = fieldPath === (this._itemAlias || DEFAULT_MODEL_ALIAS) ? "" : "." + fieldPath,                        collectionField = itemIndex !== undefined,                        optionOuterBag = [parentPrefix],                        optionOuterPath;                    if (collectionField)                        optionOuterBag.push("[", itemIndex, "]");                    optionOuterBag.push(innerPathSuffix);                    optionOuterPath = optionOuterBag.join("");                    var clearParentWatcher = parentScope.$watch(optionOuterPath, function(newValue, oldValue) {                            if (newValue !== oldValue)                                compileSetter(fieldPath)(childScope, newValue)                        });                    var clearItemWatcher = childScope.$watch(fieldPath, function(newValue, oldValue) {                            if (newValue !== oldValue) {                                if (collectionField && !compileGetter(parentPrefix)(parentScope)[itemIndex]) {                                    clearItemWatcher();                                    return                                }                                compileSetter(optionOuterPath)(parentScope, newValue)                            }                        });                    this._componentDisposing.add([clearParentWatcher, clearItemWatcher])                },                _evalOptions: function(scope) {                    var result = $.extend({}, this._ngOptions);                    delete result.data;                    delete result.bindingOptions;                    if (this._ngOptions.bindingOptions)                        $.each(this._ngOptions.bindingOptions, function(key, value) {                            result[key] = scope.$eval(value.dataPath)                        });                    result._optionChangedCallbacks = this._optionChangedCallbacks;                    result._disposingCallbacks = this._disposingCallbacks;                    result.templateProvider = ui.NgTemplateProvider;                    result.templateCompiler = $.proxy(function($template) {                        return this._compilerByTemplate($template)                    }, this);                    return result                },                _enshureDataIsPlainObject: function(object) {                    var result;                    if ($.isPlainObject(object))                        result = object;                    else {                        result = {};                        result[DEFAULT_MODEL_ALIAS] = object                    }                    if (this._itemAlias)                        result[this._itemAlias] = object;                    return result                }            });        ComponentBuilder = ComponentBuilder.inherit({            ctor: function(options) {                this.callBase.apply(this, arguments);                this._componentName = options.componentName;                this._ngModel = options.ngModel;                this._ngModelController = options.ngModelController            },            _isNgModelRequired: function() {                return this._componentClass.subclassOf(ui.Editor) && this._ngModel            },            _initComponentBindings: function() {                this.callBase.apply(this, arguments);                this._initNgModelBinding()            },            _initNgModelBinding: function() {                if (!this._isNgModelRequired())                    return;                var that = this;                var ngModelWatcher = this._scope.$watch(this._ngModel, function(newValue, oldValue) {                        if (newValue === oldValue)                            return;                        that._component.option(that._ngModelOption(), newValue)                    });                that._optionChangedCallbacks.add(function(args) {                    if (args.name !== that._ngModelOption())                        return;                    that._ngModelController.$setViewValue(args.value)                });                this._disposingCallbacks.add(function() {                    ngModelWatcher()                })            },            _ngModelOption: function() {                if ($.inArray(this._componentName, ["dxFileUploader", "dxTagBox"]) > -1)                    return "values";                return "value"            },            _evalOptions: function() {                if (!this._isNgModelRequired())                    return this.callBase.apply(this, arguments);                var result = this.callBase.apply(this, arguments);                result[this._ngModelOption()] = this._parse(this._ngModel)(this._scope);                return result            }        });        var NgComponent = DX.DOMComponent.inherit({                _modelByElement: function(element) {                    if (element.length)                        return element.scope()                },                _createActionByOption: function(optionName, config) {                    var action = this.callBase.apply(this, arguments);                    if (config && $.inArray(config.category, SKIP_APPLY_ACTION_CATEGORIES) > -1)                        return action;                    var component = this,                        wrappedAction = function() {                            var that = this,                                scope = component._modelByElement(component.element()),                                args = arguments;                            if (!scope || !scope.$root || scope.$root.$$phase)                                return action.apply(that, args);                            return scope.$apply(function() {                                    return action.apply(that, args)                                })                        };                    return wrappedAction                },                _createComponent: function(element, name, config) {                    return this.callBase(element, name, $.extend({templateCompiler: this.option("templateCompiler")}, config))                }            });        var registeredComponents = {};        var originalRegisterComponent = DX.registerComponent;        var registerNgComponent = function(componentName, _, componentClass) {                componentClass = componentClass || _;                originalRegisterComponent.apply(this, arguments);                if (!registeredComponents[componentName])                    registerComponentDirective(componentName);                registeredComponents[componentName] = componentClass            };        var registerComponentDirective = function(componentName) {                var priority = componentName !== "dxValidator" ? 1 : 10;                phoneJsModule.directive(componentName, ["$compile", "$parse", function($compile, $parse) {                        return {                                restrict: "A",                                require: "^?ngModel",                                priority: priority,                                compile: function($element) {                                    var componentClass = registeredComponents[componentName],                                        $content = componentClass.subclassOf(ui.Widget) ? $element.contents().detach() : null;                                    return function(scope, $element, attrs, ngModelController) {                                            $element.append($content);                                            var componentBuilder = new ComponentBuilder({                                                    componentClass: componentClass,                                                    componentName: componentName,                                                    compile: $compile,                                                    parse: $parse,                                                    $element: $element,                                                    scope: scope,                                                    ngOptions: attrs[componentName] ? scope.$eval(attrs[componentName]) : {},                                                    ngModel: attrs.ngModel,                                                    ngModelController: ngModelController,                                                    itemAlias: attrs[ITEM_ALIAS_ATTRIBUTE_NAME]                                                });                                            componentBuilder.initComponentWithBindings()                                        }                                }                            }                    }])            };        phoneJsModule.filter('dxGlobalize', function() {            return function(input, param) {                    return Globalize.format(input, param)                }        });        phoneJsModule.directive("dxIcon", ["$compile", function($compile) {                return {                        restrict: 'E',                        link: function($scope, $element, $attrs) {                            var html = DX.utils.getImageContainer($scope.icon || $scope.iconSrc);                            if (html) {                                var e = $compile(html.get(0))($scope);                                $element.replaceWith(e)                            }                        }                    }            }]);        DX.registerComponent = registerNgComponent;        registerNgComponent("DOMComponent", NgComponent)    })(jQuery, DevExpress);    /*! Module core, file ko.templates.js */    (function($, DX, undefined) {        if (!DX.support.hasKo)            return;        var ko = window.ko,            ui = DX.ui;        var KoTemplate = ui.TemplateBase.inherit({                ctor: function(element) {                    this.callBase.apply(this, arguments);                    this._template = $("<div>").append(DX.utils.normalizeTemplateElement(element));                    this._registerKoTemplate()                },                _registerKoTemplate: function() {                    var template = this._template.get(0);                    new ko.templateSources.anonymousTemplate(template)['nodes'](template)                },                _prepareDataForContainer: function(data, container) {                    var result = data,                        containerElement,                        containerContext;                    if (container.length) {                        containerElement = container.get(0);                        data = data !== undefined ? data : ko.dataFor(containerElement) || {};                        containerContext = ko.contextFor(containerElement);                        if (containerContext)                            result = data === containerContext.$data ? containerContext : containerContext.createChildContext(data);                        else                            result = data                    }                    return result                },                _renderCore: function(data) {                    var $renderBag = $("<div>");                    ko.renderTemplate(this._template.get(0), data, null, $renderBag.get(0));                    var $result = $renderBag.contents().detach();                    $renderBag.remove();                    return $result                },                dispose: function() {                    this.callBase();                    this._template.remove()                }            });        var KoTemplateProvider = new(ui.TemplateProviderBase.inherit({                createTemplate: function(element, owner) {                    return new KoTemplate(element, owner)                },                applyTemplate: function(element, model) {                    ko.applyBindings(model, element)                },                _templatesForWidget: function(widgetName) {                    var templateGenerators = TEMPLATE_GENERATORS[widgetName] || {},                        templates = {};                    $.each(templateGenerators, function(name, generator) {                        var $markup = DX.utils.createMarkupFromString(generator());                        if (name !== "itemFrame")                            $markup = $markup.contents();                        templates[name] = new KoTemplate($markup, KoTemplateProvider)                    });                    return templates                }            }));        var createElementWithBindAttr = function(tagName, bindings, closeTag, additionalProperties) {                closeTag = closeTag === undefined ? true : closeTag;                var bindAttr = $.map(bindings, function(value, key) {                        return key + ":" + value                    }).join(",");                additionalProperties = additionalProperties || "";                return "<" + tagName + " data-bind=\"" + bindAttr + "\" " + additionalProperties + ">" + (closeTag ? "</" + tagName + ">" : "")            };        var defaultKoTemplateBasicBindings = {css: "{ 'dx-state-disabled': $data.disabled, 'dx-state-invisible': !($data.visible === undefined || ko.unwrap($data.visible)) }"};        var TEMPLATE_GENERATORS = {};        var emptyTemplate = function() {                return ""            };        TEMPLATE_GENERATORS.CollectionWidget = {            itemFrame: function() {                var markup = [createElementWithBindAttr("div", defaultKoTemplateBasicBindings, false), "<div class='dx-item-content-placeholder'></div>", "</div>"];                return markup.join("")            },            item: function() {                var htmlBinding = createElementWithBindAttr("div", {html: "html"}),                    textBinding = createElementWithBindAttr("div", {text: "text"}),                    primitiveBinding = createElementWithBindAttr("div", {text: "String($data)"});                var markup = ["<div>", "<!-- ko if: $data.html && !$data.text -->", htmlBinding, "<!-- /ko -->", "<!-- ko if: !$data.html && $data.text -->", textBinding, "<!-- /ko -->", "<!-- ko ifnot: $.isPlainObject($data) -->", primitiveBinding, "<!-- /ko -->", "</div>"];                return markup.join("")            }        };        var BUTTON_TEXT_CLASS = "dx-button-text";        TEMPLATE_GENERATORS.dxButton = {content: function() {                var textBinding = createElementWithBindAttr("span", {                        text: "$data.text",                        css: "{ '" + BUTTON_TEXT_CLASS + "' : !!$data.text }"                    });                var markup = ["<div>", "<!-- ko dxIcon: $data.icon || $data.iconSrc --><!-- /ko -->", textBinding, "</div>"];                return markup.join("")            }};        var LIST_ITEM_BADGE_CONTAINER_CLASS = "dx-list-item-badge-container",            LIST_ITEM_BADGE_CLASS = "dx-list-item-badge",            BADGE_CLASS = "dx-badge",            LIST_ITEM_CHEVRON_CONTAINER_CLASS = "dx-list-item-chevron-container",            LIST_ITEM_CHEVRON_CLASS = "dx-list-item-chevron";        TEMPLATE_GENERATORS.dxList = {            item: function() {                var template = TEMPLATE_GENERATORS.CollectionWidget.item(),                    keyBinding = createElementWithBindAttr("div", {text: "key"});                template = [template.substring(0, template.length - 6), "<!-- ko if: $data.key -->" + keyBinding + "<!-- /ko -->", "</div>"];                return template.join("")            },            itemFrame: function() {                var template = TEMPLATE_GENERATORS.CollectionWidget.itemFrame(),                    badgeBinding = createElementWithBindAttr("div", {text: "badge"}, true, 'class="' + LIST_ITEM_BADGE_CLASS + " " + BADGE_CLASS + '"');                var markup = [template.substring(0, template.length - 6), "<!-- ko if: $data.badge -->", "<div class=\"" + LIST_ITEM_BADGE_CONTAINER_CLASS + "\">", badgeBinding, "</div>", "<!-- /ko -->", "<!-- ko if: $data.showChevron -->", "<div class=\"" + LIST_ITEM_CHEVRON_CONTAINER_CLASS + "\">", "<div class=\"" + LIST_ITEM_CHEVRON_CLASS + "\"></div>", "</div>", "<!-- /ko -->", "</div>"];                return markup.join("")            },            group: function() {                var keyBinding = createElementWithBindAttr("div", {text: "key"}),                    primitiveBinding = createElementWithBindAttr("div", {text: "String($data)"});                var markup = ["<div>", "<!-- ko if: $data.key -->", keyBinding, "<!-- /ko -->", "<!-- ko ifnot: $.isPlainObject($data) -->", primitiveBinding, "<!-- /ko -->", "</div>"];                return markup.join("")            }        };        TEMPLATE_GENERATORS.dxDropDownMenu = {item: TEMPLATE_GENERATORS.dxList.item};        TEMPLATE_GENERATORS.dxDropDownList = {item: TEMPLATE_GENERATORS.dxList.item};        TEMPLATE_GENERATORS.dxRadioGroup = {item: TEMPLATE_GENERATORS.CollectionWidget.item};        TEMPLATE_GENERATORS.dxScheduler = {item: function() {                var template = TEMPLATE_GENERATORS.CollectionWidget.item(),                    startDateBinding = createElementWithBindAttr("strong", {text: "Globalize.format(DevExpress.utils.makeDate($data.startDate), 't')"}),                    endDateBinding = createElementWithBindAttr("strong", {text: "' - ' + Globalize.format(DevExpress.utils.makeDate($data.endDate), 't')"});                template = [template.substring(0, template.length - 6), "<div class='dx-scheduler-appointment-content-details'>", "<!-- ko if: $data.startDate -->" + startDateBinding + "<!-- /ko -->", "<!-- ko if: $data.endDate -->" + endDateBinding + "<!-- /ko -->", "</div>", "<!-- ko if: $data.recurrenceRule --><span class='dx-scheduler-appointment-recurrence-icon'></span><!-- /ko -->", "</div>"];                return template.join("")            }};        TEMPLATE_GENERATORS.dxOverlay = {content: emptyTemplate};        TEMPLATE_GENERATORS.dxSlideOutView = {            menu: emptyTemplate,            content: emptyTemplate        };        TEMPLATE_GENERATORS.dxSlideOut = {            menuItem: TEMPLATE_GENERATORS.dxList.item,            menuGroup: TEMPLATE_GENERATORS.dxList.group,            content: emptyTemplate        };        TEMPLATE_GENERATORS.dxAccordion = {            title: function() {                var titleBinding = createElementWithBindAttr("span", {text: "$.isPlainObject($data) ? $data.title : String($data)"});                var markup = ["<div>", "<!-- ko dxIcon: $data.icon || $data.iconSrc --><!-- /ko -->", titleBinding, "</div>"];                return markup.join("")            },            item: TEMPLATE_GENERATORS.CollectionWidget.item        };        TEMPLATE_GENERATORS.dxResponsiveBox = {item: TEMPLATE_GENERATORS.CollectionWidget.item},        TEMPLATE_GENERATORS.dxPivotTabs = {item: function() {                var titleBinding = createElementWithBindAttr("span", {text: "title"}),                    primitiveBinding = createElementWithBindAttr("div", {text: "String($data)"});                var markup = ["<div>", "<!-- ko if: $data.title -->", titleBinding, "<!-- /ko -->", "<!-- ko ifnot: $.isPlainObject($data) -->", primitiveBinding, "<!-- /ko -->", "</div>"];                return markup.join("")            }};        TEMPLATE_GENERATORS.dxPivot = {            title: TEMPLATE_GENERATORS.dxPivotTabs.item,            content: emptyTemplate        };        var PANORAMA_ITEM_TITLE_CLASS = "dx-panorama-item-title";        TEMPLATE_GENERATORS.dxPanorama = {itemFrame: function() {                var template = TEMPLATE_GENERATORS.CollectionWidget.itemFrame(),                    headerBinding = createElementWithBindAttr("div", {text: "title"}, true, 'class="' + PANORAMA_ITEM_TITLE_CLASS + '"');                var divInnerStart = template.indexOf(">") + 1;                template = [template.substring(0, divInnerStart), "<!-- ko if: $data.title -->", headerBinding, "<!-- /ko -->", template.substring(divInnerStart, template.length)];                return template.join("")            }};        TEMPLATE_GENERATORS.dxActionSheet = {item: function() {                return ["<div>", createElementWithBindAttr("div", {dxButton: "{ text: $data.text, onClick: $data.clickAction || $data.onClick, type: $data.type, disabled: !!ko.unwrap($data.disabled) }"}), "</div>"].join("")            }};        TEMPLATE_GENERATORS.dxToolbar = {            item: function() {                var template = TEMPLATE_GENERATORS.CollectionWidget.item();                template = [template.substring(0, template.length - 6), "<!-- ko if: $data.widget -->"];                $.each(["button", "tabs", "dropDownMenu"], function() {                    var bindingName = DX.inflector.camelize(["dx", "-", this].join("")),                        bindingObj = {};                    bindingObj[bindingName] = "$data.options";                    template.push("<!-- ko if: $data.widget === '", this, "' -->", createElementWithBindAttr("div", bindingObj), "<!-- /ko -->")                });                template.push("<!-- /ko -->");                return template.join("")            },            menuItem: TEMPLATE_GENERATORS.dxList.item,            actionSheetItem: TEMPLATE_GENERATORS.dxActionSheet.item        };        TEMPLATE_GENERATORS.dxGallery = {item: function() {                var template = TEMPLATE_GENERATORS.CollectionWidget.item(),                    primitiveBinding = createElementWithBindAttr("div", {text: "String($data)"}),                    imgBinding = createElementWithBindAttr("img", {attr: "{ src: String($data) }"}, false);                template = [template.substring(0, template.length - 6).replace(primitiveBinding, imgBinding), "<!-- ko if: $data.imageSrc -->", createElementWithBindAttr("img", {attr: "{ src: $data.imageSrc }"}, false), "<!-- /ko -->"].join("");                return template            }};        TEMPLATE_GENERATORS.dxTabs = {            item: function() {                var template = TEMPLATE_GENERATORS.CollectionWidget.item(),                    basePrimitiveBinding = createElementWithBindAttr("div", {text: "String($data)"}),                    primitiveBinding = "<span class=\"dx-tab-text\" data-bind=\"text: String($data)\"></span>",                    baseTextBinding = createElementWithBindAttr("div", {text: "text"}),                    textBinding = "<!-- ko dxIcon: $data.icon || $data.iconSrc --><!-- /ko -->" + "<span class=\"dx-tab-text\" data-bind=\"text: $data.text\"></span>";                template = template.replace("<!-- ko if: !$data.html && $data.text -->", "<!-- ko if: !$data.html && ($data.text || $data.icon || $data.iconSrc) -->").replace(basePrimitiveBinding, primitiveBinding).replace(baseTextBinding, textBinding);                return template            },            itemFrame: function() {                var template = TEMPLATE_GENERATORS.CollectionWidget.itemFrame(),                    badgeBinding = createElementWithBindAttr("div", {                        attr: "{ 'class': 'dx-tabs-item-badge dx-badge' }",                        text: "badge"                    });                var markup = [template.substring(0, template.length - 6), "<!-- ko if: $data.badge -->", badgeBinding, "<!-- /ko -->", "</div>"];                return markup.join("")            }        };        TEMPLATE_GENERATORS.dxTabPanel = {            item: TEMPLATE_GENERATORS.CollectionWidget.item,            title: function() {                var template = TEMPLATE_GENERATORS.dxTabs.item();                return template.replace(/\$data\.text/g, '$data.title')            }        };        var NAVBAR_ITEM_BADGE_CLASS = "dx-navbar-item-badge";        TEMPLATE_GENERATORS.dxNavBar = {itemFrame: function() {                var template = TEMPLATE_GENERATORS.CollectionWidget.itemFrame(),                    badgeBinding = createElementWithBindAttr("div", {text: "badge"}, true, 'class="' + NAVBAR_ITEM_BADGE_CLASS + " " + BADGE_CLASS + '"');                var markup = [template.substring(0, template.length - 6), "<!-- ko if: $data.badge -->", badgeBinding, "<!-- /ko -->", "</div>"];                return markup.join("")            }};        TEMPLATE_GENERATORS.dxMenuBase = {item: function() {                var template = [createElementWithBindAttr("div", defaultKoTemplateBasicBindings, false)],                    textBinding = createElementWithBindAttr("span", {                        text: "text",                        css: "{ 'dx-menu-item-text': true }"                    }),                    primitiveBinding = createElementWithBindAttr("span", {                        text: "String($data)",                        css: "{ 'dx-menu-item-text': true }"                    }),                    popout = "<span class='dx-menu-item-popout-container'><div class='dx-menu-item-popout'></div></span>";                template.push("<!-- ko dxIcon: $data.icon || $data.iconSrc --><!-- /ko -->", "<!-- ko if: $.isPlainObject($data) && $data.text -->", textBinding, "<!-- /ko -->", "<!-- ko ifnot: $.isPlainObject($data) -->", primitiveBinding, "<!-- /ko -->", "<!-- ko if: $data.items -->", popout, "<!-- /ko -->", "</div>");                return template.join("")            }};        TEMPLATE_GENERATORS.dxTreeView = {item: function() {                var node = [],                    link = createElementWithBindAttr("span", {text: "text"}, true),                    htmlBinding = createElementWithBindAttr("div", {html: "html"});                node.push("<div>", "<!-- ko if: $data.html && !$data.text -->", htmlBinding, "<!-- /ko -->", "<!-- ko dxIcon: $data.icon || $data.iconSrc --><!-- /ko -->", "<!-- ko if: !$data.html && $data.text -->" + link + "<!-- /ko -->", "</div>");                return node.join("")            }};        TEMPLATE_GENERATORS.dxCalendar = {cell: function() {                var textBinding = createElementWithBindAttr("span", {text: "text"}),                    primitiveBinding = createElementWithBindAttr("span", {text: "String($data)"});                var markup = ["<div>", "<!-- ko if: !$data.html && $data.text -->", textBinding, "<!-- /ko -->", "<!-- ko ifnot: $.isPlainObject($data) -->", primitiveBinding, "<!-- /ko -->", "</div>"];                return markup.join("")            }};        var popupTitleAndBottom = function() {                return ["<div>", createElementWithBindAttr("div", {dxToolbar: "{ items: $data }"}), "</div>"].join("")            };        TEMPLATE_GENERATORS.dxPopup = {            title: popupTitleAndBottom,            bottom: popupTitleAndBottom        };        TEMPLATE_GENERATORS.dxLookup = {            title: TEMPLATE_GENERATORS.dxPopup.title,            group: TEMPLATE_GENERATORS.dxList.group        };        TEMPLATE_GENERATORS.dxTagBox = {tag: function() {                return ["<div>", createElementWithBindAttr("span", {text: "$data"})].join("")            }};        $.extend(ui, {            KoTemplateProvider: KoTemplateProvider,            KoTemplate: KoTemplate        })    })(jQuery, DevExpress);    /*! Module core, file ng.templates.js */    (function($, DX, undefined) {        if (!DX.support.hasNg)            return;        var ui = DX.ui;        var TEMPLATE_WRAPPER_CLASS = "dx-template-wrapper";        var NgTemplate = ui.TemplateBase.inherit({                ctor: function() {                    this.callBase.apply(this, arguments);                    this.setCompiler(this._getParentTemplateCompiler())                },                _getParentTemplateCompiler: function() {                    var templateCompiler = null,                        owner = this.owner();                    while (!templateCompiler && owner) {                        templateCompiler = $.isFunction(owner.option) ? owner.option("templateCompiler") : null;                        owner = $.isFunction(owner.owner) ? owner.owner() : null                    }                    return templateCompiler                },                _renderCore: function(data, index, $container) {                    var compiledTemplate = this._compiledTemplate,                        result = $.isFunction(compiledTemplate) ? compiledTemplate(data, index, $container) : compiledTemplate;                    return result                },                setCompiler: function(templateCompiler) {                    if (!templateCompiler)                        return;                    this._compiledTemplate = templateCompiler(DX.utils.normalizeTemplateElement(this._element))                }            });        var NgTemplateProvider = new(ui.TemplateProviderBase.inherit({                createTemplate: function(element, owner) {                    return new NgTemplate(element, owner)                },                getTemplates: function(widget) {                    var templateCompiler = widget.option("templateCompiler"),                        templates = this.callBase.apply(this, arguments);                    $.each(templates, function(_, template) {                        template.setCompiler(templateCompiler)                    });                    return templates                },                _templatesForWidget: function(widgetName) {                    var templateGenerators = TEMPLATE_GENERATORS[widgetName] || {},                        templates = {};                    $.each(templateGenerators, function(name, generator) {                        var $markup = DX.utils.createMarkupFromString(generator());                        templates[name] = new NgTemplate($markup.wrap(), NgTemplateProvider)                    });                    return templates                }            }));        var baseElements = {                container: function() {                    return $("<div>").addClass(TEMPLATE_WRAPPER_CLASS)                },                html: function() {                    return $("<div>").attr("ng-if", "html").attr("ng-bind-html", "html")                },                text: function() {                    return $("<div>").attr("ng-if", "text").attr("ng-bind", "text")                },                primitive: function() {                    return $("<div>").attr("ng-if", "scopeValue").attr("ng-bind-html", "'' + scopeValue")                }            };        var TEMPLATE_GENERATORS = {};        var emptyTemplate = function() {                return $()            };        TEMPLATE_GENERATORS.CollectionWidget = {            item: function() {                return baseElements.container().append(baseElements.html()).append(baseElements.text()).append(baseElements.primitive())            },            itemFrame: function() {                var $container = $("<div>").attr("ng-class", "{ 'dx-state-invisible': !visible && visible != undefined, 'dx-state-disabled': !!disabled }"),                    $placeholder = $("<div>").addClass("dx-item-content-placeholder");                $container.append($placeholder);                return $container            }        };        var BUTTON_TEXT_CLASS = "dx-button-text";        TEMPLATE_GENERATORS.dxButton = {content: function() {                var $titleBinding = $("<span>").attr("ng-bind", "text").attr("ng-class", "{ '" + BUTTON_TEXT_CLASS + "' : !!text }"),                    icon = $("<dx-icon>");                return baseElements.container().append(icon).append($titleBinding).append(baseElements.primitive())            }};        var LIST_ITEM_BADGE_CONTAINER_CLASS = "dx-list-item-badge-container",            LIST_ITEM_BADGE_CLASS = "dx-list-item-badge",            BADGE_CLASS = "dx-badge",            LIST_ITEM_CHEVRON_CONTAINER_CLASS = "dx-list-item-chevron-container",            LIST_ITEM_CHEVRON_CLASS = "dx-list-item-chevron";        TEMPLATE_GENERATORS.dxList = {            item: function() {                return TEMPLATE_GENERATORS.CollectionWidget.item().append($("<div>").attr("ng-if", "key").attr("ng-bind", "key"))            },            itemFrame: function() {                var $badgeContainer = $("<div>").addClass(LIST_ITEM_BADGE_CONTAINER_CLASS).attr("ng-if", "badge"),                    $badge = $("<div>").addClass(LIST_ITEM_BADGE_CLASS).addClass(BADGE_CLASS).attr("ng-bind", "badge");                var $chevronContainer = $("<div>").addClass(LIST_ITEM_CHEVRON_CONTAINER_CLASS).attr("ng-if", "showChevron"),                    $chevron = $("<div>").addClass(LIST_ITEM_CHEVRON_CLASS);                return TEMPLATE_GENERATORS.CollectionWidget.itemFrame().append($badgeContainer.append($badge)).append($chevronContainer.append($chevron))            },            group: function() {                var $keyBinding = $("<div>").attr("ng-if", "key").attr("ng-bind", "key");                return baseElements.container().append($keyBinding).append(baseElements.primitive())            }        };        TEMPLATE_GENERATORS.dxDropDownMenu = {item: TEMPLATE_GENERATORS.dxList.item};        TEMPLATE_GENERATORS.dxDropDownList = {item: TEMPLATE_GENERATORS.dxList.item};        TEMPLATE_GENERATORS.dxRadioGroup = {item: TEMPLATE_GENERATORS.CollectionWidget.item};        TEMPLATE_GENERATORS.dxScheduler = {item: function() {                var $itemContent = TEMPLATE_GENERATORS.CollectionWidget.item();                var $details = $("<div>").addClass("dx-scheduler-appointment-content-details");                $("<strong>").attr("ng-if", "startDate").text("{{startDate | date : 'shortTime' }}").appendTo($details);                $("<strong>").attr("ng-if", "endDate").text(" - {{endDate | date : 'shortTime' }}").appendTo($details);                $details.appendTo($itemContent);                $("<span>").attr("ng-if", "recurrenceRule").addClass("dx-scheduler-appointment-recurrence-icon").appendTo($itemContent);                return $itemContent            }};        TEMPLATE_GENERATORS.dxOverlay = {content: emptyTemplate};        TEMPLATE_GENERATORS.dxSlideOutView = {            menu: emptyTemplate,            content: emptyTemplate        };        TEMPLATE_GENERATORS.dxSlideOut = {            menuItem: TEMPLATE_GENERATORS.dxList.item,            menuGroup: TEMPLATE_GENERATORS.dxList.group,            content: emptyTemplate        };        TEMPLATE_GENERATORS.dxAccordion = {            title: function() {                var $titleBinding = $("<span>").attr("ng-if", "title").attr("ng-bind", "title"),                    icon = $("<dx-icon>");                return baseElements.container().append(icon).append($titleBinding).append(baseElements.primitive())            },            content: TEMPLATE_GENERATORS.CollectionWidget.item        };        TEMPLATE_GENERATORS.dxPivotTabs = {item: function() {                return baseElements.container().append($("<span>").attr("ng-if", "title").attr("ng-bind", "title")).append(baseElements.primitive())            }};        TEMPLATE_GENERATORS.dxPivot = {            title: TEMPLATE_GENERATORS.dxPivotTabs.item,            content: emptyTemplate        };        var PANORAMA_ITEM_TITLE_CLASS = "dx-panorama-item-title";        TEMPLATE_GENERATORS.dxPanorama = {itemFrame: function() {                return TEMPLATE_GENERATORS.CollectionWidget.itemFrame().prepend($("<div>").addClass(PANORAMA_ITEM_TITLE_CLASS).attr("ng-if", "title").attr("ng-bind", "title"))            }};        TEMPLATE_GENERATORS.dxActionSheet = {item: function() {                return baseElements.container().append($("<div>").attr("dx-button", "{ bindingOptions: { text: 'text', onClick: 'onClick', type: 'type', disabled: 'disabled' } }"))            }};        TEMPLATE_GENERATORS.dxToolbar = {            item: function() {                var template = TEMPLATE_GENERATORS.CollectionWidget.item();                $.each(["button", "tabs", "dropDownMenu"], function(i, widgetName) {                    var bindingName = "dx-" + DX.inflector.dasherize(this);                    $("<div>").attr("ng-if", "widget === '" + widgetName + "'").attr(bindingName, "options").appendTo(template)                });                return template            },            menuItem: TEMPLATE_GENERATORS.dxList.item,            actionSheetItem: TEMPLATE_GENERATORS.dxActionSheet.item        };        TEMPLATE_GENERATORS.dxGallery = {item: function() {                return baseElements.container().append(baseElements.html()).append(baseElements.text()).append($("<img>").attr("ng-if", "scopeValue").attr("ng-src", "{{'' + scopeValue}}")).append($("<img>").attr("ng-if", "imageSrc").attr("ng-src", "{{imageSrc}}"))            }};        var TABS_ITEM_TEXT_CLASS = "dx-tab-text";        TEMPLATE_GENERATORS.dxTabs = {            item: function() {                var container = baseElements.container();                var text = $("<span>").addClass(TABS_ITEM_TEXT_CLASS).attr("ng-bind", "text").attr("ng-if", "text"),                    icon = $("<dx-icon>");                return container.append(baseElements.html()).append(icon).append(text).append(baseElements.primitive().addClass(TABS_ITEM_TEXT_CLASS))            },            itemFrame: function() {                var $badge = $("<div>").addClass("dx-tabs-item-badge dx-badge").attr("ng-bind", "badge").attr("ng-if", "badge");                return TEMPLATE_GENERATORS.CollectionWidget.itemFrame().append($badge)            }        };        var NAVBAR_ITEM_BADGE_CLASS = "dx-navbar-item-badge";        TEMPLATE_GENERATORS.dxNavBar = {itemFrame: function() {                var $badge = $("<div>").addClass(NAVBAR_ITEM_BADGE_CLASS).addClass(BADGE_CLASS).attr("ng-if", "badge").attr("ng-bind", "badge");                return TEMPLATE_GENERATORS.CollectionWidget.itemFrame().append($badge)            }};        TEMPLATE_GENERATORS.dxMenuBase = {item: function() {                var container = baseElements.container();                var text = $("<span>").attr("ng-if", "text").addClass("dx-menu-item-text").attr("ng-bind", "text"),                    icon = $("<dx-icon>"),                    popout = $("<span>").addClass("dx-menu-item-popout-container").attr("ng-if", "items").append($("<div>").addClass("dx-menu-item-popout"));                container.append(baseElements.html()).append(icon).append(text).append(popout).append(baseElements.primitive()).appendTo(container);                return container            }};        TEMPLATE_GENERATORS.dxTreeView = {item: function() {                var content = baseElements.container(),                    link = $("<span/>").attr("ng-bind", "text"),                    icon = $("<dx-icon>");                content.append(baseElements.html()).append(icon).append(link).append(baseElements.primitive());                return content            }};        TEMPLATE_GENERATORS.dxTabPanel = {            item: TEMPLATE_GENERATORS.CollectionWidget.item,            title: function() {                var content = TEMPLATE_GENERATORS.dxTabs.item();                content.find(".dx-tab-text").eq(0).attr("ng-bind", "title").attr("ng-if", "title");                return content            }        };        var popupTitleAndBottom = function() {                return $("<div>").attr("dx-toolbar", "{ bindingOptions: { items: 'scopeValue' } }")            };        TEMPLATE_GENERATORS.dxPopup = {            title: popupTitleAndBottom,            bottom: popupTitleAndBottom        };        TEMPLATE_GENERATORS.dxLookup = {            title: TEMPLATE_GENERATORS.dxPopup.title,            group: TEMPLATE_GENERATORS.dxList.group        };        TEMPLATE_GENERATORS.dxTagBox = {tag: function() {                return $("<div>").append($("<span>").attr("ng-bind", "scopeValue"))            }};        TEMPLATE_GENERATORS.dxCalendar = {cell: function() {                var $cell = $("<span>").attr("ng-if", "text").attr("ng-bind", "text");                return baseElements.container().append($cell).append(baseElements.primitive())            }};        $.extend(ui, {            NgTemplate: NgTemplate,            NgTemplateProvider: NgTemplateProvider        })    })(jQuery, DevExpress);    /*! Module core, file ko.validation.js */    (function($, DX, undefined) {        if (!DX.support.hasKo)            return;        var ko = window.ko;        var koDxValidator = DX.Class.inherit({                ctor: function(target, option) {                    var that = this;                    that.target = target;                    that.validationRules = option.validationRules;                    that.name = option.name;                    that.isValid = ko.observable(true);                    that.validationError = ko.observable();                    $.each(this.validationRules, function(_, rule) {                        rule.validator = that                    })                },                validate: function() {                    var result = DevExpress.validationEngine.validate(this.target(), this.validationRules, this.name);                    this._applyValidationResult(result);                    return result                },                reset: function() {                    this.target(null);                    var result = {                            isValid: true,                            brokenRule: null                        };                    this._applyValidationResult(result);                    return result                },                _applyValidationResult: function(result) {                    result.validator = this;                    this.target.dxValidator.isValid(result.isValid);                    this.target.dxValidator.validationError(result.brokenRule);                    this.fireEvent("validated", [result])                }            }).include(DX.EventsMixin);        ko.extenders.dxValidator = function(target, option) {            target.dxValidator = new koDxValidator(target, option);            target.subscribe($.proxy(target.dxValidator.validate, target.dxValidator));            return target        };        DevExpress.validationEngine.registerModelForValidation = function(model) {            $.each(model, function(name, member) {                if (ko.isObservable(member) && member.dxValidator)                    DevExpress.validationEngine.registerValidatorInGroup(model, member.dxValidator)            })        };        DevExpress.validationEngine.validateModel = DevExpress.validationEngine.validateGroup    })(jQuery, DevExpress);    /*! Module core, file ui.themes.js */    (function($, DX, undefined) {        var DX_LINK_SELECTOR = "link[rel=dx-theme]",            THEME_ATTR = "data-theme",            ACTIVE_ATTR = "data-active";        var context,            $activeThemeLink,            knownThemes,            currentThemeName,            pendingThemeName;        var THEME_MARKER_PREFIX = "dx.";        function readThemeMarker() {            var element = $("<div></div>", context).addClass("dx-theme-marker").appendTo(context.documentElement),                result;            try {                result = element.css("font-family");                if (!result)                    return null;                result = result.replace(/["']/g, "");                if (result.substr(0, THEME_MARKER_PREFIX.length) !== THEME_MARKER_PREFIX)                    return null;                return result.substr(THEME_MARKER_PREFIX.length)            }            finally {                element.remove()            }        }        function waitForThemeLoad(themeName, callback) {            var timerId,                waitStartTime;            pendingThemeName = themeName;            function handleLoaded() {                pendingThemeName = null;                callback()            }            if (isPendingThemeLoaded())                handleLoaded();            else {                waitStartTime = $.now();                timerId = setInterval(function() {                    var isLoaded = isPendingThemeLoaded(),                        isTimeout = !isLoaded && $.now() - waitStartTime > 15 * 1000;                    if (isTimeout)                        DX.log("W0004", pendingThemeName);                    if (isLoaded || isTimeout) {                        clearInterval(timerId);                        handleLoaded()                    }                }, 10)            }        }        function isPendingThemeLoaded() {            return !pendingThemeName || readThemeMarker() === pendingThemeName        }        function processMarkup() {            var $allThemeLinks = $(DX_LINK_SELECTOR, context);            if (!$allThemeLinks.length)                return;            knownThemes = {};            $activeThemeLink = $(DX.utils.createMarkupFromString("<link rel=stylesheet>"), context);            $allThemeLinks.each(function() {                var link = $(this, context),                    fullThemeName = link.attr(THEME_ATTR),                    url = link.attr("href"),                    isActive = link.attr(ACTIVE_ATTR) === "true";                knownThemes[fullThemeName] = {                    url: url,                    isActive: isActive                }            });            $allThemeLinks.last().after($activeThemeLink);            $allThemeLinks.remove()        }        function resolveFullThemeName(desiredThemeName) {            var desiredThemeParts = desiredThemeName.split("."),                result = null;            if (knownThemes)                $.each(knownThemes, function(knownThemeName, themeData) {                    var knownThemeParts = knownThemeName.split(".");                    if (knownThemeParts[0] !== desiredThemeParts[0])                        return;                    if (desiredThemeParts[1] && desiredThemeParts[1] !== knownThemeParts[1])                        return;                    if (desiredThemeParts[2] && desiredThemeParts[2] !== knownThemeParts[2])                        return;                    if (!result || themeData.isActive)                        result = knownThemeName;                    if (themeData.isActive)                        return false                });            return result        }        function initContext(newContext) {            try {                if (newContext !== context)                    knownThemes = null            }            catch(x) {                knownThemes = null            }            context = newContext        }        function init(options) {            options = options || {};            initContext(options.context || document);            processMarkup();            currentThemeName = undefined;            current(options)        }        function current(options) {            if (!arguments.length)                return currentThemeName || readThemeMarker();            detachCssClasses(DX.viewPort(), currentThemeName);            options = options || {};            if (typeof options === "string")                options = {theme: options};            var isAutoInit = options._autoInit,                loadCallback = options.loadCallback,                currentThemeData;            currentThemeName = options.theme || currentThemeName;            if (isAutoInit && !currentThemeName)                currentThemeName = themeNameFromDevice(DX.devices.current());            currentThemeName = resolveFullThemeName(currentThemeName);            if (currentThemeName)                currentThemeData = knownThemes[currentThemeName];            if (currentThemeData) {                $activeThemeLink.attr("href", knownThemes[currentThemeName].url);                if (loadCallback)                    waitForThemeLoad(currentThemeName, loadCallback);                else if (pendingThemeName)                    pendingThemeName = currentThemeName            }            else if (isAutoInit) {                if (loadCallback)                    loadCallback()            }            else                throw DX.Error("E0021", currentThemeName);            attachCssClasses(DX.viewPort(), currentThemeName)        }        function themeNameFromDevice(device) {            var themeName = device.platform;            if (themeName === "ios")                themeName += "7";            if (themeName === "android")                themeName += "5";            return themeName        }        function getCssClasses(themeName) {            themeName = themeName || current();            var result = [],                themeNameParts = themeName && themeName.split(".");            if (themeNameParts) {                result.push("dx-theme-" + themeNameParts[0], "dx-theme-" + themeNameParts[0] + "-typography");                if (themeNameParts.length > 1)                    result.push("dx-color-scheme-" + themeNameParts[1])            }            return result        }        var themeClasses;        function attachCssClasses(element, themeName) {            themeClasses = getCssClasses(themeName).join(" ");            $(element).addClass(themeClasses)        }        function detachCssClasses(element, themeName) {            $(element).removeClass(themeClasses)        }        $.holdReady(true);        init({            _autoInit: true,            loadCallback: function() {                $.holdReady(false)            }        });        $(function() {            if ($(DX_LINK_SELECTOR, context).length)                throw DX.Error("E0022");        });        DX.viewPortChanged.add(function(viewPort, prevViewPort) {            detachCssClasses(prevViewPort);            attachCssClasses(viewPort)        });        DX.ui.themes = {            init: init,            current: current,            attachCssClasses: attachCssClasses,            detachCssClasses: detachCssClasses        };        DX.ui.themes.__internals = {            themeNameFromDevice: themeNameFromDevice,            waitForThemeLoad: waitForThemeLoad,            resetTheme: function() {                $activeThemeLink.attr("href", "about:blank");                currentThemeName = null;                pendingThemeName = null            }        }    })(jQuery, DevExpress);    /*! Module core, file ui.events.js */    (function($, DX, undefined) {        var ui = DX.ui,            eventNS = $.event,            hooksNS = eventNS.fixHooks,            specialNS = eventNS.special,            EVENT_SOURCES_REGEX = {                dx: /^dx/i,                mouse: /(mouse|wheel)/i,                touch: /^touch/i,                keyboard: /^key/i,                pointer: /^(ms)?pointer/i            };        var eventSource = function(e) {                var result = "other";                $.each(EVENT_SOURCES_REGEX, function(key) {                    if (this.test(e.type)) {                        result = key;                        return false                    }                });                return result            };        var isDxEvent = function(e) {                return eventSource(e) === "dx"            };        var isNativeMouseEvent = function(e) {                return eventSource(e) === "mouse"            };        var isNativeTouchEvent = function(e) {                return eventSource(e) === "touch"            };        var isPointerEvent = function(e) {                return eventSource(e) === "pointer"            };        var isMouseEvent = function(e) {                return isNativeMouseEvent(e) || (isPointerEvent(e) || isDxEvent(e)) && e.pointerType === "mouse"            };        var isTouchEvent = function(e) {                return isNativeTouchEvent(e) || (isPointerEvent(e) || isDxEvent(e)) && e.pointerType === "touch"            };        var isKeyboardEvent = function(e) {                return eventSource(e) === "keyboard"            };        var eventData = function(e) {                return {                        x: e.pageX,                        y: e.pageY,                        time: e.timeStamp                    }            };        var eventDelta = function(from, to) {                return {                        x: to.x - from.x,                        y: to.y - from.y,                        time: to.time - from.time || 1                    }            };        var hasTouches = function(e) {                if (isNativeTouchEvent(e))                    return (e.originalEvent.touches || []).length;                if (isDxEvent(e))                    return (e.pointers || []).length;                return 0            };        var needSkipEvent = function(e) {                var $target = $(e.target),                    touchInInput = $target.is("input, textarea, select");                if (e.type === 'dxmousewheel')                    return $target.is("input[type='number'], textarea, select") && $target.is(':focus');                if (isMouseEvent(e))                    return touchInInput || e.which > 1;                if (isTouchEvent(e))                    return touchInInput && $target.is(":focus")            };        var createEvent = function(originalEvent, args) {                var event = $.Event(originalEvent),                    fixHook = hooksNS[originalEvent.type] || eventNS.mouseHooks;                var props = fixHook.props ? eventNS.props.concat(fixHook.props) : eventNS.props,                    propIndex = props.length;                while (propIndex--) {                    var prop = props[propIndex];                    event[prop] = originalEvent[prop]                }                if (args)                    $.extend(event, args);                return fixHook.filter ? fixHook.filter(event, originalEvent) : event            };        var fireEvent = function(props) {                var event = createEvent(props.originalEvent, props);                eventNS.trigger(event, null, props.delegateTarget || event.target);                return event            };        var addNamespace = function(eventNames, namespace) {                if (!namespace)                    throw DX.Error("E0017");                if (typeof eventNames === "string")                    return addNamespace(eventNames.split(/\s+/g), namespace);                $.each(eventNames, function(index, eventName) {                    eventNames[index] = eventName + "." + namespace                });                return eventNames.join(" ")            };        var dxEventHook = {props: eventNS.mouseHooks.props.concat(["pointerType", "pointerId", "pointers"])};        var registerEvent = function(eventName, eventObject) {                var strategy = {};                if ("noBubble" in eventObject)                    strategy.noBubble = eventObject.noBubble;                if ("bindType" in eventObject)                    strategy.bindType = eventObject.bindType;                if ("delegateType" in eventObject)                    strategy.delegateType = eventObject.delegateType;                $.each(["setup", "teardown", "add", "remove", "trigger", "handle", "_default", "dispose"], function(_, methodName) {                    if (!eventObject[methodName])                        return;                    strategy[methodName] = function() {                        var args = $.makeArray(arguments);                        args.unshift(this);                        return eventObject[methodName].apply(eventObject, args)                    }                });                hooksNS[eventName] = dxEventHook;                specialNS[eventName] = strategy            };        ui.events = {            eventSource: eventSource,            isPointerEvent: isPointerEvent,            isMouseEvent: isMouseEvent,            isTouchEvent: isTouchEvent,            isKeyboardEvent: isKeyboardEvent,            hasTouches: hasTouches,            eventData: eventData,            eventDelta: eventDelta,            needSkipEvent: needSkipEvent,            createEvent: createEvent,            fireEvent: fireEvent,            addNamespace: addNamespace,            registerEvent: registerEvent        }    })(jQuery, DevExpress);    /*! Module core, file ko.events.js */    (function($, DX, undefined) {        if (!DX.support.hasKo)            return;        var ko = window.ko,            events = DX.ui.events;        var originalRegisterEvent = events.registerEvent;        var registerKoEvent = function(eventName, eventObject) {                originalRegisterEvent(eventName, eventObject);                var koBindingEventName = events.addNamespace(eventName, eventName + "Binding");                ko.bindingHandlers[eventName] = {update: function(element, valueAccessor, allBindingsAccessor, viewModel) {                        var $element = $(element),                            unwrappedValue = ko.utils.unwrapObservable(valueAccessor()),                            eventSource = unwrappedValue.execute ? unwrappedValue.execute : unwrappedValue;                        $element.off(koBindingEventName).on(koBindingEventName, $.isPlainObject(unwrappedValue) ? unwrappedValue : {}, function(e) {                            eventSource.call(viewModel, viewModel, e)                        })                    }}            };        $.extend(events, {registerEvent: registerKoEvent})    })(jQuery, DevExpress);    /*! Module core, file ng.events.js */    (function($, DX, undefined) {        if (!DX.support.hasNg)            return;        var events = DX.ui.events;        var originalRegisterEvent = events.registerEvent;        var registerNgEvent = function(eventName, eventObject) {                originalRegisterEvent(eventName, eventObject);                var ngEventName = eventName.slice(0, 2) + eventName.charAt(2).toUpperCase() + eventName.slice(3);                DX.ng.module.directive(ngEventName, ['$parse', function($parse) {                        return function(scope, element, attr) {                                var attrValue = $.trim(attr[ngEventName]),                                    handler,                                    eventOptions = {};                                if (attrValue.charAt(0) === "{") {                                    eventOptions = scope.$eval(attrValue);                                    handler = $parse(eventOptions.execute)                                }                                else                                    handler = $parse(attr[ngEventName]);                                element.on(eventName, eventOptions, function(e) {                                    scope.$apply(function() {                                        handler(scope, {$event: e})                                    })                                })                            }                    }])            };        $.extend(events, {registerEvent: registerNgEvent})    })(jQuery, DevExpress);    /*! Module core, file ui.keyboardProcessor.js */    (function($, DX, undefined) {        var ui = DX.ui,            events = ui.events;        ui.KeyboardProcessor = DX.Class.inherit({            _keydown: events.addNamespace("keydown", "KeyboardProcessor"),            codes: {                "8": "backspace",                "9": "tab",                "13": "enter",                "27": "escape",                "33": "pageUp",                "34": "pageDown",                "35": "end",                "36": "home",                "37": "leftArrow",                "38": "upArrow",                "39": "rightArrow",                "40": "downArrow",                "46": "del",                "32": "space",                "70": "F",                "65": "A",                "106": "asterisk",                "109": "minus"            },            ctor: function(options) {                var _this = this;                options = options || {};                if (options.element)                    this._element = $(options.element);                if (options.focusTarget)                    this._focusTarget = options.focusTarget;                this._handler = options.handler;                this._context = options.context;                this._childProcessors = [];                if (this._element)                    this._element.on(this._keydown, function(e) {                        _this.process(e)                    })            },            dispose: function() {                if (this._element)                    this._element.off(this._keydown);                this._element = undefined;                this._handler = undefined;                this._context = undefined;                this._childProcessors = undefined            },            clearChildren: function() {                this._childProcessors = []            },            push: function(child) {                if (!this._childProcessors)                    this.clearChildren();                this._childProcessors.push(child);                return child            },            attachChildProcessor: function() {                var childProcessor = new ui.KeyboardProcessor;                this._childProcessors.push(childProcessor);                return childProcessor            },            reinitialize: function(childHandler, childContext) {                this._context = childContext;                this._handler = childHandler;                return this            },            process: function(e) {                if (this._focusTarget && this._focusTarget !== e.target && $.inArray(e.target, this._focusTarget) < 0)                    return false;                var args = {                        key: this.codes[e.which] || e.which,                        ctrl: e.ctrlKey,                        shift: e.shiftKey,                        alt: e.altKey,                        originalEvent: e                    };                var handlerResult = this._handler && this._handler.call(this._context, args);                if (handlerResult && this._childProcessors)                    $.each(this._childProcessors, function(index, childProcessor) {                        childProcessor.process(e)                    })            }        })    })(jQuery, DevExpress);    /*! Module core, file ui.dialog.js */    (function($, DX, undefined) {        var ui = DX.ui,            utils = DX.utils;        var DEFAULT_BUTTON = {                text: "OK",                onClick: function() {                    return true                }            };        var DX_DIALOG_CLASSNAME = "dx-dialog",            DX_DIALOG_WRAPPER_CLASSNAME = DX_DIALOG_CLASSNAME + "-wrapper",            DX_DIALOG_ROOT_CLASSNAME = DX_DIALOG_CLASSNAME + "-root",            DX_DIALOG_CONTENT_CLASSNAME = DX_DIALOG_CLASSNAME + "-content",            DX_DIALOG_MESSAGE_CLASSNAME = DX_DIALOG_CLASSNAME + "-message",            DX_DIALOG_BUTTONS_CLASSNAME = DX_DIALOG_CLASSNAME + "-buttons",            DX_DIALOG_BUTTON_CLASSNAME = DX_DIALOG_CLASSNAME + "-button";        var FakeDialogComponent = DX.Component.inherit({                NAME: "dxDialog",                ctor: function(element, options) {                    this.callBase(options)                },                _defaultOptionsRules: function() {                    return this.callBase().concat([{                                device: {platform: "ios"},                                options: {width: 276}                            }, {                                device: {platform: "android"},                                options: {                                    lWidth: "60%",                                    pWidth: "80%"                                }                            }, {                                device: {                                    platform: "win8",                                    phone: false                                },                                options: {width: function() {                                        return $(window).width()                                    }}                            }, {                                device: {                                    platform: "win8",                                    phone: true                                },                                options: {position: {                                        my: "top center",                                        at: "top center",                                        of: window,                                        offset: "0 0"                                    }}                            }])                }            });        var dialog = function(options) {                if (!ui.dxPopup)                    throw DX.Error("E0018");                var deferred = $.Deferred();                var defaultOptions = (new FakeDialogComponent).option();                options = $.extend(defaultOptions, options);                var $element = $("<div>").addClass(DX_DIALOG_CLASSNAME).appendTo(DX.viewPort());                var $message = $("<div>").addClass(DX_DIALOG_MESSAGE_CLASSNAME).html(String(options.message));                var popupButtons = [];                $.each(options.buttons || [DEFAULT_BUTTON], function() {                    if (this.clickAction) {                        DX.log("W0001", "Dialog", "clickAction", "14.2", "Use 'onClick' option instead");                        this.onClick = this.clickAction                    }                    var action = new DX.Action(this.onClick || this.clickAction, {context: popupInstance});                    popupButtons.push({                        toolbar: 'bottom',                        location: 'center',                        widget: 'button',                        options: {                            text: this.text,                            onClick: function() {                                var result = action.execute(arguments);                                hide(result)                            }                        }                    })                });                var popupInstance = $element.dxPopup({                        title: options.title || this.title,                        showTitle: function() {                            var isTitle = options.showTitle === undefined ? true : options.showTitle;                            return isTitle                        }(),                        height: "auto",                        width: function() {                            var isPortrait = $(window).height() > $(window).width(),                                key = (isPortrait ? "p" : "l") + "Width",                                widthOption = options.hasOwnProperty(key) ? options[key] : options["width"];                            return $.isFunction(widthOption) ? widthOption() : widthOption                        },                        showCloseButton: false,                        focusStateEnabled: false,                        onContentReady: function(args) {                            args.component.content().addClass(DX_DIALOG_CONTENT_CLASSNAME).append($message)                        },                        onShowing: function(e) {                            e.component.bottomToolbar().addClass(DX_DIALOG_BUTTONS_CLASSNAME).find(".dx-button").addClass(DX_DIALOG_BUTTON_CLASSNAME).first().focus()                        },                        buttons: popupButtons,                        animation: {                            show: {                                type: "pop",                                duration: 400                            },                            hide: {                                type: "pop",                                duration: 400,                                to: {                                    opacity: 0,                                    scale: 0                                },                                from: {                                    opacity: 1,                                    scale: 1                                }                            }                        },                        rtlEnabled: DX.rtlEnabled,                        boundaryOffset: {                            h: 10,                            v: 0                        }                    }).dxPopup("instance");                popupInstance._wrapper().addClass(DX_DIALOG_WRAPPER_CLASSNAME);                if (options.position)                    popupInstance.option("position", options.position);                popupInstance._wrapper().addClass(DX_DIALOG_ROOT_CLASSNAME);                function show() {                    popupInstance.show();                    utils.resetActiveElement();                    return deferred.promise()                }                function hide(value) {                    popupInstance.hide().done(function() {                        popupInstance.element().remove()                    });                    deferred.resolve(value)                }                return {                        show: show,                        hide: hide                    }            };        var alert = function(message, title, showTitle) {                var dialogInstance,                    options = $.isPlainObject(message) ? message : {                        title: title,                        message: message,                        showTitle: showTitle                    };                dialogInstance = ui.dialog.custom(options);                return dialogInstance.show()            };        var confirm = function(message, title, showTitle) {                var dialogInstance,                    options = $.isPlainObject(message) ? message : {                        title: title,                        message: message,                        showTitle: showTitle,                        buttons: [{                                text: Globalize.localize("Yes"),                                onClick: function() {                                    return true                                }                            }, {                                text: Globalize.localize("No"),                                onClick: function() {                                    return false                                }                            }]                    };                dialogInstance = ui.dialog.custom(options);                return dialogInstance.show()            };        var $notify = null;        var notify = function(message, type, displayTime) {                var options = $.isPlainObject(message) ? message : {message: message};                if (!ui.dxToast) {                    alert(options.message);                    return                }                if (options.hiddenAction) {                    DX.log("W0001", "Dialog", "hiddenAction", "14.2", "Use 'onHidden' option instead");                    options.onHidden = options.hiddenAction                }                var userHiddenAction = options.onHidden;                $.extend(options, {                    type: type,                    displayTime: displayTime,                    onHidden: function(args) {                        args.element.remove();                        new DX.Action(userHiddenAction, {context: args.model}).execute(arguments)                    }                });                $notify = $("<div>").appendTo(DX.viewPort()).dxToast(options);                $notify.dxToast("instance").show()            };        $.extend(ui, {            notify: notify,            dialog: {                custom: dialog,                alert: alert,                confirm: confirm            }        });        ui.dialog.FakeDialogComponent = FakeDialogComponent    })(jQuery, DevExpress);    /*! Module core, file ui.dataHelper.js */    (function($, DX, undefined) {        var data = DX.data;        var DATA_SOURCE_OPTIONS_METHOD = "_dataSourceOptions",            DATA_SOURCE_CHANGED_METHOD = "_dataSourceChangedHandler",            DATA_SOURCE_LOAD_ERROR_METHOD = "_dataSourceLoadErrorHandler",            DATA_SOURCE_LOADING_CHANGED_METHOD = "_dataSourceLoadingChangedHandler";        DX.ui.DataHelperMixin = {            postCtor: function() {                this.on("disposing", function() {                    this._disposeDataSource()                })            },            _isDataSourceReady: function() {                return !this._dataSource || this._dataSource.isLoaded()            },            _refreshDataSource: function() {                this._initDataSource();                this._loadDataSource()            },            _initDataSource: function() {                var dataSourceOptions = this.option("dataSource"),                    widgetDataSourceOptions,                    dataSourceType;                this._disposeDataSource();                if (dataSourceOptions) {                    if (dataSourceOptions instanceof data.DataSource) {                        this._isSharedDataSource = true;                        this._dataSource = dataSourceOptions                    }                    else {                        widgetDataSourceOptions = DATA_SOURCE_OPTIONS_METHOD in this ? this[DATA_SOURCE_OPTIONS_METHOD]() : {};                        dataSourceType = this._dataSourceType ? this._dataSourceType() : data.DataSource;                        this._dataSource = new dataSourceType($.extend(true, {}, widgetDataSourceOptions, data.utils.normalizeDataSourceOptions(dataSourceOptions)))                    }                    this._addDataSourceHandlers()                }            },            _addDataSourceHandlers: function() {                if (DATA_SOURCE_CHANGED_METHOD in this)                    this._addDataSourceChangeHandler();                if (DATA_SOURCE_LOAD_ERROR_METHOD in this)                    this._addDataSourceLoadErrorHandler();                if (DATA_SOURCE_LOADING_CHANGED_METHOD in this)                    this._addDataSourceLoadingChangedHandler();                this._addReadyWatcher()            },            _addReadyWatcher: function() {                this._dataSource.on("loadingChanged", $.proxy(function(isLoading) {                    this._ready && this._ready(!isLoading)                }, this))            },            _addDataSourceChangeHandler: function() {                var dataSource = this._dataSource;                this._proxiedDataSourceChangedHandler = $.proxy(function() {                    this[DATA_SOURCE_CHANGED_METHOD](dataSource.items())                }, this);                dataSource.on("changed", this._proxiedDataSourceChangedHandler)            },            _addDataSourceLoadErrorHandler: function() {                this._proxiedDataSourceLoadErrorHandler = $.proxy(this[DATA_SOURCE_LOAD_ERROR_METHOD], this);                this._dataSource.on("loadError", this._proxiedDataSourceLoadErrorHandler)            },            _addDataSourceLoadingChangedHandler: function() {                this._proxiedDataSourceLoadingChangedHandler = $.proxy(this[DATA_SOURCE_LOADING_CHANGED_METHOD], this);                this._dataSource.on("loadingChanged", this._proxiedDataSourceLoadingChangedHandler)            },            _loadDataSource: function() {                if (this._dataSource) {                    var dataSource = this._dataSource;                    if (dataSource.isLoaded())                        this._proxiedDataSourceChangedHandler && this._proxiedDataSourceChangedHandler();                    else                        dataSource.load()                }            },            _loadSingle: function(key, value) {                key = key === "this" ? this._dataSource.key() || "this" : key;                return this._dataSource.loadSingle(key, value)            },            _isLastPage: function() {                return !this._dataSource || this._dataSource.isLastPage() || !this._dataSource._pageSize            },            _isDataSourceLoading: function() {                return this._dataSource && this._dataSource.isLoading()            },            _disposeDataSource: function() {                if (this._dataSource) {                    if (this._isSharedDataSource) {                        delete this._isSharedDataSource;                        this._proxiedDataSourceChangedHandler && this._dataSource.off("changed", this._proxiedDataSourceChangedHandler);                        this._proxiedDataSourceLoadErrorHandler && this._dataSource.off("loadError", this._proxiedDataSourceLoadErrorHandler);                        this._proxiedDataSourceLoadingChangedHandler && this._dataSource.off("loadingChanged", this._proxiedDataSourceLoadingChangedHandler)                    }                    else                        this._dataSource.dispose();                    delete this._dataSource;                    delete this._proxiedDataSourceChangedHandler;                    delete this._proxiedDataSourceLoadErrorHandler;                    delete this._proxiedDataSourceLoadingChangedHandler                }            }        }    })(jQuery, DevExpress);    /*! Module core, file ui.dataExpression.js */    (function($, DX, undefined) {        var ui = DX.ui,            utils = DX.utils,            dataUtils = DX.data.utils;        ui.DataExpressionMixin = $.extend(ui.DataHelperMixin, {            _dataExpressionDeprecatedOptions: function() {                return {itemRender: {                            since: "14.2",                            alias: "itemTemplate"                        }}            },            _dataExpressionDefaultOptions: function() {                return {                        items: [],                        dataSource: null,                        itemTemplate: "item",                        value: null,                        valueExpr: "this",                        displayExpr: undefined                    }            },            _initDataExpressions: function() {                this._compileValueGetter();                this._compileDisplayGetter();                this._initDynamicTemplates();                this._initDataSource();                this._itemsToDataSource()            },            _itemsToDataSource: function() {                if (!this.option("dataSource"))                    this._dataSource = new DevExpress.data.DataSource({                        store: new DevExpress.data.ArrayStore(this.option("items")),                        pageSize: 0                    })            },            _compileDisplayGetter: function() {                this._displayGetter = dataUtils.compileGetter(this._displayGetterExpr())            },            _displayGetterExpr: function() {                return this.option("displayExpr")            },            _compileValueGetter: function() {                this._valueGetter = dataUtils.compileGetter(this._valueGetterExpr())            },            _valueGetterExpr: function() {                return this.option("valueExpr") || "this"            },            _loadValue: function(value) {                var deferred = $.Deferred();                value = this._unwrappedValue(value);                if (!utils.isDefined(value))                    return deferred.reject().promise();                this._loadSingle(this._valueGetterExpr(), value).done($.proxy(function(item) {                    this._isValueEquals(this._valueGetter(item), value) ? deferred.resolve(item) : deferred.reject()                }, this)).fail(function() {                    deferred.reject()                });                return deferred.promise()            },            _unwrappedValue: function(value) {                value = DX.utils.isDefined(value) ? value : this.option("value");                if (value && this._dataSource && this._valueGetterExpr() === "this") {                    var key = this._dataSource.key();                    if (key && typeof value === "object")                        value = value[key]                }                return utils.unwrapObservable(value)            },            _isValueEquals: function(value1, value2) {                var isDefined = utils.isDefined;                var ensureDefined = utils.ensureDefined;                var unwrapObservable = utils.unwrapObservable;                var dataSourceKey = this._dataSource && this._dataSource.key();                var result = this._compareValues(value1, value2);                if (!result && isDefined(value1) && isDefined(value2) && dataSourceKey) {                    var valueKey1 = ensureDefined(unwrapObservable(value1[dataSourceKey]), value1);                    var valueKey2 = ensureDefined(unwrapObservable(value2[dataSourceKey]), value2);                    result = this._compareValues(valueKey1, valueKey2)                }                return result            },            _compareValues: function(value1, value2) {                return dataUtils.toComparable(value1) === dataUtils.toComparable(value2)            },            _initDynamicTemplates: function() {                if (this._displayGetterExpr())                    this._dynamicTemplates["item"] = new ui.DefaultTemplate($.proxy(function(data) {                        return this._displayGetter(data)                    }, this));                else                    delete this._dynamicTemplates["item"]            },            _setCollectionWidgetItemTemplate: function() {                this._initDynamicTemplates();                this._setCollectionWidgetOption("itemTemplate", this._getTemplateByOption("itemTemplate"))            },            _dataExpressionOptionChanged: function(args) {                switch (args.name) {                    case"items":                        this._itemsToDataSource();                        this._setCollectionWidgetOption("items");                        break;                    case"dataSource":                        this._initDataSource();                        break;                    case"itemTemplate":                        this._setCollectionWidgetItemTemplate();                        break;                    case"valueExpr":                        this._compileValueGetter();                        break;                    case"displayExpr":                        this._compileDisplayGetter();                        this._setCollectionWidgetItemTemplate();                        break                }            }        })    })(jQuery, DevExpress);    /*! Module core, file ui.events.pointer.touchHooks.js */    (function($, DX, undefined) {        var touchEventHook = {                filter: function(event, originalEvent) {                    var touches = originalEvent.touches.length ? originalEvent.touches : originalEvent.changedTouches;                    $.each(["pageX", "pageY", "screenX", "screenY", "clientX", "clientY"], function() {                        event[this] = touches[0][this]                    });                    return event                },                props: $.event.mouseHooks.props.concat(["touches", "changedTouches", "targetTouches", "detail", "result", "originalTarget", "charCode", "prevValue"])            };        $.each(["touchstart", "touchmove", "touchend", "touchcancel"], function() {            $.event.fixHooks[this] = touchEventHook        })    })(jQuery, DevExpress);    /*! Module core, file ui.events.pointer.mspointerHooks.js */    (function($, DX, undefined) {        var POINTER_TYPE_MAP = {                2: "touch",                3: "pen",                4: "mouse"            };        var pointerEventHook = {                filter: function(event, originalEvent) {                    var pointerType = originalEvent.pointerType;                    if ($.isNumeric(pointerType))                        event.pointerType = POINTER_TYPE_MAP[pointerType];                    return event                },                props: $.event.mouseHooks.props.concat(["pointerId", "pointerType", "originalTarget", "width", "height", "pressure", "result", "tiltX", "charCode", "tiltY", "detail", "isPrimary", "prevValue"])            };        $.each(["MSPointerDown", "MSPointerMove", "MSPointerUp", "MSPointerCancel", "MSPointerOver", "MSPointerOut", "mouseenter", "mouseleave", "pointerdown", "pointermove", "pointerup", "pointercancel", "pointerover", "pointerout", "pointerenter", "pointerleave"], function() {            $.event.fixHooks[this] = pointerEventHook        })    })(jQuery, DevExpress);    /*! Module core, file ui.events.pointer.base.js */    (function($, DX, undefined) {        var ui = DX.ui,            events = ui.events;        var POINTER_EVENTS_NAMESPACE = "dxPointerEvents";        var BaseStrategy = DX.Class.inherit({                ctor: function(eventName, originalEvents) {                    this._eventName = eventName;                    this._eventNamespace = [POINTER_EVENTS_NAMESPACE, ".", this._eventName].join("");                    this._originalEvents = originalEvents;                    this._handlerCount = 0;                    this.noBubble = this._isNoBubble()                },                _isNoBubble: function() {                    var eventName = this._eventName;                    return eventName === "dxpointerenter" || eventName === "dxpointerleave"                },                _handler: function(e) {                    var delegateTarget = this._getDelegateTarget(e);                    return this._fireEvent({                            type: this._eventName,                            pointerType: e.pointerType || events.eventSource(e),                            originalEvent: e,                            delegateTarget: delegateTarget                        })                },                _getDelegateTarget: function(e) {                    var delegateTarget;                    if (this.noBubble)                        delegateTarget = e.delegateTarget;                    return delegateTarget                },                _fireEvent: function(args) {                    return events.fireEvent(args)                },                setup: function() {                    return true                },                add: function(element, handleObj) {                    if (this._handlerCount <= 0 || this.noBubble) {                        this._selector = handleObj.selector;                        element = this.noBubble ? element : document;                        $(element).on(events.addNamespace(this._originalEvents, this._eventNamespace), this._selector, $.proxy(this._handler, this))                    }                    if (!this.noBubble)                        this._handlerCount++                },                remove: function(element) {                    if (!this.noBubble)                        this._handlerCount--                },                teardown: function(element) {                    if (this._handlerCount && !this.noBubble)                        return;                    element = this.noBubble ? element : document;                    $(element).off("." + this._eventNamespace, this._selector)                },                dispose: function(element) {                    element = this.noBubble ? element : document;                    $(element).off("." + this._eventNamespace)                }            });        events.pointer = {};        events.pointer.BaseStrategy = BaseStrategy    })(jQuery, DevExpress);    /*! Module core, file ui.events.pointer.mouse.js */    (function($, DX, undefined) {        var ui = DX.ui,            events = ui.events,            pointer = events.pointer;        var MouseStrategyEventMap = {                dxpointerdown: "mousedown",                dxpointermove: "mousemove",                dxpointerup: "mouseup",                dxpointercancel: "",                dxpointerover: "mouseover",                dxpointerout: "mouseout",                dxpointerenter: "mouseenter",                dxpointerleave: "mouseleave"            };        var normalizeMouseEvent = function(e) {                var pointers = [];                e.pointerId = 1;                if (e.type !== "mouseup")                    pointers.push(e);                return {                        pointers: pointers,                        pointerId: 1                    }            };        var MouseStrategy = pointer.BaseStrategy.inherit({_fireEvent: function(args) {                    return this.callBase($.extend(normalizeMouseEvent(args.originalEvent), args))                }});        pointer.mouse = {            strategy: MouseStrategy,            map: MouseStrategyEventMap,            normalize: normalizeMouseEvent        }    })(jQuery, DevExpress);    /*! Module core, file ui.events.pointer.touch.js */    (function($, DX, undefined) {        var ui = DX.ui,            device = $.proxy(DX.devices.real, DX.devices),            events = ui.events,            pointer = events.pointer;        var TouchStrategyEventMap = {                dxpointerdown: "touchstart",                dxpointermove: "touchmove",                dxpointerup: "touchend",                dxpointercancel: "touchcancel"            };        var normalizeTouchEvent = function(e) {                var pointers = [];                $.each(e.touches, function(_, touch) {                    pointers.push($.extend({pointerId: touch.identifier}, touch))                });                return {                        pointers: pointers,                        pointerId: e.changedTouches[0].identifier                    }            };        var skipTouchWithSameIdentifier = function(pointerEvent) {                return device().platform === "ios" && (pointerEvent === "dxpointerdown" || pointerEvent === "dxpointerup")            };        var TouchStrategy = pointer.BaseStrategy.inherit({                ctor: function() {                    this.callBase.apply(this, arguments);                    this._pointerId = 0                },                _handler: function(e) {                    if (skipTouchWithSameIdentifier(this._eventName)) {                        var touch = e.changedTouches[0];                        if (this._pointerId === touch.identifier && this._pointerId !== 0)                            return;                        this._pointerId = touch.identifier                    }                    return this.callBase.apply(this, arguments)                },                _fireEvent: function(args) {                    return this.callBase($.extend(normalizeTouchEvent(args.originalEvent), args))                }            });        pointer.touch = {            strategy: TouchStrategy,            map: TouchStrategyEventMap,            normalize: normalizeTouchEvent        }    })(jQuery, DevExpress);    /*! Module core, file ui.events.pointer.mouseAndTouch.js */    (function($, DX, undefined) {        var ui = DX.ui,            events = ui.events,            pointer = events.pointer;        var MouseAndTouchStrategyEventMap = {                dxpointerdown: "touchstart mousedown",                dxpointermove: "touchmove mousemove",                dxpointerup: "touchend mouseup",                dxpointercancel: "touchcancel",                dxpointerover: "mouseover",                dxpointerout: "mouseout",                dxpointerenter: "mouseenter",                dxpointerleave: "mouseleave"            };        var MouseAndTouchStrategy = pointer.BaseStrategy.inherit({                EVENT_LOCK_TIMEOUT: 100,                _handler: function(e) {                    var isMouseEvent = events.isMouseEvent(e);                    if (!isMouseEvent)                        this._skipNextEvents = true;                    if (isMouseEvent && this._mouseLocked)                        return;                    if (isMouseEvent && this._skipNextEvents) {                        this._skipNextEvents = false;                        this._mouseLocked = true;                        clearTimeout(this._unlockMouseTimer);                        this._unlockMouseTimer = setTimeout($.proxy(function() {                            this._mouseLocked = false                        }, this), this.EVENT_LOCK_TIMEOUT);                        return                    }                    return this.callBase(e)                },                _fireEvent: function(args) {                    var isMouseEvent = events.isMouseEvent(args.originalEvent),                        normalizer = isMouseEvent ? pointer.mouse.normalize : pointer.touch.normalize;                    return this.callBase($.extend(normalizer(args.originalEvent), args))                },                dispose: function() {                    this.callBase();                    this._skipNextEvents = false;                    this._mouseLocked = false;                    clearTimeout(this._unlockMouseTimer)                }            });        pointer.mouseAndTouch = {            strategy: MouseAndTouchStrategy,            map: MouseAndTouchStrategyEventMap        }    })(jQuery, DevExpress);    /*! Module core, file ui.events.pointer.mspointer.js */    (function($, DX, undefined) {        var ui = DX.ui,            events = ui.events,            pointer = events.pointer;        var MsPointerStrategyEventMap = {                dxpointerdown: "MSPointerDown pointerdown",                dxpointermove: "MSPointerMove pointermove",                dxpointerup: "MSPointerUp pointerup",                dxpointercancel: "MSPointerCancel pointercancel",                dxpointerover: "MSPointerOver pointerover",                dxpointerout: "MSPointerOut pointerout",                dxpointerenter: "mouseenter",                dxpointerleave: "mouseleave"            };        var pointers = [];        var getPointerIndex = function(e) {                var index = -1;                $.each(pointers, function(i, pointer) {                    if (e.pointerId === pointer.pointerId) {                        index = i;                        return true                    }                });                return index            };        var addPointer = function(e) {                if (getPointerIndex(e) === -1)                    pointers.push(e)            };        var removePointer = function(e) {                pointers.splice(getPointerIndex(e), 1)            };        var updatePointer = function(e) {                pointers[getPointerIndex(e)] = e            };        var addEventsListner = function(events, handler) {                events = events.split(" ");                $.each(events, function(_, event) {                    document.addEventListener(event, handler, true)                })            };        var activateMspointerStrategy = function() {                var eventMap = MsPointerStrategyEventMap;                addEventsListner(eventMap.dxpointerdown, addPointer);                addEventsListner(eventMap.dxpointermove, updatePointer);                addEventsListner(eventMap.dxpointerup, removePointer);                addEventsListner(eventMap.dxpointercancel, removePointer);                activateMspointerStrategy = $.noop            };        var MsPointerStrategy = pointer.BaseStrategy.inherit({                ctor: function() {                    this.callBase.apply(this, arguments);                    activateMspointerStrategy()                },                _fireEvent: function(args) {                    return this.callBase($.extend({                            pointers: pointers,                            pointerId: args.originalEvent.pointerId                        }, args))                }            });        pointer.msPointer = {            strategy: MsPointerStrategy,            map: MsPointerStrategyEventMap        };        DX.ui.events.__internals = DX.ui.events.__internals || {};        $.extend(DX.ui.events.__internals, {cleanMsPointers: function() {                pointers = []            }})    })(jQuery, DevExpress);    /*! Module core, file ui.events.pointer.js */    (function($, DX, undefined) {        var ui = DX.ui,            support = DX.support,            device = $.proxy(DX.devices.real, DX.devices),            events = ui.events,            pointer = events.pointer;        var eventType = function() {                if (support.pointer)                    return pointer.msPointer;                if (support.touch && !(device().tablet || device().phone))                    return pointer.mouseAndTouch;                if (support.touch)                    return pointer.touch;                return pointer.mouse            }();        $.each(eventType.map, function(pointerEvent, originalEvents) {            events.registerEvent(pointerEvent, new eventType.strategy(pointerEvent, originalEvents))        })    })(jQuery, DevExpress);    /*! Module core, file ui.events.wheel.js */    (function($, DX, undefined) {        var ui = DX.ui,            events = ui.events;        var EVENT_NAME = "dxmousewheel",            EVENT_NAMESPACE = "dxWheel";        $.event.fixHooks["wheel"] = $.event.mouseHooks;        var wheelEvent = document.onmousewheel !== undefined ? "mousewheel" : "wheel";        var wheel = {                setup: function(element, data) {                    var $element = $(element);                    $element.on(events.addNamespace(wheelEvent, EVENT_NAMESPACE), $.proxy(wheel._wheelHandler, wheel))                },                teardown: function(element) {                    var $element = $(element);                    $element.off("." + EVENT_NAMESPACE)                },                _wheelHandler: function(e) {                    var delta = this._getWheelDelta(e.originalEvent);                    events.fireEvent({                        type: EVENT_NAME,                        originalEvent: e,                        delta: delta,                        pointerType: "mouse"                    });                    e.stopPropagation()                },                _getWheelDelta: function(event) {                    return event.wheelDelta ? event.wheelDelta : -event.deltaY * 30                }            };        events.registerEvent(EVENT_NAME, wheel)    })(jQuery, DevExpress);    /*! Module core, file ui.events.hover.js */    (function($, DX, undefined) {        var ui = DX.ui,            events = ui.events;        var HOVERSTART_NAMESPACE = "dxHoverStart",            HOVERSTART = "dxhoverstart",            POINTERENTER_NAMESPACED_EVENT_NAME = events.addNamespace("dxpointerenter", HOVERSTART_NAMESPACE),            POINTERDOWN_NAMESPACED_EVENT_NAME = events.addNamespace("dxpointerdown", HOVERSTART_NAMESPACE),            POINTERUP_NAMESPACED_EVENT_NAME = events.addNamespace("dxpointerup", HOVERSTART_NAMESPACE),            HOVEREND_NAMESPACE = "dxHoverEnd",            HOVEREND = "dxhoverend",            POINTERLEAVE_NAMESPACED_EVENT_NAME = events.addNamespace("dxpointerleave", HOVEREND_NAMESPACE);        var Hover = DX.Class.inherit({                noBubble: true,                add: function(element, handleObj) {                    var $element = $(element);                    $element.off("." + this._namespace).on(this._originalEventName, handleObj.selector, $.proxy(this._handler, this))                },                _handler: function(e) {                    if (events.isTouchEvent(e))                        return;                    events.fireEvent({                        type: this._eventName,                        originalEvent: e,                        delegateTarget: e.delegateTarget                    })                },                teardown: function(element) {                    $(element).off("." + this._namespace)                }            });        var HoverStart = Hover.inherit({                ctor: function() {                    this._eventName = HOVERSTART;                    this._originalEventName = POINTERENTER_NAMESPACED_EVENT_NAME;                    this._namespace = HOVERSTART_NAMESPACE;                    this._isMouseDown = false;                    this._eventsAttached = 0                },                _handler: function(e) {                    if (!this._isMouseDown)                        this.callBase.apply(this, arguments)                },                setup: function() {                    $(document).off("." + HOVERSTART_NAMESPACE).on(POINTERDOWN_NAMESPACED_EVENT_NAME, $.proxy(function() {                        this._isMouseDown = true                    }, this)).on(POINTERUP_NAMESPACED_EVENT_NAME, $.proxy(function() {                        this._isMouseDown = false                    }, this));                    this._eventsAttached++                },                teardown: function() {                    this._eventsAttached--;                    if (this._eventsAttached === 0)                        $(document).off("." + HOVERSTART_NAMESPACE)                }            });        var HoverEnd = Hover.inherit({ctor: function() {                    this._eventName = HOVEREND;                    this._originalEventName = POINTERLEAVE_NAMESPACED_EVENT_NAME;                    this._namespace = HOVEREND_NAMESPACE                }});        events.registerEvent(HOVERSTART, new HoverStart);        events.registerEvent(HOVEREND, new HoverEnd)    })(jQuery, DevExpress);    /*! Module core, file ui.events.manager.js */    (function($, DX, undefined) {        var ui = DX.ui,            events = ui.events;        var MANAGER_EVENT = "dxEventManager",            EMITTER_DATA = "dxEmitter";        var EventManager = DX.Class.inherit({                ctor: function() {                    this._attachHandlers();                    this.reset();                    this._proxiedCancelHandler = $.proxy(this._cancelHandler, this);                    this._proxiedAcceptHandler = $.proxy(this._acceptHandler, this)                },                _attachHandlers: function() {                    $(document).on(events.addNamespace("dxpointerdown", MANAGER_EVENT), $.proxy(this._pointerDownHandler, this)).on(events.addNamespace("dxpointermove", MANAGER_EVENT), $.proxy(this._pointerMoveHandler, this)).on(events.addNamespace("dxpointerup dxpointercancel", MANAGER_EVENT), $.proxy(this._pointerUpHandler, this)).on(events.addNamespace("dxmousewheel", MANAGER_EVENT), $.proxy(this._mouseWheelHandler, this))                },                _eachEmitter: function(callback) {                    var activeEmitters = this._activeEmitters || [];                    var i = 0;                    while (activeEmitters.length > i) {                        var emitter = activeEmitters[i];                        if (callback(emitter) === false)                            break;                        if (activeEmitters[i] === emitter)                            i++                    }                },                _applyToEmitters: function(method, arg) {                    this._eachEmitter(function(emitter) {                        emitter[method].call(emitter, arg)                    })                },                reset: function() {                    this._eachEmitter(this._proxiedCancelHandler);                    this._activeEmitters = []                },                resetEmitter: function(emitter) {                    this._proxiedCancelHandler(emitter)                },                _pointerDownHandler: function(e) {                    if (events.isMouseEvent(e) && e.which > 1)                        return;                    this._updateEmitters(e)                },                _updateEmitters: function(e) {                    if (!this._isSetChanged(e))                        return;                    this._cleanEmitters(e);                    this._fetchEmitters(e)                },                _isSetChanged: function(e) {                    var currentSet = this._closestEmitter(e);                    var previousSet = this._emittersSet || [];                    var setChanged = currentSet.length !== previousSet.length;                    $.each(currentSet, function(index, emitter) {                        setChanged = setChanged || previousSet[index] !== emitter;                        return !setChanged                    });                    this._emittersSet = currentSet;                    return setChanged                },                _closestEmitter: function(e) {                    var that = this,                        result = [],                        $element = $(e.target);                    function handleEmitter(_, emitter) {                        if (!!emitter && emitter.validatePointers(e) && emitter.validate(e)) {                            emitter.addCancelCallback(that._proxiedCancelHandler);                            emitter.addAcceptCallback(that._proxiedAcceptHandler);                            result.push(emitter)                        }                    }                    while ($element.length) {                        var emitters = $.data($element.get(0), EMITTER_DATA) || [];                        $.each(emitters, handleEmitter);                        $element = $element.parent()                    }                    return result                },                _acceptHandler: function(acceptedEmitter, e) {                    var that = this;                    this._eachEmitter(function(emitter) {                        if (emitter !== acceptedEmitter)                            that._cancelEmitter(emitter, e)                    })                },                _cancelHandler: function(canceledEmitter, e) {                    this._cancelEmitter(canceledEmitter, e)                },                _cancelEmitter: function(emitter, e) {                    var activeEmitters = this._activeEmitters;                    if (e)                        emitter.cancel(e);                    else                        emitter.reset();                    emitter.removeCancelCallback();                    emitter.removeAcceptCallback();                    var emitterIndex = $.inArray(emitter, activeEmitters);                    if (emitterIndex > -1)                        activeEmitters.splice(emitterIndex, 1)                },                _cleanEmitters: function(e) {                    this._applyToEmitters("end", e);                    this.reset(e)                },                _fetchEmitters: function(e) {                    this._activeEmitters = this._emittersSet.slice();                    this._applyToEmitters("start", e)                },                _pointerMoveHandler: function(e) {                    this._applyToEmitters("move", e)                },                _pointerUpHandler: function(e) {                    this._updateEmitters(e)                },                _mouseWheelHandler: function(e) {                    var allowInterruption = true;                    this._eachEmitter(function(emitter) {                        allowInterruption = emitter.allowInterruptionByMousewheel() && allowInterruption;                        return allowInterruption                    });                    if (!allowInterruption)                        return;                    e.pointers = [null];                    this._pointerDownHandler(e);                    this._eachEmitter(function(emitter) {                        var direction = emitter.getDirection ? emitter.getDirection(e) : "",                            prop = direction !== "horizontal" ? "pageY" : "pageX";                        if (direction)                            e[prop] += e.delta;                        return !direction                    });                    this._pointerMoveHandler(e);                    e.pointers = [];                    this._pointerUpHandler(e)                },                isActive: function(element) {                    var result = false;                    this._eachEmitter(function(emitter) {                        result = result || emitter.getElement().is(element)                    });                    return result                }            });        var eventManager = new EventManager;        var EMITTER_SUBSCRIPTION_DATA = "dxEmitterSubscription";        var registerEmitter = function(emitterConfig) {                var emitterClass = emitterConfig.emitter,                    emitterName = emitterConfig.events[0],                    emitterEvents = emitterConfig.events;                $.each(emitterEvents, function(_, eventName) {                    events.registerEvent(eventName, {                        noBubble: !emitterConfig.bubble,                        setup: function(element, data) {                            var subscriptions = $.data(element, EMITTER_SUBSCRIPTION_DATA) || {},                                emitters = $.data(element, EMITTER_DATA) || {},                                emitter = emitters[emitterName] || new emitterClass(element);                            subscriptions[eventName] = true;                            emitters[emitterName] = emitter;                            $.data(element, EMITTER_DATA, emitters);                            $.data(element, EMITTER_SUBSCRIPTION_DATA, subscriptions)                        },                        add: function(element, handleObj) {                            var emitters = $.data(element, EMITTER_DATA),                                emitter = emitters[emitterName];                            emitter.configurate($.extend({delegateSelector: handleObj.selector}, handleObj.data), handleObj.type)                        },                        teardown: function(element) {                            var subscriptions = $.data(element, EMITTER_SUBSCRIPTION_DATA),                                emitters = $.data(element, EMITTER_DATA),                                emitter = emitters[emitterName];                            delete subscriptions[eventName];                            var disposeEmitter = true;                            $.each(emitterEvents, function(_, eventName) {                                disposeEmitter = disposeEmitter && !subscriptions[eventName];                                return disposeEmitter                            });                            if (disposeEmitter) {                                if (eventManager.isActive(element))                                    eventManager.resetEmitter(emitter);                                emitter && emitter.dispose();                                delete emitters[emitterName]                            }                        }                    })                })            };        $.extend(events, {registerEmitter: registerEmitter})    })(jQuery, DevExpress);    /*! Module core, file ui.events.emitter.js */    (function($, DX, undefined) {        var ui = DX.ui,            events = ui.events;        var Emitter = DX.Class.inherit({                ctor: function(element) {                    this._$element = $(element);                    this._cancelCallback = $.Callbacks();                    this._acceptCallback = $.Callbacks()                },                getElement: function() {                    return this._$element                },                validate: function(e) {                    return e.type !== "dxmousewheel"                },                validatePointers: function(e) {                    return events.hasTouches(e) === 1                },                allowInterruptionByMousewheel: function() {                    return true                },                configurate: function(data) {                    $.extend(this, data)                },                addCancelCallback: function(callback) {                    this._cancelCallback.add(callback)                },                removeCancelCallback: function() {                    this._cancelCallback.empty()                },                _cancel: function(e) {                    this._cancelCallback.fire(this, e)                },                addAcceptCallback: function(callback) {                    this._acceptCallback.add(callback)                },                removeAcceptCallback: function() {                    this._acceptCallback.empty()                },                _accept: function(e) {                    this._acceptCallback.fire(this, e)                },                _requestAccept: function(e) {                    this._acceptRequestEvent = e                },                _forgetAccept: function() {                    this._accept(this._acceptRequestEvent);                    this._acceptRequestEvent = null                },                start: $.noop,                move: $.noop,                end: $.noop,                cancel: $.noop,                reset: function() {                    if (this._acceptRequestEvent)                        this._accept(this._acceptRequestEvent)                },                _fireEvent: function(eventName, e, params) {                    var eventData = $.extend({                            type: eventName,                            originalEvent: e,                            target: this._getEmitterTarget(e),                            delegateTarget: this.getElement().get(0)                        }, params);                    e = events.fireEvent(eventData);                    if (e.cancel)                        this._cancel(e);                    return e                },                _getEmitterTarget: function(e) {                    return (this.delegateSelector ? $(e.target).closest(this.delegateSelector) : this.getElement()).get(0)                },                dispose: $.noop            });        $.extend(events, {Emitter: Emitter})    })(jQuery, DevExpress);    /*! Module core, file ui.events.emitter.feedback.js */    (function($, DX, undefined) {        var ui = DX.ui,            events = ui.events,            ACTIVE_EVENT_NAME = "dxactive",            INACTIVE_EVENT_NAME = "dxinactive",            ACTIVE_TIMEOUT = 30,            INACTIVE_TIMEOUT = 400;        var activeEmitter;        var FeedbackEmitter = events.Emitter.inherit({                configurate: function(data, eventName) {                    switch (eventName) {                        case ACTIVE_EVENT_NAME:                            data.activeTimeout = data.timeout;                            break;                        case INACTIVE_EVENT_NAME:                            data.inactiveTimeout = data.timeout;                            break                    }                    this.callBase(data)                },                start: function(e) {                    var element = this.getElement().get(0);                    var activeElement = activeEmitter && activeEmitter.getElement().get(0);                    var activeChildExists = $.contains(element, activeElement);                    var childJustActivated = activeEmitter && activeEmitter._activeTimer !== null;                    if (activeChildExists && childJustActivated)                        this._cancel();                    else {                        if (activeEmitter)                            activeEmitter._forceInactiveTimer();                        activeEmitter = this;                        var eventTarget = this._getEmitterTarget(e);                        this._forceActiveTimer = $.proxy(this._fireActive, this, e, eventTarget);                        this._forceInactiveTimer = $.proxy(this._fireInctive, this, e, eventTarget);                        this._startActiveTimer(e)                    }                },                cancel: function(e) {                    this.end(e)                },                end: function(e) {                    var skipTimers = e.type !== "dxpointerup";                    if (skipTimers)                        this._stopActiveTimer();                    else                        this._forceActiveTimer();                    this._startInactiveTimer(e);                    if (skipTimers)                        this._forceInactiveTimer()                },                dispose: function() {                    this._stopActiveTimer();                    this._stopInactiveTimer();                    this.callBase()                },                _startActiveTimer: function(e) {                    var activeTimeout = "activeTimeout" in this ? this.activeTimeout : ACTIVE_TIMEOUT;                    this._activeTimer = window.setTimeout(this._forceActiveTimer, activeTimeout)                },                _fireActive: function(e, eventTarget) {                    this._stopActiveTimer();                    this._fireEvent(ACTIVE_EVENT_NAME, e, {target: eventTarget})                },                _stopActiveTimer: function() {                    clearTimeout(this._activeTimer);                    this._activeTimer = null                },                _forceActiveTimer: $.noop,                _startInactiveTimer: function(e) {                    var inactiveTimeout = "inactiveTimeout" in this ? this.inactiveTimeout : INACTIVE_TIMEOUT;                    this._inactiveTimer = window.setTimeout(this._forceInactiveTimer, inactiveTimeout)                },                _fireInctive: function(e, eventTarget) {                    this._stopInactiveTimer();                    activeEmitter = null;                    this._fireEvent(INACTIVE_EVENT_NAME, e, {target: eventTarget})                },                _stopInactiveTimer: function() {                    clearTimeout(this._inactiveTimer);                    this._inactiveTimer = null                },                _forceInactiveTimer: $.noop,                lockInactive: function() {                    this._forceActiveTimer();                    this._stopInactiveTimer();                    activeEmitter = null;                    this._cancel();                    return this._forceInactiveTimer                }            });        ui.events = $.extend(ui.events, {lockFeedback: function(deferred) {                var lockInactive = activeEmitter ? activeEmitter.lockInactive() : $.noop;                $.when(deferred).always(lockInactive)            }});        events.registerEmitter({            emitter: FeedbackEmitter,            events: [ACTIVE_EVENT_NAME, INACTIVE_EVENT_NAME]        })    })(jQuery, DevExpress);    /*! Module core, file ui.events.emitter.click.js */    (function($, DX, wnd, undefined) {        var ui = DX.ui,            utils = DX.utils,            events = ui.events,            abs = Math.abs,            CLICK_EVENT_NAME = "dxclick",            TOUCH_BOUNDARY = 10;        var isInput = function(element) {                return $(element).is("input, textarea, select, button ,:focus, :focus *")            };        var misc = {requestAnimationFrame: DX.requestAnimationFrame};        var ClickEmitter = events.Emitter.inherit({                ctor: function(element) {                    this.callBase(element);                    this._makeElementClickable($(element))                },                _makeElementClickable: function($element) {                    if (!$element.attr("onclick"))                        $element.attr("onclick", "void(0)")                },                start: function(e) {                    this._blurPrevented = e.dxPreventBlur;                    this._startTarget = e.target;                    this._startEventData = events.eventData(e)                },                end: function(e) {                    if (this._eventOutOfElement(e, this.getElement().get(0)) || e.type === "dxpointercancel") {                        this._cancel(e);                        return                    }                    if (!isInput(e.target) && !this._blurPrevented)                        utils.resetActiveElement();                    this._accept(e);                    misc.requestAnimationFrame($.proxy(function() {                        this._fireClickEvent(e)                    }, this))                },                _eventOutOfElement: function(e, element) {                    var target = e.target,                        targetChanged = !$.contains(element, target) && element !== target,                        gestureDelta = events.eventDelta(events.eventData(e), this._startEventData),                        boundsExceeded = abs(gestureDelta.x) > TOUCH_BOUNDARY || abs(gestureDelta.y) > TOUCH_BOUNDARY;                    return targetChanged || boundsExceeded                },                _fireClickEvent: function(e) {                    this._fireEvent(CLICK_EVENT_NAME, e, {target: utils.closestCommonParent(this._startTarget, e.target)})                }            });        (function() {            var useNativeClick = DX.devices.real().generic;            if (useNativeClick) {                var prevented = null;                ClickEmitter = ClickEmitter.inherit({                    start: function() {                        prevented = null                    },                    end: $.noop,                    cancel: function() {                        prevented = true                    }                });                var clickHandler = function(e) {                        if ((!e.which || e.which === 1) && !prevented)                            events.fireEvent({                                type: CLICK_EVENT_NAME,                                originalEvent: e                            })                    };                $(document).on(events.addNamespace("click", "NATIVE_DXCLICK_STRATEGY"), clickHandler)            }            $.extend(events.__internals, {useNativeClick: useNativeClick})        })();        (function() {            var fixBuggyInertia = DX.devices.real().ios;            if (fixBuggyInertia) {                var GESTURE_LOCK_KEY = "dxGestureLock";                ClickEmitter = ClickEmitter.inherit({_fireClickEvent: function(e) {                        var $element = $(e.target);                        while ($element.length) {                            if ($.data($element.get(0), GESTURE_LOCK_KEY))                                return;                            $element = $element.parent()                        }                        this.callBase.apply(this, arguments)                    }})            }            $.extend(events.__internals, {fixBuggyInertia: fixBuggyInertia})        })();        (function() {            var desktopDevice = DX.devices.real().generic;            if (!desktopDevice) {                var startTarget = null,                    blurPrevented = false;                var pointerDownHandler = function(e) {                        startTarget = e.target;                        blurPrevented = e.dxPreventBlur                    };                var clickHandler = function(e) {                        var $target = $(e.target);                        if (!blurPrevented && startTarget && !$target.is(startTarget) && !$(startTarget).is("label") && isInput($target))                            utils.resetActiveElement();                        startTarget = null;                        blurPrevented = false                    };                var NATIVE_CLICK_FIXER_NAMESPACE = "NATIVE_CLICK_FIXER";                $(document).on(events.addNamespace("dxpointerdown", NATIVE_CLICK_FIXER_NAMESPACE), pointerDownHandler).on(events.addNamespace("click", NATIVE_CLICK_FIXER_NAMESPACE), clickHandler)            }        })();        events.registerEmitter({            emitter: ClickEmitter,            bubble: true,            events: [CLICK_EVENT_NAME]        });        $.extend(events.__internals, {            useFastClick: !events.__internals.useNativeClick && !events.__internals.fixBuggyInertia,            misc: misc        })    })(jQuery, DevExpress, window);    /*! Module core, file ui.events.emitter.hold.js */    (function($, DX, undefined) {        var ui = DX.ui,            events = ui.events,            abs = Math.abs,            HOLD_EVENT_NAME = "dxhold",            HOLD_TIMEOUT = 750,            TOUCH_BOUNDARY = 5;        var HoldEmitter = events.Emitter.inherit({                start: function(e) {                    this._startEventData = events.eventData(e);                    this._startTimer(e)                },                _startTimer: function(e) {                    var holdTimeout = "timeout" in this ? this.timeout : HOLD_TIMEOUT;                    this._holdTimer = setTimeout($.proxy(function() {                        this._requestAccept(e);                        this._fireEvent(HOLD_EVENT_NAME, e, {target: e.target});                        this._forgetAccept()                    }, this), holdTimeout)                },                move: function(e) {                    if (this._touchWasMoved(e))                        this._cancel(e)                },                _touchWasMoved: function(e) {                    var delta = events.eventDelta(this._startEventData, events.eventData(e));                    return abs(delta.x) > TOUCH_BOUNDARY || abs(delta.y) > TOUCH_BOUNDARY                },                end: function() {                    this._stopTimer()                },                _stopTimer: function() {                    clearTimeout(this._holdTimer)                },                cancel: function() {                    this._stopTimer()                }            });        events.registerEmitter({            emitter: HoldEmitter,            bubble: true,            events: [HOLD_EVENT_NAME]        })    })(jQuery, DevExpress);    /*! Module core, file ui.events.emitter.gesture.js */    (function($, DX, undefined) {        var ui = DX.ui,            utils = DX.utils,            events = ui.events,            devices = DX.devices,            support = DX.support,            abs = Math.abs;        var SLEEP = 0,            INITED = 1,            STARTED = 2,            TOUCH_BOUNDARY = 10,            IMMEDIATE_TOUCH_BOUNDARY = 0,            IMMEDIATE_TIMEOUT = 180;        var isMousewheelEvent = function(e) {                return e && e.type === "dxmousewheel"            };        var GestureEmitter = events.Emitter.inherit({                configurate: function(data) {                    this.getElement().css("msTouchAction", data.immediate ? "pinch-zoom" : "");                    this.callBase(data)                },                allowInterruptionByMousewheel: function() {                    return this._stage !== STARTED                },                getDirection: function() {                    return this.direction                },                _cancel: function(e) {                    this.callBase.apply(this, arguments);                    this._togglePointerAddons(true);                    this._stage = SLEEP                },                start: function(e) {                    if (events.needSkipEvent(e)) {                        this._cancel(e);                        return                    }                    this._startEvent = events.createEvent(e);                    this._startEventData = events.eventData(e);                    this._prevEventData = this._startEventData;                    this._stage = INITED;                    this._init(e);                    this._setupImmediateTimer()                },                _setupImmediateTimer: function() {                    clearTimeout(this._immediateTimer);                    this._immedeateAccepted = false;                    if (!this.immediate)                        return;                    this._immediateTimer = setTimeout($.proxy(function() {                        this._immedeateAccepted = true                    }, this), IMMEDIATE_TIMEOUT)                },                move: function(e) {                    if (this._stage === INITED && this._directionConfirmed(e)) {                        this._stage = STARTED;                        this._resetActiveElement();                        this._togglePointerAddons(false, e);                        this._clearSelection(e);                        this._adjustStartEvent(e);                        this._start(this._startEvent);                        this._prevEventData = events.eventData(this._startEvent);                        if (this._stage === SLEEP)                            return;                        this._requestAccept(e);                        this._move(e);                        this._forgetAccept()                    }                    else if (this._stage === STARTED)                        this._move(e);                    this._prevEventData = events.eventData(e)                },                _directionConfirmed: function(e) {                    var touchBoundary = this._getTouchBoundary(e),                        delta = events.eventDelta(this._startEventData, events.eventData(e)),                        deltaX = abs(delta.x),                        deltaY = abs(delta.y);                    var horizontalMove = this._validateMove(touchBoundary, deltaX, deltaY),                        verticalMove = this._validateMove(touchBoundary, deltaY, deltaX);                    var direction = this.getDirection(e),                        bothAccepted = direction === "both" && (horizontalMove || verticalMove),                        horizontalAccepted = direction === "horizontal" && horizontalMove,                        verticalAccepted = direction === "vertical" && verticalMove;                    return bothAccepted || horizontalAccepted || verticalAccepted || this._immedeateAccepted                },                _validateMove: function(touchBoundary, mainAxis, crossAxis) {                    return mainAxis && mainAxis >= touchBoundary && (this.immediate ? mainAxis >= crossAxis : true)                },                _getTouchBoundary: function(e) {                    return this.immediate || isMousewheelEvent(e) ? IMMEDIATE_TOUCH_BOUNDARY : TOUCH_BOUNDARY                },                _adjustStartEvent: function(e) {                    var touchBoundary = this._getTouchBoundary(e),                        delta = events.eventDelta(this._startEventData, events.eventData(e));                    this._startEvent.pageX += utils.sign(delta.x) * touchBoundary;                    this._startEvent.pageY += utils.sign(delta.y) * touchBoundary                },                _resetActiveElement: function() {                    if (devices.real().platform === "ios" && $(":focus", this.getElement()).length)                        utils.resetActiveElement()                },                _togglePointerAddons: function(toggle, e) {                    var isStarted = this._stage === STARTED;                    if (isStarted) {                        this._togglePointerInteration(toggle);                        if (!isMousewheelEvent(e))                            this._togglePointerCursor(toggle)                    }                },                _togglePointerInteration: function(toggle) {                    var isDesktop = devices.real().platform === "generic";                    if (isDesktop) {                        $("body").css("pointer-events", toggle ? "" : "none");                        if (support.supportProp("user-select"))                            $("body").css(support.styleProp("user-select"), toggle ? "" : "none")                    }                },                _togglePointerCursor: function(toggle) {                    if (toggle)                        $("html").css("cursor", this._originalCursor);                    else {                        this._originalCursor = $("html").css("cursor");                        $("html").css("cursor", this.getElement().css("cursor"))                    }                },                _clearSelection: function(e) {                    if (isMousewheelEvent(e) || events.isTouchEvent(e))                        return;                    utils.clearSelection()                },                end: function(e) {                    this._togglePointerAddons(true, e);                    if (this._stage === STARTED)                        this._end(e);                    else if (this._stage === INITED)                        this._stop(e);                    this._stage = SLEEP                },                dispose: function() {                    clearTimeout(this._immediateTimer);                    this.callBase.apply(this, arguments);                    this._togglePointerAddons(true)                },                _init: $.noop,                _start: $.noop,                _move: $.noop,                _stop: $.noop,                _end: $.noop            });        $.extend(events, {GestureEmitter: GestureEmitter});        var ORIG_TOUCH_BOUNDARY = TOUCH_BOUNDARY;        $.extend(DX.ui.events.__internals, {            GESTURE_TOUCH_BOUNDARY: ORIG_TOUCH_BOUNDARY,            resetTouchBoundary: function() {                TOUCH_BOUNDARY = ORIG_TOUCH_BOUNDARY;                events.__internals.GESTURE_TOUCH_BOUNDARY = ORIG_TOUCH_BOUNDARY            },            cleanTouchBoundary: function() {                TOUCH_BOUNDARY = 0            }        })    })(jQuery, DevExpress);    /*! Module core, file ui.events.emitter.gesture.scroll.js */    (function($, DX, undefined) {        var ui = DX.ui,            events = ui.events;        var SCROLL_INIT_EVENT = "dxscrollinit",            SCROLL_START_EVENT = "dxscrollstart",            SCROLL_MOVE_EVENT = "dxscroll",            SCROLL_END_EVENT = "dxscrollend",            SCROLL_STOP_EVENT = "dxscrollstop",            SCROLL_CANCEL_EVENT = "dxscrollcancel",            INERTIA_TIMEOUT = 100,            VELOCITY_CALC_TIMEOUT = 200,            FRAME_DURATION = Math.round(1000 / 60),            GESTURE_LOCK_KEY = "dxGestureLock",            GESTURE_LOCK_TIMEOUT = 200,            NAMESPACED_SCROLL_EVENT = events.addNamespace("scroll", "dxScrollEmitter");        var ScrollEmitter = events.GestureEmitter.inherit({                ctor: function(element) {                    this.callBase.apply(this, arguments);                    this.direction = "both";                    $.data(element, "scroll", $.proxy(this._treatScroll, this));                    $(element).on(NAMESPACED_SCROLL_EVENT, $.proxy(this._treatScroll, this))                },                validate: function() {                    return true                },                _domElement: function() {                    return this.getElement().get(0)                },                _treatScroll: function() {                    this._prepareGesture();                    this._forgetGesture()                },                _prepareGesture: function() {                    if (this._gestureEndTimer)                        this._clearGestureTimer();                    else                        $.data(this._domElement(), GESTURE_LOCK_KEY, true)                },                _forgetGesture: function() {                    var that = this;                    this._gestureEndTimer = setTimeout(function() {                        $.data(that._domElement(), GESTURE_LOCK_KEY, false);                        that._gestureEndTimer = null                    }, GESTURE_LOCK_TIMEOUT)                },                _init: function(e) {                    if ($.data(this._domElement(), GESTURE_LOCK_KEY))                        this._accept(e);                    this._fireEvent(SCROLL_INIT_EVENT, e)                },                move: function(e) {                    this.callBase.apply(this, arguments);                    e.isScrollingEvent = this.isNative || e.isScrollingEvent                },                _start: function(e) {                    this._savedEventData = events.eventData(e);                    this._fireEvent(SCROLL_START_EVENT, e, {delta: events.eventDelta(this._savedEventData, events.eventData(e))})                },                _move: function(e) {                    var currentEventData = events.eventData(e);                    this._fireEvent(SCROLL_MOVE_EVENT, e, {delta: events.eventDelta(this._prevEventData, currentEventData)});                    var eventDelta = events.eventDelta(this._savedEventData, currentEventData);                    if (eventDelta.time > VELOCITY_CALC_TIMEOUT)                        this._savedEventData = this._prevEventData                },                _end: function(e) {                    var endEventDelta = events.eventDelta(this._prevEventData, events.eventData(e));                    var velocity = {                            x: 0,                            y: 0                        };                    var isWheelEvent = e.type === "dxmousewheel";                    if (endEventDelta.time < INERTIA_TIMEOUT) {                        var deltaEventData = events.eventDelta(this._savedEventData, this._prevEventData);                        velocity = {                            x: isWheelEvent ? 0 : deltaEventData.x * FRAME_DURATION / deltaEventData.time,                            y: isWheelEvent ? 0 : deltaEventData.y * FRAME_DURATION / deltaEventData.time                        }                    }                    this._fireEvent(SCROLL_END_EVENT, e, {velocity: velocity})                },                _stop: function(e) {                    this._fireEvent(SCROLL_STOP_EVENT, e)                },                cancel: function(e) {                    this.callBase.apply(this, arguments);                    this._fireEvent(SCROLL_CANCEL_EVENT, e)                },                dispose: function() {                    this.callBase.apply(this, arguments);                    $.data(this._domElement(), GESTURE_LOCK_KEY, false);                    this._clearGestureTimer();                    this.getElement().off(NAMESPACED_SCROLL_EVENT)                },                _clearGestureTimer: function() {                    clearTimeout(this._gestureEndTimer);                    this._gestureEndTimer = null                }            });        events.registerEmitter({            emitter: ScrollEmitter,            events: [SCROLL_INIT_EVENT, SCROLL_START_EVENT, SCROLL_MOVE_EVENT, SCROLL_END_EVENT, SCROLL_STOP_EVENT, SCROLL_CANCEL_EVENT]        })    })(jQuery, DevExpress);    /*! Module core, file ui.events.emitter.gesture.swipe.js */    (function($, DX, undefined) {        var ui = DX.ui,            events = ui.events,            SWIPE_START_EVENT = "dxswipestart",            SWIPE_EVENT = "dxswipe",            SWIPE_END_EVENT = "dxswipeend";        var HorizontalStrategy = {                defaultItemSizeFunc: function() {                    return this.getElement().width()                },                getBounds: function() {                    return [this._maxLeftOffset, this._maxRightOffset]                },                calcOffsetRatio: function(e) {                    var endEventData = events.eventData(e);                    return (endEventData.x - (this._savedEventData && this._savedEventData.x || 0)) / this._itemSizeFunc().call(this, e)                },                isFastSwipe: function(e) {                    var endEventData = events.eventData(e);                    return this.FAST_SWIPE_SPEED_LIMIT * Math.abs(endEventData.x - this._tickData.x) >= endEventData.time - this._tickData.time                }            };        var VerticalStrategy = {                defaultItemSizeFunc: function() {                    return this.getElement().height()                },                getBounds: function() {                    return [this._maxTopOffset, this._maxBottomOffset]                },                calcOffsetRatio: function(e) {                    var endEventData = events.eventData(e);                    return (endEventData.y - (this._savedEventData && this._savedEventData.y || 0)) / this._itemSizeFunc().call(this, e)                },                isFastSwipe: function(e) {                    var endEventData = events.eventData(e);                    return this.FAST_SWIPE_SPEED_LIMIT * Math.abs(endEventData.y - this._tickData.y) >= endEventData.time - this._tickData.time                }            };        var STRATEGIES = {                horizontal: HorizontalStrategy,                vertical: VerticalStrategy            };        var SwipeEmitter = events.GestureEmitter.inherit({                TICK_INTERVAL: 300,                FAST_SWIPE_SPEED_LIMIT: 5,                ctor: function(element) {                    this.callBase(element);                    this.direction = "horizontal";                    this.elastic = true                },                _getStrategy: function() {                    return STRATEGIES[this.direction]                },                _defaultItemSizeFunc: function() {                    return this._getStrategy().defaultItemSizeFunc.call(this)                },                _itemSizeFunc: function() {                    return this.itemSizeFunc || this._defaultItemSizeFunc                },                _start: function(e) {                    this._savedEventData = events.eventData(e);                    this._tickData = {time: 0};                    e = this._fireEvent(SWIPE_START_EVENT, e);                    if (!e.cancel) {                        this._maxLeftOffset = e.maxLeftOffset;                        this._maxRightOffset = e.maxRightOffset;                        this._maxTopOffset = e.maxTopOffset;                        this._maxBottomOffset = e.maxBottomOffset                    }                },                _move: function(e) {                    var strategy = this._getStrategy(),                        moveEventData = events.eventData(e),                        offset = strategy.calcOffsetRatio.call(this, e);                    offset = this._fitOffset(offset, this.elastic);                    if (moveEventData.time - this._tickData.time > this.TICK_INTERVAL)                        this._tickData = moveEventData;                    this._fireEvent(SWIPE_EVENT, e, {offset: offset});                    e.preventDefault()                },                _end: function(e) {                    var strategy = this._getStrategy(),                        offsetRatio = strategy.calcOffsetRatio.call(this, e),                        isFast = strategy.isFastSwipe.call(this, e),                        startOffset = offsetRatio,                        targetOffset = this._calcTargetOffset(offsetRatio, isFast);                    startOffset = this._fitOffset(startOffset, this.elastic);                    targetOffset = this._fitOffset(targetOffset, false);                    this._fireEvent(SWIPE_END_EVENT, e, {                        offset: startOffset,                        targetOffset: targetOffset                    })                },                _fitOffset: function(offset, elastic) {                    var strategy = this._getStrategy(),                        bounds = strategy.getBounds.call(this);                    if (offset < -bounds[0])                        return elastic ? (-2 * bounds[0] + offset) / 3 : -bounds[0];                    if (offset > bounds[1])                        return elastic ? (2 * bounds[1] + offset) / 3 : bounds[1];                    return offset                },                _calcTargetOffset: function(offsetRatio, isFast) {                    var result;                    if (isFast) {                        result = Math.ceil(Math.abs(offsetRatio));                        if (offsetRatio < 0)                            result = -result                    }                    else                        result = Math.round(offsetRatio);                    return result                }            });        events.registerEmitter({            emitter: SwipeEmitter,            events: [SWIPE_START_EVENT, SWIPE_EVENT, SWIPE_END_EVENT]        })    })(jQuery, DevExpress);    /*! Module core, file ui.events.emitter.gesture.drag.js */    (function($, DX, undefined) {        var ui = DX.ui,            utils = DX.utils,            events = ui.events,            wrapToArray = utils.wrapToArray;        var DRAG_START_EVENT = "dxdragstart",            DRAG_EVENT = "dxdrag",            DRAG_END_EVENT = "dxdragend",            DRAG_ENTER_EVENT = "dxdragenter",            DRAG_LEAVE_EVENT = "dxdragleave",            DROP_EVENT = "dxdrop";        var knownDropTargets = [],            knownDropTargetSelectors = [],            knownDropTargetConfigs = [];        var dropTargetRegistration = {                setup: function(element, data) {                    var knownDropTarget = $.inArray(element, knownDropTargets) !== -1;                    if (!knownDropTarget) {                        knownDropTargets.push(element);                        knownDropTargetSelectors.push([]);                        knownDropTargetConfigs.push(data || {})                    }                },                add: function(element, handleObj) {                    var index = $.inArray(element, knownDropTargets);                    var selector = handleObj.selector;                    if ($.inArray(selector, knownDropTargetSelectors[index]) === -1)                        knownDropTargetSelectors[index].push(selector)                },                teardown: function(element, data) {                    var elementEvents = $._data(element, "events"),                        handlersCount = 0;                    $.each([DRAG_ENTER_EVENT, DRAG_LEAVE_EVENT, DROP_EVENT], function(_, eventName) {                        var eventHandlers = elementEvents[eventName];                        if (eventHandlers)                            handlersCount += eventHandlers.length                    });                    if (!handlersCount) {                        var index = $.inArray(element, knownDropTargets);                        knownDropTargets.splice(index, 1);                        knownDropTargetSelectors.splice(index, 1);                        knownDropTargetConfigs.splice(index, 1)                    }                }            };        events.registerEvent(DRAG_ENTER_EVENT, dropTargetRegistration);        events.registerEvent(DRAG_LEAVE_EVENT, dropTargetRegistration);        events.registerEvent(DROP_EVENT, dropTargetRegistration);        var getItemDelegatedTargets = function($element) {                var dropTargetIndex = $.inArray($element.get(0), knownDropTargets),                    dropTargetSelectors = knownDropTargetSelectors[dropTargetIndex];                var $delegatedTargets = $element.find(dropTargetSelectors.join(", "));                if ($.inArray(undefined, dropTargetSelectors) !== -1)                    $delegatedTargets = $delegatedTargets.addBack();                return $delegatedTargets            };        var getItemConfig = function($element) {                var dropTargetIndex = $.inArray($element.get(0), knownDropTargets);                return knownDropTargetConfigs[dropTargetIndex]            };        var getItemPosition = function(dropTargetConfig, $element) {                if (dropTargetConfig.itemPositionFunc)                    return dropTargetConfig.itemPositionFunc($element);                else                    return $element.offset()            };        var getItemSize = function(dropTargetConfig, $element) {                if (dropTargetConfig.itemSizeFunc)                    return dropTargetConfig.itemSizeFunc($element);                return {                        width: $element.width(),                        height: $element.height()                    }            };        var DragEmitter = events.GestureEmitter.inherit({                ctor: function(element) {                    this.callBase(element);                    this.direction = "both"                },                _init: function(e) {                    this._initEvent = e                },                _start: function(e) {                    e = this._fireEvent(DRAG_START_EVENT, this._initEvent);                    this._maxLeftOffset = e.maxLeftOffset;                    this._maxRightOffset = e.maxRightOffset;                    this._maxTopOffset = e.maxTopOffset;                    this._maxBottomOffset = e.maxBottomOffset;                    var dropTargets = wrapToArray(e.targetElements || (e.targetElements === null ? [] : knownDropTargets));                    this._dropTargets = $.map(dropTargets, function(element) {                        return $(element).get(0)                    })                },                _move: function(e) {                    var eventData = events.eventData(e),                        dragOffset = this._calculateOffset(eventData);                    this._fireEvent(DRAG_EVENT, e, {offset: dragOffset});                    this._processDropTargets(e, dragOffset);                    e.preventDefault()                },                _calculateOffset: function(eventData) {                    return {                            x: this._calculateXOffset(eventData),                            y: this._calculateYOffset(eventData)                        }                },                _calculateXOffset: function(eventData) {                    if (this.direction !== "vertical") {                        var offset = eventData.x - this._startEventData.x;                        return this._fitOffset(offset, this._maxLeftOffset, this._maxRightOffset)                    }                    return 0                },                _calculateYOffset: function(eventData) {                    if (this.direction !== "horizontal") {                        var offset = eventData.y - this._startEventData.y;                        return this._fitOffset(offset, this._maxTopOffset, this._maxBottomOffset)                    }                    return 0                },                _fitOffset: function(offset, minOffset, maxOffset) {                    if (minOffset != null)                        offset = Math.max(offset, -minOffset);                    if (maxOffset != null)                        offset = Math.min(offset, maxOffset);                    return offset                },                _processDropTargets: function(e, dragOffset) {                    var target = this._findDropTarget(e),                        sameTarget = target === this._currentDropTarget;                    if (!sameTarget) {                        this._fireDropTargetEvent(e, DRAG_LEAVE_EVENT);                        this._currentDropTarget = target;                        this._fireDropTargetEvent(e, DRAG_ENTER_EVENT)                    }                },                _fireDropTargetEvent: function(event, eventName) {                    if (!this._currentDropTarget)                        return;                    var eventData = {                            type: eventName,                            originalEvent: event,                            draggingElement: this._$element.get(0),                            target: this._currentDropTarget                        };                    events.fireEvent(eventData)                },                _findDropTarget: function(e) {                    var that = this,                        result;                    $.each(knownDropTargets, function(_, target) {                        if (!that._checkDropTargetActive(target))                            return;                        var $target = $(target);                        $.each(getItemDelegatedTargets($target), function(_, delegatedTarget) {                            var $delegatedTarget = $(delegatedTarget);                            if (that._checkDropTarget(getItemConfig($target), $delegatedTarget, e))                                result = delegatedTarget                        })                    });                    return result                },                _checkDropTargetActive: function(target) {                    var active = false;                    $.each(this._dropTargets, function(_, activeTarget) {                        active = active || activeTarget === target || $.contains(activeTarget, target);                        return !active                    });                    return active                },                _checkDropTarget: function(config, $target, e) {                    var isDraggingElement = $target.get(0) === this._$element.get(0);                    if (isDraggingElement)                        return false;                    var targetPosition = getItemPosition(config, $target);                    if (e.pageX < targetPosition.left)                        return false;                    if (e.pageY < targetPosition.top)                        return false;                    var targetSize = getItemSize(config, $target);                    if (e.pageX > targetPosition.left + targetSize.width)                        return false;                    if (e.pageY > targetPosition.top + targetSize.height)                        return false;                    return $target                },                _end: function(e) {                    var eventData = events.eventData(e);                    this._fireEvent(DRAG_END_EVENT, e, {offset: this._calculateOffset(eventData)});                    this._fireDropTargetEvent(e, DROP_EVENT);                    delete this._currentDropTarget                }            });        events.registerEmitter({            emitter: DragEmitter,            events: [DRAG_START_EVENT, DRAG_EVENT, DRAG_END_EVENT]        });        DX.ui.events.__internals = DX.ui.events.__internals || {};        $.extend(DX.ui.events.__internals, {dropTargets: knownDropTargets})    })(jQuery, DevExpress);    /*! Module core, file ui.events.emitter.transform.js */    (function($, DX, undefined) {        var ui = DX.ui,            utils = DX.utils,            events = ui.events,            fitIntoRange = utils.fitIntoRange;        var DX_PREFIX = "dx",            TRANSFORM = "transform",            TRANSLATE = "translate",            ZOOM = "zoom",            PINCH = "pinch",            ROTATE = "rotate",            START_POSTFIX = "start",            UPDATE_POSTFIX = "",            END_POSTFIX = "end";        var eventAliases = [];        var addAlias = function(eventName, eventArgs) {                eventAliases.push({                    name: eventName,                    args: eventArgs                })            };        addAlias(TRANSFORM, {            scale: true,            deltaScale: true,            rotation: true,            deltaRotation: true,            translation: true,            deltaTranslation: true        });        addAlias(TRANSLATE, {            translation: true,            deltaTranslation: true        });        addAlias(ZOOM, {            scale: true,            deltaScale: true        });        addAlias(PINCH, {            scale: true,            deltaScale: true        });        addAlias(ROTATE, {            rotation: true,            deltaRotation: true        });        var getVector = function(first, second) {                return {                        x: second.pageX - first.pageX,                        y: -second.pageY + first.pageY,                        centerX: (second.pageX + first.pageX) * 0.5,                        centerY: (second.pageY + first.pageY) * 0.5                    }            };        var getEventVector = function(e) {                var pointers = e.pointers;                return getVector(pointers[0], pointers[1])            };        var getDistance = function(vector) {                return Math.sqrt(vector.x * vector.x + vector.y * vector.y)            };        var getScale = function(firstVector, secondVector) {                return getDistance(firstVector) / getDistance(secondVector)            };        var getRotation = function(firstVector, secondVector) {                var scalarProduct = firstVector.x * secondVector.x + firstVector.y * secondVector.y;                var distanceProduct = getDistance(firstVector) * getDistance(secondVector);                if (distanceProduct === 0)                    return 0;                var sign = utils.sign(firstVector.x * secondVector.y - secondVector.x * firstVector.y);                var angle = Math.acos(fitIntoRange(scalarProduct / distanceProduct, -1, 1));                return sign * angle            };        var getTranslation = function(firstVector, secondVector) {                return {                        x: firstVector.centerX - secondVector.centerX,                        y: firstVector.centerY - secondVector.centerY                    }            };        var TransformEmitter = events.Emitter.inherit({                configurate: function(data, eventName) {                    if (eventName.indexOf(ZOOM) > -1)                        DX.log("W0005", eventName, "15.1", "Use '" + eventName.replace(ZOOM, PINCH) + "' event instead");                    this.callBase(data)                },                validatePointers: function(e) {                    return events.hasTouches(e) > 1                },                start: function(e) {                    this._accept(e);                    var startVector = getEventVector(e);                    this._startVector = startVector;                    this._prevVector = startVector;                    this._fireEventAliases(START_POSTFIX, e)                },                move: function(e) {                    var currentVector = getEventVector(e),                        eventArgs = this._getEventArgs(currentVector);                    this._fireEventAliases(UPDATE_POSTFIX, e, eventArgs);                    this._prevVector = currentVector                },                end: function(e) {                    var eventArgs = this._getEventArgs(this._prevVector);                    this._fireEventAliases(END_POSTFIX, e, eventArgs)                },                _getEventArgs: function(vector) {                    return {                            scale: getScale(vector, this._startVector),                            deltaScale: getScale(vector, this._prevVector),                            rotation: getRotation(vector, this._startVector),                            deltaRotation: getRotation(vector, this._prevVector),                            translation: getTranslation(vector, this._startVector),                            deltaTranslation: getTranslation(vector, this._prevVector)                        }                },                _fireEventAliases: function(eventPostfix, originalEvent, eventArgs) {                    eventArgs = eventArgs || {};                    $.each(eventAliases, $.proxy(function(_, eventAlias) {                        var args = {};                        $.each(eventAlias.args, function(name) {                            if (name in eventArgs)                                args[name] = eventArgs[name]                        });                        this._fireEvent(DX_PREFIX + eventAlias.name + eventPostfix, originalEvent, args)                    }, this))                }            });        events.registerEmitter({            emitter: TransformEmitter,            events: $.map(eventAliases, function(eventAlias) {                var eventNames = [];                $.each([START_POSTFIX, UPDATE_POSTFIX, END_POSTFIX], function(_, eventPostfix) {                    eventNames.push(DX_PREFIX + eventAlias.name + eventPostfix)                });                return eventNames            })        })    })(jQuery, DevExpress);    /*! Module core, file ui.events.dblclick.js */    (function($, DX, undefined) {        var ui = DX.ui,            events = ui.events,            utils = DX.utils,            DBLCLICK_EVENT_NAME = "dxdblclick",            DBLCLICK_NAMESPACE = "dxDblClick",            NAMESPACED_CLICK_EVENT = events.addNamespace("dxclick", DBLCLICK_NAMESPACE),            DBLCLICK_TIMEOUT = 300;        var DblClick = DX.Class.inherit({                ctor: function() {                    this._handlerCount = 0;                    this._forgetLastClick()                },                _forgetLastClick: function() {                    this._firstClickTarget = null;                    this._lastClickTimeStamp = -DBLCLICK_TIMEOUT                },                add: function() {                    if (this._handlerCount <= 0)                        $(document).on(NAMESPACED_CLICK_EVENT, $.proxy(this._clickHandler, this));                    this._handlerCount++                },                _clickHandler: function(e) {                    var timeStamp = e.timeStamp || $.now();                    if (timeStamp - this._lastClickTimeStamp < DBLCLICK_TIMEOUT) {                        events.fireEvent({                            type: DBLCLICK_EVENT_NAME,                            target: utils.closestCommonParent(this._firstClickTarget, e.target),                            originalEvent: e                        });                        this._forgetLastClick()                    }                    else {                        this._firstClickTarget = e.target;                        this._lastClickTimeStamp = timeStamp                    }                },                remove: function() {                    this._handlerCount--;                    if (this._handlerCount <= 0) {                        this._forgetLastClick();                        $(document).off(NAMESPACED_CLICK_EVENT)                    }                }            });        events.registerEvent(DBLCLICK_EVENT_NAME, new DblClick)    })(jQuery, DevExpress);    /*! Module core, file ui.events.remove.js */    (function($) {        (function(cleanData) {            $.cleanData = function(elements) {                $.each(elements, function() {                    $(this).triggerHandler("dxremove")                });                return cleanData.apply(this, arguments)            }        })($.cleanData)    })(jQuery);    /*! Module core, file ui.events.contextmenu.js */    (function($, DX, undefined) {        var ui = DX.ui,            events = ui.events,            support = DX.support,            CONTEXTMENU_NAMESPACE = "dxContexMenu",            CONTEXTMENU_NAMESPACED_EVENT_NAME = events.addNamespace("contextmenu", CONTEXTMENU_NAMESPACE),            HOLD_NAMESPACED_EVENT_NAME = events.addNamespace("dxhold", CONTEXTMENU_NAMESPACE),            CONTEXTMENU_EVENT_NAME = "dxcontextmenu";        var ContextMenu = DX.Class.inherit({                setup: function(element, data) {                    var $element = $(element);                    $element.on(CONTEXTMENU_NAMESPACED_EVENT_NAME, $.proxy(this._contextMenuHandler, this));                    if (support.touch || DX.devices.isSimulator())                        $element.on(HOLD_NAMESPACED_EVENT_NAME, $.proxy(this._holdHandler, this))                },                _holdHandler: function(e) {                    if (events.isMouseEvent(e) && !DX.devices.isSimulator())                        return;                    this._fireContextMenu(e)                },                _contextMenuHandler: function(e) {                    e = this._fireContextMenu(e);                    if (!e.cancel)                        e.preventDefault()                },                _fireContextMenu: function(e) {                    return events.fireEvent({                            type: CONTEXTMENU_EVENT_NAME,                            originalEvent: e                        })                },                teardown: function(element) {                    $(element).off("." + CONTEXTMENU_NAMESPACE)                }            });        events.registerEvent(CONTEXTMENU_EVENT_NAME, new ContextMenu)    })(jQuery, DevExpress);    /*! Module core, file ui.widget.js */    (function($, DX, undefined) {        var ui = DX.ui,            utils = DX.utils,            events = ui.events,            UI_FEEDBACK = "UIFeedback",            WIDGET_CLASS = "dx-widget",            ACTIVE_STATE_CLASS = "dx-state-active",            DISABLED_STATE_CLASS = "dx-state-disabled",            INVISIBLE_STATE_CLASS = "dx-state-invisible",            HOVER_STATE_CLASS = "dx-state-hover",            FOCUSED_STATE_CLASS = "dx-state-focused",            FEEDBACK_SHOW_TIMEOUT = 30,            FEEDBACK_HIDE_TIMEOUT = 400,            HOVER_START = "dxhoverstart",            HOVER_END = "dxhoverend",            FOCUS_NAMESPACE = "Focus",            ANONYMOUS_TEMPLATE_NAME = "template",            TEXT_NODE = 3,            TEMPLATE_SELECTOR = "[data-options*='dxTemplate']",            TEMPLATE_WRAPPER_CLASS = "dx-template-wrapper";        var DynamicTemplate = ui.TemplateBase.inherit({                ctor: function(compileFunction, owner) {                    this.callBase($(), owner);                    this._compileFunction = compileFunction                },                _renderCore: function(data, index, container) {                    if (data === undefined && index === undefined) {                        data = container;                        container = undefined                    }                    var compiledTemplate = index === undefined ? this._compileFunction(data, container) : this._compileFunction(data, index, container);                    var renderResult = compiledTemplate.render(data, container, index);                    if (compiledTemplate.owner() === this)                        compiledTemplate.dispose();                    return renderResult                }            });        var EmptyTemplate = ui.TemplateBase.inherit({                ctor: function(owner) {                    this.callBase($(), owner)                },                _renderCore: function(data, index, container) {                    return $()                }            });        var RendererTemplate = ui.TemplateBase.inherit({_renderCore: function() {                    return this._element                }});        ui.Widget = DX.DOMComponent.inherit({            NAME: "Widget",            _supportedKeys: function() {                return {}            },            _setDeprecatedOptions: function() {                this.callBase();                $.extend(this._deprecatedOptions, {contentReadyAction: {                        since: "14.2",                        alias: "onContentReady"                    }})            },            _setDefaultOptions: function() {                this.callBase();                this.option({                    disabled: false,                    visible: true,                    hint: undefined,                    activeStateEnabled: false,                    onContentReady: null,                    hoverStateEnabled: false,                    focusStateEnabled: false,                    tabIndex: 0,                    accessKey: null,                    onFocusIn: null,                    onFocusOut: null,                    templateProvider: ui.TemplateProvider,                    _keyboardProcessor: undefined,                    _templates: {}                })            },            _init: function() {                this.callBase();                this._feedbackShowTimeout = FEEDBACK_SHOW_TIMEOUT;                this._feedbackHideTimeout = FEEDBACK_HIDE_TIMEOUT;                this._tempTemplates = [];                this._dynamicTemplates = {};                this._initTemplates();                this._initContentReadyAction();                this._initFocusActions()            },            _initTemplates: function() {                this._extractTemplates();                this._extractAnonimousTemplate()            },            _extractTemplates: function() {                var templates = this.option("_templates"),                    templateElements = this.element().contents().filter(TEMPLATE_SELECTOR);                var templatesMap = {};                templateElements.each(function(_, template) {                    var templateOptions = utils.getElementOptions(template).dxTemplate;                    if (!templateOptions)                        return;                    if (!templateOptions.name)                        throw DX.Error("E0023");                    $(template).addClass(TEMPLATE_WRAPPER_CLASS).detach();                    templatesMap[templateOptions.name] = templatesMap[templateOptions.name] || [];                    templatesMap[templateOptions.name].push(template)                });                $.each(templatesMap, $.proxy(function(templateName, value) {                    var deviceTemplate = this._findTemplateByDevice(value);                    if (deviceTemplate)                        templates[templateName] = this._createTemplate(deviceTemplate, this)                }, this))            },            _findTemplateByDevice: function(templates) {                var suitableTemplate = DX.utils.findBestMatches(DX.devices.current(), templates, function(template) {                        return utils.getElementOptions(template).dxTemplate                    })[0];                $.each(templates, function(index, template) {                    if (template !== suitableTemplate)                        $(template).remove()                });                return suitableTemplate            },            _extractAnonimousTemplate: function() {                var templates = this.option("_templates"),                    anonimiousTemplateName = this._getAnonimousTemplateName(),                    $anonimiousTemplate = this.element().contents().detach();                var $notJunkTemplateContent = $anonimiousTemplate.filter(function(_, element) {                        var isTextNode = element.nodeType === TEXT_NODE,                            isEmptyText = $.trim($(element).text()).length < 1;                        return !(isTextNode && isEmptyText)                    }),                    onlyJunkTemplateContent = $notJunkTemplateContent.length < 1;                if (!templates[anonimiousTemplateName] && !onlyJunkTemplateContent)                    templates[anonimiousTemplateName] = this._createTemplate($anonimiousTemplate, this)            },            _getAriaTarget: function() {                return this.element()            },            _getAnonimousTemplateName: function() {                return ANONYMOUS_TEMPLATE_NAME            },            _getTemplateByOption: function(optionName) {                return this._getTemplate(this.option(optionName))            },            _getTemplate: function(templateSource) {                if ($.isFunction(templateSource)) {                    var that = this;                    return new DynamicTemplate(function() {                            var templateSourceResult = templateSource.apply(that, arguments);                            if (utils.isDefined(templateSourceResult))                                return that._acquireTemplate(templateSourceResult, this, true);                            else                                return new EmptyTemplate                        }, this)                }                return this._acquireTemplate(templateSource, this)            },            _acquireTemplate: function(templateSource, owner, preferRenderer) {                if (templateSource == null)                    return this._createTemplate(utils.normalizeTemplateElement(templateSource), owner);                if (templateSource instanceof ui.TemplateBase)                    return templateSource;                if (templateSource.nodeType || templateSource.jquery) {                    templateSource = $(templateSource);                    if (preferRenderer && !templateSource.is("script"))                        return new RendererTemplate(templateSource, owner);                    return this._createTemplate(templateSource, owner)                }                if (typeof templateSource === "string") {                    var userTemplate = this.option("_templates")[templateSource];                    if (userTemplate)                        return userTemplate;                    var dynamicTemplate = this._dynamicTemplates[templateSource];                    if (dynamicTemplate)                        return dynamicTemplate;                    var defaultTemplate = this.option("templateProvider").getTemplates(this)[templateSource];                    if (defaultTemplate)                        return defaultTemplate;                    return this._createTemplate(utils.normalizeTemplateElement(templateSource), owner)                }                return this._acquireTemplate(templateSource.toString(), owner)            },            _createTemplate: function(element, owner) {                var template = this.option("templateProvider").createTemplate(element, owner);                this._tempTemplates.push(template);                return template            },            _cleanTemplates: function() {                var that = this;                $.each(this.option("_templates"), function(_, template) {                    if (that === template.owner())                        template.dispose()                });                $.each(this._tempTemplates, function(_, template) {                    template.dispose()                })            },            _initContentReadyAction: function() {                this._contentReadyAction = this._createActionByOption("onContentReady", {excludeValidators: ["designMode", "disabled", "readOnly"]})            },            _initFocusActions: function() {                var focusInAction = this._createActionByOption("onFocusIn", {excludeValidators: ["readOnly"]});                var focusOutAction = this._createActionByOption("onFocusOut", {excludeValidators: ["readOnly"]});                this._focusInAction = this._createAction(function(e) {                    e.component._focusInHandler(e.jQueryEvent);                    focusInAction(e)                }, {excludeValidators: ["readOnly"]});                this._focusOutAction = this._createAction(function(e) {                    e.component._focusOutHandler(e.jQueryEvent);                    focusOutAction(e)                }, {excludeValidators: ["readOnly"]})            },            _render: function() {                this.element().addClass(WIDGET_CLASS);                this.callBase();                this._toggleDisabledState(this.option("disabled"));                this._toggleVisibility(this.option("visible"));                this._renderHint();                this._renderContent();                this._renderFocusState();                this._attachFeedbackEvents();                this._attachHoverEvents()            },            _renderHint: function() {                utils.toggleAttr(this.element(), "title", this.option("hint"))            },            _renderContent: function() {                this._renderContentImpl();                this._fireContentReadyAction()            },            _renderContentImpl: $.noop,            _fireContentReadyAction: function() {                this._contentReadyAction()            },            _dispose: function() {                this._cleanTemplates();                this._contentReadyAction = null;                this.callBase()            },            _clean: function() {                this._cleanFocusState();                this.callBase();                this.element().empty()            },            _toggleVisibility: function(visible) {                this.element().toggleClass(INVISIBLE_STATE_CLASS, !visible);                this.setAria("hidden", !visible || undefined)            },            _renderFocusState: function() {                if (!this.option("focusStateEnabled") || this.option("disabled"))                    return;                this._renderFocusTarget();                this._attachFocusEvents();                this._attachKeyboardEvents();                this._renderAccessKey()            },            _renderAccessKey: function() {                var focusTarget = this._focusTarget();                focusTarget.attr("accesskey", this.option("accessKey"));                var clickNamespace = events.addNamespace("dxclick", UI_FEEDBACK);                focusTarget.off(clickNamespace);                this.option("accessKey") && focusTarget.on(clickNamespace, $.proxy(function(e) {                    if (e.screenX === 0 && !e.offsetX && e.pageX === 0) {                        e.stopImmediatePropagation();                        this.focus()                    }                }, this))            },            _eventBindingTarget: function() {                return this.element()            },            _focusTarget: function() {                return this._getActiveElement()            },            _getActiveElement: function() {                var activeElement = this._eventBindingTarget();                if (this._activeStateUnit)                    activeElement = activeElement.find(this._activeStateUnit).not("." + DISABLED_STATE_CLASS);                return activeElement            },            _renderFocusTarget: function() {                this._focusTarget().attr("tabindex", this.option("tabIndex"))            },            _keyboardEventBindingTarget: function() {                return this._eventBindingTarget()            },            _attachFocusEvents: function() {                var focusInEvent = events.addNamespace("focusin", this.NAME + FOCUS_NAMESPACE);                var focusOutEvent = events.addNamespace("focusout", this.NAME + FOCUS_NAMESPACE);                var beforeactivateEventNamespace = events.addNamespace("beforeactivate", this.NAME + FOCUS_NAMESPACE);                this._focusTarget().off("." + this.NAME + FOCUS_NAMESPACE).on(focusInEvent, $.proxy(function(e) {                    this._focusInAction({jQueryEvent: e})                }, this)).on(focusOutEvent, $.proxy(function(e) {                    this._focusOutAction({jQueryEvent: e})                }, this)).on(beforeactivateEventNamespace, function(e) {                    if (!$(e.target).is(":dx-focusable"))                        e.preventDefault()                })            },            _focusInHandler: function(e) {                this._updateFocusState(e, true)            },            _focusOutHandler: function(e) {                this._updateFocusState(e, false)            },            _updateFocusState: function(e, isFocused) {                var currentTarget = e.currentTarget,                    focusTargets = this._focusTarget();                if ($.inArray(currentTarget, focusTargets) !== -1)                    $(e.currentTarget).toggleClass(FOCUSED_STATE_CLASS, isFocused)            },            _attachKeyboardEvents: function() {                var processor = this.option("_keyboardProcessor") || new ui.KeyboardProcessor({                        element: this._keyboardEventBindingTarget(),                        focusTarget: this._focusTarget()                    });                this._keyboardProcessor = processor.reinitialize(this._keyboardHandler, this)            },            _keyboardHandler: function(options) {                var e = options.originalEvent,                    key = options.key;                var keys = this._supportedKeys(),                    func = keys[key];                if (func !== undefined) {                    var handler = $.proxy(func, this);                    return handler(e) || false                }                else                    return true            },            _refreshFocusState: function() {                this._cleanFocusState();                this._renderFocusState()            },            _cleanFocusState: function() {                var $element = this._focusTarget();                $element.off("." + this.NAME + FOCUS_NAMESPACE);                $element.removeClass(FOCUSED_STATE_CLASS);                $element.removeAttr("tabindex");                if (this._keyboardProcessor)                    this._keyboardProcessor.dispose()            },            _attachHoverEvents: function() {                var that = this,                    hoverableSelector = that._activeStateUnit,                    nameStart = events.addNamespace(HOVER_START, UI_FEEDBACK),                    nameEnd = events.addNamespace(HOVER_END, UI_FEEDBACK);                that._eventBindingTarget().off(nameStart, hoverableSelector).off(nameEnd, hoverableSelector);                if (that.option("hoverStateEnabled")) {                    var startAction = new DX.Action(function(args) {                            that._hoverStartHandler(args.event);                            var $target = args.element;                            that._refreshHoveredElement($target)                        });                    that._eventBindingTarget().on(nameStart, hoverableSelector, function(e) {                        startAction.execute({                            element: $(e.target),                            event: e                        })                    }).on(nameEnd, hoverableSelector, function(e) {                        that._hoverEndHandler(e);                        that._forgetHoveredElement()                    })                }                else                    that._toggleHoverClass(false)            },            _hoverStartHandler: $.noop,            _hoverEndHandler: $.noop,            _attachFeedbackEvents: function() {                var that = this,                    feedbackSelector = that._activeStateUnit,                    activeEventName = events.addNamespace("dxactive", UI_FEEDBACK),                    inactiveEventName = events.addNamespace("dxinactive", UI_FEEDBACK);                that._eventBindingTarget().off(activeEventName, feedbackSelector).off(inactiveEventName, feedbackSelector);                if (that.option("activeStateEnabled")) {                    var feedbackActionHandler = function(args) {                            var $element = args.element,                                value = args.value;                            that._toggleActiveState($element, value)                        };                    var feedbackAction = new DX.Action(function(args) {                            feedbackActionHandler(args)                        }),                        feedbackActionDisabled = new DX.Action(function(args) {                            feedbackActionHandler(args)                        }, {excludeValidators: ["disabled", "readOnly"]});                    that._eventBindingTarget().on(activeEventName, feedbackSelector, {timeout: that._feedbackShowTimeout}, function(e) {                        feedbackAction.execute({                            element: $(e.currentTarget),                            value: true                        })                    }).on(inactiveEventName, feedbackSelector, {timeout: that._feedbackHideTimeout}, function(e) {                        feedbackActionDisabled.execute({                            element: $(e.currentTarget),                            value: false                        })                    })                }            },            _toggleActiveState: function($element, value) {                this._toggleHoverClass(!value);                $element.toggleClass(ACTIVE_STATE_CLASS, value)            },            _refreshHoveredElement: function(hoveredElement) {                var selector = this._activeStateUnit || this.element();                this._forgetHoveredElement();                this._hoveredElement = hoveredElement.closest(selector);                this._toggleHoverClass(true)            },            _forgetHoveredElement: function() {                this._toggleHoverClass(false);                delete this._hoveredElement            },            _toggleHoverClass: function(value) {                if (this._hoveredElement)                    this._hoveredElement.toggleClass(HOVER_STATE_CLASS, value && this.option("hoverStateEnabled"))            },            _toggleDisabledState: function(value) {                this.element().toggleClass(DISABLED_STATE_CLASS, Boolean(value));                this._toggleHoverClass(!value);                this.setAria("disabled", value || undefined)            },            _setWidgetOption: function(widgetName, args) {                if (!this[widgetName])                    return;                if ($.isPlainObject(args[0])) {                    $.each(args[0], $.proxy(function(option, value) {                        this._setWidgetOption(widgetName, [option, value])                    }, this));                    return                }                var optionName = args[0];                var value = args[1];                if (args.length === 1)                    value = this.option(optionName);                var widgetOptionMap = this[widgetName + "OptionMap"];                this[widgetName].option(widgetOptionMap ? widgetOptionMap(optionName) : optionName, value)            },            _createComponent: function(element, name, config) {                config = config || {};                this._extendConfig(config, {                    templateProvider: this.option("templateProvider"),                    _templates: this.option("_templates")                });                return this.callBase(element, name, config)            },            _optionChanged: function(args) {                switch (args.name) {                    case"disabled":                        this._toggleDisabledState(args.value);                        this._refreshFocusState();                        break;                    case"hint":                        this._renderHint();                        break;                    case"activeStateEnabled":                        this._attachFeedbackEvents();                        break;                    case"hoverStateEnabled":                        this._attachHoverEvents();                        break;                    case"tabIndex":                    case"_keyboardProcessor":                    case"focusStateEnabled":                        this._refreshFocusState();                        break;                    case"onFocusIn":                    case"onFocusOut":                        this._initFocusActions();                        break;                    case"accessKey":                        this._renderAccessKey();                        break;                    case"visible":                        var visible = args.value;                        this._toggleVisibility(visible);                        if (this._isVisibilityChangeSupported())                            this._visibilityChanged(visible);                        break;                    case"onContentReady":                        this._initContentReadyAction();                        break;                    case"_templates":                    case"templateProvider":                        this._refresh();                        break;                    default:                        this.callBase(args)                }            },            beginUpdate: function() {                this._ready(false);                this.callBase()            },            endUpdate: function() {                this.callBase();                if (this._initialized)                    this._ready(true)            },            _ready: function(value) {                if (arguments.length === 0)                    return this._isReady;                this._isReady = value            },            setAria: function() {                var setAttribute = function(option) {                        var attrName = $.inArray(option.name, ["role", "id"]) + 1 ? option.name : "aria-" + option.name,                            attrValue = option.value;                        if (attrValue === null || attrValue === undefined)                            attrValue = undefined;                        else                            attrValue = attrValue.toString();                        utils.toggleAttr(option.target, attrName, attrValue)                    };                if (!$.isPlainObject(arguments[0]))                    setAttribute({                        name: arguments[0],                        value: arguments[1],                        target: arguments[2] || this._getAriaTarget()                    });                else {                    var $target = arguments[1] || this._getAriaTarget();                    $.each(arguments[0], function(key, value) {                        setAttribute({                            name: key,                            value: value,                            target: $target                        })                    })                }            },            isReady: function() {                return this._ready()            },            repaint: function() {                this._refresh()            },            focus: function() {                this._focusTarget().focus()            },            registerKeyHandler: function(key, handler) {                var currentKeys = this._supportedKeys(),                    addingKeys = {};                addingKeys[key] = handler;                this._supportedKeys = function() {                    return $.extend(currentKeys, addingKeys)                }            }        })    })(jQuery, DevExpress);    /*! Module core, file ui.editor.js */    (function($, DX, undefined) {        var ui = DX.ui,            READONLY_STATE_CLASS = "dx-state-readonly",            INVALID_CLASS = "dx-invalid",            INVALID_MESSAGE = "dx-invalid-message",            INVALID_MESSAGE_AUTO = "dx-invalid-message-auto",            INVALID_MESSAGE_ALWAYS = "dx-invalid-message-always";        ui.validation = ui.validation || {};        ui.validation.findGroup = function() {            var group = this.option("validationGroup"),                $dxGroup;            if (!group) {                $dxGroup = this.element().parents(".dx-validationgroup:first");                if ($dxGroup.length)                    group = $dxGroup.dxValidationGroup("instance");                else                    group = this._modelByElement(this.element())            }            return group        };        ui.Editor = ui.Widget.inherit({            _init: function() {                this.callBase();                this.validationRequest = $.Callbacks();                var $element = this.element();                if ($element) {                    $element.data("dx-validation-target", this);                    this.on("disposing", function() {                        $element.data("dx-validation-target", null)                    })                }                this._createValueChangeAction()            },            _setDeprecatedOptions: function() {                this.callBase();                $.extend(this._deprecatedOptions, {valueChangeAction: {                        since: "14.2",                        alias: "onValueChanged",                        message: "'onValueChanged' option instead"                    }})            },            _setDefaultOptions: function() {                this.callBase();                this.option({                    value: null,                    onValueChanged: null,                    activeStateEnabled: true,                    readOnly: false,                    isValid: true,                    validationError: null,                    validationMessageMode: "auto",                    validationTooltipOffset: {                        h: 0,                        v: -10                    }                })            },            _defaultOptionsRules: function() {                return this.callBase().concat([{                            device: function(device) {                                return device.platform === "android"                            },                            options: {invalidTooltipOffset: {                                    h: 9,                                    v: -7                                }}                        }, {                            device: {platform: "win8"},                            options: {invalidTooltipOffset: {                                    h: 9,                                    v: -4                                }}                        }])            },            _attachKeyboardEvents: function() {                if (this.option("readOnly"))                    return;                this.callBase.apply(this, arguments);                this._attachChildKeyboardEvents()            },            _attachChildKeyboardEvents: $.noop,            _setOptionsByReference: function() {                this.callBase();                $.extend(this._optionsByReference, {validationError: true})            },            _createValueChangeAction: function() {                this._valueChangeAction = this._createActionByOption("onValueChanged", {excludeValidators: ["disabled", "readOnly"]})            },            _suppressValueChangeAction: function() {                this._valueChangeActionSuppressed = true            },            _resumeValueChangeAction: function() {                this._valueChangeActionSuppressed = false            },            _render: function() {                this._renderValidationState();                this._toggleReadOnlyState();                this.callBase()            },            _raiseValueChangeAction: function(value, previousValue, extraArguments) {                this._valueChangeAction(this._valueChangeArgs(value, previousValue))            },            _valueChangeArgs: function(value, previousValue) {                return {                        value: value,                        previousValue: previousValue,                        jQueryEvent: this._valueChangeEventInstance                    }            },            _saveValueChangeEvent: function(e) {                this._valueChangeEventInstance = e            },            _renderValidationState: function() {                var isValid = this.option("isValid"),                    validationError = this.option("validationError"),                    validationMessageMode = this.option("validationMessageMode"),                    $element = this.element();                $element.toggleClass(INVALID_CLASS, !isValid);                this.setAria("invalid", !isValid || undefined);                if (this._$validationMessage) {                    this._$validationMessage.remove();                    this._$validationMessage = null                }                if (!isValid && validationError && validationError.message) {                    this._$validationMessage = $("<div/>", {"class": INVALID_MESSAGE}).text(validationError.message).appendTo($element);                    this._createComponent(this._$validationMessage, "dxTooltip", {                        target: $element,                        container: $element,                        position: this._getValidationTooltipPosition("below"),                        closeOnOutsideClick: false,                        closeOnTargetScroll: false,                        animation: null,                        visible: true                    });                    this._$validationMessage.toggleClass(INVALID_MESSAGE_AUTO, validationMessageMode === "auto").toggleClass(INVALID_MESSAGE_ALWAYS, validationMessageMode === "always")                }            },            _getValidationTooltipPosition: function(positionRequest) {                var rtlEnabled = this.option("rtlEnabled"),                    tooltipPositionSide = rtlEnabled ? "right" : "left",                    tooltipOriginalOffset = this.option("validationTooltipOffset"),                    tooltipOffset = {                        h: tooltipOriginalOffset.h,                        v: tooltipOriginalOffset.v                    },                    verticalPositions = positionRequest === "below" ? [" top", " bottom"] : [" bottom", " top"];                if (rtlEnabled)                    tooltipOffset.h = -tooltipOffset.h;                if (positionRequest !== "below")                    tooltipOffset.v = -tooltipOffset.v;                return {                        offset: tooltipOffset,                        my: tooltipPositionSide + verticalPositions[0],                        at: tooltipPositionSide + verticalPositions[1],                        collision: "none"                    }            },            _toggleReadOnlyState: function() {                this.element().toggleClass(READONLY_STATE_CLASS, this.option("readOnly"));                this.setAria("readonly", this.option("readOnly") || undefined)            },            _optionChanged: function(args) {                switch (args.name) {                    case"onValueChanged":                        this._createValueChangeAction();                        break;                    case"isValid":                    case"validationError":                    case"validationMessageMode":                        this._renderValidationState();                        break;                    case"readOnly":                        this._toggleReadOnlyState();                        this._refreshFocusState();                        break;                    case"value":                        if (!this._valueChangeActionSuppressed) {                            this._raiseValueChangeAction(args.value, args.previousValue);                            this._saveValueChangeEvent(undefined)                        }                        if (args.value != args.previousValue)                            this.validationRequest.fire({                                value: args.value,                                editor: this                            });                        break;                    default:                        this.callBase(args)                }            },            reset: function() {                this.option("value", null)            }        })    })(jQuery, DevExpress);    /*! Module core, file ui.CollectionWidget.js */    (function($, DX, undefined) {        var ui = DX.ui,            utils = DX.utils,            events = ui.events;        var COLLECTION_CLASS = "dx-collection",            ITEM_CLASS = "dx-item",            CONTENT_CLASS_POSTFIX = "-content",            ITEM_CONTENT_PLACEHOLDER_CLASS = "dx-item-content-placeholder",            ITEM_DATA_KEY = "dxItemData",            ITEM_TEMPLATE_ID_PREFIX = "tmpl-",            ITEMS_SELECTOR = "[data-options*='dxItem']",            SELECTED_ITEM_CLASS = "dx-item-selected",            FOCUSED_STATE_CLASS = "dx-state-focused",            ITEM_RESPONSE_WAIT_CLASS = "dx-item-response-wait",            EMPTY_COLLECTION = "dx-empty-collection",            TEMPLATE_WRAPPER_CLASS = "dx-template-wrapper";        var FOCUS_UP = "up",            FOCUS_DOWN = "down",            FOCUS_LEFT = "left",            FOCUS_RIGHT = "right",            FOCUS_PAGE_UP = "pageup",            FOCUS_PAGE_DOWN = "pagedown",            FOCUS_LAST = "last",            FOCUS_FIRST = "first";        var CollectionWidget = ui.Widget.inherit({                NAME: "CollectionWidget",                _activeStateUnit: "." + ITEM_CLASS,                _supportedKeys: function() {                    var click = function(e) {                            var $itemElement = this.option("focusedElement");                            if (!$itemElement)                                return;                            e.target = $itemElement;                            e.currentTarget = $itemElement;                            this._itemClickHandler(e)                        },                        move = function(location, e) {                            e.preventDefault();                            e.stopPropagation();                            this._moveFocus(location, e)                        };                    return $.extend(this.callBase(), {                            space: click,                            enter: click,                            leftArrow: $.proxy(move, this, FOCUS_LEFT),                            rightArrow: $.proxy(move, this, FOCUS_RIGHT),                            upArrow: $.proxy(move, this, FOCUS_UP),                            downArrow: $.proxy(move, this, FOCUS_DOWN),                            pageUp: $.proxy(move, this, FOCUS_UP),                            pageDown: $.proxy(move, this, FOCUS_DOWN),                            home: $.proxy(move, this, FOCUS_FIRST),                            end: $.proxy(move, this, FOCUS_LAST)                        })                },                _setDeprecatedOptions: function() {                    this.callBase();                    $.extend(this._deprecatedOptions, {                        itemClickAction: {                            since: "14.2",                            alias: "onItemClick"                        },                        itemHoldAction: {                            since: "14.2",                            alias: "onItemHold"                        },                        itemRenderedAction: {                            since: "14.2",                            alias: "onItemRendered"                        },                        itemRender: {                            since: "14.2",                            alias: "itemTemplate"                        }                    })                },                _setDefaultOptions: function() {                    this.callBase();                    this.option({                        selectOnFocus: false,                        loopItemFocus: true,                        items: [],                        itemTemplate: "item",                        onItemRendered: null,                        onItemClick: null,                        onItemHold: null,                        itemHoldTimeout: 750,                        onItemContextMenu: null,                        onFocusedItemChanged: null,                        noDataText: Globalize.localize("dxCollectionWidget-noDataText"),                        dataSource: null,                        _itemAttributes: {},                        itemTemplateProperty: "template",                        focusOnSelectedItem: true,                        focusedElement: null                    })                },                _getAnonimousTemplateName: function() {                    return "item"                },                _init: function() {                    this.callBase();                    this._cleanRenderedItems();                    this._refreshDataSource()                },                _initTemplates: function() {                    this._initItemsFromMarkup();                    this.callBase()                },                _initItemsFromMarkup: function() {                    var $items = this.element().contents().filter(ITEMS_SELECTOR);                    if (!$items.length || this.option("items").length)                        return;                    var items = $.map($items, $.proxy(function(item) {                            var $item = $(item);                            var result = utils.getElementOptions(item).dxItem;                            var isTemplateRequired = $.trim($item.html()) && !result.template;                            if (isTemplateRequired)                                result.template = this._prepareItemTemplate($item);                            else                                $item.remove();                            return result                        }, this));                    this.option("items", items)                },                _prepareItemTemplate: function($item) {                    var templateId = ITEM_TEMPLATE_ID_PREFIX + new DX.data.Guid;                    var templateOptions = "dxTemplate: { name: \"" + templateId + "\" }";                    $item.attr("data-options", templateOptions).data("options", templateOptions);                    return templateId                },                _dataSourceOptions: function() {                    return {paginate: false}                },                _cleanRenderedItems: function() {                    this._renderedItemsCount = 0                },                _focusTarget: function() {                    return this.element()                },                _focusInHandler: function(e) {                    this.callBase.apply(this, arguments);                    var $focusedElement = this.option("focusedElement");                    if ($focusedElement && $focusedElement.length)                        this._setFocusedItem($focusedElement);                    else {                        var $activeItem = this._getActiveItem();                        this.option("focusedElement", $activeItem)                    }                },                _focusOutHandler: function(e) {                    this.callBase.apply(this, arguments);                    var $target = this.option("focusedElement");                    if ($target)                        $target.removeClass(FOCUSED_STATE_CLASS)                },                _getActiveItem: function(last) {                    var $focusedElement = this.option("focusedElement");                    if ($focusedElement && $focusedElement.length)                        return $focusedElement;                    var index = this.option("focusOnSelectedItem") ? this.option("selectedIndex") : 0,                        activeElements = this._getActiveElement(),                        lastIndex = activeElements.length - 1;                    if (index < 0)                        index = last ? lastIndex : 0;                    return activeElements.eq(index)                },                _renderFocusTarget: function() {                    this.callBase.apply(this, arguments);                    this._refreshActiveDescendant()                },                _moveFocus: function(location) {                    var $items = this._itemElements().filter(":visible").not(".dx-state-disabled"),                        $newTarget;                    switch (location) {                        case FOCUS_PAGE_UP:                        case FOCUS_UP:                            $newTarget = this._prevItem($items);                            break;                        case FOCUS_PAGE_DOWN:                        case FOCUS_DOWN:                            $newTarget = this._nextItem($items);                            break;                        case FOCUS_RIGHT:                            $newTarget = this.option("rtlEnabled") ? this._prevItem($items) : this._nextItem($items);                            break;                        case FOCUS_LEFT:                            $newTarget = this.option("rtlEnabled") ? this._nextItem($items) : this._prevItem($items);                            break;                        case FOCUS_FIRST:                            $newTarget = $items.first();                            break;                        case FOCUS_LAST:                            $newTarget = $items.last();                            break;                        default:                            return false                    }                    if ($newTarget.length !== 0)                        this.option("focusedElement", $newTarget)                },                _prevItem: function($items) {                    var $target = this._getActiveItem(),                        targetIndex = $items.index($target),                        $last = $items.last(),                        $item = $($items[targetIndex - 1]),                        loop = this.option("loopItemFocus");                    if ($item.length === 0 && loop)                        $item = $last;                    return $item                },                _nextItem: function($items) {                    var $target = this._getActiveItem(true),                        targetIndex = $items.index($target),                        $first = $items.first(),                        $item = $($items[targetIndex + 1]),                        loop = this.option("loopItemFocus");                    if ($item.length === 0 && loop)                        $item = $first;                    return $item                },                _selectFocusedItem: function($target) {                    this.selectItem($target)                },                _removeFocusedItem: function($target) {                    if ($target && $target.length) {                        $target.removeClass(FOCUSED_STATE_CLASS);                        $target.removeAttr("id")                    }                },                _refreshActiveDescendant: function() {                    this.setAria("activedescendant", "");                    this.setAria("activedescendant", this.getFocusedItemId())                },                _setFocusedItem: function($target) {                    if (!$target || !$target.length)                        return;                    $target.attr("id", this.getFocusedItemId());                    $target.addClass(FOCUSED_STATE_CLASS);                    this.onFocusedItemChanged(this.getFocusedItemId());                    this._refreshActiveDescendant();                    if (this.option("selectOnFocus"))                        this._selectFocusedItem($target)                },                _optionChanged: function(args) {                    switch (args.name) {                        case"items":                        case"_itemAttributes":                        case"itemTemplateProperty":                            this._cleanRenderedItems();                            this._invalidate();                            break;                        case"dataSource":                            this._refreshDataSource();                            if (!this._dataSource)                                this.option("items", []);                            this._renderEmptyMessage();                            break;                        case"noDataText":                            this._renderEmptyMessage();                            break;                        case"itemTemplate":                            this._invalidate();                            break;                        case"onItemRendered":                            this._createItemRenderAction();                            break;                        case"onItemClick":                            break;                        case"onItemHold":                        case"itemHoldTimeout":                            this._attachHoldEvent();                            break;                        case"onItemContextMenu":                            this._attachContextMenuEvent();                            break;                        case"onFocusedItemChanged":                            this.onFocusedItemChanged = this._createActionByOption("onFocusedItemChanged");                            break;                        case"selectOnFocus":                        case"loopItemFocus":                        case"focusOnSelectedItem":                            break;                        case"focusedElement":                            this._removeFocusedItem(args.previousValue);                            this._setFocusedItem(args.value);                            break;                        default:                            this.callBase(args)                    }                },                _loadNextPage: function() {                    var dataSource = this._dataSource;                    this._expectNextPageLoading();                    dataSource.pageIndex(1 + dataSource.pageIndex());                    return dataSource.load()                },                _expectNextPageLoading: function() {                    this._startIndexForAppendedItems = 0                },                _expectLastItemLoading: function() {                    this._startIndexForAppendedItems = -1                },                _forgetNextPageLoading: function() {                    this._startIndexForAppendedItems = null                },                _dataSourceChangedHandler: function(newItems) {                    var items = this.option("items");                    if (this._initialized && items && this._shouldAppendItems()) {                        this._renderedItemsCount = items.length;                        if (!this._isLastPage() || this._startIndexForAppendedItems !== -1)                            this.option().items = items.concat(newItems.slice(this._startIndexForAppendedItems));                        this._forgetNextPageLoading();                        this._renderContent();                        this._renderFocusTarget()                    }                    else                        this.option("items", newItems)                },                _dataSourceLoadErrorHandler: function() {                    this._forgetNextPageLoading();                    this.option("items", this.option("items"))                },                _shouldAppendItems: function() {                    return this._startIndexForAppendedItems != null && this._allowDinamicItemsAppend()                },                _allowDinamicItemsAppend: function() {                    return false                },                _clean: function() {                    this._cleanFocusState();                    this._cleanItemContainer()                },                _cleanItemContainer: function() {                    this._itemContainer().empty()                },                _refresh: function() {                    this._cleanRenderedItems();                    this.callBase.apply(this, arguments)                },                _itemContainer: function() {                    return this.element()                },                _itemClass: function() {                    return ITEM_CLASS                },                _itemContentClass: function() {                    return this._itemClass() + CONTENT_CLASS_POSTFIX                },                _selectedItemClass: function() {                    return SELECTED_ITEM_CLASS                },                _itemResponseWaitClass: function() {                    return ITEM_RESPONSE_WAIT_CLASS                },                _itemSelector: function() {                    return "." + this._itemClass()                },                _itemDataKey: function() {                    return ITEM_DATA_KEY                },                _itemElements: function() {                    return this._itemContainer().find(this._itemSelector())                },                _render: function() {                    this.callBase();                    this.element().addClass(COLLECTION_CLASS);                    this._attachClickEvent();                    this._attachHoldEvent();                    this._attachContextMenuEvent();                    this.onFocusedItemChanged = this._createActionByOption("onFocusedItemChanged")                },                _attachClickEvent: function() {                    var itemSelector = this._itemSelector(),                        clickEventNamespace = events.addNamespace("dxclick", this.NAME),                        pointerDownEventNamespace = events.addNamespace("dxpointerdown", this.NAME),                        that = this;                    var pointerDownAction = new DX.Action(function(args) {                            var event = args.event;                            that._itemPointerDownHandler(event)                        });                    this._itemContainer().off(clickEventNamespace, itemSelector).off(pointerDownEventNamespace, itemSelector).on(clickEventNamespace, itemSelector, $.proxy(this._itemClickHandler, this)).on(pointerDownEventNamespace, itemSelector, function(e) {                        pointerDownAction.execute({                            element: $(e.target),                            event: e                        })                    })                },                _itemClickHandler: function(e) {                    this._itemJQueryEventHandler(e, "onItemClick")                },                _itemPointerDownHandler: function(e) {                    if (!this.option("focusStateEnabled"))                        return;                    var elementClass = this._itemClass(),                        $target = $(e.target).closest("." + elementClass);                    if ($target.hasClass(elementClass))                        this.option("focusedElement", $target)                },                _attachHoldEvent: function() {                    var $itemContainer = this._itemContainer(),                        itemSelector = this._itemSelector(),                        eventName = events.addNamespace("dxhold", this.NAME);                    $itemContainer.off(eventName, itemSelector);                    if (this._shouldAttachHoldEvent())                        $itemContainer.on(eventName, itemSelector, {timeout: this._getHoldTimeout()}, $.proxy(this._itemHoldHandler, this))                },                _getHoldTimeout: function() {                    return this.option("itemHoldTimeout")                },                _shouldAttachHoldEvent: function() {                    return this.option("onItemHold")                },                _itemHoldHandler: function(e) {                    this._itemJQueryEventHandler(e, "onItemHold")                },                _attachContextMenuEvent: function() {                    var $itemContainer = this._itemContainer(),                        itemSelector = this._itemSelector(),                        eventName = events.addNamespace("dxcontextmenu", this.NAME);                    $itemContainer.off(eventName, itemSelector);                    if (this._shouldAttachContextMenuEvent())                        $itemContainer.on(eventName, itemSelector, $.proxy(this._itemContextMenuHandler, this))                },                _shouldAttachContextMenuEvent: function() {                    return this.option("onItemContextMenu")                },                _itemContextMenuHandler: function(e) {                    this._itemJQueryEventHandler(e, "onItemContextMenu")                },                _renderContentImpl: function() {                    var items = this.option("items") || [];                    if (this._renderedItemsCount)                        this._renderItems(items.slice(this._renderedItemsCount));                    else                        this._renderItems(items)                },                _renderItems: function(items) {                    if (items.length)                        $.each(items, $.proxy(this._renderItem, this));                    this._renderEmptyMessage()                },                _renderItem: function(index, itemData, $container) {                    $container = $container || this._itemContainer();                    var $itemFrame = this._renderItemFrame(index, itemData, $container);                    this._setElementData($itemFrame, itemData);                    var $itemContent = $itemFrame.find("." + ITEM_CONTENT_PLACEHOLDER_CLASS);                    $itemContent.removeClass(ITEM_CONTENT_PLACEHOLDER_CLASS);                    $itemContent = this._renderItemContent(index, itemData, $itemContent);                    this._postprocessRenderItem({                        itemElement: $itemFrame,                        itemContent: $itemContent,                        itemData: itemData,                        itemIndex: index                    });                    this._executeItemRenderAction(index, itemData, $itemFrame);                    this._attachItemClickEvent(itemData, $itemFrame);                    return $itemFrame.attr(this.option("_itemAttributes"))                },                _attachItemClickEvent: function(itemData, $itemElement) {                    if (!itemData || !itemData.onClick)                        return;                    $itemElement.on("dxclick", $.proxy(function(e) {                        this._itemEventHandlerByHandler($itemElement, itemData.onClick, {jQueryEvent: e})                    }, this))                },                _renderItemContent: function(index, itemData, $container) {                    var $itemNode = itemData && itemData.node;                    var itemTemplateName = this._getItemTemplateName(itemData);                    var itemTemplate = this._getTemplate(itemTemplateName, itemData, index, $container);                    var renderArgs = {                            index: index,                            item: itemData,                            container: $container                        };                    if ($itemNode) {                        $container.replaceWith($itemNode);                        $container = $itemNode;                        this._addItemContentClasses($container, itemData)                    }                    else {                        this._addItemContentClasses($container, itemData);                        var $result = this._createItemByTemplate(itemTemplate, renderArgs);                        if ($result.hasClass(TEMPLATE_WRAPPER_CLASS)) {                            $container.replaceWith($result);                            $container = $result;                            this._addItemContentClasses($container, itemData)                        }                    }                    return $container                },                _addItemContentClasses: function($container) {                    $container.addClass([ITEM_CLASS + CONTENT_CLASS_POSTFIX, this._itemContentClass()].join(" "))                },                _renderItemFrame: function(index, itemData, $container) {                    var itemFrameTemplate = this.option("templateProvider").getTemplates(this)["itemFrame"],                        $itemFrame = itemFrameTemplate.render(utils.isDefined(itemData) ? itemData : {}, $container, index);                    $itemFrame.appendTo($container);                    return $itemFrame                },                _postprocessRenderItem: $.noop,                _executeItemRenderAction: function(index, itemData, itemElement) {                    this._getItemRenderAction()({                        itemElement: itemElement,                        itemIndex: index,                        itemData: itemData                    })                },                _setElementData: function(element, data) {                    element.addClass([ITEM_CLASS, this._itemClass()].join(" ")).data(this._itemDataKey(), data)                },                _createItemRenderAction: function() {                    return this._itemRenderAction = this._createActionByOption("onItemRendered", {                            element: this.element(),                            excludeValidators: ["designMode", "disabled", "readOnly"],                            category: "rendering"                        })                },                _getItemRenderAction: function() {                    return this._itemRenderAction || this._createItemRenderAction()                },                _getItemTemplateName: function(itemData) {                    var templateProperty = this.option("itemTemplateProperty");                    return itemData && itemData[templateProperty] || this.option("itemTemplate")                },                _createItemByTemplate: function(itemTemplate, renderArgs) {                    return itemTemplate.render(renderArgs.item, renderArgs.container, renderArgs.index, "ignoreTarget")                },                _renderEmptyMessage: function() {                    var noDataText = this.option("noDataText"),                        items = this.option("items"),                        hideNoData = !noDataText || items && items.length || this._isDataSourceLoading();                    if (hideNoData && this._$nodata) {                        this._$nodata.remove();                        this._$nodata = null;                        this.setAria("label", undefined)                    }                    if (!hideNoData) {                        this._$nodata = this._$nodata || $("<div>").addClass("dx-empty-message");                        this._$nodata.appendTo(this._itemContainer()).html(noDataText);                        this.setAria("label", noDataText)                    }                    this.element().toggleClass(EMPTY_COLLECTION, !hideNoData)                },                _itemJQueryEventHandler: function(jQueryEvent, handlerOptionName, actionArgs, actionConfig) {                    this._itemEventHandler(jQueryEvent.target, handlerOptionName, $.extend(actionArgs, {jQueryEvent: jQueryEvent}), actionConfig)                },                _itemEventHandler: function(initiator, handlerOptionName, actionArgs, actionConfig) {                    var action = this._createActionByOption(handlerOptionName, $.extend({validatingTargetName: "itemElement"}, actionConfig));                    return this._itemEventHandlerImpl(initiator, action, actionArgs)                },                _itemEventHandlerByHandler: function(initiator, handler, actionArgs, actionConfig) {                    var action = this._createAction(handler, $.extend({validatingTargetName: "itemElement"}, actionConfig));                    return this._itemEventHandlerImpl(initiator, action, actionArgs)                },                _itemEventHandlerImpl: function(initiator, action, actionArgs) {                    var $itemElement = this._closestItemElement($(initiator));                    return action($.extend(this._extendActionArgs($itemElement), actionArgs))                },                _extendActionArgs: function($itemElement) {                    return {                            itemElement: $itemElement,                            itemIndex: $itemElement.index(this._itemSelector()),                            itemData: this._getItemData($itemElement)                        }                },                _closestItemElement: function($element) {                    return $($element).closest(this._itemSelector())                },                _getItemData: function(itemElement) {                    return $(itemElement).data(this._itemDataKey())                },                getFocusedItemId: function() {                    if (!this._focusedItemId)                        this._focusedItemId = new DevExpress.data.Guid;                    return this._focusedItemId                },                itemElements: function() {                    return this._itemElements()                },                itemsContainer: function() {                    return this._itemContainer()                }            }).include(ui.DataHelperMixin);        ui.CollectionWidget = CollectionWidget    })(jQuery, DevExpress);    /*! Module core, file ui.CollectionWidget.edit.js */    (function($, DX, undefined) {        var ui = DX.ui,            utils = DX.utils;        var ITEM_DELETING_DATA_KEY = "dxItemDeleting";        var CollectionWidget = ui.CollectionWidget.inherit({                _setOptionsByReference: function() {                    this.callBase();                    $.extend(this._optionsByReference, {selectedItem: true})                },                _setDeprecatedOptions: function() {                    this.callBase();                    $.extend(this._deprecatedOptions, {itemSelectAction: {                            since: "14.2",                            message: "Use the 'onSelectionChanged' option instead"                        }})                },                _setDefaultOptions: function() {                    this.callBase();                    this.option({                        selectionMode: 'none',                        selectionRequired: false,                        selectionByClick: true,                        selectedItems: [],                        selectedIndex: -1,                        selectedItem: null,                        onSelectionChanged: null,                        onItemReordered: null,                        onItemDeleting: null,                        onItemDeleted: null                    })                },                _init: function() {                    this.callBase();                    this._initEditStrategy();                    this._selectedItemIndices = []                },                _initEditStrategy: function() {                    var strategy = ui.CollectionWidget.PlainEditStrategy;                    this._editStrategy = new strategy(this)                },                _render: function() {                    this._syncSelectionOptions();                    this._normalizeSelectedItems();                    this._initSelectedItems();                    this.callBase();                    this._renderSelection(this._selectedItemIndices, [])                },                _syncSelectionOptions: function(byOption) {                    byOption = byOption || this._chooseSelectOption();                    var selectedItem,                        selectedItems;                    switch (byOption) {                        case"selectedIndex":                            selectedItem = this._editStrategy.getItemDataByIndex(this.option("selectedIndex"));                            if (utils.isDefined(selectedItem)) {                                this._setOptionSilent("selectedItems", [selectedItem]);                                this._setOptionSilent("selectedItem", selectedItem)                            }                            else {                                this._setOptionSilent("selectedItems", []);                                this._setOptionSilent("selectedItem", null)                            }                            break;                        case"selectedItems":                            selectedItems = this.option("selectedItems") || [];                            this._setOptionSilent("selectedItem", selectedItems[0]);                            this._setOptionSilent("selectedIndex", this._editStrategy.getIndexByItemData(selectedItems[0]));                            break;                        case"selectedItem":                            selectedItem = this.option("selectedItem");                            if (utils.isDefined(selectedItem)) {                                this._setOptionSilent("selectedItems", [selectedItem]);                                this._setOptionSilent("selectedIndex", this._editStrategy.getIndexByItemData(selectedItem))                            }                            else {                                this._setOptionSilent("selectedItems", []);                                this._setOptionSilent("selectedIndex", -1)                            }                            break                    }                },                _chooseSelectOption: function() {                    var optionName = "selectedIndex";                    if (this.option("selectedItems").length)                        optionName = "selectedItems";                    else if (utils.isDefined(this.option("selectedItem")))                        optionName = "selectedItem";                    return optionName                },                _normalizeSelectedItems: function() {                    if (this.option("selectionMode") === "none") {                        this._setOptionSilent("selectedItems", []);                        this._syncSelectionOptions("selectedItems")                    }                    else if (this.option("selectionMode") === "single") {                        var newSelection = this._editStrategy.selectedItemIndices(this.option("selectedItems"));                        if (newSelection.length > 1 || !newSelection.length && this.option("selectionRequired") && this.option("items") && this.option("items").length) {                            var normalizedSelection = [newSelection[0] || this._selectedItemIndices[0] || 0];                            this._setOptionSilent("selectedItems", this._editStrategy.fetchSelectedItems(normalizedSelection));                            this._syncSelectionOptions("selectedItems")                        }                    }                },                _initSelectedItems: function() {                    this._selectedItemIndices = this._editStrategy.selectedItemIndices(this.option("selectedItems"))                },                _renderSelection: $.noop,                _itemClickHandler: function(e) {                    this._createAction($.proxy(function(e) {                        this._itemSelectHandler(e.jQueryEvent)                    }, this), {validatingTargetName: "itemElement"})({                        itemElement: $(e.currentTarget),                        jQueryEvent: e                    });                    this.callBase.apply(this, arguments)                },                _itemSelectHandler: function(e) {                    if (!this.option("selectionByClick"))                        return;                    var $itemElement = e.currentTarget;                    if (this.isItemSelected($itemElement))                        this.unselectItem(e.currentTarget);                    else                        this.selectItem(e.currentTarget)                },                _selectedItemElement: function(index) {                    return this._itemElements().eq(index)                },                _postprocessRenderItem: function(args) {                    var $itemElement = $(args.itemElement);                    if (this._isItemSelected(this._editStrategy.getNormalizedIndex($itemElement))) {                        $itemElement.addClass(this._selectedItemClass());                        this._setAriaSelected($itemElement, "true")                    }                    else                        this._setAriaSelected($itemElement, "false")                },                _updateSelectedItems: function() {                    var oldSelection = this._selectedItemIndices.slice(),                        newSelection = this._editStrategy.selectedItemIndices(),                        addedSelection = utils.removeDublicates(newSelection, oldSelection),                        removedSelection = utils.removeDublicates(oldSelection, newSelection);                    $.each(removedSelection, $.proxy(function(_, normalizedIndex) {                        this._removeSelection(normalizedIndex)                    }, this));                    $.each(addedSelection, $.proxy(function(_, normalizedIndex) {                        this._addSelection(normalizedIndex)                    }, this));                    if (removedSelection.length || addedSelection.length) {                        var selectionChangePromise = this._selectionChangePromise;                        this._updateSelection(addedSelection, removedSelection);                        $.when(selectionChangePromise).done($.proxy(function() {                            this._fireSelectItemEvent(addedSelection, removedSelection);                            this._fireSelectionChangeEvent(addedSelection, removedSelection)                        }, this))                    }                },                _fireSelectionChangeEvent: function(addedSelection, removedSelection) {                    this._createActionByOption("onSelectionChanged", {excludeValidators: ["disabled", "readOnly"]})({                        addedItems: this._editStrategy.fetchSelectedItems(addedSelection),                        removedItems: this._editStrategy.fetchSelectedItems(removedSelection)                    })                },                _fireSelectItemEvent: function(addedSelection, removedSelection) {                    if (this.NAME === "dxList" && this.option("selectionMode") !== "single")                        return;                    this._itemEventHandler(this._selectedItemElement(addedSelection[0]), "itemSelectAction", {                        selectedIndex: addedSelection[0],                        previousIndex: removedSelection[0]                    }, {excludeValidators: ["disabled", "readOnly"]})                },                _updateSelection: function() {                    this._renderSelection.apply(this, arguments)                },                _setAriaSelected: function($target, value) {                    this.setAria("selected", value, $target)                },                _removeSelection: function(normalizedIndex) {                    var $itemElement = this._editStrategy.getItemElement(normalizedIndex),                        itemSelectionIndex = $.inArray(normalizedIndex, this._selectedItemIndices);                    if (itemSelectionIndex > -1) {                        $itemElement.removeClass(this._selectedItemClass());                        this._setAriaSelected($itemElement, "false");                        this._selectedItemIndices.splice(itemSelectionIndex, 1);                        $itemElement.triggerHandler("stateChanged");                        if (this.NAME === "dxList")                            this._itemEventHandler($itemElement, "itemUnselectAction", {}, {excludeValidators: ["disabled", "readOnly"]})                    }                },                _addSelection: function(normalizedIndex) {                    var $itemElement = this._editStrategy.getItemElement(normalizedIndex);                    if (normalizedIndex > -1 && !this._isItemSelected(normalizedIndex)) {                        $itemElement.addClass(this._selectedItemClass());                        this._setAriaSelected($itemElement, "true");                        this._selectedItemIndices.push(normalizedIndex);                        $itemElement.triggerHandler("stateChanged");                        if (this.NAME === "dxList")                            this._itemEventHandler($itemElement, "itemSelectAction", {}, {excludeValidators: ["disabled", "readOnly"]})                    }                },                _isItemSelected: function(index) {                    return $.inArray(index, this._selectedItemIndices) > -1                },                _optionChanged: function(args) {                    if (this._cancelOptionChange)                        return;                    switch (args.name) {                        case"items":                            if (args.previousValue && args.previousValue.length > 0)                                this._clearSelectedItems();                            this.callBase(args);                            break;                        case"selectionMode":                            this._invalidate();                            break;                        case"selectedIndex":                        case"selectedItem":                        case"selectedItems":                            this._syncSelectionOptions(args.name);                            this._normalizeSelectedItems();                            this._updateSelectedItems();                            break;                        case"selectionRequired":                            this._normalizeSelectedItems();                            this._updateSelectedItems();                            break;                        case"selectionByClick":                        case"onSelectionChanged":                        case"onItemDeleting":                        case"onItemDeleted":                        case"onItemReordered":                        case"itemSelectAction":                        case"itemUnselectAction":                            break;                        default:                            this.callBase(args)                    }                },                _clearSelectedItems: function() {                    this._selectedItemIndices = [];                    this.option("selectedItems", [])                },                _setOptionSilent: function(name, value) {                    this._cancelOptionChange = true;                    this.option(name, value);                    this._cancelOptionChange = false                },                _waitDeletingPrepare: function($itemElement) {                    if ($itemElement.data(ITEM_DELETING_DATA_KEY))                        return $.Deferred().resolve().promise();                    $itemElement.data(ITEM_DELETING_DATA_KEY, true);                    var deferred = $.Deferred(),                        deletePromise = this._itemEventHandler($itemElement, "onItemDeleting", {}, {excludeValidators: ["disabled", "readOnly"]});                    $.when(deletePromise).always($.proxy(function(value) {                        var deletePromiseExists = !deletePromise,                            deletePromiseResolved = !deletePromiseExists && deletePromise.state() === "resolved",                            argumentsSpecified = !!arguments.length,                            shouldDelete = deletePromiseExists || deletePromiseResolved && !argumentsSpecified || deletePromiseResolved && value;                        $itemElement.data(ITEM_DELETING_DATA_KEY, false);                        shouldDelete ? deferred.resolve() : deferred.reject()                    }, this));                    return deferred.promise()                },                _deleteItemFromDS: function($item) {                    if (!this._dataSource)                        return $.Deferred().resolve().promise();                    var deferred = $.Deferred(),                        disabledState = this.option("disabled"),                        dataStore = this._dataSource.store();                    this.option("disabled", true);                    if (!dataStore.remove)                        throw DX.Error("E1011");                    dataStore.remove(dataStore.keyOf(this._getItemData($item))).done(function(key) {                        if (key !== undefined)                            deferred.resolve();                        else                            deferred.reject()                    }).fail(function() {                        deferred.reject()                    });                    deferred.always($.proxy(function() {                        this.option("disabled", disabledState)                    }, this));                    return deferred                },                _tryRefreshLastPage: function() {                    var deferred = $.Deferred();                    if (this._isLastPage() || this.option("grouped"))                        deferred.resolve();                    else                        this._refreshLastPage().done(function() {                            deferred.resolve()                        });                    return deferred.promise()                },                _refreshLastPage: function() {                    this._expectLastItemLoading();                    return this._dataSource.load()                },                _updateSelectionAfterDelete: function(fromIndex) {                    var itemIndex = $.inArray(fromIndex, this._selectedItemIndices);                    if (itemIndex > -1)                        this._selectedItemIndices.splice(itemIndex, 1);                    this._editStrategy.updateSelectionAfterDelete(fromIndex);                    this.option("selectedItems", this._editStrategy.fetchSelectedItems())                },                _simulateOptionChange: function(optionName) {                    var optionValue = this.option(optionName);                    if (optionValue instanceof DX.data.DataSource)                        return;                    this.fireEvent("optionChanged", [{                            name: optionName,                            fullName: optionName,                            value: optionValue                        }])                },                isItemSelected: function(itemElement) {                    return this._isItemSelected(this._editStrategy.getNormalizedIndex(itemElement))                },                selectItem: function(itemElement) {                    var itemIndex = this._editStrategy.getNormalizedIndex(itemElement);                    if (itemIndex === -1)                        return;                    var itemSelectionIndex = $.inArray(itemIndex, this._selectedItemIndices);                    if (itemSelectionIndex !== -1)                        return;                    if (this.option("selectionMode") === "single")                        this.option("selectedItems", this._editStrategy.fetchSelectedItems([itemIndex]));                    else {                        var newSelectedIndices = this._selectedItemIndices.slice();                        newSelectedIndices.push(itemIndex);                        this.option("selectedItems", this._editStrategy.fetchSelectedItems(newSelectedIndices))                    }                },                unselectItem: function(itemElement) {                    var itemIndex = this._editStrategy.getNormalizedIndex(itemElement);                    if (itemIndex === -1)                        return;                    var itemSelectionIndex = $.inArray(itemIndex, this._selectedItemIndices);                    if (itemSelectionIndex === -1)                        return;                    var newSelectedIndices = this._selectedItemIndices.slice();                    newSelectedIndices.splice(itemSelectionIndex, 1);                    if (this.option("selectionRequired") && newSelectedIndices.length === 0)                        return;                    this.option("selectedItems", this._editStrategy.fetchSelectedItems(newSelectedIndices))                },                deleteItem: function(itemElement) {                    var that = this,                        deferred = $.Deferred(),                        $item = this._editStrategy.getItemElement(itemElement),                        index = this._editStrategy.getNormalizedIndex(itemElement),                        changingOption = this._dataSource ? "dataSource" : "items",                        itemResponseWaitClass = this._itemResponseWaitClass();                    if (index > -1)                        this._waitDeletingPrepare($item).done(function() {                            $item.addClass(itemResponseWaitClass);                            that._deleteItemFromDS($item).done(function() {                                that._editStrategy.deleteItemAtIndex(index);                                that._simulateOptionChange(changingOption);                                that._updateSelectionAfterDelete(index);                                that._itemEventHandler($item, "onItemDeleted", {}, {                                    beforeExecute: function() {                                        $item.detach()                                    },                                    excludeValidators: ["disabled", "readOnly"]                                });                                that._renderEmptyMessage();                                that._tryRefreshLastPage().done(function() {                                    deferred.resolveWith(that)                                })                            }).fail(function() {                                $item.removeClass(itemResponseWaitClass);                                deferred.rejectWith(that)                            })                        }).fail(function() {                            deferred.rejectWith(that)                        });                    else                        deferred.rejectWith(that);                    return deferred.promise()                },                reorderItem: function(itemElement, toItemElement) {                    var deferred = $.Deferred(),                        that = this,                        strategy = this._editStrategy,                        $movingItem = strategy.getItemElement(itemElement),                        $destinationItem = strategy.getItemElement(toItemElement),                        movingIndex = strategy.getNormalizedIndex(itemElement),                        destinationIndex = strategy.getNormalizedIndex(toItemElement),                        changingOption;                    var canMoveItems = movingIndex > -1 && destinationIndex > -1 && movingIndex !== destinationIndex;                    if (canMoveItems)                        if (this._dataSource) {                            changingOption = "dataSource";                            deferred.resolveWith(this)                        }                        else {                            changingOption = "items";                            deferred.resolveWith(this)                        }                    else                        deferred.rejectWith(this);                    return deferred.promise().done(function() {                            $destinationItem[strategy.itemPlacementFunc(movingIndex, destinationIndex)]($movingItem);                            var newSelectedItems = strategy.getSelectedItemsAfterReorderItem(movingIndex, destinationIndex);                            strategy.moveItemAtIndexToIndex(movingIndex, destinationIndex);                            that._selectedItemIndices = strategy.selectedItemIndices(newSelectedItems);                            that.option("selectedItems", strategy.fetchSelectedItems());                            that._simulateOptionChange(changingOption);                            that._itemEventHandler($movingItem, "onItemReordered", {                                fromIndex: strategy.getIndex(movingIndex),                                toIndex: strategy.getIndex(destinationIndex)                            }, {excludeValidators: ["disabled", "readOnly"]})                        })                }            });        ui.CollectionWidget = CollectionWidget    })(jQuery, DevExpress);    /*! Module core, file ui.collectionWidget.edit.strategy.js */    (function($, DX, undefined) {        var ui = DX.ui;        ui.CollectionWidget.EditStrategy = DX.Class.inherit({            ctor: function(collectionWidget) {                this._collectionWidget = collectionWidget            },            getIndexByItemData: DX.abstract,            getItemDataByIndex: DX.abstract,            getNormalizedIndex: function(value) {                if (this._isNormalisedItemIndex(value))                    return value;                if (this._isItemIndex(value))                    return this._normalizeItemIndex(value);                return this._getNormalizedItemIndex(value)            },            getIndex: function(value) {                if (this._isNormalisedItemIndex(value))                    return this._denormalizeItemIndex(value);                if (this._isItemIndex(value))                    return value;                return this._denormalizeItemIndex(this._getNormalizedItemIndex(value))            },            getItemElement: function(value) {                if (this._isNormalisedItemIndex(value))                    return this._getItemByNormalizedIndex(value);                if (this._isItemIndex(value))                    return this._getItemByNormalizedIndex(this._normalizeItemIndex(value));                return $(value)            },            deleteItemAtIndex: DX.abstract,            updateSelectionAfterDelete: DX.abstract,            fetchSelectedItems: DX.abstract,            selectedItemIndices: DX.abstract,            itemPlacementFunc: function(movingIndex, destinationIndex) {                return this._itemsFromSameParent(movingIndex, destinationIndex) && movingIndex < destinationIndex ? "after" : "before"            },            moveItemAtIndexToIndex: DX.abstract,            getSelectedItemsAfterReorderItem: function() {                return this._collectionWidget.option("selectedItems")            },            _isNormalisedItemIndex: function(index) {                return $.isNumeric(index)            },            _isItemIndex: DX.abstract,            _getNormalizedItemIndex: DX.abstract,            _normalizeItemIndex: DX.abstract,            _denormalizeItemIndex: DX.abstract,            _getItemByNormalizedIndex: DX.abstract,            _itemsFromSameParent: DX.abstract        })    })(jQuery, DevExpress);    /*! Module core, file ui.collectionWidget.edit.strategy.plain.js */    (function($, DX, undefined) {        var ui = DX.ui;        ui.CollectionWidget.PlainEditStrategy = ui.CollectionWidget.EditStrategy.inherit({            _getPlainItems: function() {                return this._collectionWidget.option("items") || []            },            getIndexByItemData: function(itemData) {                return $.inArray(itemData, this._getPlainItems())            },            getItemDataByIndex: function(index) {                return this._getPlainItems()[index]            },            deleteItemAtIndex: function(index) {                this._getPlainItems().splice(index, 1)            },            updateSelectionAfterDelete: function(fromIndex) {                var selectedItemIndices = this._collectionWidget._selectedItemIndices;                $.each(selectedItemIndices, function(i, index) {                    if (index > fromIndex)                        selectedItemIndices[i] -= 1                })            },            fetchSelectedItems: function(indices) {                indices = indices || this._collectionWidget._selectedItemIndices;                var items = this._getPlainItems(),                    selectedItems = [];                $.each(indices, function(_, index) {                    selectedItems.push(items[index])                });                return selectedItems            },            selectedItemIndices: function() {                var selectedIndices = [],                    items = this._getPlainItems(),                    selected = this._collectionWidget.option("selectedItems");                $.each(selected, function(_, selectedItem) {                    var index = $.inArray(selectedItem, items);                    if (index !== -1)                        selectedIndices.push(index);                    else                        DX.log("W1002", selectedItem)                });                return selectedIndices            },            moveItemAtIndexToIndex: function(movingIndex, destinationIndex) {                var items = this._getPlainItems(),                    movedItemData = items[movingIndex];                items.splice(movingIndex, 1);                items.splice(destinationIndex, 0, movedItemData)            },            _isItemIndex: function(index) {                return $.isNumeric(index)            },            _getNormalizedItemIndex: function(itemElement) {                return this._collectionWidget._itemElements().index(itemElement)            },            _normalizeItemIndex: function(index) {                return index            },            _denormalizeItemIndex: function(index) {                return index            },            _getItemByNormalizedIndex: function(index) {                return this._collectionWidget._itemElements().eq(index)            },            _itemsFromSameParent: function() {                return true            }        })    })(jQuery, DevExpress);    /*! Module core, file ui.tooltip.js */    (function($, DX, undefined) {        var $tooltip = null;        var createTooltip = function(options) {                options = $.extend({position: "top"}, options);                var content = options.content;                delete options.content;                return $("<div />").html(content).appendTo(DX.viewPort()).dxTooltip(options)            };        var removeTooltip = function() {                if (!$tooltip)                    return;                $tooltip.remove();                $tooltip = null            };        var tooltip = {                show: function(options) {                    removeTooltip();                    $tooltip = createTooltip(options);                    return $tooltip.dxTooltip("show")                },                hide: function() {                    if (!$tooltip)                        return $.when();                    return $tooltip.dxTooltip("hide").done(removeTooltip).promise()                }            };        DX.ui.tooltip = tooltip    })(jQuery, DevExpress)}if (!DevExpress.MOD_WIDGETS_BASE) {    if (!window.DevExpress)        throw Error('Required module is not referenced: core');    /*! Module widgets-base, file ui.errors.js */    (function($, DX) {        $.extend(DX.ERROR_MESSAGES, {            E1001: "Module '{0}'. Controller '{1}' is already registered",            E1002: "Module '{0}'. Controller '{1}' must be inheritor of DevExpress.ui.dxDataGrid.Controller",            E1003: "Module '{0}'. View '{1}' is already registered",            E1004: "Module '{0}'. View '{1}' must be inheritor of DevExpress.ui.dxDataGrid.View",            E1005: "Public method '{0}' is already registered",            E1006: "Public method '{0}.{1}' is not exists",            E1007: "State storing can not be provided due to the restrictions of your browser",            E1010: "A template should contain dxTextBox widget",            E1011: "You have to implement 'remove' method in dataStore used by dxList to be able to delete items",            E1012: "Editing type '{0}' with name '{1}' not supported",            E1016: "Unexpected type of data source is provided for a lookup column",            E1018: "The 'collapseAll' method cannot be called when using a remote data source",            E1019: "Search mode '{0}' is unavailable",            E1020: "Type can not be changed after initialization",            E1021: "{0} '{1}' you are trying to remove does not exist",            E1022: "Markers option should be an array",            E1023: "Routes option should be an array",            E1024: "Google provider cannot be used in WinJS application",            E1025: "This layout is too complex to render",            E1026: "The 'custom' value is set to a summary item's summaryType option, but a function for calculating the custom summary is not assigned to the grid's calculateCustomSummary option",            E1030: "Unknown dxScrollView refresh strategy: '{0}'",            E1031: "Unknown subscription is detected in the dxScheduler widget: '{0}'",            E1032: "Unknown start date is detected in an appointment of the dxScheduler widget: '{0}'",            E1033: "Unknown step is specified for the scheduler's navigator: '{0}'",            E1034: "The current browser does not implement an API required for saving files",            W1001: "Key option can not be modified after initialization",            W1002: "Item '{0}' you are trying to select does not exist",            W1003: "Group with key '{0}' in which you are trying to select items does not exist",            W1004: "Item '{0}' you are trying to select in group '{1}' does not exist",            W1005: "Due to column data types being unspecified, data has been loaded twice in order to apply initial filter settings. To resolve this issue, specify data types for all grid columns."        })    })(jQuery, DevExpress);    /*! Module widgets-base, file ui.scrollable.js */    (function($, DX, undefined) {        var ui = DX.ui,            events = ui.events;        var SCROLLABLE = "dxScrollable",            SCROLLABLE_STRATEGY = "dxScrollableStrategy",            SCROLLABLE_CLASS = "dx-scrollable",            SCROLLABLE_DISABLED_CLASS = "dx-scrollable-disabled",            SCROLLABLE_CONTAINER_CLASS = "dx-scrollable-container",            SCROLLABLE_CONTENT_CLASS = "dx-scrollable-content",            VERTICAL = "vertical",            HORIZONTAL = "horizontal",            BOTH = "both";        var deviceDependentOptions = function() {                return [{                            device: function(device) {                                return !DX.support.nativeScrolling                            },                            options: {useNative: false}                        }, {                            device: function(device) {                                return !DX.support.nativeScrolling && !DX.devices.isSimulator() && DX.devices.real().platform === "generic" && device.platform === "generic"                            },                            options: {                                bounceEnabled: false,                                scrollByThumb: true,                                scrollByContent: DX.support.touch,                                showScrollbar: "onHover"                            }                        }]            };        DX.registerComponent(SCROLLABLE, ui, DX.DOMComponent.inherit({            _setDeprecatedOptions: function() {                this.callBase();                $.extend(this._deprecatedOptions, {                    updateAction: {                        since: "14.2",                        alias: "onUpdated"                    },                    scrollAction: {                        since: "14.2",                        alias: "onScroll"                    },                    startAction: {                        since: "14.2",                        alias: "onStart"                    },                    stopAction: {                        since: "14.2",                        alias: "onStop"                    },                    endAction: {                        since: "14.2",                        alias: "onEnd"                    }                })            },            _setDefaultOptions: function() {                this.callBase();                this.option({                    disabled: false,                    onScroll: null,                    direction: VERTICAL,                    showScrollbar: "onScroll",                    useNative: true,                    bounceEnabled: true,                    scrollByContent: true,                    scrollByThumb: false,                    onUpdated: null,                    onStart: null,                    onEnd: null,                    onBounce: null,                    onStop: null,                    useSimulatedScrollbar: false,                    useKeyboard: true,                    inertiaEnabled: true,                    pushBackValue: 0                })            },            _defaultOptionsRules: function() {                return this.callBase().concat(deviceDependentOptions(), [{                            device: function(device) {                                return DX.support.nativeScrolling && DX.devices.real().platform === "android"                            },                            options: {useSimulatedScrollbar: true}                        }, {                            device: function(device) {                                return DX.devices.real().platform === "ios"                            },                            options: {pushBackValue: 1}                        }])            },            _initOptions: function(options) {                this.callBase(options);                if (!("useSimulatedScrollbar" in options))                    this._setUseSimulatedScrollbar()            },            _setUseSimulatedScrollbar: function() {                if (!this._initialOptions.useSimulatedScrollbar)                    this.option("useSimulatedScrollbar", !this.option("useNative"))            },            _init: function() {                this.callBase();                this._initMarkup();                this._attachNativeScrollbarsCustomizationCss();                this._locked = false            },            _visibilityChanged: function(visible) {                if (this.element().is(":hidden"))                    return;                if (visible) {                    this.update();                    this._toggleRTLDirection(this.option("rtlEnabled"));                    this._savedScrollOffset && this.scrollTo(this._savedScrollOffset)                }                else                    this._savedScrollOffset = this.scrollOffset()            },            _initMarkup: function() {                var $element = this.element().addClass(SCROLLABLE_CLASS),                    $container = this._$container = $("<div>").addClass(SCROLLABLE_CONTAINER_CLASS),                    $content = this._$content = $("<div>").addClass(SCROLLABLE_CONTENT_CLASS);                $content.append($element.contents()).appendTo($container);                $container.appendTo($element)            },            _dimensionChanged: function() {                this.update()            },            _attachNativeScrollbarsCustomizationCss: function() {                if (!(navigator.platform.indexOf('Mac') > -1 && DevExpress.browser['webkit']))                    this.element().addClass("dx-scrollable-customizable-scrollbars")            },            _render: function() {                this._renderPushBackOffset();                this._renderDirection();                this._renderStrategy();                this._attachEventHandlers();                this._renderDisabledState();                this._createActions();                this.update();                this.callBase()            },            _renderPushBackOffset: function() {                var pushBackValue = this.option("pushBackValue");                this._$content.css({                    paddingTop: pushBackValue,                    paddingBottom: pushBackValue                })            },            _toggleRTLDirection: function(rtl) {                this.callBase(rtl);                if (rtl && this.option("direction") !== VERTICAL)                    this.scrollTo({left: this.scrollWidth() - this.clientWidth()})            },            _attachEventHandlers: function() {                var strategy = this._strategy;                var initEventData = {                        getDirection: $.proxy(strategy.getDirection, strategy),                        validate: $.proxy(this._validate, this),                        isNative: this.option("useNative")                    };                this._$container.off("." + SCROLLABLE).on(events.addNamespace("scroll", SCROLLABLE), $.proxy(strategy.handleScroll, strategy)).on(events.addNamespace("dxscrollinit", SCROLLABLE), initEventData, $.proxy(this._initHandler, this)).on(events.addNamespace("dxscrollstart", SCROLLABLE), $.proxy(strategy.handleStart, strategy)).on(events.addNamespace("dxscroll", SCROLLABLE), $.proxy(strategy.handleMove, strategy)).on(events.addNamespace("dxscrollend", SCROLLABLE), $.proxy(strategy.handleEnd, strategy)).on(events.addNamespace("dxscrollcancel", SCROLLABLE), $.proxy(strategy.handleCancel, strategy)).on(events.addNamespace("dxscrollstop", SCROLLABLE), $.proxy(strategy.handleStop, strategy))            },            _validate: function(e) {                if (this._isLocked())                    return false;                this.update();                return this._strategy.validate(e)            },            _initHandler: function() {                var strategy = this._strategy;                strategy.handleInit.apply(strategy, arguments)            },            _renderDisabledState: function() {                this.element().toggleClass(SCROLLABLE_DISABLED_CLASS, this.option("disabled"));                if (this.option("disabled"))                    this._lock();                else                    this._unlock()            },            _renderDirection: function() {                this.element().removeClass("dx-scrollable-" + HORIZONTAL).removeClass("dx-scrollable-" + VERTICAL).removeClass("dx-scrollable-" + BOTH).addClass("dx-scrollable-" + this.option("direction"))            },            _renderStrategy: function() {                this._createStrategy();                this._strategy.render();                this.element().data(SCROLLABLE_STRATEGY, this._strategy)            },            _createStrategy: function() {                this._strategy = this.option("useNative") ? new ui.dxScrollable.NativeStrategy(this) : new ui.dxScrollable.SimulatedStrategy(this)            },            _createActions: function() {                this._strategy.createActions()            },            _clean: function() {                this._strategy.dispose()            },            _optionChanged: function(args) {                switch (args.name) {                    case"onStart":                    case"onEnd":                    case"onStop":                    case"onUpdated":                    case"onScroll":                    case"onBounce":                        this._createActions();                        break;                    case"direction":                        this._resetInactiveDirection();                        this._invalidate();                        break;                    case"useNative":                        this._setUseSimulatedScrollbar();                        this._invalidate();                        break;                    case"inertiaEnabled":                    case"bounceEnabled":                    case"scrollByContent":                    case"scrollByThumb":                    case"bounceEnabled":                    case"useKeyboard":                    case"showScrollbar":                    case"useSimulatedScrollbar":                    case"pushBackValue":                        this._invalidate();                        break;                    case"disabled":                        this._renderDisabledState();                        break;                    default:                        this.callBase(args)                }            },            _resetInactiveDirection: function() {                var inactiveProp = this._getInactiveProp();                if (!inactiveProp)                    return;                var scrollOffset = this.scrollOffset();                scrollOffset[inactiveProp] = 0;                this.scrollTo(scrollOffset)            },            _getInactiveProp: function() {                var direction = this.option("direction");                if (direction === VERTICAL)                    return "left";                if (direction === HORIZONTAL)                    return "top"            },            _location: function() {                return this._strategy.location()            },            _normalizeLocation: function(location) {                var direction = this.option("direction");                return {                        left: $.isPlainObject(location) ? -(location.left || location.x || 0) : direction !== VERTICAL ? -location : 0,                        top: $.isPlainObject(location) ? -(location.top || location.y || 0) : direction !== HORIZONTAL ? -location : 0                    }            },            _isLocked: function() {                return this._locked            },            _lock: function() {                this._locked = true            },            _unlock: function() {                this._locked = false            },            _isDirection: function(direction) {                var current = this.option("direction");                if (direction === VERTICAL)                    return current !== HORIZONTAL;                if (direction === HORIZONTAL)                    return current !== VERTICAL;                return current === direction            },            _updateAllowedDirection: function() {                var allowedDirections = this._strategy._allowedDirections();                if (this._isDirection(BOTH) && allowedDirections.vertical && allowedDirections.horizontal)                    this._allowedDirectionValue = BOTH;                else if (this._isDirection(HORIZONTAL) && allowedDirections.horizontal)                    this._allowedDirectionValue = HORIZONTAL;                else if (this._isDirection(VERTICAL) && allowedDirections.vertical)                    this._allowedDirectionValue = VERTICAL;                else                    this._allowedDirectionValue = null            },            _allowedDirection: function() {                return this._allowedDirectionValue            },            content: function() {                return this._$content            },            scrollOffset: function() {                var location = this._location();                return {                        top: -location.top,                        left: -location.left                    }            },            scrollTop: function() {                return this.scrollOffset().top            },            scrollLeft: function() {                return this.scrollOffset().left            },            clientHeight: function() {                return this._$container.height()            },            scrollHeight: function() {                return this.content().height()            },            clientWidth: function() {                return this._$container.width()            },            scrollWidth: function() {                return this.content().width()            },            update: function() {                this._strategy.update();                this._updateAllowedDirection();                return $.when().promise()            },            scrollBy: function(distance) {                distance = this._normalizeLocation(distance);                if (!distance.top && !distance.left)                    return;                this._strategy.scrollBy(distance)            },            scrollTo: function(targetLocation) {                targetLocation = this._normalizeLocation(targetLocation);                var location = this._location();                this.scrollBy({                    left: location.left - targetLocation.left,                    top: location.top - targetLocation.top                })            },            scrollToElement: function(element, offset) {                offset = offset || {};                var $element = $(element);                var elementInsideContent = this.content().find(element).length;                var elementIsInsideContent = $element.parents("." + SCROLLABLE_CLASS).length - $element.parents("." + SCROLLABLE_CONTENT_CLASS).length === 0;                if (!elementInsideContent || !elementIsInsideContent)                    return;                var scrollPosition = {                        top: 0,                        left: 0                    };                var direction = this.option("direction");                if (direction !== VERTICAL)                    scrollPosition.left = this._scrollToElementPosition($element, HORIZONTAL, offset);                if (direction !== HORIZONTAL)                    scrollPosition.top = this._scrollToElementPosition($element, VERTICAL, offset);                this.scrollTo(scrollPosition)            },            _scrollToElementPosition: function($element, direction, offset) {                var isVertical = direction === VERTICAL;                var startOffset = (isVertical ? offset.top : offset.left) || 0;                var endOffset = (isVertical ? offset.bottom : offset.right) || 0;                var pushBackOffset = isVertical ? this.option("pushBackValue") : 0;                var elementPositionRelativeToContent = this._elementPositionRelativeToContent($element, isVertical ? 'top' : 'left');                var elementPosition = elementPositionRelativeToContent - pushBackOffset;                var elementSize = $element[isVertical ? 'outerHeight' : 'outerWidth']();                var elementBottom = elementPositionRelativeToContent + elementSize;                var scrollLocation = (isVertical ? this.scrollTop() : this.scrollLeft()) - startOffset;                var clientSize = (isVertical ? this.clientHeight() : this.clientWidth()) - startOffset - endOffset;                var scrollBottom = scrollLocation + clientSize;                var isEntirelyVisible = scrollLocation <= elementPosition && scrollBottom >= elementBottom;                var isEntirelyWithOversizeVisible = scrollLocation >= elementPosition && scrollBottom <= elementBottom;                var isAlreadyVisible = isEntirelyVisible || isEntirelyWithOversizeVisible;                var isElementAboveScrollLocation = scrollLocation > elementPosition;                return isAlreadyVisible ? scrollLocation : elementPosition - (isElementAboveScrollLocation ? 0 : clientSize - elementSize)            },            _elementPositionRelativeToContent: function($element, prop) {                var result = 0;                while (this._hasScrollContent($element)) {                    result += $element.position()[prop];                    $element = $element.offsetParent()                }                return result            },            _hasScrollContent: function($element) {                var $content = this.content();                return $element.closest($content).length && !$element.is($content)            }        }));        ui.dxScrollable.deviceDependentOptions = deviceDependentOptions    })(jQuery, DevExpress);    /*! Module widgets-base, file ui.scrollbar.js */    (function($, DX, undefined) {        var ui = DX.ui,            events = ui.events;        var SCROLLBAR = "dxScrollbar",            SCROLLABLE_SCROLLBAR_CLASS = "dx-scrollable-scrollbar",            SCROLLABLE_SCROLLBAR_ACTIVE_CLASS = SCROLLABLE_SCROLLBAR_CLASS + "-active",            SCROLLABLE_SCROLL_CLASS = "dx-scrollable-scroll",            SCROLLABLE_SCROLL_CONTENT_CLASS = "dx-scrollable-scroll-content",            HOVER_ENABLED_STATE = "dx-scrollbar-hoverable",            HORIZONTAL = "horizontal",            THUMB_MIN_SIZE = 15;        var SCROLLBAR_VISIBLE = {                onScroll: "onScroll",                onHover: "onHover",                always: "always",                never: "never"            };        DX.registerComponent(SCROLLBAR, ui.dxScrollable, ui.Widget.inherit({            _setDefaultOptions: function() {                this.callBase();                this.option({                    direction: null,                    visible: false,                    activeStateEnabled: false,                    visibilityMode: SCROLLBAR_VISIBLE.onScroll,                    containerSize: 0,                    contentSize: 0,                    expandable: true                })            },            _init: function() {                this.callBase();                this._isHovered = false            },            _render: function() {                this._renderThumb();                this.callBase();                this._renderDirection();                this._update();                this._attachPointerDownHandler();                this.option("hoverStateEnabled", this._isHoverMode());                this.element().toggleClass(HOVER_ENABLED_STATE, this.option("hoverStateEnabled"))            },            _renderThumb: function() {                this._$thumb = $("<div>").addClass(SCROLLABLE_SCROLL_CLASS);                $("<div>").addClass(SCROLLABLE_SCROLL_CONTENT_CLASS).appendTo(this._$thumb);                this.element().addClass(SCROLLABLE_SCROLLBAR_CLASS).append(this._$thumb)            },            isThumb: function($element) {                return !!this.element().find($element).length            },            _isHoverMode: function() {                return this.option("visibilityMode") === SCROLLBAR_VISIBLE.onHover && this.option("expandable")            },            _renderDirection: function() {                var direction = this.option("direction");                this.element().addClass("dx-scrollbar-" + direction);                this._dimension = direction === HORIZONTAL ? "width" : "height";                this._prop = direction === HORIZONTAL ? "left" : "top"            },            _attachPointerDownHandler: function() {                this._$thumb.on(events.addNamespace("dxpointerdown", SCROLLBAR), $.proxy(this.feedbackOn, this))            },            feedbackOn: function() {                this.element().addClass(SCROLLABLE_SCROLLBAR_ACTIVE_CLASS);                activeScrollbar = this            },            feedbackOff: function() {                this.element().removeClass(SCROLLABLE_SCROLLBAR_ACTIVE_CLASS);                activeScrollbar = null            },            cursorEnter: function() {                this._isHovered = true;                this.option("visible", true)            },            cursorLeave: function() {                this._isHovered = false;                this.option("visible", false)            },            _renderDimensions: function() {                this._$thumb.outerHeight(this.option("height"));                this._$thumb.outerWidth(this.option("width"))            },            _toggleVisibility: function(visible) {                if (this.option("visibilityMode") === SCROLLBAR_VISIBLE.onScroll)                    this._$thumb.css("opacity");                visible = this._adjustVisibility(visible);                this.option().visible = visible;                this._$thumb.toggleClass("dx-state-invisible", !visible)            },            _adjustVisibility: function(visible) {                if (this.containerToContentRatio() && !this._needScrollbar())                    return false;                switch (this.option("visibilityMode")) {                    case SCROLLBAR_VISIBLE.onScroll:                        break;                    case SCROLLBAR_VISIBLE.onHover:                        visible = visible || !!this._isHovered;                        break;                    case SCROLLBAR_VISIBLE.never:                        visible = false;                        break;                    case SCROLLBAR_VISIBLE.always:                        visible = true;                        break                }                return visible            },            moveTo: function(location) {                if (this._isHidden())                    return;                if ($.isPlainObject(location))                    location = location[this._prop] || 0;                var scrollBarLocation = {};                scrollBarLocation[this._prop] = this._calculateScrollBarPosition(location);                DX.translator.move(this._$thumb, scrollBarLocation)            },            _calculateScrollBarPosition: function(location) {                return -location * this._thumbRatio            },            _update: function() {                var containerSize = this.option("containerSize"),                    contentSize = this.option("contentSize");                this._containerToContentRatio = containerSize / contentSize;                var thumbSize = Math.round(Math.max(Math.round(containerSize * this._containerToContentRatio), THUMB_MIN_SIZE));                this._thumbRatio = (containerSize - thumbSize) / (contentSize - containerSize);                this.option(this._dimension, thumbSize);                this.element().toggle(this._needScrollbar())            },            _isHidden: function() {                return this.option("visibilityMode") === SCROLLBAR_VISIBLE.never            },            _needScrollbar: function() {                return !this._isHidden() && this._containerToContentRatio < 1            },            containerToContentRatio: function() {                return this._containerToContentRatio            },            _normalizeSize: function(size) {                return $.isPlainObject(size) ? size[this._dimension] || 0 : size            },            _clean: function() {                this.callBase();                if (this === activeScrollbar)                    activeScrollbar = null;                this._$thumb.off("." + SCROLLBAR)            },            _optionChanged: function(args) {                if (this._isHidden())                    return;                switch (args.name) {                    case"containerSize":                    case"contentSize":                        this.option()[args.name] = this._normalizeSize(args.value);                        this._update();                        break;                    case"visibilityMode":                    case"direction":                        this._invalidate();                        break;                    default:                        this.callBase.apply(this, arguments)                }            },            update: function() {                this._adjustVisibility() && this.option("visible", true)            }        }));        var activeScrollbar = null;        $(document).on(events.addNamespace("dxpointerup", SCROLLBAR), function() {            if (activeScrollbar)                activeScrollbar.feedbackOff()        })    })(jQuery, DevExpress);    /*! Module widgets-base, file ui.scrollable.native.js */    (function($, DX, undefined) {        var ui = DX.ui,            devices = DX.devices;        var SCROLLABLE_NATIVE = "dxNativeScrollable",            SCROLLABLE_NATIVE_CLASS = "dx-scrollable-native",            SCROLLABLE_SCROLLBAR_SIMULATED = "dx-scrollable-scrollbar-simulated",            SCROLLABLE_SCROLLBARS_HIDDEN = "dx-scrollable-scrollbars-hidden",            VERTICAL = "vertical",            HORIZONTAL = "horizontal",            HIDE_SCROLLBAR_TIMOUT = 500;        ui.dxScrollable.NativeStrategy = DX.Class.inherit({            ctor: function(scrollable) {                this._init(scrollable)            },            _init: function(scrollable) {                this._component = scrollable;                this._$element = scrollable.element();                this._$container = scrollable._$container;                this._$content = scrollable._$content;                this._direction = scrollable.option("direction");                this._useSimulatedScrollbar = scrollable.option("useSimulatedScrollbar");                this._showScrollbar = scrollable.option("showScrollbar");                this.option = $.proxy(scrollable.option, scrollable);                this._createActionByOption = $.proxy(scrollable._createActionByOption, scrollable);                this._isLocked = $.proxy(scrollable._isLocked, scrollable);                this._isDirection = $.proxy(scrollable._isDirection, scrollable);                this._allowedDirection = $.proxy(scrollable._allowedDirection, scrollable)            },            render: function() {                var device = devices.real(),                    deviceType = device.platform;                this._$element.addClass(SCROLLABLE_NATIVE_CLASS).addClass(SCROLLABLE_NATIVE_CLASS + "-" + deviceType).toggleClass(SCROLLABLE_SCROLLBARS_HIDDEN, !this._showScrollbar);                if (this._showScrollbar && this._useSimulatedScrollbar)                    this._renderScrollbars()            },            _renderScrollbars: function() {                this._scrollbars = {};                this._hideScrollbarTimeout = 0;                this._$element.addClass(SCROLLABLE_SCROLLBAR_SIMULATED);                this._renderScrollbar(VERTICAL);                this._renderScrollbar(HORIZONTAL)            },            _renderScrollbar: function(direction) {                if (!this._isDirection(direction))                    return;                var $scrollbar = $("<div>").dxScrollbar({                        direction: direction,                        expandable: this._component.option("scrollByThumb")                    }).appendTo(this._$element);                this._scrollbars[direction] = $scrollbar.dxScrollbar("instance")            },            handleInit: $.noop,            handleStart: $.noop,            handleMove: function(e) {                if (this._isLocked()) {                    e.cancel = true;                    return                }                if (this._allowedDirection())                    e.originalEvent.isScrollingEvent = true            },            handleEnd: $.noop,            handleStop: $.noop,            _eachScrollbar: function(callback) {                callback = $.proxy(callback, this);                $.each(this._scrollbars || {}, function(direction, scrollbar) {                    callback(scrollbar, direction)                })            },            createActions: function() {                this._scrollAction = this._createActionByOption("onScroll");                this._updateAction = this._createActionByOption("onUpdated")            },            _createActionArgs: function() {                var location = this.location();                return {                        jQueryEvent: this._eventForUserAction,                        scrollOffset: {                            top: -location.top,                            left: -location.left                        },                        reachedLeft: this._isDirection(HORIZONTAL) ? location.left >= 0 : undefined,                        reachedRight: this._isDirection(HORIZONTAL) ? location.left <= this._containerSize.width - this._componentContentSize.width : undefined,                        reachedTop: this._isDirection(VERTICAL) ? location.top >= 0 : undefined,                        reachedBottom: this._isDirection(VERTICAL) ? location.top <= this._containerSize.height - this._componentContentSize.height : undefined                    }            },            handleScroll: function(e) {                if (!this._isScrollLocationChanged()) {                    e.stopImmediatePropagation();                    return                }                this._eventForUserAction = e;                this._moveScrollbars();                this._scrollAction(this._createActionArgs());                this._lastLocation = this.location();                this._pushBackFromBoundary()            },            _pushBackFromBoundary: function() {                var pushBackValue = this.option("pushBackValue");                if (!pushBackValue)                    return;                var scrollOffset = this._containerSize.height - this._contentSize.height,                    scrollTopPos = this._$container.scrollTop(),                    scrollBottomPos = scrollOffset + scrollTopPos - pushBackValue * 2;                if (!scrollTopPos)                    this._$container.scrollTop(pushBackValue);                else if (!scrollBottomPos)                    this._$container.scrollTop(pushBackValue - scrollOffset)            },            _isScrollLocationChanged: function() {                var currentLocation = this.location(),                    lastLocation = this._lastLocation || {},                    isTopChanged = lastLocation.top !== currentLocation.top,                    isLeftChanged = lastLocation.left !== currentLocation.left;                return isTopChanged || isLeftChanged            },            _moveScrollbars: function() {                this._eachScrollbar(function(scrollbar) {                    scrollbar.moveTo(this.location());                    scrollbar.option("visible", true)                });                this._hideScrollbars()            },            _hideScrollbars: function() {                clearTimeout(this._hideScrollbarTimeout);                this._hideScrollbarTimeout = setTimeout($.proxy(function() {                    this._eachScrollbar(function(scrollbar) {                        scrollbar.option("visible", false)                    })                }, this), HIDE_SCROLLBAR_TIMOUT)            },            location: function() {                return {                        left: -this._$container.scrollLeft(),                        top: this.option("pushBackValue") - this._$container.scrollTop()                    }            },            disabledChanged: $.noop,            update: function() {                this._update();                this._updateAction(this._createActionArgs())            },            _update: function() {                this._updateDimensions();                this._updateScrollbars()            },            _updateDimensions: function() {                this._containerSize = {                    height: this._$container.height(),                    width: this._$container.width()                };                this._componentContentSize = {                    height: this._component.content().height(),                    width: this._component.content().width()                };                this._contentSize = {                    height: this._$content.height(),                    width: this._$content.width()                };                this._pushBackFromBoundary()            },            _updateScrollbars: function() {                this._eachScrollbar(function(scrollbar, direction) {                    var dimension = direction === VERTICAL ? "height" : "width";                    scrollbar.option({                        containerSize: this._containerSize[dimension],                        contentSize: this._componentContentSize[dimension]                    });                    scrollbar.update()                })            },            _allowedDirections: function() {                return {                        vertical: this._isDirection(VERTICAL) && this._contentSize.height > this._containerSize.height,                        horizontal: this._isDirection(HORIZONTAL) && this._contentSize.width > this._containerSize.width                    }            },            dispose: function() {                this._$element.removeClass(function(index, className) {                    var scrollableNativeRegexp = new RegExp(SCROLLABLE_NATIVE_CLASS + "\\S*", "g");                    if (scrollableNativeRegexp.test(className))                        return className.match(scrollableNativeRegexp).join(" ")                });                this._$element.off("." + SCROLLABLE_NATIVE);                this._$container.off("." + SCROLLABLE_NATIVE);                this._removeScrollbars();                clearTimeout(this._gestureEndTimer);                clearTimeout(this._hideScrollbarTimeout)            },            _removeScrollbars: function() {                this._eachScrollbar(function(scrollbar) {                    scrollbar.element().remove()                })            },            scrollBy: function(distance) {                var location = this.location();                this._$container.scrollTop(-location.top - distance.top + this.option("pushBackValue"));                this._$container.scrollLeft(-location.left - distance.left)            },            validate: function() {                return !this.option("disabled") && this._allowedDirection()            },            getDirection: function() {                return this._allowedDirection()            }        })    })(jQuery, DevExpress);    /*! Module widgets-base, file ui.scrollable.simulated.js */    (function($, DX, undefined) {        var ui = DX.ui,            events = ui.events,            math = Math,            translator = DX.translator;        var realDevice = DX.devices.real;        var isSluggishPlatform = realDevice.platform === "win8" || realDevice.platform === "android";        var SCROLLABLE_SIMULATED = "dxSimulatedScrollable",            SCROLLABLE_STRATEGY = "dxScrollableStrategy",            SCROLLABLE_SIMULATED_CURSOR = SCROLLABLE_SIMULATED + "Cursor",            SCROLLABLE_SIMULATED_KEYBOARD = SCROLLABLE_SIMULATED + "Keyboard",            SCROLLABLE_SIMULATED_CLASS = "dx-scrollable-simulated",            SCROLLABLE_SCROLLBARS_HIDDEN = "dx-scrollable-scrollbars-hidden",            SCROLLABLE_SCROLLBAR_CLASS = "dx-scrollable-scrollbar",            VERTICAL = "vertical",            HORIZONTAL = "horizontal",            ACCELERATION = isSluggishPlatform ? 0.95 : 0.92,            OUT_BOUNDS_ACCELERATION = 0.5,            MIN_VELOCITY_LIMIT = 1,            FRAME_DURATION = math.round(1000 / 60),            SCROLL_LINE_HEIGHT = 20,            BOUNCE_MIN_VELOCITY_LIMIT = MIN_VELOCITY_LIMIT / 5,            BOUNCE_DURATION = isSluggishPlatform ? 300 : 400,            BOUNCE_FRAMES = BOUNCE_DURATION / FRAME_DURATION,            BOUNCE_ACCELERATION_SUM = (1 - math.pow(ACCELERATION, BOUNCE_FRAMES)) / (1 - ACCELERATION);        var KEY_CODES = {                PAGE_UP: 33,                PAGE_DOWN: 34,                END: 35,                HOME: 36,                LEFT: 37,                UP: 38,                RIGHT: 39,                DOWN: 40            };        var scrollIntoViewIfNeededCallbacks = function() {                var callbacks = $.Callbacks();                var FOCUS_TIMEOUT = 50,                    cancelChangeTimestamp = null;                $(window).on(events.addNamespace("focus", SCROLLABLE_STRATEGY), function() {                    cancelChangeTimestamp = $.now()                });                $(document).on(events.addNamespace("dxpointerdown", SCROLLABLE_STRATEGY), function() {                    cancelChangeTimestamp = $.now()                });                var focusChange = function(e) {                        var keyboardElementChange = $.now() - cancelChangeTimestamp > FOCUS_TIMEOUT,                            focusedCorrectElement = e.target === document.activeElement;                        if (keyboardElementChange && focusedCorrectElement)                            callbacks.fire(e.target)                    };                if (window.addEventListener)                    window.addEventListener("focus", focusChange, true);                else                    window.attachEvent("onfocusin", focusChange);                return callbacks            }();        var InertiaAnimator = DX.Animator.inherit({                ctor: function(scroller) {                    this.callBase();                    this.scroller = scroller                },                VELOCITY_LIMIT: MIN_VELOCITY_LIMIT,                _isFinished: function() {                    return math.abs(this.scroller._velocity) <= this.VELOCITY_LIMIT                },                _step: function() {                    this.scroller._scrollStep(this.scroller._velocity);                    this.scroller._velocity *= this._acceleration()                },                _acceleration: function() {                    return this.scroller._inBounds() ? ACCELERATION : OUT_BOUNDS_ACCELERATION                },                _complete: function() {                    this.scroller._scrollComplete()                },                _stop: function() {                    this.scroller._stopComplete()                }            });        var BounceAnimator = InertiaAnimator.inherit({                VELOCITY_LIMIT: BOUNCE_MIN_VELOCITY_LIMIT,                _isFinished: function() {                    return this.scroller._crossBoundOnNextStep() || this.callBase()                },                _acceleration: function() {                    return ACCELERATION                },                _complete: function() {                    this.scroller._move(this.scroller._bounceLocation);                    this.callBase()                }            });        var isWheelEvent = function(e) {                return e.type === "dxmousewheel"            };        var Scroller = ui.dxScrollable.Scroller = DX.Class.inherit({                ctor: function(options) {                    this._initOptions(options);                    this._initAnimators();                    this._initScrollbar()                },                _initOptions: function(options) {                    this._location = 0;                    this._topReached = false;                    this._bottomReached = false;                    this._axis = options.direction === HORIZONTAL ? "x" : "y";                    this._prop = options.direction === HORIZONTAL ? "left" : "top";                    this._dimension = options.direction === HORIZONTAL ? "width" : "height";                    this._scrollProp = options.direction === HORIZONTAL ? "scrollLeft" : "scrollTop";                    $.each(options, $.proxy(function(optionName, optionValue) {                        this["_" + optionName] = optionValue                    }, this))                },                _initAnimators: function() {                    this._inertiaAnimator = new InertiaAnimator(this);                    this._bounceAnimator = new BounceAnimator(this)                },                _initScrollbar: function() {                    this._$scrollbar = $("<div>").dxScrollbar({                        direction: this._direction,                        visible: this._scrollByThumb,                        visibilityMode: this._visibilityModeNormalize(this._scrollbarVisible),                        containerSize: this._containerSize(),                        contentSize: this._contentSize(),                        expandable: this._scrollByThumb                    }).appendTo(this._$container);                    this._scrollbar = this._$scrollbar.dxScrollbar("instance")                },                _visibilityModeNormalize: function(mode) {                    return mode === true ? "onScroll" : mode === false ? "never" : mode                },                _scrollStep: function(delta) {                    var prevLocation = this._location;                    this._location += delta;                    this._suppressBounce();                    this._move();                    if (prevLocation !== this._location) {                        this._scrollAction();                        $.data(this._$container.get(0), "scroll")()                    }                },                _suppressBounce: function() {                    if (this._bounceEnabled || this._inBounds(this._location))                        return;                    this._velocity = 0;                    this._location = this._boundLocation()                },                _boundLocation: function() {                    var location = math.min(this._location, this._maxOffset);                    return math.max(location, this._minOffset)                },                _move: function(location) {                    this._location = location !== undefined ? location : this._location;                    this._moveContent();                    this._moveScrollbar()                },                _moveContent: function() {                    var targetLocation = {};                    targetLocation[this._prop] = this._location;                    translator.move(this._$content, targetLocation)                },                _moveScrollbar: function() {                    this._scrollbar.moveTo(this._location)                },                _scrollComplete: function() {                    if (this._inBounds()) {                        this._hideScrollbar();                        this._correctLocation();                        if (this._completeDeferred)                            this._completeDeferred.resolve()                    }                    this._scrollToBounds()                },                _correctLocation: function() {                    this._location = math.round(this._location);                    this._move()                },                _scrollToBounds: function() {                    if (this._inBounds())                        return;                    this._bounceAction();                    this._setupBounce();                    this._bounceAnimator.start()                },                _setupBounce: function() {                    var boundLocation = this._bounceLocation = this._boundLocation(),                        bounceDistance = boundLocation - this._location;                    this._velocity = bounceDistance / BOUNCE_ACCELERATION_SUM                },                _inBounds: function(location) {                    location = location !== undefined ? location : this._location;                    return location >= this._minOffset && location <= this._maxOffset                },                _crossBoundOnNextStep: function() {                    var location = this._location,                        nextLocation = location + this._velocity;                    return location < this._minOffset && nextLocation >= this._minOffset || location > this._maxOffset && nextLocation <= this._maxOffset                },                _initHandler: function(e) {                    this._stopDeferred = $.Deferred();                    this._stopScrolling();                    this._prepareThumbScrolling(e);                    return this._stopDeferred.promise()                },                _stopScrolling: function() {                    this._hideScrollbar();                    this._inertiaAnimator.stop();                    this._bounceAnimator.stop()                },                _prepareThumbScrolling: function(e) {                    if (isWheelEvent(e.originalEvent))                        return;                    var $target = $(e.originalEvent.target);                    var scrollbarClicked = this._isScrollbar($target);                    if (scrollbarClicked)                        this._moveToMouseLocation(e);                    this._thumbScrolling = scrollbarClicked || this._isThumb($target);                    if (this._thumbScrolling)                        this._scrollbar.feedbackOn()                },                _moveToMouseLocation: function(e) {                    var mouseLocation = e["page" + this._axis.toUpperCase()] - this._$element.offset()[this._prop];                    var location = this._location + mouseLocation / this._containerToContentRatio() - this._$container.height() / 2;                    this._scrollStep(-location)                },                _stopComplete: function() {                    if (this._stopDeferred)                        this._stopDeferred.resolve()                },                _startHandler: function() {                    this._showScrollbar()                },                _moveHandler: function(delta) {                    delta = delta[this._axis];                    if (this._thumbScrolling)                        delta = -delta / this._containerToContentRatio();                    if (!this._inBounds())                        delta *= OUT_BOUNDS_ACCELERATION;                    this._scrollStep(delta)                },                _containerToContentRatio: function() {                    return this._scrollbar.containerToContentRatio()                },                _endHandler: function(velocity) {                    this._completeDeferred = $.Deferred();                    this._velocity = velocity[this._axis];                    this._inertiaHandler();                    this._resetThumbScrolling();                    return this._completeDeferred.promise()                },                _inertiaHandler: function() {                    this._suppressIntertia();                    this._inertiaAnimator.start()                },                _suppressIntertia: function() {                    if (!this._inertiaEnabled || this._thumbScrolling)                        this._velocity = 0                },                _resetThumbScrolling: function() {                    this._thumbScrolling = false                },                _stopHandler: function() {                    this._resetThumbScrolling();                    this._scrollToBounds()                },                _disposeHandler: function() {                    this._stopScrolling();                    this._$scrollbar.remove()                },                _updateHandler: function() {                    this._update();                    this._moveToBounds()                },                _update: function() {                    this._stopScrolling();                    this._updateLocation();                    this._updateBounds();                    this._updateScrollbar();                    this._moveScrollbar();                    this._scrollbar.update()                },                _updateLocation: function() {                    this._location = translator.locate(this._$content)[this._prop]                },                _updateBounds: function() {                    this._maxOffset = this._getMaxOffset();                    this._minOffset = this._getMinOffset()                },                _getMaxOffset: function() {                    return 0                },                _getMinOffset: function() {                    return math.min(this._containerSize() - this._contentSize(), 0)                },                _updateScrollbar: function() {                    this._scrollbar.option({                        containerSize: this._containerSize(),                        contentSize: this._contentSize()                    })                },                _moveToBounds: function() {                    this._location = this._boundLocation();                    this._move()                },                _createActionsHandler: function(actions) {                    this._scrollAction = actions.scroll;                    this._bounceAction = actions.bounce                },                _showScrollbar: function() {                    this._scrollbar.option("visible", true)                },                _hideScrollbar: function() {                    this._scrollbar.option("visible", false)                },                _containerSize: function() {                    return this._$container[this._dimension]()                },                _contentSize: function() {                    return this._$content[this._dimension]()                },                _validateEvent: function(e) {                    var $target = $(e.originalEvent.target);                    if (this._isThumb($target) || this._isScrollbar($target)) {                        e.preventDefault();                        return true                    }                    return this._isContent($target)                },                _isThumb: function($element) {                    return this._scrollByThumb && this._scrollbar.isThumb($element)                },                _isScrollbar: function($element) {                    return this._scrollByThumb && $element && $element.is(this._$scrollbar)                },                _isContent: function($element) {                    return this._scrollByContent && !!$element.closest(this._$element).length                },                _reachedMin: function() {                    return this._location <= this._minOffset                },                _reachedMax: function() {                    return this._location >= this._maxOffset                },                _cursorEnterHandler: function() {                    this._scrollbar.cursorEnter()                },                _cursorLeaveHandler: function() {                    this._scrollbar.cursorLeave()                },                dispose: $.noop            });        var hoveredScrollable,            activeScrollable;        ui.dxScrollable.SimulatedStrategy = DX.Class.inherit({            ctor: function(scrollable) {                this._init(scrollable)            },            _init: function(scrollable) {                this._component = scrollable;                this._$element = scrollable.element();                this._$container = scrollable._$container;                this._$content = scrollable._$content;                this.option = $.proxy(scrollable.option, scrollable);                this._createActionByOption = $.proxy(scrollable._createActionByOption, scrollable);                this._isLocked = $.proxy(scrollable._isLocked, scrollable);                this._isDirection = $.proxy(scrollable._isDirection, scrollable);                this._allowedDirection = $.proxy(scrollable._allowedDirection, scrollable);                this._proxiedActiveElementChangeHandler = $.proxy(this._activeElementChangeHandler, this);                scrollIntoViewIfNeededCallbacks.add(this._proxiedActiveElementChangeHandler)            },            _activeElementChangeHandler: function(activeElement) {                this._component.scrollToElement(activeElement)            },            render: function() {                this._$element.addClass(SCROLLABLE_SIMULATED_CLASS);                this._createScrollers();                if (this.option("useKeyboard"))                    this._$container.prop("tabindex", 0);                this._attachKeyboardHandler();                this._attachCursorHandlers()            },            _createScrollers: function() {                this._scrollers = {};                if (this._isDirection(HORIZONTAL))                    this._createScroller(HORIZONTAL);                if (this._isDirection(VERTICAL))                    this._createScroller(VERTICAL);                this._$element.toggleClass(SCROLLABLE_SCROLLBARS_HIDDEN, !this.option("showScrollbar"))            },            _createScroller: function(direction) {                this._scrollers[direction] = new Scroller(this._scrollerOptions(direction))            },            _scrollerOptions: function(direction) {                return {                        direction: direction,                        $content: this._$content,                        $container: this._$container,                        $element: this._$element,                        scrollByContent: this.option("scrollByContent"),                        scrollByThumb: this.option("scrollByThumb"),                        scrollbarVisible: this.option("showScrollbar"),                        bounceEnabled: this.option("bounceEnabled"),                        inertiaEnabled: this.option("inertiaEnabled")                    }            },            handleInit: function(e) {                this._supressDirections(e);                this._eventForUserAction = e;                this._eventHandler("init", e).done(this._stopAction)            },            _supressDirections: function(e) {                if (isWheelEvent(e.originalEvent)) {                    this._prepareDirections(true);                    return                }                this._prepareDirections();                this._eachScroller(function(scroller, direction) {                    var isValid = scroller._validateEvent(e);                    this._validDirections[direction] = isValid                })            },            _prepareDirections: function(value) {                value = value || false;                this._validDirections = {};                this._validDirections[HORIZONTAL] = value;                this._validDirections[VERTICAL] = value            },            _eachScroller: function(callback) {                callback = $.proxy(callback, this);                $.each(this._scrollers, function(direction, scroller) {                    callback(scroller, direction)                })            },            handleStart: function(e) {                this._saveActive();                this._eventHandler("start").done(this._startAction)            },            _saveActive: function() {                activeScrollable = this            },            _resetActive: function() {                activeScrollable = null            },            _validateDirection: function(delta) {                var result = false;                this._eachScroller(function(scroller) {                    result = result || scroller._validateDirection(delta)                });                return result            },            handleMove: function(e) {                if (this._isLocked()) {                    e.cancel = true;                    this._resetActive();                    return                }                e.preventDefault && e.preventDefault();                this._adjustDistance(e.delta);                this._eventForUserAction = e;                this._eventHandler("move", e.delta)            },            _adjustDistance: function(distance) {                distance.x *= this._validDirections[HORIZONTAL];                distance.y *= this._validDirections[VERTICAL]            },            handleEnd: function(e) {                this._resetActive();                this._refreshCursorState(e.originalEvent && e.originalEvent.target);                this._adjustDistance(e.velocity);                this._eventForUserAction = e;                return this._eventHandler("end", e.velocity).done(this._endAction)            },            handleCancel: function(e) {                this._resetActive();                this._eventForUserAction = e;                return this._eventHandler("end", {                        x: 0,                        y: 0                    })            },            handleStop: function() {                this._resetActive();                this._eventHandler("stop")            },            handleScroll: function() {                var distance = {                        left: this.option("direction") !== VERTICAL ? -this._$container.scrollLeft() : 0,                        top: this.option("direction") !== HORIZONTAL ? -this._$container.scrollTop() : 0                    };                if (!distance.left && !distance.top)                    return;                this._$container.scrollLeft(0);                this._$container.scrollTop(0);                this.scrollBy(distance)            },            _attachKeyboardHandler: function() {                this._$element.off("." + SCROLLABLE_SIMULATED_KEYBOARD);                if (!this.option("disabled") && this.option("useKeyboard"))                    this._$element.on(events.addNamespace("keydown", SCROLLABLE_SIMULATED_KEYBOARD), $.proxy(this._keyDownHandler, this))            },            _keyDownHandler: function(e) {                if (!this._$container.is(document.activeElement))                    return;                var handled = true;                switch (e.keyCode) {                    case KEY_CODES.DOWN:                        this._scrollByLine({y: 1});                        break;                    case KEY_CODES.UP:                        this._scrollByLine({y: -1});                        break;                    case KEY_CODES.RIGHT:                        this._scrollByLine({x: 1});                        break;                    case KEY_CODES.LEFT:                        this._scrollByLine({x: -1});                        break;                    case KEY_CODES.PAGE_DOWN:                        this._scrollByPage(1);                        break;                    case KEY_CODES.PAGE_UP:                        this._scrollByPage(-1);                        break;                    case KEY_CODES.HOME:                        this._scrollToHome();                        break;                    case KEY_CODES.END:                        this._scrollToEnd();                        break;                    default:                        handled = false;                        break                }                if (handled) {                    e.stopPropagation();                    e.preventDefault()                }            },            _scrollByLine: function(lines) {                this.scrollBy({                    top: (lines.y || 0) * -SCROLL_LINE_HEIGHT,                    left: (lines.x || 0) * -SCROLL_LINE_HEIGHT                })            },            _scrollByPage: function(page) {                var prop = this._wheelProp(),                    dimension = this._dimensionByProp(prop);                var distance = {};                distance[prop] = page * -this._$container[dimension]();                this.scrollBy(distance)            },            _dimensionByProp: function(prop) {                return prop === "left" ? "width" : "height"            },            _scrollToHome: function() {                var prop = this._wheelProp();                var distance = {};                distance[prop] = 0;                this._component.scrollTo(distance)            },            _scrollToEnd: function() {                var prop = this._wheelProp(),                    dimension = this._dimensionByProp(prop);                var distance = {};                distance[prop] = this._$content[dimension]() - this._$container[dimension]();                this._component.scrollTo(distance)            },            createActions: function() {                this._startAction = this._createActionHandler("onStart");                this._stopAction = this._createActionHandler("onStop");                this._endAction = this._createActionHandler("onEnd");                this._updateAction = this._createActionHandler("onUpdated");                this._createScrollerActions()            },            _createScrollerActions: function() {                this._eventHandler("createActions", {                    scroll: this._createActionHandler("onScroll"),                    bounce: this._createActionHandler("onBounce")                })            },            _createActionHandler: function(optionName) {                var that = this,                    actionHandler = that._createActionByOption(optionName);                return function() {                        actionHandler($.extend(that._createActionArgs(), arguments))                    }            },            _createActionArgs: function() {                var scrollerX = this._scrollers[HORIZONTAL],                    scrollerY = this._scrollers[VERTICAL];                return {                        jQueryEvent: this._eventForUserAction,                        scrollOffset: {                            top: scrollerY && -scrollerY._location,                            left: scrollerX && -scrollerX._location                        },                        reachedLeft: scrollerX && scrollerX._reachedMax(),                        reachedRight: scrollerX && scrollerX._reachedMin(),                        reachedTop: scrollerY && scrollerY._reachedMax(),                        reachedBottom: scrollerY && scrollerY._reachedMin()                    }            },            _eventHandler: function(eventName) {                var args = $.makeArray(arguments).slice(1),                    deferreds = $.map(this._scrollers, function(scroller) {                        return scroller["_" + eventName + "Handler"].apply(scroller, args)                    });                return $.when.apply($, deferreds).promise()            },            location: function() {                return translator.locate(this._$content)            },            disabledChanged: function() {                this._attachCursorHandlers()            },            _attachCursorHandlers: function() {                this._$element.off("." + SCROLLABLE_SIMULATED_CURSOR);                if (!this.option("disabled") && this._isHoverMode())                    this._$element.on(events.addNamespace("mouseenter", SCROLLABLE_SIMULATED_CURSOR), $.proxy(this._cursorEnterHandler, this)).on(events.addNamespace("mouseleave", SCROLLABLE_SIMULATED_CURSOR), $.proxy(this._cursorLeaveHandler, this))            },            _isHoverMode: function() {                return this.option("showScrollbar") === "onHover"            },            _cursorEnterHandler: function(e) {                e = e || {};                e.originalEvent = e.originalEvent || {};                if (activeScrollable || e.originalEvent._hoverHandled)                    return;                if (hoveredScrollable)                    hoveredScrollable._cursorLeaveHandler();                hoveredScrollable = this;                this._eventHandler("cursorEnter");                e.originalEvent._hoverHandled = true            },            _cursorLeaveHandler: function(e) {                if (hoveredScrollable !== this || activeScrollable === hoveredScrollable)                    return;                this._eventHandler("cursorLeave");                hoveredScrollable = null;                this._refreshCursorState(e && e.relatedTarget)            },            _refreshCursorState: function(target) {                if (!this._isHoverMode() && (!target || activeScrollable))                    return;                var $target = $(target);                var $scrollable = $target.closest("." + SCROLLABLE_SIMULATED_CLASS + ":not(.dx-state-disabled)");                var targetScrollable = $scrollable.length && $scrollable.data(SCROLLABLE_STRATEGY);                if (hoveredScrollable && hoveredScrollable !== targetScrollable)                    hoveredScrollable._cursorLeaveHandler();                if (targetScrollable)                    targetScrollable._cursorEnterHandler()            },            update: function() {                return this._eventHandler("update").done(this._updateAction)            },            _allowedDirections: function() {                var bounceEnabled = this.option("bounceEnabled");                return {                        vertical: this._isDirection(VERTICAL) && (this._scrollers[VERTICAL]._minOffset < 0 || bounceEnabled),                        horizontal: this._isDirection(HORIZONTAL) && (this._scrollers[HORIZONTAL]._minOffset < 0 || bounceEnabled)                    }            },            scrollBy: function(distance) {                this._prepareDirections(true);                this._eventHandler("start").done(this._startAction);                this._eventHandler("move", {                    x: distance.left,                    y: distance.top                });                this._eventHandler("end", {                    x: 0,                    y: 0                }).done(this._endAction)            },            validate: function(e) {                if (this.option("disabled"))                    return false;                if (this.option("bounceEnabled"))                    return true;                return isWheelEvent(e) ? this._validateWheel(e) : this._validateMove(e)            },            _validateWheel: function(e) {                var scroller = this._scrollers[this._wheelDirection()];                var reachedMin = scroller._reachedMin();                var reachedMax = scroller._reachedMax();                var contentGreaterThanContainer = !reachedMin || !reachedMax;                var locatedNotAtBound = !reachedMin && !reachedMax;                var scrollFromMin = reachedMin && e.delta > 0;                var scrollFromMax = reachedMax && e.delta < 0;                return contentGreaterThanContainer && (locatedNotAtBound || scrollFromMin || scrollFromMax)            },            _validateMove: function(e) {                if (!this.option("scrollByContent") && !$(e.target).closest("." + SCROLLABLE_SCROLLBAR_CLASS).length)                    return false;                return this._allowedDirection()            },            getDirection: function(e) {                return isWheelEvent(e) ? this._wheelDirection() : this._allowedDirection()            },            _wheelProp: function() {                return this._wheelDirection() === HORIZONTAL ? "left" : "top"            },            _wheelDirection: function() {                switch (this.option("direction")) {                    case HORIZONTAL:                        return HORIZONTAL;                    case VERTICAL:                        return VERTICAL;                    default:                        return this._scrollers[VERTICAL]._containerToContentRatio() >= 1 ? HORIZONTAL : VERTICAL                }            },            dispose: function() {                scrollIntoViewIfNeededCallbacks.remove(this._proxiedActiveElementChangeHandler);                if (activeScrollable === this)                    activeScrollable = null;                if (hoveredScrollable === this)                    hoveredScrollable = null;                this._eventHandler("dispose");                this._detachEventHandlers();                this._$element.removeClass(SCROLLABLE_SIMULATED_CLASS);                this._eventForUserAction = null;                clearTimeout(this._gestureEndTimer)            },            _detachEventHandlers: function() {                this._$element.off("." + SCROLLABLE_SIMULATED_CURSOR);                this._$container.off("." + SCROLLABLE_SIMULATED_KEYBOARD)            }        });        ui.dxScrollable.__internals = $.extend(ui.dxScrollable.__internals || {}, {            ACCELERATION: ACCELERATION,            MIN_VELOCITY_LIMIT: MIN_VELOCITY_LIMIT,            FRAME_DURATION: FRAME_DURATION,            SCROLL_LINE_HEIGHT: SCROLL_LINE_HEIGHT,            scrollIntoViewIfNeededCallbacks: scrollIntoViewIfNeededCallbacks        })    })(jQuery, DevExpress);    /*! Module widgets-base, file ui.scrollView.js */    (function($, DX, undefined) {        var ui = DX.ui;        var SCROLLVIEW_CLASS = "dx-scrollview",            SCROLLVIEW_CONTENT_CLASS = SCROLLVIEW_CLASS + "-content",            SCROLLVIEW_TOP_POCKET_CLASS = SCROLLVIEW_CLASS + "-top-pocket",            SCROLLVIEW_BOTTOM_POCKET_CLASS = SCROLLVIEW_CLASS + "-bottom-pocket",            SCROLLVIEW_PULLDOWN_CLASS = SCROLLVIEW_CLASS + "-pull-down",            SCROLLVIEW_REACHBOTTOM_CLASS = SCROLLVIEW_CLASS + "-scrollbottom",            SCROLLVIEW_REACHBOTTOM_INDICATOR_CLASS = SCROLLVIEW_REACHBOTTOM_CLASS + "-indicator",            SCROLLVIEW_REACHBOTTOM_TEXT_CLASS = SCROLLVIEW_REACHBOTTOM_CLASS + "-text",            SCROLLVIEW_LOADPANEL = SCROLLVIEW_CLASS + "-loadpanel";        DX.registerComponent("dxScrollView", ui, ui.dxScrollable.inherit({            _setDeprecatedOptions: function() {                this.callBase();                $.extend(this._deprecatedOptions, {                    pullDownAction: {                        since: "14.2",                        alias: "onPullDown"                    },                    reachBottomAction: {                        since: "14.2",                        alias: "onReachBottom"                    }                })            },            _setDefaultOptions: function() {                this.callBase();                this.option({                    pullingDownText: Globalize.localize("dxScrollView-pullingDownText"),                    pulledDownText: Globalize.localize("dxScrollView-pulledDownText"),                    refreshingText: Globalize.localize("dxScrollView-refreshingText"),                    reachBottomText: Globalize.localize("dxScrollView-reachBottomText"),                    onPullDown: null,                    onReachBottom: null,                    refreshStrategy: "pullDown"                })            },            _defaultOptionsRules: function() {                return this.callBase().concat([{                            device: function(device) {                                var realDevice = DevExpress.devices.real();                                return realDevice.platform === "android"                            },                            options: {refreshStrategy: "swipeDown"}                        }, {                            device: function(device) {                                return DevExpress.devices.real().platform === "win8"                            },                            options: {refreshStrategy: "slideDown"}                        }])            },            _init: function() {                this.callBase();                this._loadingIndicatorEnabled = true            },            _initMarkup: function() {                this.callBase();                this.element().addClass(SCROLLVIEW_CLASS);                this._initContent();                this._initTopPocket();                this._initBottomPocket();                this._initLoadPanel()            },            _initContent: function() {                var $content = $("<div>").addClass(SCROLLVIEW_CONTENT_CLASS);                this._$content.wrapInner($content)            },            _initTopPocket: function() {                var $topPocket = this._$topPocket = $("<div>").addClass(SCROLLVIEW_TOP_POCKET_CLASS),                    $pullDown = this._$pullDown = $("<div>").addClass(SCROLLVIEW_PULLDOWN_CLASS);                $topPocket.append($pullDown);                this._$content.prepend($topPocket)            },            _initBottomPocket: function() {                var $bottomPocket = this._$bottomPocket = $("<div>").addClass(SCROLLVIEW_BOTTOM_POCKET_CLASS),                    $reachBottom = this._$reachBottom = $("<div>").addClass(SCROLLVIEW_REACHBOTTOM_CLASS),                    $loadContainer = $("<div>").addClass(SCROLLVIEW_REACHBOTTOM_INDICATOR_CLASS),                    $loadIndicator = $("<div>").dxLoadIndicator(),                    $text = this._$reachBottomText = $("<div>").addClass(SCROLLVIEW_REACHBOTTOM_TEXT_CLASS);                this._updateReachBottomText();                $reachBottom.append($loadContainer.append($loadIndicator)).append($text);                $bottomPocket.append($reachBottom);                this._$content.append($bottomPocket)            },            _initLoadPanel: function() {                this._loadPanel = this._createComponent($("<div>").addClass(SCROLLVIEW_LOADPANEL).appendTo(this.element()), "dxLoadPanel", {                    shading: false,                    delay: 400,                    message: this.option("refreshingText"),                    position: {of: this.element()}                })            },            _updateReachBottomText: function() {                this._$reachBottomText.text(this.option("reachBottomText"))            },            _createStrategy: function() {                var strategyName = this.option("useNative") ? this.option("refreshStrategy") : "simulated";                var strategyClass = ui.dxScrollView.refreshStrategies[strategyName];                if (!strategyClass)                    throw Error("E1030", this.option("refreshStrategy"));                this._strategy = new strategyClass(this);                this._strategy.pullDownCallbacks.add($.proxy(this._pullDownHandler, this));                this._strategy.releaseCallbacks.add($.proxy(this._releaseHandler, this));                this._strategy.reachBottomCallbacks.add($.proxy(this._reachBottomHandler, this))            },            _createActions: function() {                this.callBase();                this._pullDownAction = this._createActionByOption("onPullDown");                this._reachBottomAction = this._createActionByOption("onReachBottom");                this._pullDownEnable(!!this.option("onPullDown") && !DX.designMode);                this._reachBottomEnable(!!this.option("onReachBottom") && !DX.designMode)            },            _pullDownEnable: function(enabled) {                if (arguments.length === 0)                    return this._pullDownEnabled;                this._$pullDown.toggle(enabled);                this._strategy.pullDownEnable(enabled);                this._pullDownEnabled = enabled            },            _reachBottomEnable: function(enabled) {                if (arguments.length === 0)                    return this._reachBottomEnabled;                this._$reachBottom.toggle(enabled);                this._strategy.reachBottomEnable(enabled);                this._reachBottomEnabled = enabled            },            _pullDownHandler: function() {                this._loadingIndicator(false);                this._pullDownLoading()            },            _loadingIndicator: function(value) {                if (arguments.length < 1)                    return this._loadingIndicatorEnabled;                this._loadingIndicatorEnabled = value            },            _pullDownLoading: function() {                this.startLoading();                this._pullDownAction()            },            _reachBottomHandler: function() {                this._loadingIndicator(false);                this._reachBottomLoading()            },            _reachBottomLoading: function() {                this.startLoading();                this._reachBottomAction()            },            _releaseHandler: function() {                this.finishLoading();                this._loadingIndicator(true)            },            _optionChanged: function(args) {                switch (args.name) {                    case"onPullDown":                    case"onReachBottom":                        this._createActions();                        break;                    case"pullingDownText":                    case"pulledDownText":                    case"refreshingText":                    case"refreshStrategy":                        this._invalidate();                        break;                    case"reachBottomText":                        this._updateReachBottomText();                        break;                    default:                        this.callBase(args)                }            },            isEmpty: function() {                return !this.content().children().length            },            content: function() {                return this._$content.children().eq(1)            },            release: function(preventReachBottom) {                if (preventReachBottom !== undefined)                    this.toggleLoading(!preventReachBottom);                return this._strategy.release()            },            toggleLoading: function(showOrHide) {                this._reachBottomEnable(showOrHide)            },            isFull: function() {                return this.content().height() >= this._$container.height()            },            refresh: function() {                if (!this.option("onPullDown"))                    return;                this._strategy.pendingRelease();                this._pullDownLoading()            },            startLoading: function() {                if (this._loadingIndicator() && this.element().is(":visible"))                    this._loadPanel.show();                this._lock()            },            finishLoading: function() {                this._loadPanel.hide();                this._unlock()            },            _dispose: function() {                this._strategy.dispose();                this.callBase();                if (this._loadPanel)                    this._loadPanel.element().remove()            }        }));        ui.dxScrollView.refreshStrategies = {}    })(jQuery, DevExpress);    /*! Module widgets-base, file ui.scrollView.native.pullDown.js */    (function($, DX, undefined) {        var ui = DX.ui;        var SCROLLVIEW_PULLDOWN_REFRESHING_CLASS = "dx-scrollview-pull-down-loading",            SCROLLVIEW_PULLDOWN_READY_CLASS = "dx-scrollview-pull-down-ready",            SCROLLVIEW_PULLDOWN_IMAGE_CLASS = "dx-scrollview-pull-down-image",            SCROLLVIEW_PULLDOWN_INDICATOR_CLASS = "dx-scrollview-pull-down-indicator",            SCROLLVIEW_PULLDOWN_TEXT_CLASS = "dx-scrollview-pull-down-text",            STATE_RELEASED = 0,            STATE_READY = 1,            STATE_REFRESHING = 2,            STATE_LOADING = 3;        var PullDownNativeScrollViewStrategy = ui.dxScrollable.NativeStrategy.inherit({                _init: function(scrollView) {                    this.callBase(scrollView);                    this._$topPocket = scrollView._$topPocket;                    this._$pullDown = scrollView._$pullDown;                    this._$bottomPocket = scrollView._$bottomPocket;                    this._$refreshingText = scrollView._$refreshingText;                    this._$scrollViewContent = scrollView.content();                    this._initCallbacks()                },                _initCallbacks: function() {                    this.pullDownCallbacks = $.Callbacks();                    this.releaseCallbacks = $.Callbacks();                    this.reachBottomCallbacks = $.Callbacks()                },                render: function() {                    this.callBase();                    this._renderPullDown();                    this._releaseState()                },                _renderPullDown: function() {                    var $image = $("<div>").addClass(SCROLLVIEW_PULLDOWN_IMAGE_CLASS),                        $loadContainer = $("<div>").addClass(SCROLLVIEW_PULLDOWN_INDICATOR_CLASS),                        $loadIndicator = $("<div>").dxLoadIndicator(),                        $text = this._$pullDownText = $("<div>").addClass(SCROLLVIEW_PULLDOWN_TEXT_CLASS);                    this._$pullingDownText = $("<div>").text(this.option("pullingDownText")).appendTo($text);                    this._$pulledDownText = $("<div>").text(this.option("pulledDownText")).appendTo($text);                    this._$refreshingText = $("<div>").text(this.option("refreshingText")).appendTo($text);                    this._$pullDown.empty().append($image).append($loadContainer.append($loadIndicator)).append($text)                },                _releaseState: function() {                    this._state = STATE_RELEASED;                    this._refreshPullDownText()                },                _pushBackFromBoundary: function() {                    if (!this._isLocked() && !this._component.isEmpty())                        this.callBase()                },                _refreshPullDownText: function() {                    this._$pullingDownText.css("opacity", this._state === STATE_RELEASED ? 1 : 0);                    this._$pulledDownText.css("opacity", this._state === STATE_READY ? 1 : 0);                    this._$refreshingText.css("opacity", this._state === STATE_REFRESHING ? 1 : 0)                },                update: function() {                    this.callBase();                    this._setTopPocketOffset()                },                _updateDimensions: function() {                    this.callBase();                    this._topPocketSize = this._$topPocket.height();                    this._bottomPocketSize = this._$bottomPocket.height();                    this._scrollOffset = this._$container.height() - this._$content.height()                },                _allowedDirections: function() {                    var allowedDirections = this.callBase();                    allowedDirections.vertical = allowedDirections.vertical || this._pullDownEnabled;                    return allowedDirections                },                _setTopPocketOffset: function() {                    this._$topPocket.css({top: -this._topPocketSize})                },                handleEnd: function() {                    this._complete()                },                handleStop: function() {                    this._complete()                },                _complete: function() {                    if (this._state === STATE_READY) {                        this._setPullDownOffset(this._topPocketSize);                        clearTimeout(this._pullDownRefreshTimeout);                        this._pullDownRefreshTimeout = setTimeout($.proxy(function() {                            this._pullDownRefreshing()                        }, this), 400)                    }                },                _setPullDownOffset: function(offset) {                    DX.translator.move(this._$topPocket, {top: offset});                    DX.translator.move(this._$scrollViewContent, {top: offset})                },                handleScroll: function(e) {                    this.callBase(e);                    if (this._state === STATE_REFRESHING)                        return;                    this._location = this.location().top;                    if (this._isPullDown())                        this._pullDownReady();                    else if (this._isReachBottom())                        this._reachBottom();                    else                        this._stateReleased()                },                _isPullDown: function() {                    return this._pullDownEnabled && this._location >= this._topPocketSize                },                _isReachBottom: function() {                    return this._reachBottomEnabled && this._location <= this._scrollOffset + this._bottomPocketSize                },                _reachBottom: function() {                    if (this._state === STATE_LOADING)                        return;                    this._state = STATE_LOADING;                    this.reachBottomCallbacks.fire()                },                _pullDownReady: function() {                    if (this._state === STATE_READY)                        return;                    this._state = STATE_READY;                    this._$pullDown.addClass(SCROLLVIEW_PULLDOWN_READY_CLASS);                    this._refreshPullDownText()                },                _stateReleased: function() {                    if (this._state === STATE_RELEASED)                        return;                    this._$pullDown.removeClass(SCROLLVIEW_PULLDOWN_REFRESHING_CLASS).removeClass(SCROLLVIEW_PULLDOWN_READY_CLASS);                    this._releaseState()                },                _pullDownRefreshing: function() {                    if (this._state === STATE_REFRESHING)                        return;                    this._state = STATE_REFRESHING;                    this._$pullDown.addClass(SCROLLVIEW_PULLDOWN_REFRESHING_CLASS).removeClass(SCROLLVIEW_PULLDOWN_READY_CLASS);                    this._refreshPullDownText();                    this.pullDownCallbacks.fire()                },                pullDownEnable: function(enabled) {                    this._pullDownEnabled = enabled                },                reachBottomEnable: function(enabled) {                    this._reachBottomEnabled = enabled                },                pendingRelease: function() {                    this._state = STATE_READY                },                release: function() {                    var deferred = $.Deferred();                    this._updateDimensions();                    clearTimeout(this._releaseTimeout);                    this._releaseTimeout = setTimeout($.proxy(function() {                        this._setPullDownOffset(0);                        this._stateReleased();                        this.releaseCallbacks.fire();                        this._updateAction();                        deferred.resolve()                    }, this), 400);                    return deferred.promise()                },                dispose: function() {                    clearTimeout(this._pullDownRefreshTimeout);                    clearTimeout(this._releaseTimeout);                    this.callBase()                }            });        ui.dxScrollView.refreshStrategies.pullDown = PullDownNativeScrollViewStrategy    })(jQuery, DevExpress);    /*! Module widgets-base, file ui.scrollView.native.swipeDown.js */    (function($, DX, undefined) {        var ui = DX.ui,            events = ui.events;        var SCROLLVIEW_PULLDOWN_DOWN_LOADING_CLASS = "dx-scrollview-pull-down-loading",            SCROLLVIEW_PULLDOWN_INDICATOR_CLASS = "dx-scrollview-pull-down-indicator",            SCROLLVIEW_PULLDOWN_REFRESHING_CLASS = "dx-scrollview-pull-down-refreshing",            PULLDOWN_ICON_CLASS = "dx-icon-pulldown",            STATE_RELEASED = 0,            STATE_READY = 1,            STATE_REFRESHING = 2,            STATE_TOUCHED = 4,            STATE_PULLED = 5;        var SwipeDownNativeScrollViewStrategy = ui.dxScrollable.NativeStrategy.inherit({                _init: function(scrollView) {                    this.callBase(scrollView);                    this._$topPocket = scrollView._$topPocket;                    this._$bottomPocket = scrollView._$bottomPocket;                    this._$pullDown = scrollView._$pullDown;                    this._$scrollViewContent = scrollView.content();                    this._initCallbacks();                    this._location = 0                },                _initCallbacks: function() {                    this.pullDownCallbacks = $.Callbacks();                    this.releaseCallbacks = $.Callbacks();                    this.reachBottomCallbacks = $.Callbacks()                },                render: function() {                    this.callBase();                    this._renderPullDown();                    this._releaseState()                },                _renderPullDown: function() {                    var $loadContainer = $("<div>").addClass(SCROLLVIEW_PULLDOWN_INDICATOR_CLASS),                        $loadIndicator = $("<div>").dxLoadIndicator({});                    this._$icon = $("<div>").addClass(PULLDOWN_ICON_CLASS);                    this._$pullDown.empty().append(this._$icon).append($loadContainer.append($loadIndicator))                },                _releaseState: function() {                    this._state = STATE_RELEASED;                    this._releasePullDown();                    this._updateDimensions()                },                _releasePullDown: function() {                    this._$pullDown.css({opacity: 0})                },                _updateDimensions: function() {                    this.callBase();                    this._topPocketSize = this._$topPocket.height();                    this._bottomPocketSize = this._$bottomPocket.height();                    this._scrollOffset = this._$container.height() - this._$content.height()                },                _allowedDirections: function() {                    var allowedDirections = this.callBase();                    allowedDirections.vertical = allowedDirections.vertical || this._pullDownEnabled;                    return allowedDirections                },                handleInit: function(e) {                    this.callBase(e);                    if (this._state === STATE_RELEASED && this._location === 0) {                        this._startClientY = events.eventData(e.originalEvent).y;                        this._state = STATE_TOUCHED                    }                },                handleMove: function(e) {                    this.callBase(e);                    this._deltaY = events.eventData(e.originalEvent).y - this._startClientY;                    if (this._state === STATE_TOUCHED)                        if (this._pullDownEnabled && this._deltaY > 0)                            this._state = STATE_PULLED;                        else                            this._complete();                    if (this._state === STATE_PULLED) {                        e.preventDefault();                        this._movePullDown()                    }                },                _movePullDown: function() {                    var pullDownHeight = this._getPullDownHeight(),                        top = Math.min(pullDownHeight * 3, this._deltaY + this._getPullDownStartPosition()),                        angle = 180 * top / pullDownHeight / 3;                    this._$pullDown.css({opacity: 1}).toggleClass(SCROLLVIEW_PULLDOWN_REFRESHING_CLASS, top < pullDownHeight);                    DX.translator.move(this._$pullDown, {top: top});                    this._$icon.css({transform: "rotate(" + angle + "deg)"})                },                _isPullDown: function() {                    return this._pullDownEnabled && this._deltaY >= this._getPullDownHeight() - this._getPullDownStartPosition()                },                _getPullDownHeight: function() {                    return Math.round(this._$element.outerHeight() * 0.05)                },                _getPullDownStartPosition: function() {                    return -Math.round(this._$pullDown.outerHeight() * 1.5)                },                handleEnd: function() {                    if (this._isPullDown())                        this._pullDownRefreshing();                    this._complete()                },                handleStop: function() {                    this._complete()                },                _complete: function() {                    if (this._state === STATE_TOUCHED || this._state === STATE_PULLED)                        this._releaseState()                },                handleScroll: function(e) {                    this.callBase(e);                    if (this._state === STATE_REFRESHING)                        return;                    var currentLocation = this.location().top,                        scrollDelta = this._location - currentLocation;                    this._location = currentLocation;                    if (scrollDelta > 0 && this._isReachBottom())                        this._reachBottom();                    else                        this._stateReleased()                },                _isReachBottom: function() {                    return this._reachBottomEnabled && this._location <= this._scrollOffset + this._bottomPocketSize                },                _reachBottom: function() {                    this.reachBottomCallbacks.fire()                },                _stateReleased: function() {                    if (this._state === STATE_RELEASED)                        return;                    this._$pullDown.removeClass(SCROLLVIEW_PULLDOWN_DOWN_LOADING_CLASS);                    this._releaseState()                },                _pullDownRefreshing: function() {                    this._state = STATE_REFRESHING;                    this._pullDownRefreshHandler()                },                _pullDownRefreshHandler: function() {                    this._refreshPullDown();                    this.pullDownCallbacks.fire()                },                _refreshPullDown: function() {                    this._$pullDown.addClass(SCROLLVIEW_PULLDOWN_DOWN_LOADING_CLASS);                    DX.translator.move(this._$pullDown, {top: this._getPullDownHeight()})                },                pullDownEnable: function(enabled) {                    this._$topPocket.toggle(enabled);                    this._pullDownEnabled = enabled                },                reachBottomEnable: function(enabled) {                    this._reachBottomEnabled = enabled                },                pendingRelease: function() {                    this._state = STATE_READY                },                release: function() {                    var deferred = $.Deferred();                    this._updateDimensions();                    clearTimeout(this._releaseTimeout);                    this._releaseTimeout = setTimeout($.proxy(function() {                        this._stateReleased();                        this.releaseCallbacks.fire();                        this._updateAction();                        deferred.resolve()                    }, this), 800);                    return deferred.promise()                },                dispose: function() {                    clearTimeout(this._pullDownRefreshTimeout);                    clearTimeout(this._releaseTimeout);                    this.callBase()                }            });        ui.dxScrollView.refreshStrategies.swipeDown = SwipeDownNativeScrollViewStrategy    })(jQuery, DevExpress);    /*! Module widgets-base, file ui.scrollView.native.slideDown.js */    (function($, DX, undefined) {        var ui = DX.ui;        var STATE_RELEASED = 0,            STATE_READY = 1,            STATE_LOADING = 2,            LOADING_HEIGHT = 80;        var SlideDownNativeScrollViewStrategy = ui.dxScrollable.NativeStrategy.inherit({                _init: function(scrollView) {                    this.callBase(scrollView);                    this._$topPocket = scrollView._$topPocket;                    this._$bottomPocket = scrollView._$bottomPocket;                    this._initCallbacks()                },                _initCallbacks: function() {                    this.pullDownCallbacks = $.Callbacks();                    this.releaseCallbacks = $.Callbacks();                    this.reachBottomCallbacks = $.Callbacks()                },                render: function() {                    this.callBase();                    this._renderPullDown();                    this._renderBottom();                    this._releaseState();                    this._updateDimensions()                },                _renderPullDown: function() {                    this._$topPocket.empty()                },                _renderBottom: function() {                    this._$bottomPocket.empty().append("<progress>")                },                _releaseState: function() {                    if (this._state === STATE_RELEASED)                        return;                    this._state = STATE_RELEASED                },                _updateDimensions: function() {                    this._scrollOffset = this._$container.prop("scrollHeight") - this._$container.prop("clientHeight");                    this._containerSize = {                        height: this._$container.prop("clientHeight"),                        width: this._$container.prop("clientWidth")                    };                    this._contentSize = this._componentContentSize = {                        height: this._$container.prop("scrollHeight"),                        width: this._$container.prop("scrollWidth")                    }                },                handleScroll: function(e) {                    this.callBase(e);                    if (this._isReachBottom(this._lastLocation.top))                        this._reachBottom()                },                _isReachBottom: function(location) {                    this._scrollContent = this._$container.prop("scrollHeight") - this._$container.prop("clientHeight");                    return this._reachBottomEnabled && location < -this._scrollContent + LOADING_HEIGHT                },                _reachBottom: function() {                    if (this._state === STATE_LOADING)                        return;                    this._state = STATE_LOADING;                    this.reachBottomCallbacks.fire()                },                pullDownEnable: function(enabled) {                    this._pullDownEnabled = enabled                },                reachBottomEnable: function(enabled) {                    this._reachBottomEnabled = enabled;                    this._$bottomPocket.toggle(enabled)                },                pendingRelease: function() {                    this._state = STATE_READY                },                release: function() {                    var deferred = $.Deferred();                    this._state = STATE_RELEASED;                    this.releaseCallbacks.fire();                    this.update();                    return deferred.resolve().promise()                }            });        ui.dxScrollView.refreshStrategies.slideDown = SlideDownNativeScrollViewStrategy    })(jQuery, DevExpress);    /*! Module widgets-base, file ui.scrollView.simulated.js */    (function($, DX, undefined) {        var ui = DX.ui,            math = Math;        var SCROLLVIEW_PULLDOWN_REFRESHING_CLASS = "dx-scrollview-pull-down-loading",            SCROLLVIEW_PULLDOWN_READY_CLASS = "dx-scrollview-pull-down-ready",            SCROLLVIEW_PULLDOWN_IMAGE_CLASS = "dx-scrollview-pull-down-image",            SCROLLVIEW_PULLDOWN_INDICATOR_CLASS = "dx-scrollview-pull-down-indicator",            SCROLLVIEW_PULLDOWN_TEXT_CLASS = "dx-scrollview-pull-down-text",            STATE_RELEASED = 0,            STATE_READY = 1,            STATE_REFRESHING = 2,            STATE_LOADING = 3;        var ScrollViewScroller = ui.dxScrollView.Scroller = ui.dxScrollable.Scroller.inherit({                ctor: function() {                    this.callBase.apply(this, arguments);                    this._initCallbacks();                    this._releaseState()                },                _releaseState: function() {                    this._state = STATE_RELEASED;                    this._refreshPullDownText()                },                _refreshPullDownText: function() {                    this._$pullingDownText.css("opacity", this._state === STATE_RELEASED ? 1 : 0);                    this._$pulledDownText.css("opacity", this._state === STATE_READY ? 1 : 0);                    this._$refreshingText.css("opacity", this._state === STATE_REFRESHING ? 1 : 0)                },                _initCallbacks: function() {                    this.pullDownCallbacks = $.Callbacks();                    this.releaseCallbacks = $.Callbacks();                    this.reachBottomCallbacks = $.Callbacks()                },                _updateBounds: function() {                    var considerPockets = this._direction !== "horizontal";                    this._topPocketSize = considerPockets ? this._$topPocket[this._dimension]() : 0;                    this._bottomPocketSize = considerPockets ? this._$bottomPocket[this._dimension]() : 0;                    this.callBase();                    this._bottomBound = this._minOffset                },                _updateScrollbar: function() {                    this._scrollbar.option({                        containerSize: this._containerSize(),                        contentSize: this._contentSize() - this._topPocketSize - this._bottomPocketSize                    })                },                _moveContent: function() {                    this.callBase();                    if (this._isPullDown())                        this._pullDownReady();                    else if (this._isReachBottom())                        this._reachBottomReady();                    else if (this._state !== STATE_RELEASED)                        this._stateReleased()                },                _moveScrollbar: function() {                    this._scrollbar.moveTo(this._topPocketSize + this._location)                },                _isPullDown: function() {                    return this._pullDownEnabled && this._location >= 0                },                _isReachBottom: function() {                    return this._reachBottomEnabled && this._location <= this._bottomBound                },                _scrollComplete: function() {                    if (this._inBounds() && this._state === STATE_READY)                        this._pullDownRefreshing();                    else if (this._inBounds() && this._state === STATE_LOADING)                        this._reachBottomLoading();                    else                        this.callBase()                },                _reachBottomReady: function() {                    if (this._state === STATE_LOADING)                        return;                    this._state = STATE_LOADING;                    this._minOffset = this._getMinOffset()                },                _getMaxOffset: function() {                    return -this._topPocketSize                },                _getMinOffset: function() {                    return math.min(this.callBase(), -this._topPocketSize)                },                _reachBottomLoading: function() {                    this.reachBottomCallbacks.fire()                },                _pullDownReady: function() {                    if (this._state === STATE_READY)                        return;                    this._state = STATE_READY;                    this._maxOffset = 0;                    this._$pullDown.addClass(SCROLLVIEW_PULLDOWN_READY_CLASS);                    this._refreshPullDownText()                },                _stateReleased: function() {                    if (this._state === STATE_RELEASED)                        return;                    this._releaseState();                    this._updateBounds();                    this._$pullDown.removeClass(SCROLLVIEW_PULLDOWN_REFRESHING_CLASS).removeClass(SCROLLVIEW_PULLDOWN_READY_CLASS);                    this.releaseCallbacks.fire()                },                _pullDownRefreshing: function() {                    if (this._state === STATE_REFRESHING)                        return;                    this._state = STATE_REFRESHING;                    this._$pullDown.addClass(SCROLLVIEW_PULLDOWN_REFRESHING_CLASS).removeClass(SCROLLVIEW_PULLDOWN_READY_CLASS);                    this._refreshPullDownText();                    this.pullDownCallbacks.fire()                },                _releaseHandler: function() {                    if (this._state === STATE_RELEASED)                        this._moveToBounds();                    this._update();                    if (this._releaseTask)                        this._releaseTask.abort();                    this._releaseTask = DX.utils.executeAsync($.proxy(this._release, this));                    return this._releaseTask.promise                },                _release: function() {                    this._stateReleased();                    this._scrollComplete()                },                _reachBottomEnablingHandler: function(enabled) {                    if (this._reachBottomEnabled === enabled)                        return;                    this._reachBottomEnabled = enabled;                    this._updateBounds()                },                _pullDownEnablingHandler: function(enabled) {                    if (this._pullDownEnabled === enabled)                        return;                    this._pullDownEnabled = enabled;                    this._considerTopPocketChange();                    this._updateHandler()                },                _considerTopPocketChange: function() {                    this._location -= this._$topPocket.height() || -this._topPocketSize;                    this._move()                },                _pendingReleaseHandler: function() {                    this._state = STATE_READY                },                dispose: function() {                    if (this._releaseTask)                        this._releaseTask.abort();                    this.callBase()                }            });        var SimulatedScrollViewStrategy = ui.dxScrollable.SimulatedStrategy.inherit({                _init: function(scrollView) {                    this.callBase(scrollView);                    this._$pullDown = scrollView._$pullDown;                    this._$topPocket = scrollView._$topPocket;                    this._$bottomPocket = scrollView._$bottomPocket;                    this._initCallbacks()                },                _initCallbacks: function() {                    this.pullDownCallbacks = $.Callbacks();                    this.releaseCallbacks = $.Callbacks();                    this.reachBottomCallbacks = $.Callbacks()                },                render: function() {                    this._renderPullDown();                    this.callBase()                },                _renderPullDown: function() {                    var $image = $("<div>").addClass(SCROLLVIEW_PULLDOWN_IMAGE_CLASS),                        $loadContainer = $("<div>").addClass(SCROLLVIEW_PULLDOWN_INDICATOR_CLASS),                        $loadIndicator = $("<div>").dxLoadIndicator(),                        $text = this._$pullDownText = $("<div>").addClass(SCROLLVIEW_PULLDOWN_TEXT_CLASS);                    this._$pullingDownText = $("<div>").text(this.option("pullingDownText")).appendTo($text);                    this._$pulledDownText = $("<div>").text(this.option("pulledDownText")).appendTo($text);                    this._$refreshingText = $("<div>").text(this.option("refreshingText")).appendTo($text);                    this._$pullDown.empty().append($image).append($loadContainer.append($loadIndicator)).append($text)                },                pullDownEnable: function(enabled) {                    this._eventHandler("pullDownEnabling", enabled)                },                reachBottomEnable: function(enabled) {                    this._eventHandler("reachBottomEnabling", enabled)                },                _createScroller: function(direction) {                    var that = this;                    var scroller = that._scrollers[direction] = new ScrollViewScroller(that._scrollerOptions(direction));                    scroller.pullDownCallbacks.add(function() {                        that.pullDownCallbacks.fire()                    });                    scroller.releaseCallbacks.add(function() {                        that.releaseCallbacks.fire()                    });                    scroller.reachBottomCallbacks.add(function() {                        that.reachBottomCallbacks.fire()                    })                },                _scrollerOptions: function(direction) {                    return $.extend(this.callBase(direction), {                            $topPocket: this._$topPocket,                            $bottomPocket: this._$bottomPocket,                            $pullDown: this._$pullDown,                            $pullDownText: this._$pullDownText,                            $pullingDownText: this._$pullingDownText,                            $pulledDownText: this._$pulledDownText,                            $refreshingText: this._$refreshingText                        })                },                pendingRelease: function() {                    this._eventHandler("pendingRelease")                },                release: function() {                    return this._eventHandler("release").done(this._updateAction)                },                location: function() {                    var location = this.callBase();                    location.top += this._$topPocket.height();                    return location                },                dispose: function() {                    $.each(this._scrollers, function() {                        this.dispose()                    });                    this.callBase()                }            });        ui.dxScrollView.refreshStrategies.simulated = SimulatedScrollViewStrategy    })(jQuery, DevExpress);    /*! Module widgets-base, file ui.map.js */    (function($, DX, undefined) {        var ui = DX.ui,            events = ui.events,            utils = DX.utils,            winJS = DX.support.winJS,            wrapToArray = utils.wrapToArray,            removeDublicates = utils.removeDublicates,            titleize = DX.inflector.titleize;        var MAP_CLASS = "dx-map",            MAP_CONTAINER_CLASS = "dx-map-container",            MAP_SHIELD_CLASS = "dx-map-shield";        DX.registerComponent("dxMap", ui, ui.Widget.inherit({            ctor: function() {                this.callBase.apply(this, arguments);                this.addMarker = $.proxy(this._addFunction, this, "markers");                this.removeMarker = $.proxy(this._removeFunction, this, "markers");                this.addRoute = $.proxy(this._addFunction, this, "routes");                this.removeRoute = $.proxy(this._removeFunction, this, "routes")            },            _addFunction: function(optionName, addingValue) {                var deferred = $.Deferred(),                    that = this,                    providerDeffered = $.Deferred(),                    optionValue = this.option(optionName),                    addingValues = wrapToArray(addingValue);                optionValue.push.apply(optionValue, addingValues);                this._notificationDeffered = providerDeffered;                this.option(optionName, optionValue);                providerDeffered.done(function(instance) {                    deferred.resolveWith(that, instance && instance.length > 1 ? [instance] : instance)                });                return deferred.promise()            },            _removeFunction: function(optionName, removingValue) {                var deferred = $.Deferred(),                    that = this,                    providerDeffered = $.Deferred(),                    optionValue = this.option(optionName),                    removingValues = wrapToArray(removingValue);                $.each(removingValues, function(_, removingValue) {                    var index = $.isNumeric(removingValue) ? removingValue : $.inArray(removingValue, optionValue);                    if (index !== -1)                        optionValue.splice(index, 1);                    else                        throw DX.log("E1021", titleize(optionName.substring(0, optionName.length - 1)), removingValue);                });                this._notificationDeffered = providerDeffered;                this.option(optionName, optionValue);                providerDeffered.done(function() {                    deferred.resolveWith(that)                });                return deferred.promise()            },            _setDeprecatedOptions: function() {                this.callBase();                $.extend(this._deprecatedOptions, {                    markerAddedAction: {                        since: "14.2",                        alias: "onMarkerAdded"                    },                    markerRemovedAction: {                        since: "14.2",                        alias: "onMarkerRemoved"                    },                    readyAction: {                        since: "14.2",                        alias: "onReady"                    },                    routeAddedAction: {                        since: "14.2",                        alias: "onRouteAdded"                    },                    routeRemovedAction: {                        since: "14.2",                        alias: "onRouteRemoved"                    },                    clickAction: {                        since: "14.2",                        alias: "onClick"                    }                })            },            _setDefaultOptions: function() {                this.callBase();                this.option({                    bounds: {                        northEast: null,                        southWest: null                    },                    center: {                        lat: 0,                        lng: 0                    },                    zoom: 1,                    width: 300,                    height: 300,                    type: "roadmap",                    provider: "google",                    autoAdjust: true,                    markers: [],                    markerIconSrc: null,                    onMarkerAdded: null,                    onMarkerRemoved: null,                    routes: [],                    onRouteAdded: null,                    onRouteRemoved: null,                    key: {                        bing: "",                        google: "",                        googleStatic: ""                    },                    controls: false,                    onReady: null,                    onUpdated: null,                    onClick: null                })            },            _defaultOptionsRules: function() {                return this.callBase().concat([{                            device: function(device) {                                return DX.devices.real().generic && !DX.devices.isSimulator()                            },                            options: {focusStateEnabled: true}                        }])            },            _init: function() {                this.callBase();                this._asyncQueue = [];                this._checkProvider();                this._checkMarkersOption(this.option("markers"));                this._checkRoutesOption(this.option("routes"));                this._initContainer();                this._grabEvents();                this._cleanRenderedMarkers();                this._cleanRenderedRoutes()            },            _checkProvider: function() {                if (winJS && this.option("provider") === "google")                    throw DX.Error("E1024");            },            _checkMarkersOption: function(markers) {                if (!$.isArray(markers))                    throw DX.Error("E1022");            },            _checkRoutesOption: function(routes) {                if (!$.isArray(routes))                    throw DX.Error("E1023");            },            _initContainer: function() {                this._$container = $("<div />").addClass(MAP_CONTAINER_CLASS);                this.element().append(this._$container)            },            _grabEvents: function() {                var eventName = events.addNamespace("dxpointerdown", this.NAME);                this.element().on(eventName, $.proxy(this._cancelEvent, this))            },            _cancelEvent: function(e) {                var cancelByProvider = this._provider.cancelEvents && !this.option("disabled");                if (!DX.designMode && cancelByProvider)                    e.stopPropagation()            },            _cleanRenderedMarkers: function() {                this._renderedMarkers = []            },            _cleanRenderedRoutes: function(routes) {                this._renderedRoutes = []            },            _render: function() {                this.callBase();                this.element().addClass(MAP_CLASS);                this._renderShield();                this._queueAsyncAction("render", this.option("markers"), this.option("routes"));                this._saveRenderedMarkers();                this._saveRenderedRoutes()            },            _saveRenderedMarkers: function(markers) {                markers = markers || this.option("markers");                this._renderedMarkers = markers.slice()            },            _saveRenderedRoutes: function(routes) {                routes = routes || this.option("routes");                this._renderedRoutes = routes.slice()            },            _renderShield: function() {                var $shield;                if (DX.designMode || this.option("disabled")) {                    $shield = $("<div/>").addClass(MAP_SHIELD_CLASS);                    this.element().append($shield)                }                else {                    $shield = this.element().find("." + MAP_SHIELD_CLASS);                    $shield.remove()                }            },            _clean: function() {                this._cleanFocusState();                if (!this._provider)                    return;                this._queueAsyncAction("clean");                this._cleanRenderedMarkers();                this._cleanRenderedRoutes()            },            _optionChanged: function(args) {                var value = args.value;                if (this._cancelOptionChange)                    return;                var notificationDeffered = this._notificationDeffered;                delete this._notificationDeffered;                switch (args.name) {                    case"disabled":                        this._renderShield();                        this.callBase(args);                        break;                    case"width":                    case"height":                        this.callBase(args);                        this._dimensionChanged();                        break;                    case"provider":                        this._invalidate();                        break;                    case"key":                        DX.log("W1001");                        break;                    case"bounds":                        this._queueAsyncAction("updateBounds");                        break;                    case"center":                        this._queueAsyncAction("updateCenter");                        break;                    case"zoom":                        this._queueAsyncAction("updateZoom");                        break;                    case"type":                        this._queueAsyncAction("updateMapType");                        break;                    case"controls":                        this._queueAsyncAction("updateControls", this.option("markers"), this.option("routes"));                        break;                    case"autoAdjust":                        this._queueAsyncAction("adjustViewport");                        break;                    case"markers":                        this._checkMarkersOption(value);                        this._queueAsyncAction("updateMarkers", notificationDeffered ? removeDublicates(this._renderedMarkers, value) : this._renderedMarkers, notificationDeffered ? removeDublicates(value, this._renderedMarkers) : value).done($.proxy(function() {                            if (notificationDeffered)                                notificationDeffered.resolve.apply(notificationDeffered, arguments)                        }, this));                        this._saveRenderedMarkers(value);                        break;                    case"markerIconSrc":                        this._queueAsyncAction("updateMarkers", this._renderedMarkers, this._renderedMarkers);                        break;                    case"routes":                        this._checkRoutesOption(value);                        this._queueAsyncAction("updateRoutes", notificationDeffered ? removeDublicates(this._renderedRoutes, value) : this._renderedRoutes, notificationDeffered ? removeDublicates(value, this._renderedRoutes) : value).done($.proxy(function() {                            if (notificationDeffered)                                notificationDeffered.resolve.apply(notificationDeffered, arguments)                        }, this));                        this._saveRenderedRoutes(value);                        break;                    case"onReady":                    case"onUpdated":                    case"onMarkerAdded":                    case"onMarkerRemoved":                    case"onRouteAdded":                    case"onRouteRemoved":                    case"onClick":                        break;                    default:                        this.callBase.apply(this, arguments)                }            },            _visibilityChanged: function(visible) {                if (visible)                    this._dimensionChanged()            },            _dimensionChanged: function() {                this._queueAsyncAction("updateDimensions")            },            _queueAsyncAction: function(name) {                var deferred = $.Deferred(),                    emptyQueue = !this._asyncQueue.length;                this._asyncQueue.push({                    name: name,                    options: $.makeArray(arguments).slice(1),                    deferred: deferred                });                if (emptyQueue)                    this._enqueueAsyncAction();                return deferred.promise()            },            _enqueueAsyncAction: function() {                var emptyQueue = !this._asyncQueue.length;                if (emptyQueue)                    return;                this._execAsyncAction(this._asyncQueue[0]).done($.proxy(function() {                    this._asyncQueue.shift();                    this._enqueueAsyncAction()                }, this))            },            _execAsyncAction: function(action) {                var deferred = $.Deferred(),                    actionName = action.name,                    actionOptions = action.options,                    actionDeferred = action.deferred,                    provider = this._getProvider(actionName);                provider[actionName].apply(provider, actionOptions).done($.proxy(function(mapRefreshed) {                    actionDeferred.resolve.apply(actionDeferred, $.makeArray(arguments).slice(1));                    if (mapRefreshed)                        this._triggerReadyAction();                    else if (actionName !== "clean")                        this._triggerUpdateAction();                    deferred.resolve()                }, this));                return deferred.promise()            },            _getProvider: function(actionName) {                var currentProvider = this.option("provider");                if (actionName !== "clean" && this._usedProvider !== currentProvider) {                    this._provider = new providers[currentProvider](this, this._$container);                    this._usedProvider = currentProvider                }                return this._provider            },            _triggerReadyAction: function() {                this._createActionByOption("onReady")({originalMap: this._provider.map()})            },            _triggerUpdateAction: function() {                this._createActionByOption("onUpdated")()            },            setOptionSilent: function(name, value) {                this._cancelOptionChange = true;                this.option(name, value);                this._cancelOptionChange = false            }        }));        var providers = {};        ui.dxMap.registerProvider = function(name, provider) {            providers[name] = provider        }    })(jQuery, DevExpress);    /*! Module widgets-base, file ui.map.provider.js */    (function($, DX, undefined) {        var ui = DX.ui,            events = ui.events;        ui.dxMap.Provider = DX.Class.inherit({            _defaultRouteWeight: function() {                return 5            },            _defaultRouteOpacity: function() {                return 0.5            },            _defaultRouteColor: function() {                return "#0000FF"            },            cancelEvents: false,            ctor: function(map, $container) {                this._mapWidget = map;                this._$container = $container            },            render: function(markerOptions, routeOptions) {                var deferred = $.Deferred();                this._renderImpl().done($.proxy(function() {                    var markersPromise = this.addMarkers(markerOptions);                    var routesPromise = this.addRoutes(routeOptions);                    $.when(markersPromise, routesPromise).done(function() {                        deferred.resolve(true)                    })                }, this));                return deferred.promise()            },            _renderImpl: DX.abstract,            updateDimensions: DX.abstract,            updateMapType: DX.abstract,            updateBounds: DX.abstract,            updateCenter: DX.abstract,            updateZoom: DX.abstract,            updateControls: DX.abstract,            updateMarkers: function(markerOptionsToRemove, markerOptionsToAdd) {                var deferred = $.Deferred(),                    that = this;                this.removeMarkers(markerOptionsToRemove).done(function() {                    that.addMarkers(markerOptionsToAdd).done(function() {                        deferred.resolve.apply(deferred, arguments)                    })                });                return deferred.promise()            },            addMarkers: DX.abstract,            removeMarkers: DX.abstract,            adjustViewport: DX.abstract,            updateRoutes: function(routeOptionsToRemove, routeOptionsToAdd) {                var deferred = $.Deferred(),                    that = this;                this.removeRoutes(routeOptionsToRemove).done(function() {                    that.addRoutes(routeOptionsToAdd).done(function() {                        deferred.resolve.apply(deferred, arguments)                    })                });                return deferred.promise()            },            addRoutes: DX.abstract,            removeRoutes: DX.abstract,            clean: DX.abstract,            map: function() {                return this._map            },            _option: function(name, value) {                if (value === undefined)                    return this._mapWidget.option(name);                this._mapWidget.setOptionSilent(name, value)            },            _keyOption: function(providerName) {                var key = this._option("key");                return key[providerName] === undefined ? key : key[providerName]            },            _parseTooltipOptions: function(option) {                return {                        text: option.text || option,                        visible: option.isShown || false                    }            },            _getLatLng: function(location) {                if (typeof location === "string") {                    var coords = $.map(location.split(","), $.trim),                        numericRegex = /[-+]?[0-9]*\.?[0-9]*/;                    if (coords.length === 2 && coords[0].match(numericRegex) && coords[1].match(numericRegex))                        return {                                lat: parseFloat(coords[0]),                                lng: parseFloat(coords[1])                            }                }                else if ($.isArray(location) && location.length === 2)                    return {                            lat: location[0],                            lng: location[1]                        };                else if ($.isPlainObject(location) && $.isNumeric(location.lat) && $.isNumeric(location.lng))                    return location;                return null            },            _isBoundsSetted: function() {                return this._option("bounds.northEast") && this._option("bounds.southWest")            },            _addEventNamespace: function(name) {                return events.addNamespace(name, this._mapWidget.NAME)            },            _createAction: function() {                var mapWidget = this._mapWidget;                return mapWidget._createAction.apply(mapWidget, arguments)            },            _fireAction: function(name, actionArguments) {                var option = this._option(name);                if (option)                    this._createAction(option)(actionArguments)            },            _fireClickAction: function(actionArguments) {                this._fireAction("onClick", actionArguments)            },            _fireMarkerAddedAction: function(actionArguments) {                this._fireAction("onMarkerAdded", actionArguments)            },            _fireMarkerRemovedAction: function(actionArguments) {                this._fireAction("onMarkerRemoved", actionArguments)            },            _fireRouteAddedAction: function(actionArguments) {                this._fireAction("onRouteAdded", actionArguments)            },            _fireRouteRemovedAction: function(actionArguments) {                this._fireAction("onRouteRemoved", actionArguments)            }        })    })(jQuery, DevExpress);    /*! Module widgets-base, file ui.map.provider.googleStatic.js */    (function($, DX, undefined) {        var ui = DX.ui;        var GOOGLE_STATIC_URL = "https://maps.google.com/maps/api/staticmap?";        ui.dxMap.registerProvider("googleStatic", ui.dxMap.Provider.inherit({            _locationToString: function(location) {                var latlng = this._getLatLng(location);                return latlng ? latlng.lat + "," + latlng.lng : location.toString().replace(/ /g, "+")            },            _renderImpl: function() {                return this._updateMap()            },            updateDimensions: function() {                return this._updateMap()            },            updateMapType: function() {                return this._updateMap()            },            updateBounds: function() {                return $.Deferred().resolve().promise()            },            updateCenter: function() {                return this._updateMap()            },            updateZoom: function() {                return this._updateMap()            },            updateControls: function() {                return $.Deferred().resolve().promise()            },            addMarkers: function(options) {                var that = this;                return this._updateMap().done(function() {                        $.each(options, function(_, options) {                            that._fireMarkerAddedAction({options: options})                        })                    })            },            removeMarkers: function(options) {                var that = this;                return this._updateMap().done(function() {                        $.each(options, function(_, options) {                            that._fireMarkerRemovedAction({options: options})                        })                    })            },            adjustViewport: function() {                return $.Deferred().resolve().promise()            },            addRoutes: function(options) {                var that = this;                return this._updateMap().done(function() {                        $.each(options, function(_, options) {                            that._fireRouteAddedAction({options: options})                        })                    })            },            removeRoutes: function(options) {                var that = this;                return this._updateMap().done(function() {                        $.each(options, function(_, options) {                            that._fireRouteRemovedAction({options: options})                        })                    })            },            clean: function() {                this._$container.css("background-image", "none");                this._$container.off(this._addEventNamespace("dxclick"));                return $.Deferred().resolve().promise()            },            mapRendered: function() {                return true            },            _updateMap: function() {                var key = this._keyOption("googleStatic"),                    $container = this._$container;                var requestOptions = ["sensor=false", "size=" + $container.width() + "x" + $container.height(), "maptype=" + this._option("type"), "center=" + this._locationToString(this._option("center")), "zoom=" + this._option("zoom"), this._markersSubstring()];                requestOptions.push.apply(requestOptions, this._routeSubstrings());                if (key)                    requestOptions.push("key=" + key);                var request = GOOGLE_STATIC_URL + requestOptions.join("&");                this._$container.css("background", "url(\"" + request + "\") no-repeat 0 0");                this._attachClickEvent();                return $.Deferred().resolve(true).promise()            },            _markersSubstring: function() {                var that = this,                    markers = [],                    markerIcon = this._option("markerIconSrc");                if (markerIcon)                    markers.push("icon:" + markerIcon);                $.each(this._option("markers"), function(_, marker) {                    markers.push(that._locationToString(marker.location))                });                return "markers=" + markers.join("|")            },            _routeSubstrings: function() {                var that = this,                    routes = [];                $.each(this._option("routes"), function(_, route) {                    var color = new DX.Color(route.color || that._defaultRouteColor()).toHex().replace('#', '0x'),                        opacity = Math.round((route.opacity || that._defaultRouteOpacity()) * 255).toString(16),                        width = route.weight || that._defaultRouteWeight(),                        locations = [];                    $.each(route.locations, function(_, routePoint) {                        locations.push(that._locationToString(routePoint))                    });                    routes.push("path=color:" + color + opacity + "|weight:" + width + "|" + locations.join("|"))                });                return routes            },            _attachClickEvent: function() {                var that = this,                    eventName = this._addEventNamespace("dxclick");                this._$container.off(eventName).on(eventName, function(e) {                    that._fireClickAction({jQueryEvent: e})                })            }        }));        ui.dxMap.__internals = $.extend(ui.dxMap.__internals, {remapGoogleStaticConstant: function(newValue) {                GOOGLE_STATIC_URL = newValue            }})    })(jQuery, DevExpress);    /*! Module widgets-base, file ui.map.provider.dynamic.js */    (function($, DX, undefined) {        var ui = DX.ui;        ui.dxMap.DynamicProvider = ui.dxMap.Provider.inherit({            cancelEvents: true,            _renderImpl: function(markerOptions, routeOptions) {                var deferred = $.Deferred();                this._load().done($.proxy(function() {                    this._init().done($.proxy(function() {                        var mapTypePromise = this.updateMapType(),                            boundsPromise = this._isBoundsSetted() ? this.updateBounds() : this.updateCenter();                        $.when(mapTypePromise, boundsPromise).done($.proxy(function() {                            this._attachHandlers();                            setTimeout(function() {                                deferred.resolve()                            })                        }, this))                    }, this))                }, this));                return deferred.promise()            },            _load: function() {                if (!this._mapsLoader) {                    this._mapsLoader = $.Deferred();                    this._loadImpl().done($.proxy(function() {                        this._mapsLoader.resolve()                    }, this))                }                this._markers = [];                this._routes = [];                return this._mapsLoader.promise()            },            _loadImpl: DX.abstract,            _init: DX.abstract,            _attachHandlers: DX.abstract,            addMarkers: function(options) {                var deferred = $.Deferred(),                    that = this;                var markerPromises = $.map(options, function(options) {                        return that._addMarker(options)                    });                $.when.apply($, markerPromises).done(function() {                    var instances = $.map($.makeArray(arguments), function(markerObject) {                            return markerObject.marker                        });                    deferred.resolve(false, instances)                });                return deferred.promise()            },            _addMarker: function(options) {                var that = this;                return this._renderMarker(options).done(function(markerObject) {                        that._markers.push($.extend({options: options}, markerObject));                        that._fitBounds();                        that._fireMarkerAddedAction({                            options: options,                            originalMarker: markerObject.marker                        })                    })            },            _renderMarker: DX.abstract,            removeMarkers: function(markersOptionsToRemove) {                var that = this;                $.each(markersOptionsToRemove, function(_, markerOptionToRemove) {                    that._removeMarker(markerOptionToRemove)                });                return $.Deferred().resolve().promise()            },            _removeMarker: function(markersOptionToRemove) {                var that = this;                $.each(this._markers, function(markerIndex, markerObject) {                    if (markerObject.options !== markersOptionToRemove)                        return true;                    that._destroyMarker(markerObject);                    that._markers.splice(markerIndex, 1);                    that._fireMarkerRemovedAction({options: markerObject.options});                    return false                })            },            _destroyMarker: DX.abstract,            _clearMarkers: function() {                while (this._markers.length > 0)                    this._removeMarker(this._markers[0].options)            },            addRoutes: function(options) {                var deferred = $.Deferred(),                    that = this;                var routePromises = $.map(options, function(options) {                        return that._addRoute(options)                    });                $.when.apply($, routePromises).done(function() {                    var instances = $.map($.makeArray(arguments), function(routeObject) {                            return routeObject.instance                        });                    deferred.resolve(false, instances)                });                return deferred.promise()            },            _addRoute: function(options) {                var that = this;                return this._renderRoute(options).done(function(routeObject) {                        that._routes.push($.extend({options: options}, routeObject));                        that._fitBounds();                        that._fireRouteAddedAction({                            options: options,                            originalRoute: routeObject.instance                        })                    })            },            _renderRoute: DX.abstract,            removeRoutes: function(options) {                var that = this;                $.each(options, function(routeIndex, options) {                    that._removeRoute(options)                });                return $.Deferred().resolve().promise()            },            _removeRoute: function(options) {                var that = this;                $.each(this._routes, function(routeIndex, routeObject) {                    if (routeObject.options !== options)                        return true;                    that._destroyRoute(routeObject);                    that._routes.splice(routeIndex, 1);                    that._fireRouteRemovedAction({options: options});                    return false                })            },            _destroyRoute: DX.abstract,            _clearRoutes: function() {                while (this._routes.length > 0)                    this._removeRoute(this._routes[0].options)            },            adjustViewport: function() {                return this._fitBounds()            },            _fitBounds: DX.abstract,            _updateBounds: function() {                var that = this;                this._clearBounds();                $.each(this._markers, function(_, markerObject) {                    that._extendBounds(markerObject.location)                });                $.each(this._routes, function(_, routeObject) {                    that._extendBounds(routeObject.northEast);                    that._extendBounds(routeObject.southWest)                })            },            _clearBounds: function() {                this._bounds = null            },            _extendBounds: DX.abstract        })    })(jQuery, DevExpress);    /*! Module widgets-base, file ui.map.provider.dynamic.bing.js */    (function($, DX, undefined) {        var ui = DX.ui,            winJS = DX.support.winJS;        var BING_MAP_READY = "_bingScriptReady",            BING_URL = "https://ecn.dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=7.0&s=1&onScriptLoad=" + BING_MAP_READY,            BING_LOCAL_FILES1 = "ms-appx:///Bing.Maps.JavaScript/js/veapicore.js",            BING_LOCAL_FILES2 = "ms-appx:///Bing.Maps.JavaScript/js/veapiModules.js",            BING_CREDENTIALS = "AhuxC0dQ1DBTNo8L-H9ToVMQStmizZzBJdraTSgCzDSWPsA1Qd8uIvFSflzxdaLH",            MIN_LOCATION_RECT_LENGTH = 0.0000000000000001;        var msMapsLoaded = function() {                return window.Microsoft && window.Microsoft.Maps            };        var msMapsLoader;        ui.dxMap.registerProvider("bing", ui.dxMap.DynamicProvider.inherit({            _mapType: function(type) {                var mapTypes = {                        roadmap: Microsoft.Maps.MapTypeId.road,                        hybrid: Microsoft.Maps.MapTypeId.aerial,                        satellite: Microsoft.Maps.MapTypeId.aerial                    };                return mapTypes[type] || mapTypes.road            },            _movementMode: function(type) {                var movementTypes = {                        driving: Microsoft.Maps.Directions.RouteMode.driving,                        walking: Microsoft.Maps.Directions.RouteMode.walking                    };                return movementTypes[type] || movementTypes.driving            },            _resolveLocation: function(location) {                var d = $.Deferred();                var latLng = this._getLatLng(location);                if (latLng)                    d.resolve(new Microsoft.Maps.Location(latLng.lat, latLng.lng));                else {                    var searchManager = new Microsoft.Maps.Search.SearchManager(this._map);                    var searchRequest = {                            where: location,                            count: 1,                            callback: function(searchResponse) {                                var boundsBox = searchResponse.results[0].location;                                d.resolve(new Microsoft.Maps.Location(boundsBox.latitude, boundsBox.longitude))                            }                        };                    searchManager.geocode(searchRequest)                }                return d.promise()            },            _normalizeLocation: function(location) {                return {                        lat: location.latitude,                        lng: location.longitude                    }            },            _normalizeLocationRect: function(locationRect) {                var northWest = this._normalizeLocation(locationRect.getNorthwest()),                    southEast = this._normalizeLocation(locationRect.getSoutheast());                return {                        northEast: {                            lat: northWest.lat,                            lng: southEast.lng                        },                        southWest: {                            lat: southEast.lat,                            lng: northWest.lng                        }                    }            },            _loadImpl: function() {                this._msMapsLoader = $.Deferred();                if (msMapsLoaded())                    this._mapReady();                else {                    if (!msMapsLoader || msMapsLoader.state() === "resolved" && !msMapsLoaded()) {                        msMapsLoader = $.Deferred();                        window[BING_MAP_READY] = $.proxy(msMapsLoader.resolve, msMapsLoader);                        if (winJS)                            $.when($.getScript(BING_LOCAL_FILES1), $.getScript(BING_LOCAL_FILES2)).done(function() {                                Microsoft.Maps.loadModule("Microsoft.Maps.Map", {callback: window[BING_MAP_READY]})                            });                        else                            $.getScript(BING_URL)                    }                    msMapsLoader.done($.proxy(this._mapReady, this))                }                return this._msMapsLoader.promise()            },            _mapReady: function() {                try {                    delete window[BING_MAP_READY]                }                catch(e) {                    window[BING_MAP_READY] = undefined                }                var searchModulePromise = $.Deferred();                var directionsModulePromise = $.Deferred();                Microsoft.Maps.loadModule('Microsoft.Maps.Search', {callback: $.proxy(searchModulePromise.resolve, searchModulePromise)});                Microsoft.Maps.loadModule('Microsoft.Maps.Directions', {callback: $.proxy(directionsModulePromise.resolve, directionsModulePromise)});                $.when(searchModulePromise, directionsModulePromise).done($.proxy(function() {                    this._msMapsLoader.resolve()                }, this))            },            _init: function() {                var deferred = $.Deferred(),                    initPromise = $.Deferred(),                    controls = this._option("controls");                this._map = new Microsoft.Maps.Map(this._$container[0], {                    credentials: this._keyOption("bing") || BING_CREDENTIALS,                    zoom: this._option("zoom"),                    showDashboard: controls,                    showMapTypeSelector: controls,                    showScalebar: controls                });                var handler = Microsoft.Maps.Events.addHandler(this._map, 'tiledownloadcomplete', $.proxy(initPromise.resolve, initPromise));                $.when(initPromise).done($.proxy(function() {                    Microsoft.Maps.Events.removeHandler(handler);                    deferred.resolve()                }, this));                return deferred.promise()            },            _attachHandlers: function() {                this._providerViewChangeHandler = Microsoft.Maps.Events.addHandler(this._map, 'viewchange', $.proxy(this._viewChangeHandler, this));                this._providerClickHandler = Microsoft.Maps.Events.addHandler(this._map, 'click', $.proxy(this._clickActionHandler, this))            },            _viewChangeHandler: function() {                var bounds = this._map.getBounds();                this._option("bounds", this._normalizeLocationRect(bounds));                var center = this._map.getCenter();                this._option("center", this._normalizeLocation(center));                if (!this._preventZoomChangeEvent)                    this._option("zoom", this._map.getZoom())            },            _clickActionHandler: function(e) {                if (e.targetType === "map") {                    var point = new Microsoft.Maps.Point(e.getX(), e.getY()),                        location = e.target.tryPixelToLocation(point);                    this._fireClickAction({location: this._normalizeLocation(location)})                }            },            updateDimensions: function() {                var $container = this._$container;                this._map.setOptions({                    width: $container.width(),                    height: $container.height()                });                return $.Deferred().resolve().promise()            },            updateMapType: function() {                var type = this._option("type"),                    labelOverlay = Microsoft.Maps.LabelOverlay;                this._map.setView({                    animate: false,                    mapTypeId: this._mapType(type),                    labelOverlay: type === "satellite" ? labelOverlay.hidden : labelOverlay.visible                });                return $.Deferred().resolve().promise()            },            updateBounds: function() {                var deferred = $.Deferred(),                    that = this;                var northEastPromise = this._resolveLocation(this._option("bounds.northEast")),                    southWestPromise = this._resolveLocation(this._option("bounds.southWest"));                $.when(northEastPromise, southWestPromise).done(function(northEast, southWest) {                    var bounds = new Microsoft.Maps.LocationRect.fromLocations(northEast, southWest);                    that._map.setView({                        animate: false,                        bounds: bounds                    });                    deferred.resolve()                });                return deferred.promise()            },            updateCenter: function() {                var deferred = $.Deferred(),                    that = this;                this._resolveLocation(this._option("center")).done(function(location) {                    that._map.setView({                        animate: false,                        center: location                    });                    deferred.resolve()                });                return deferred.promise()            },            updateZoom: function() {                this._map.setView({                    animate: false,                    zoom: this._option("zoom")                });                return $.Deferred().resolve().promise()            },            updateControls: function() {                this.clean();                return this.render.apply(this, arguments)            },            _renderMarker: function(options) {                var d = $.Deferred(),                    that = this;                this._resolveLocation(options.location).done(function(location) {                    var pushpinOptions = {icon: options.iconSrc || that._option("markerIconSrc")};                    if (options.html) {                        $.extend(pushpinOptions, {                            htmlContent: options.html,                            width: null,                            height: null                        });                        var htmlOffset = options.htmlOffset;                        if (htmlOffset)                            pushpinOptions.anchor = new Microsoft.Maps.Point(-htmlOffset.left, -htmlOffset.top)                    }                    var pushpin = new Microsoft.Maps.Pushpin(location, pushpinOptions);                    that._map.entities.push(pushpin);                    var infobox = that._renderTooltip(location, options.tooltip);                    if (options.clickAction) {                        DX.log("W0001", "dxMap", "marker.clickAction", "14.2", "Use 'onClick' option instead");                        options.onClick = options.clickAction                    }                    var handler;                    if (options.onClick || options.tooltip) {                        var markerClickAction = that._createAction(options.onClick || $.noop),                            markerNormalizedLocation = that._normalizeLocation(location);                        handler = Microsoft.Maps.Events.addHandler(pushpin, "click", function() {                            markerClickAction({location: markerNormalizedLocation});                            if (infobox)                                infobox.setOptions({visible: true})                        })                    }                    d.resolve({                        location: location,                        marker: pushpin,                        infobox: infobox,                        handler: handler                    })                });                return d.promise()            },            _renderTooltip: function(location, options) {                if (!options)                    return;                options = this._parseTooltipOptions(options);                var infobox = new Microsoft.Maps.Infobox(location, {                        description: options.text,                        offset: new Microsoft.Maps.Point(0, 33),                        visible: options.visible                    });                this._map.entities.push(infobox, null);                return infobox            },            _destroyMarker: function(marker) {                this._map.entities.remove(marker.marker);                if (marker.infobox)                    this._map.entities.remove(marker.infobox);                if (marker.handler)                    Microsoft.Maps.Events.removeHandler(marker.handler)            },            _renderRoute: function(options) {                var d = $.Deferred(),                    that = this;                var points = $.map(options.locations, function(point) {                        return that._resolveLocation(point)                    });                $.when.apply($, points).done(function() {                    var locations = $.makeArray(arguments),                        direction = new Microsoft.Maps.Directions.DirectionsManager(that._map),                        color = new DX.Color(options.color || that._defaultRouteColor()).toHex(),                        routeColor = new Microsoft.Maps.Color.fromHex(color);                    routeColor.a = (options.opacity || that._defaultRouteOpacity()) * 255;                    direction.setRenderOptions({                        autoUpdateMapView: false,                        displayRouteSelector: false,                        waypointPushpinOptions: {visible: false},                        drivingPolylineOptions: {                            strokeColor: routeColor,                            strokeThickness: options.weight || that._defaultRouteWeight()                        },                        walkingPolylineOptions: {                            strokeColor: routeColor,                            strokeThickness: options.weight || that._defaultRouteWeight()                        }                    });                    direction.setRequestOptions({                        routeMode: that._movementMode(options.mode),                        routeDraggable: false                    });                    $.each(locations, function(_, location) {                        var waypoint = new Microsoft.Maps.Directions.Waypoint({location: location});                        direction.addWaypoint(waypoint)                    });                    var handler = Microsoft.Maps.Events.addHandler(direction, 'directionsUpdated', function(args) {                            Microsoft.Maps.Events.removeHandler(handler);                            var routeSummary = args.routeSummary[0];                            d.resolve({                                instance: direction,                                northEast: routeSummary.northEast,                                southWest: routeSummary.southWest                            })                        });                    direction.calculateDirections()                });                return d.promise()            },            _destroyRoute: function(routeObject) {                routeObject.instance.dispose()            },            _fitBounds: function() {                this._updateBounds();                if (this._bounds && this._option("autoAdjust")) {                    var zoomBeforeFitting = this._map.getZoom();                    this._preventZoomChangeEvent = true;                    var bounds = this._bounds.clone();                    bounds.height = bounds.height * 1.1;                    bounds.width = bounds.width * 1.1;                    this._map.setView({                        animate: false,                        bounds: bounds,                        zoom: zoomBeforeFitting                    });                    var zoomAfterFitting = this._map.getZoom();                    if (zoomBeforeFitting < zoomAfterFitting)                        this._map.setView({                            animate: false,                            zoom: zoomBeforeFitting                        });                    else                        this._option("zoom", zoomAfterFitting);                    delete this._preventZoomChangeEvent                }                return $.Deferred().resolve().promise()            },            _extendBounds: function(location) {                if (this._bounds)                    this._bounds = new Microsoft.Maps.LocationRect.fromLocations(this._bounds.getNorthwest(), this._bounds.getSoutheast(), location);                else                    this._bounds = new Microsoft.Maps.LocationRect(location, MIN_LOCATION_RECT_LENGTH, MIN_LOCATION_RECT_LENGTH)            },            clean: function() {                if (this._map) {                    Microsoft.Maps.Events.removeHandler(this._providerViewChangeHandler);                    Microsoft.Maps.Events.removeHandler(this._providerClickHandler);                    this._clearMarkers();                    this._clearRoutes();                    this._map.dispose()                }                return $.Deferred().resolve().promise()            }        }));        ui.dxMap.__internals = $.extend(ui.dxMap.__internals, {remapBingConstant: function(newValue) {                BING_URL = newValue            }})    })(jQuery, DevExpress);    /*! Module widgets-base, file ui.map.provider.dynamic.google.js */    (function($, DX, undefined) {        var ui = DX.ui;        var GOOGLE_MAP_READY = "_googleScriptReady",            GOOGLE_URL = "https://maps.google.com/maps/api/js?v=3.18&sensor=false&callback=" + GOOGLE_MAP_READY;        var CustomMarker;        var initCustomMarkerClass = function() {                CustomMarker = function(options) {                    this._position = options.position;                    this._offset = options.offset;                    this._$overlayContainer = $("<div>").css({                        position: "absolute",                        display: "none",                        cursor: "pointer"                    }).append(options.html);                    this.setMap(options.map)                };                CustomMarker.prototype = new google.maps.OverlayView;                CustomMarker.prototype.onAdd = function() {                    var $pane = $(this.getPanes().overlayMouseTarget);                    $pane.append(this._$overlayContainer);                    this._clickListner = google.maps.event.addDomListener(this._$overlayContainer.get(0), 'click', $.proxy(function(e) {                        google.maps.event.trigger(this, 'click');                        e.preventDefault()                    }, this));                    this.draw()                };                CustomMarker.prototype.onRemove = function() {                    google.maps.event.removeListener(this._clickListner);                    this._$overlayContainer.remove()                };                CustomMarker.prototype.draw = function() {                    var position = this.getProjection().fromLatLngToDivPixel(this._position);                    this._$overlayContainer.css({                        left: position.x + this._offset.left,                        top: position.y + this._offset.top,                        display: 'block'                    })                }            };        var googleMapsLoaded = function() {                return window.google && window.google.maps            };        var googleMapsLoader;        ui.dxMap.registerProvider("google", ui.dxMap.DynamicProvider.inherit({            _mapType: function(type) {                var mapTypes = {                        hybrid: google.maps.MapTypeId.HYBRID,                        roadmap: google.maps.MapTypeId.ROADMAP,                        satellite: google.maps.MapTypeId.SATELLITE                    };                return mapTypes[type] || mapTypes.hybrid            },            _movementMode: function(type) {                var movementTypes = {                        driving: google.maps.TravelMode.DRIVING,                        walking: google.maps.TravelMode.WALKING                    };                return movementTypes[type] || movementTypes.driving            },            _resolveLocation: function(location) {                var d = $.Deferred();                var latLng = this._getLatLng(location);                if (latLng)                    d.resolve(new google.maps.LatLng(latLng.lat, latLng.lng));                else {                    var geocoder = new google.maps.Geocoder;                    geocoder.geocode({address: location}, function(results, status) {                        if (status === google.maps.GeocoderStatus.OK)                            d.resolve(results[0].geometry.location)                    })                }                return d.promise()            },            _normalizeLocation: function(location) {                return {                        lat: location.lat(),                        lng: location.lng()                    }            },            _normalizeLocationRect: function(locationRect) {                return {                        northEast: this._normalizeLocation(locationRect.getNorthEast()),                        southWest: this._normalizeLocation(locationRect.getSouthWest())                    }            },            _loadImpl: function() {                this._googleMapsLoader = $.Deferred();                if (googleMapsLoaded())                    this._mapReady();                else {                    if (!googleMapsLoader || googleMapsLoader.state() === "resolved" && !googleMapsLoaded()) {                        googleMapsLoader = $.Deferred();                        var key = this._keyOption("google");                        window[GOOGLE_MAP_READY] = $.proxy(googleMapsLoader.resolve, googleMapsLoader);                        $.getScript(GOOGLE_URL + (key ? "&key=" + key : ""))                    }                    googleMapsLoader.done($.proxy(this._mapReady, this))                }                return this._googleMapsLoader.promise()            },            _mapReady: function() {                try {                    delete window[GOOGLE_MAP_READY]                }                catch(e) {                    window[GOOGLE_MAP_READY] = undefined                }                initCustomMarkerClass();                this._googleMapsLoader.resolve()            },            _init: function() {                var deferred = $.Deferred(),                    initPromise = $.Deferred(),                    controls = this._option("controls");                this._map = new google.maps.Map(this._$container[0], {                    zoom: this._option("zoom"),                    panControl: controls,                    zoomControl: controls,                    mapTypeControl: controls,                    streetViewControl: controls                });                var listner = google.maps.event.addListener(this._map, 'idle', $.proxy(initPromise.resolve, initPromise));                $.when(initPromise).done($.proxy(function() {                    google.maps.event.removeListener(listner);                    deferred.resolve()                }, this));                return deferred.promise()            },            _attachHandlers: function() {                this._boundsChangeListener = google.maps.event.addListener(this._map, 'bounds_changed', $.proxy(this._boundsChangeHandler, this));                this._clickListener = google.maps.event.addListener(this._map, 'click', $.proxy(this._clickActionHandler, this))            },            _boundsChangeHandler: function() {                var bounds = this._map.getBounds();                this._option("bounds", this._normalizeLocationRect(bounds));                var center = this._map.getCenter();                this._option("center", this._normalizeLocation(center));                if (!this._preventZoomChangeEvent)                    this._option("zoom", this._map.getZoom())            },            _clickActionHandler: function(e) {                this._fireClickAction({location: this._normalizeLocation(e.latLng)})            },            updateDimensions: function() {                var center = this._option("center");                google.maps.event.trigger(this._map, 'resize');                this._option("center", center);                return this.updateCenter()            },            updateMapType: function() {                this._map.setMapTypeId(this._mapType(this._option("type")));                return $.Deferred().resolve().promise()            },            updateBounds: function() {                var deferred = $.Deferred(),                    that = this;                var northEastPromise = this._resolveLocation(this._option("bounds.northEast")),                    southWestPromise = this._resolveLocation(this._option("bounds.southWest"));                $.when(northEastPromise, southWestPromise).done(function(northEast, southWest) {                    var bounds = new google.maps.LatLngBounds;                    bounds.extend(northEast);                    bounds.extend(southWest);                    that._map.fitBounds(bounds);                    deferred.resolve()                });                return deferred.promise()            },            updateCenter: function() {                var deferred = $.Deferred(),                    that = this;                this._resolveLocation(this._option("center")).done(function(center) {                    that._map.setCenter(center);                    that._option("center", that._normalizeLocation(center));                    deferred.resolve()                });                return deferred.promise()            },            updateZoom: function() {                this._map.setZoom(this._option("zoom"));                return $.Deferred().resolve().promise()            },            updateControls: function() {                var controls = this._option("controls");                this._map.setOptions({                    panControl: controls,                    zoomControl: controls,                    mapTypeControl: controls,                    streetViewControl: controls                });                return $.Deferred().resolve().promise()            },            _renderMarker: function(options) {                var d = $.Deferred(),                    that = this;                this._resolveLocation(options.location).done(function(location) {                    var marker;                    if (options.html)                        marker = new CustomMarker({                            map: that._map,                            position: location,                            html: options.html,                            offset: $.extend({                                top: 0,                                left: 0                            }, options.htmlOffset)                        });                    else                        marker = new google.maps.Marker({                            position: location,                            map: that._map,                            icon: options.iconSrc || that._option("markerIconSrc")                        });                    var infoWindow = that._renderTooltip(marker, options.tooltip);                    if (options.clickAction) {                        DX.log("W0001", "dxMap", "marker.clickAction", "14.2", "Use 'onClick' option instead");                        options.onClick = options.clickAction                    }                    var listner;                    if (options.onClick || options.tooltip) {                        var markerClickAction = that._createAction(options.onClick || $.noop),                            markerNormalizedLocation = that._normalizeLocation(location);                        listner = google.maps.event.addListener(marker, "click", function() {                            markerClickAction({location: markerNormalizedLocation});                            if (infoWindow)                                infoWindow.open(that._map, marker)                        })                    }                    d.resolve({                        location: location,                        marker: marker,                        listner: listner                    })                });                return d.promise()            },            _renderTooltip: function(marker, options) {                if (!options)                    return;                options = this._parseTooltipOptions(options);                var infoWindow = new google.maps.InfoWindow({content: options.text});                if (options.visible)                    infoWindow.open(this._map, marker);                return infoWindow            },            _destroyMarker: function(marker) {                marker.marker.setMap(null);                if (marker.listner)                    google.maps.event.removeListener(marker.listner)            },            _renderRoute: function(options) {                var d = $.Deferred(),                    that = this,                    directionsService = new google.maps.DirectionsService;                var points = $.map(options.locations, function(point) {                        return that._resolveLocation(point)                    });                $.when.apply($, points).done(function() {                    var locations = $.makeArray(arguments),                        origin = locations.shift(),                        destination = locations.pop(),                        waypoints = $.map(locations, function(location) {                            return {                                    location: location,                                    stopover: true                                }                        });                    var request = {                            origin: origin,                            destination: destination,                            waypoints: waypoints,                            optimizeWaypoints: true,                            travelMode: that._movementMode(options.mode)                        };                    directionsService.route(request, function(response, status) {                        if (status === google.maps.DirectionsStatus.OK) {                            var color = new DX.Color(options.color || that._defaultRouteColor()).toHex(),                                directionOptions = {                                    directions: response,                                    map: that._map,                                    suppressMarkers: true,                                    preserveViewport: true,                                    polylineOptions: {                                        strokeWeight: options.weight || that._defaultRouteWeight(),                                        strokeOpacity: options.opacity || that._defaultRouteOpacity(),                                        strokeColor: color                                    }                                };                            var route = new google.maps.DirectionsRenderer(directionOptions),                                bounds = response.routes[0].bounds;                            d.resolve({                                instance: route,                                northEast: bounds.getNorthEast(),                                southWest: bounds.getSouthWest()                            })                        }                    })                });                return d.promise()            },            _destroyRoute: function(routeObject) {                routeObject.instance.setMap(null)            },            _fitBounds: function() {                this._updateBounds();                if (this._bounds && this._option("autoAdjust")) {                    var zoomBeforeFitting = this._map.getZoom();                    this._preventZoomChangeEvent = true;                    this._map.fitBounds(this._bounds);                    var zoomAfterFitting = this._map.getZoom();                    if (zoomBeforeFitting < zoomAfterFitting)                        this._map.setZoom(zoomBeforeFitting);                    else                        this._option("zoom", zoomAfterFitting);                    delete this._preventZoomChangeEvent                }                return $.Deferred().resolve().promise()            },            _extendBounds: function(location) {                if (this._bounds)                    this._bounds.extend(location);                else {                    this._bounds = new google.maps.LatLngBounds;                    this._bounds.extend(location)                }            },            clean: function() {                if (this._map) {                    google.maps.event.removeListener(this._boundsChangeListener);                    google.maps.event.removeListener(this._clickListener);                    this._clearMarkers();                    this._clearRoutes();                    delete this._map;                    this._$container.empty()                }                return $.Deferred().resolve().promise()            }        }));        ui.dxMap.__internals = $.extend(ui.dxMap.__internals, {remapGoogleConstant: function(newValue) {                GOOGLE_URL = newValue            }})    })(jQuery, DevExpress);    /*! Module widgets-base, file ui.swipeable.js */    (function($, DX, undefined) {        var ui = DX.ui,            events = ui.events,            DX_SWIPEABLE = "dxSwipeable",            SWIPEABLE_CLASS = "dx-swipeable",            ACTION_TO_EVENT_MAP = {                onStart: "dxswipestart",                onUpdated: "dxswipe",                onEnd: "dxswipeend",                onCancel: "dxswipecancel"            };        DX.registerComponent(DX_SWIPEABLE, ui, DX.DOMComponent.inherit({            _setDefaultOptions: function() {                this.callBase();                this.option({                    elastic: true,                    immediate: false,                    direction: "horizontal",                    itemSizeFunc: null,                    onStart: null,                    onUpdated: null,                    onEnd: null,                    onCancel: null                })            },            _render: function() {                this.callBase();                this.element().addClass(SWIPEABLE_CLASS);                this._attachEventHandlers()            },            _attachEventHandlers: function() {                this._detachEventHanlers();                if (this.option("disabled"))                    return;                var NAME = this.NAME;                this._createEventData();                $.each(ACTION_TO_EVENT_MAP, $.proxy(function(actionName, eventName) {                    var action = this._createActionByOption(actionName, {context: this});                    eventName = events.addNamespace(eventName, NAME);                    this.element().on(eventName, this._eventData, function(e) {                        return action({jQueryEvent: e})                    })                }, this))            },            _createEventData: function() {                this._eventData = {                    elastic: this.option("elastic"),                    itemSizeFunc: this.option("itemSizeFunc"),                    direction: this.option("direction"),                    immediate: this.option("immediate")                }            },            _detachEventHanlers: function() {                this.element().off("." + DX_SWIPEABLE)            },            _optionChanged: function(args) {                switch (args.name) {                    case"disabled":                    case"onStart":                    case"onUpdated":                    case"onEnd":                    case"onCancel":                    case"elastic":                    case"immediate":                    case"itemSizeFunc":                    case"direction":                        this._detachEventHanlers();                        this._attachEventHandlers();                        break;                    case"rtlEnabled":                        break;                    default:                        this.callBase(args)                }            }        }))    })(jQuery, DevExpress);    /*! Module widgets-base, file ui.draggable.js */    (function($, DX, undefined) {        var ui = DX.ui,            translator = DX.translator,            inflector = DX.inflector,            events = ui.events,            DRAGGABLE = "dxDraggable",            DRAGSTART_EVENT_NAME = events.addNamespace("dxdragstart", DRAGGABLE),            DRAG_EVENT_NAME = events.addNamespace("dxdrag", DRAGGABLE),            DRAGEND_EVENT_NAME = events.addNamespace("dxdragend", DRAGGABLE),            POINTERDOWN_EVENT_NAME = events.addNamespace("dxpointerdown", DRAGGABLE),            DRAGGABLE_CLASS = inflector.dasherize(DRAGGABLE),            DRAGGABLE_DRAGGING_CLASS = DRAGGABLE_CLASS + "-dragging";        DX.registerComponent(DRAGGABLE, ui, DX.DOMComponent.inherit({            _setDefaultOptions: function() {                this.callBase();                this.option({                    onDragStart: $.noop,                    onDrag: $.noop,                    onDragEnd: $.noop,                    direction: "both",                    area: window,                    boundOffset: 0,                    allowMoveByClick: false                })            },            _init: function() {                this.callBase();                this._attachEventHandlers()            },            _attachEventHandlers: function() {                var $element = this.element().css("position", "absolute"),                    eventHandlers = {},                    allowMoveByClick = this.option("allowMoveByClick");                eventHandlers[DRAGSTART_EVENT_NAME] = $.proxy(this._dragStartHandler, this);                eventHandlers[DRAG_EVENT_NAME] = $.proxy(this._dragHandler, this);                eventHandlers[DRAGEND_EVENT_NAME] = $.proxy(this._dragEndHandler, this);                if (allowMoveByClick) {                    eventHandlers[POINTERDOWN_EVENT_NAME] = $.proxy(this._pointerDownHandler, this);                    $element = this._getArea()                }                $element.on(eventHandlers, {                    direction: this.option("direction"),                    immediate: true                })            },            _detachEventHandlers: function() {                this.element().off("." + DRAGGABLE);                this._getArea().off("." + DRAGGABLE)            },            _move: function(position) {                translator.move(this.element(), position)            },            _pointerDownHandler: function(e) {                var $area = $(e.currentTarget),                    areaOffset = $.isWindow($area.get(0)) ? {                        left: 0,                        top: 0                    } : $area.offset(),                    direction = this.option("direction"),                    position = {};                if (direction === "horizontal" || direction === "both")                    position.left = e.pageX - this.element().width() / 2 - areaOffset.left;                if (direction === "vertical" || direction === "both")                    position.top = e.pageY - this.element().height() / 2 - areaOffset.top;                this._move(position);                this._getAction("onDrag")({jQueryEvent: e})            },            _dragStartHandler: function(e) {                var $element = this.element(),                    $area = this._getArea(),                    boundOffset = this._getBoundOffset(),                    areaWidth = $area.outerWidth(),                    areaHeight = $area.outerHeight(),                    elementWidth = $element.width(),                    elementHeight = $element.height();                this._toggleDraggingClass(true);                this._startPosition = translator.locate($element);                e.maxLeftOffset = this._startPosition.left - boundOffset.h;                e.maxRightOffset = areaWidth - this._startPosition.left - elementWidth - boundOffset.h;                e.maxTopOffset = this._startPosition.top - boundOffset.v;                e.maxBottomOffset = areaHeight - this._startPosition.top - elementHeight - boundOffset.v;                this._getAction("onDragStart")({jQueryEvent: e})            },            _toggleDraggingClass: function(value) {                this.element().toggleClass(DRAGGABLE_DRAGGING_CLASS, value)            },            _getBoundOffset: function() {                var boundOffset = this.option("boundOffset");                if ($.isFunction(boundOffset))                    boundOffset = boundOffset.call(this);                return DX.utils.stringPairToObject(boundOffset)            },            _getArea: function() {                var area = this.option("area");                if ($.isFunction(area))                    area = area.call(this);                return $(area)            },            _dragHandler: function(e) {                var offset = e.offset,                    startPosition = this._startPosition;                this._move({                    left: startPosition.left + offset.x,                    top: startPosition.top + offset.y                });                this._getAction("onDrag")({jQueryEvent: e})            },            _dragEndHandler: function(e) {                this._toggleDraggingClass(false);                this._getAction("onDragEnd")({jQueryEvent: e})            },            _getAction: function(name) {                return this["_" + name + "Action"] || this._createActionByOption(name)            },            _render: function() {                this.callBase();                this.element().addClass(DRAGGABLE_CLASS)            },            _optionChanged: function(args) {                var name = args.name;                switch (name) {                    case"onDragStart":                    case"onDrag":                    case"onDragEnd":                        this["_" + name + "Action"] = this._createActionByOption(name);                        break;                    case"allowMoveByClick":                    case"direction":                        this._detachEventHandlers();                        this._attachEventHandlers();                        break;                    case"boundOffset":                    case"area":                        break;                    default:                        this.callBase(args)                }            },            _dispose: function() {                this.callBase();                this._detachEventHandlers()            }        }));        ui.dxDraggable.__internals = {DRAGGABLE_CLASS: DRAGGABLE_CLASS}    })(jQuery, DevExpress);    /*! Module widgets-base, file ui.resizable.js */    (function($, DX, undefined) {        var ui = DX.ui,            utils = DX.utils,            events = ui.events,            RESIZABLE = "dxResizable",            RESIZABLE_CLASS = "dx-resizable",            RESIZABLE_RESIZING_CLASS = "dx-resizable-resizing",            RESIZABLE_HANDLE_CLASS = "dx-resizable-handle",            RESIZABLE_HANDLE_TOP_CLASS = "dx-resizable-handle-top",            RESIZABLE_HANDLE_BOTTOM_CLASS = "dx-resizable-handle-bottom",            RESIZABLE_HANDLE_LEFT_CLASS = "dx-resizable-handle-left",            RESIZABLE_HANDLE_RIGHT_CLASS = "dx-resizable-handle-right",            RESIZABLE_HANDLE_CORNER_CLASS = "dx-resizable-handle-corner",            DRAGSTART_START_EVENT_NAME = events.addNamespace("dxdragstart", RESIZABLE),            DRAGSTART_EVENT_NAME = events.addNamespace("dxdrag", RESIZABLE),            DRAGSTART_END_EVENT_NAME = events.addNamespace("dxdragend", RESIZABLE);        DX.registerComponent(RESIZABLE, ui, DX.DOMComponent.inherit({            _setDefaultOptions: function() {                this.callBase();                this.option({                    handles: "all",                    step: "1",                    area: undefined,                    minWidth: 30,                    maxWidth: Infinity,                    minHeight: 30,                    maxHeight: Infinity,                    onResizeStart: null,                    onResize: null,                    onResizeEnd: null                })            },            _init: function() {                this.callBase();                this.element().addClass(RESIZABLE_CLASS)            },            _render: function() {                this.callBase();                this._renderActions();                this._renderHandles()            },            _renderActions: function() {                this._resizeStartAction = this._createActionByOption("onResizeStart");                this._resizeEndAction = this._createActionByOption("onResizeEnd");                this._resizeAction = this._createActionByOption("onResize")            },            _renderHandles: function() {                var handles = this.option("handles");                if (handles === "none")                    return;                var directions = handles === "all" ? ['top', 'bottom', 'left', 'right'] : handles.split(" ");                $.each(directions, $.proxy(function(index, handleName) {                    this._renderHandle(handleName)                }, this));                $.inArray('bottom', directions) + 1 && $.inArray('right', directions) + 1 && this._renderHandle("corner-bottom-right");                $.inArray('bottom', directions) + 1 && $.inArray('left', directions) + 1 && this._renderHandle("corner-bottom-left");                $.inArray('top', directions) + 1 && $.inArray('right', directions) + 1 && this._renderHandle("corner-top-right");                $.inArray('top', directions) + 1 && $.inArray('left', directions) + 1 && this._renderHandle("corner-top-left")            },            _renderHandle: function(handleName) {                var $element = this.element(),                    $handle = $("<div>");                $handle.addClass(RESIZABLE_HANDLE_CLASS).addClass(RESIZABLE_HANDLE_CLASS + "-" + handleName).appendTo($element);                var handlers = {};                handlers[DRAGSTART_START_EVENT_NAME] = $.proxy(this._dragStartHandler, this);                handlers[DRAGSTART_EVENT_NAME] = $.proxy(this._dragHandler, this);                handlers[DRAGSTART_END_EVENT_NAME] = $.proxy(this._dragEndHandler, this);                $handle.on(handlers, {                    direction: this._dragEventDirection(handleName),                    immediate: true                })            },            _dragEventDirection: function(handleName) {                switch (handleName) {                    case"right":                    case"left":                        return "horizontal";                    case"top":                    case"bottom":                        return "vertical";                    default:                        return "both"                }            },            _dragStartHandler: function(e) {                this._toggleResizingClass(true);                this._movingSides = this._getMovingSides(e);                var $element = this.element();                this._elementLocation = DX.translator.locate($element);                this._elementSize = {                    width: $element.outerWidth(),                    height: $element.outerHeight()                };                this._renderDragOffsets(e);                this._resizeStartAction({                    jQueryEvent: e,                    width: this._elementSize.width,                    height: this._elementSize.height,                    handles: this._movingSides                });                e.targetElements = null            },            _toggleResizingClass: function(value) {                this.element().toggleClass(RESIZABLE_RESIZING_CLASS, value)            },            _renderDragOffsets: function(e) {                var $area = this._getArea(),                    $handle = $(e.target).closest("." + RESIZABLE_HANDLE_CLASS);                if (!$area.length)                    return;                var areaWidth = $area.innerWidth(),                    areaHeight = $area.innerHeight(),                    handleWidth = $handle.outerWidth(),                    handleHeight = $handle.outerHeight();                var handleOffset = $handle.offset(),                    areaOffset = $area.offset() || {                        top: 0,                        left: 0                    };                areaOffset.left += this._getBorderWidth($area, "left") + this._getBorderWidth(this.element(), "left");                areaOffset.top += this._getBorderWidth($area, "top") + this._getBorderWidth(this.element(), "top");                areaWidth -= this.element().outerWidth() - this.element().innerWidth();                areaHeight -= this.element().outerHeight() - this.element().innerHeight();                e.maxLeftOffset = handleOffset.left - areaOffset.left;                e.maxRightOffset = areaOffset.left + areaWidth - handleOffset.left - handleWidth;                e.maxTopOffset = handleOffset.top - areaOffset.top;                e.maxBottomOffset = areaOffset.top + areaHeight - handleOffset.top - handleHeight            },            _getBorderWidth: function($element, direction) {                var borderWidth = $element.css("border-" + direction + "-width");                return parseInt(borderWidth) || 0            },            _dragHandler: function(e) {                var $element = this.element(),                    offset = this._getOffset(e),                    sides = this._movingSides;                var location = this._elementLocation,                    size = this._elementSize;                var width = size.width + offset.x * (sides.left ? -1 : 1),                    height = size.height + offset.y * (sides.top ? -1 : 1);                this._renderSize(width, height);                var offsetTop = offset.y - (this.option("height") - height),                    offsetLeft = offset.x - (this.option("width") - width);                DX.translator.move($element, {                    top: location.top + (sides.top ? offsetTop : 0),                    left: location.left + (sides.left ? offsetLeft : 0)                });                this._resizeAction({                    jQueryEvent: e,                    width: width,                    height: height,                    handles: this._movingSides                })            },            _getOffset: function(e) {                var offset = e.offset,                    steps = DX.utils.stringPairToObject(this.option("step"));                return {                        x: offset.x - offset.x % steps.h,                        y: offset.y - offset.y % steps.v                    }            },            _getMovingSides: function(e) {                var $target = $(e.target);                return {                        top: $target.hasClass(RESIZABLE_HANDLE_TOP_CLASS) || $target.hasClass(RESIZABLE_HANDLE_CORNER_CLASS + "-top-left") || $target.hasClass(RESIZABLE_HANDLE_CORNER_CLASS + "-top-right"),                        left: $target.hasClass(RESIZABLE_HANDLE_LEFT_CLASS) || $target.hasClass(RESIZABLE_HANDLE_CORNER_CLASS + "-top-left") || $target.hasClass(RESIZABLE_HANDLE_CORNER_CLASS + "-bottom-left"),                        bottom: $target.hasClass(RESIZABLE_HANDLE_BOTTOM_CLASS) || $target.hasClass(RESIZABLE_HANDLE_CORNER_CLASS + "-bottom-left") || $target.hasClass(RESIZABLE_HANDLE_CORNER_CLASS + "-bottom-right"),                        right: $target.hasClass(RESIZABLE_HANDLE_RIGHT_CLASS) || $target.hasClass(RESIZABLE_HANDLE_CORNER_CLASS + "-top-right") || $target.hasClass(RESIZABLE_HANDLE_CORNER_CLASS + "-bottom-right")                    }            },            _getArea: function() {                var area = this.option("area");                if ($.isFunction(area))                    area = area.call(this);                return $(area)            },            _dragEndHandler: function(e) {                var $element = this.element();                this._resizeEndAction({                    jQueryEvent: e,                    width: $element.outerWidth(),                    height: $element.outerHeight(),                    handles: this._movingSides                });                this._toggleResizingClass(false)            },            _renderSize: function(width, height) {                this.option("width", utils.fitIntoRange(width, this.option("minWidth"), this.option("maxWidth")));                this.option("height", utils.fitIntoRange(height, this.option("minHeight"), this.option("maxHeight")))            },            _optionChanged: function(args) {                switch (args.name) {                    case"handles":                        this._invalidate();                        break;                    case"minWidth":                    case"maxWidth":                    case"minHeight":                    case"maxHeight":                        this._renderSize(this.element().outerWidth(), this.element().outerHeight());                        break;                    case"onResize":                    case"onResizeStart":                    case"onResizeEnd":                        this._renderActions();                        break;                    case"gridStepHorizontal":                    case"gridStepVertical":                    case"area":                    case"step":                        break;                    default:                        this.callBase(args);                        break                }            },            _clean: function() {                this.element().find("." + RESIZABLE_HANDLE_CLASS).remove()            }        }))    })(jQuery, DevExpress);    /*! Module widgets-base, file ui.box.js */    (function($, DX, undefined) {        var ui = DevExpress.ui,            utils = DX.utils;        var BOX_CLASS = "dx-box",            BOX_SELECTOR = ".dx-box",            BOX_ITEM_CLASS = "dx-box-item",            BOX_ITEM_DATA_KEY = "dxBoxItemData";        var flexGrowProp = DX.support.styleProp("flexGrow");        var flexShrinkProp = DX.support.styleProp("flexShrink");        var flexPropPrefix = DX.support.stylePropPrefix("flexDirection");        var MINSIZE_MAP = {                row: "minWidth",                col: "minHeight"            };        var MAXSIZE_MAP = {                row: "maxWidth",                col: "maxHeight"            };        var SHRINK = 1;        var FLEX_JUSTIFY_CONTENT_MAP = {                start: "flex-start",                end: "flex-end",                center: "center",                "space-between": "space-between",                "space-around": "space-around"            };        var FLEX_ALIGN_ITEMS_MAP = {                start: "flex-start",                end: "flex-end",                center: "center",                stretch: "stretch"            };        var FLEX_DIRECTION_MAP = {                row: "row",                col: "column"            };        var FlexLayoutStrategy = DX.Class.inherit({                ctor: function($element, option) {                    this._$element = $element;                    this._option = option                },                renderBox: function() {                    this._$element.css({                        display: DX.support.stylePropPrefix("flexDirection") + "flex",                        flexDirection: FLEX_DIRECTION_MAP[this._option("direction")]                    })                },                renderAlign: function() {                    this._$element.css({justifyContent: this._normalizedAlign()})                },                _normalizedAlign: function() {                    var align = this._option("align");                    return align in FLEX_JUSTIFY_CONTENT_MAP ? FLEX_JUSTIFY_CONTENT_MAP[align] : align                },                renderCrossAlign: function() {                    this._$element.css({alignItems: this._normalizedCrossAlign()})                },                _normalizedCrossAlign: function() {                    var crossAlign = this._option("crossAlign");                    return crossAlign in FLEX_ALIGN_ITEMS_MAP ? FLEX_ALIGN_ITEMS_MAP[crossAlign] : crossAlign                },                renderItems: function($items) {                    var direction = this._option("direction");                    $.each($items, function() {                        var $item = $(this);                        var item = $item.data(BOX_ITEM_DATA_KEY);                        $item.css({                            display: flexPropPrefix + "flex",                            flexBasis: item.baseSize || 0                        }).css(MAXSIZE_MAP[direction], item.maxSize || "none").css(MINSIZE_MAP[direction], item.minSize || "0");                        var itemStyle = $item.get(0).style;                        itemStyle[flexGrowProp] = item.ratio;                        itemStyle[flexShrinkProp] = utils.isDefined(item.shrink) ? item.shrink : SHRINK;                        $item.children().each(function(_, itemContent) {                            $(itemContent).css({                                width: "auto",                                height: "auto",                                display: DX.support.stylePropPrefix("flexDirection") + "flex",                                flexDirection: $item.children().css("flexDirection") || "column"                            });                            itemContent.style[flexGrowProp] = 1                        })                    })                },                update: $.noop            });        var BOX_EVENTNAMESPACE = "dxBox",            UPDATE_EVENT = "dxupdate." + BOX_EVENTNAMESPACE,            FALLBACK_BOX_ITEM = "dx-box-fallback-item";        var FALLBACK_WRAP_MAP = {                row: "nowrap",                col: "normal"            };        var FALLBACK_MAIN_SIZE_MAP = {                row: "width",                col: "height"            };        var FALLBACK_CROSS_SIZE_MAP = {                row: "height",                col: "width"            };        var FALLBACK_PRE_MARGIN_MAP = {                row: "marginLeft",                col: "marginTop"            };        var FALLBACK_POST_MARGIN_MAP = {                row: "marginRight",                col: "marginBottom"            };        var FALLBACK_CROSS_PRE_MARGIN_MAP = {                row: "marginTop",                col: "marginLeft"            };        var FALLBACK_CROSS_POST_MARGIN_MAP = {                row: "marginBottom",                col: "marginRight"            };        var MARGINS_RTL_FLIP_MAP = {                marginLeft: "marginRight",                marginRight: "marginLeft"            };        var FallbackLayoutStrategy = DX.Class.inherit({                ctor: function($element, option) {                    this._$element = $element;                    this._option = option                },                renderBox: function() {                    this._$element.css({                        fontSize: 0,                        whiteSpace: FALLBACK_WRAP_MAP[this._option("direction")],                        verticalAlign: "top"                    });                    this._$element.off(UPDATE_EVENT).on(UPDATE_EVENT, $.proxy(this.update, this))                },                renderAlign: function() {                    var $items = this._$items;                    if (!$items)                        return;                    var align = this._option("align"),                        shift = 0,                        totalItemSize = this.totalItemSize,                        direction = this._option("direction"),                        boxSize = this._$element[FALLBACK_MAIN_SIZE_MAP[direction]](),                        freeSpace = boxSize - totalItemSize;                    this._setItemsMargins($items, direction, 0);                    switch (align) {                        case"start":                            break;                        case"end":                            shift = freeSpace;                            $items.first().css(this._chooseMarginSide(FALLBACK_PRE_MARGIN_MAP[direction]), shift);                            break;                        case"center":                            shift = 0.5 * freeSpace;                            $items.first().css(this._chooseMarginSide(FALLBACK_PRE_MARGIN_MAP[direction]), shift);                            $items.last().css(this._chooseMarginSide(FALLBACK_POST_MARGIN_MAP[direction]), shift);                            break;                        case"space-between":                            shift = 0.5 * freeSpace / ($items.length - 1);                            this._setItemsMargins($items, direction, shift);                            $items.first().css(this._chooseMarginSide(FALLBACK_PRE_MARGIN_MAP[direction]), 0);                            $items.last().css(this._chooseMarginSide(FALLBACK_POST_MARGIN_MAP[direction]), 0);                            break;                        case"space-around":                            shift = 0.5 * freeSpace / $items.length;                            this._setItemsMargins($items, direction, shift);                            break                    }                },                _setItemsMargins: function($items, direction, shift) {                    $items.css(this._chooseMarginSide(FALLBACK_PRE_MARGIN_MAP[direction]), shift).css(this._chooseMarginSide(FALLBACK_POST_MARGIN_MAP[direction]), shift)                },                renderCrossAlign: function() {                    var $items = this._$items;                    if (!$items)                        return;                    var crossAlign = this._option("crossAlign"),                        direction = this._option("direction"),                        size = this._$element[FALLBACK_CROSS_SIZE_MAP[direction]]();                    var that = this;                    switch (crossAlign) {                        case"start":                            break;                        case"end":                            $.each($items, function() {                                var $item = $(this),                                    itemSize = $item[FALLBACK_CROSS_SIZE_MAP[direction]](),                                    shift = size - itemSize;                                $item.css(that._chooseMarginSide(FALLBACK_CROSS_PRE_MARGIN_MAP[direction]), shift)                            });                            break;                        case"center":                            $.each($items, function() {                                var $item = $(this),                                    itemSize = $item[FALLBACK_CROSS_SIZE_MAP[direction]](),                                    shift = 0.5 * (size - itemSize);                                $item.css(that._chooseMarginSide(FALLBACK_CROSS_PRE_MARGIN_MAP[direction]), shift).css(that._chooseMarginSide(FALLBACK_CROSS_POST_MARGIN_MAP[direction]), shift)                            });                            break;                        case"stretch":                            $items.css(that._chooseMarginSide(FALLBACK_CROSS_PRE_MARGIN_MAP[direction]), 0).css(that._chooseMarginSide(FALLBACK_CROSS_POST_MARGIN_MAP[direction]), 0).css(FALLBACK_CROSS_SIZE_MAP[direction], "100%");                            break                    }                },                _chooseMarginSide: function(value) {                    if (!this._option("rtlEnabled"))                        return value;                    return MARGINS_RTL_FLIP_MAP[value] || value                },                renderItems: function($items) {                    this._$items = $items;                    var direction = this._option("direction"),                        totalRatio = 0,                        totalWeightedShrink = 0,                        totalBaseSize = 0;                    $.each($items, $.proxy(function(_, item) {                        var $item = $(item);                        $item.css({                            display: "inline-block",                            verticalAlign: "top"                        });                        $item[FALLBACK_MAIN_SIZE_MAP[direction]]("auto");                        $item.removeClass(FALLBACK_BOX_ITEM);                        var itemData = $item.data(BOX_ITEM_DATA_KEY),                            ratio = itemData.ratio || 0,                            size = this._baseSize($item),                            shrink = utils.isDefined(itemData.shrink) ? itemData.shrink : SHRINK;                        totalRatio += ratio;                        totalWeightedShrink += shrink * size;                        totalBaseSize += size                    }, this));                    var freeSpaceSize = this._boxSize() - totalBaseSize;                    var itemSize = $.proxy(function($item) {                            var itemData = $item.data(BOX_ITEM_DATA_KEY),                                size = this._baseSize($item),                                factor = freeSpaceSize >= 0 ? itemData.ratio || 0 : (utils.isDefined(itemData.shrink) ? itemData.shrink : SHRINK) * size,                                totalFactor = freeSpaceSize >= 0 ? totalRatio : totalWeightedShrink,                                shift = totalFactor ? Math.round(freeSpaceSize * factor / totalFactor) : 0;                            return size + shift                        }, this);                    var totalItemSize = 0;                    $.each($items, function(_, item) {                        var $item = $(item),                            itemData = $(item).data(BOX_ITEM_DATA_KEY),                            size = itemSize($item);                        totalItemSize += size;                        $item.css(MAXSIZE_MAP[direction], itemData.maxSize || "none").css(MINSIZE_MAP[direction], itemData.minSize || "0").css(FALLBACK_MAIN_SIZE_MAP[direction], size);                        $item.addClass(FALLBACK_BOX_ITEM)                    });                    this.totalItemSize = totalItemSize                },                _baseSize: function(item) {                    var itemData = $(item).data(BOX_ITEM_DATA_KEY);                    return itemData.baseSize == null ? 0 : itemData.baseSize === "auto" ? this._contentSize(item) : this._parseSize(itemData.baseSize)                },                _contentSize: function(item) {                    return $(item)[FALLBACK_MAIN_SIZE_MAP[this._option("direction")]]()                },                _parseSize: function(size) {                    return String(size).match(/.+%$/) ? 0.01 * parseFloat(size) * this._boxSize() : size                },                _boxSize: function() {                    return this._$element[FALLBACK_MAIN_SIZE_MAP[this._option("direction")]]()                },                _totalBaseSize: function() {                    var result = 0;                    $.each(this._$items, $.proxy(function(_, item) {                        result += this._baseSize(item)                    }, this));                    return result                },                update: function() {                    if (!this._$items || this._$element.is(":hidden"))                        return;                    this.renderItems(this._$items);                    this.renderAlign();                    this.renderCrossAlign();                    var element = this._$element.get(0);                    this._$items.find(BOX_SELECTOR).each(function() {                        if (element === $(this).parent().closest(BOX_SELECTOR).get(0))                            $(this).triggerHandler(UPDATE_EVENT)                    })                }            });        DX.registerComponent("dxBox", ui, ui.CollectionWidget.inherit({            _setDefaultOptions: function() {                this.callBase();                this.option({                    direction: "row",                    align: "start",                    crossAlign: "stretch",                    activeStateEnabled: false,                    focusStateEnabled: false,                    _layoutStrategy: "flex"                })            },            _defaultOptionsRules: function() {                return this.callBase().concat([{                            device: function() {                                var device = DX.devices.real();                                var isOldAndroid = device.platform === "android" && (device.version[0] < 4 || device.version[0] === 4 && device.version[1] < 4),                                    isOldIos = device.platform === "ios" && device.version[0] < 7;                                return device.platform === "win8" || DX.browser["msie"] || isOldAndroid || isOldIos                            },                            options: {_layoutStrategy: "fallback"}                        }])            },            _itemClass: function() {                return BOX_ITEM_CLASS            },            _itemDataKey: function() {                return BOX_ITEM_DATA_KEY            },            _itemElements: function() {                return this._itemContainer().children(this._itemSelector())            },            _init: function() {                this.callBase();                this.element().addClass(BOX_CLASS + "-" + this.option("_layoutStrategy"));                this._initLayout()            },            _initLayout: function() {                this._layout = this.option("_layoutStrategy") === "fallback" ? new FallbackLayoutStrategy(this.element(), $.proxy(this.option, this)) : new FlexLayoutStrategy(this.element(), $.proxy(this.option, this))            },            _render: function() {                this.callBase();                this.element().addClass(BOX_CLASS);                this._renderBox()            },            _renderBox: function() {                this._layout.renderBox();                this._layout.renderAlign();                this._layout.renderCrossAlign()            },            _renderItems: function(items) {                this.callBase(items);                this._layout.renderItems(this._itemElements());                clearTimeout(this._updateTimer);                this._updateTimer = setTimeout($.proxy(function() {                    if (!this._isUpdated)                        this._layout.update();                    this._isUpdated = false                }, this))            },            _postprocessRenderItem: function(args) {                var boxConfig = args.itemData.box;                if (!boxConfig)                    return;                this._createComponent(args.itemContent, "dxBox", $.extend({                    itemTemplate: this.option("itemTemplate"),                    itemHoldTimeout: this.option("itemHoldTimeout"),                    onItemHold: this.option("onItemHold"),                    onItemClick: this.option("onItemClick"),                    onItemContextMenu: this.option("onItemContextMenu"),                    onItemRendered: this.option("onItemRendered")                }, boxConfig))            },            _createItemByTemplate: function(itemTemplate, args) {                return args.item.box ? itemTemplate.source() : this.callBase(itemTemplate, args)            },            _visibilityChanged: function(visible) {                if (visible)                    this._dimensionChanged()            },            _dimensionChanged: function() {                this._isUpdated = true;                this._layout.update()            },            _dispose: function() {                clearTimeout(this._updateTimer);                this.callBase.apply(this, arguments)            },            _optionChanged: function(args) {                switch (args.name) {                    case"_layoutStrategy":                    case"direction":                        this._invalidate();                        break;                    case"align":                        this._layout.renderAlign();                        break;                    case"crossAlign":                        this._layout.renderCrossAlign();                        break;                    default:                        this.callBase(args)                }            },            repaint: function() {                this._dimensionChanged()            }        }))    })(jQuery, DevExpress);    /*! Module widgets-base, file ui.responsiveBox.js */    (function($, DX, undefined) {        var ui = DX.ui;        var RESPONSIVE_BOX_CLASS = "dx-responsivebox",            BOX_ITEM_CLASS = "dx-box-item",            BOX_ITEM_DATA_KEY = "dxBoxItemData";        var DEFAULT_SCREEN_FACTOR_FUNC = function(width) {                if (width < 768)                    return "xs";                else if (width < 992)                    return "sm";                else if (width < 1200)                    return "md";                else                    return "lg"            };        DX.registerComponent("dxResponsiveBox", ui, ui.CollectionWidget.inherit({            _setDefaultOptions: function() {                this.callBase();                this.option({                    rows: [],                    cols: [],                    screenByWidth: DEFAULT_SCREEN_FACTOR_FUNC,                    singleColumnScreen: "xs",                    activeStateEnabled: false,                    focusStateEnabled: false                })            },            _initOptions: function(options) {                if (options.screenByWidth)                    this.option("singleColumnScreen", options.screenByWidth(0));                this.callBase(options)            },            _itemClass: function() {                return BOX_ITEM_CLASS            },            _itemDataKey: function() {                return BOX_ITEM_DATA_KEY            },            _render: function() {                this.callBase();                this.element().addClass(RESPONSIVE_BOX_CLASS);                this._updateRootBox()            },            _updateRootBox: function() {                clearTimeout(this._updateTimer);                this._updateTimer = setTimeout($.proxy(function() {                    if (this._$root)                        this._$root.trigger("dxupdate")                }, this))            },            _renderItems: function() {                this._screenItems = this._itemsByScreen();                this._prepareGrid();                this._spreadItems();                this._layoutItems();                this._linkNodeToItem()            },            _prepareGrid: function() {                var grid = this._grid = [];                this._prepareRowsAndCols();                $.each(this._rows, $.proxy(function() {                    var row = [];                    grid.push(row);                    $.each(this._cols, $.proxy(function() {                        row.push(this._createEmptyCell())                    }, this))                }, this))            },            _prepareRowsAndCols: function() {                if (this._isSingleColumnScreen()) {                    this._prepareSingleColumnScreenItems();                    this._rows = this._defaultSizeConfig(this._screenItems.length);                    this._cols = this._defaultSizeConfig(1)                }                else {                    this._rows = this._sizesByScreen(this.option("rows"));                    this._cols = this._sizesByScreen(this.option("cols"))                }            },            _isSingleColumnScreen: function() {                return this._screenRegExp().test(this.option("singleColumnScreen")) || !this.option("rows").length || !this.option("cols").length            },            _prepareSingleColumnScreenItems: function() {                this._screenItems.sort(function(item1, item2) {                    return item1.location.row - item2.location.row || item1.location.col - item2.location.col                });                $.each(this._screenItems, function(index, item) {                    $.extend(item.location, {                        row: index,                        col: 0,                        rowspan: 1,                        colspan: 1                    })                })            },            _sizesByScreen: function(sizeConfigs) {                return $.map(this._filterByScreen(sizeConfigs), $.proxy(function(sizeConfig) {                        return $.extend(this._defaultSizeConfig(), sizeConfig)                    }, this))            },            _defaultSizeConfig: function(size) {                var defaultSizeConfig = {                        ratio: 1,                        baseSize: 0,                        minSize: 0,                        maxSize: 0                    };                if (!arguments.length)                    return defaultSizeConfig;                var result = [];                for (var i = 0; i < size; i++)                    result.push(defaultSizeConfig);                return result            },            _filterByScreen: function(items) {                var screenRegExp = this._screenRegExp();                return $.grep(items, function(item) {                        return !item.screen || screenRegExp.test(item.screen)                    })            },            _screenRegExp: function() {                var width = this._screenWidth();                var screen = this.option("screenByWidth")(width);                return new RegExp("(^|\\s)" + screen + "($|\\s)", "i")            },            _screenWidth: function() {                return $(window).width()            },            _createEmptyCell: function() {                return {                        item: {},                        location: {                            colspan: 1,                            rowspan: 1                        }                    }            },            _spreadItems: function() {                $.each(this._screenItems, $.proxy(function(_, itemInfo) {                    var location = itemInfo.location || {};                    var itemCol = location.col;                    var itemRow = location.row;                    var row = this._grid[itemRow];                    var itemCell = row && row[itemCol];                    this._occupyCells(itemCell, itemInfo)                }, this))            },            _itemsByScreen: function() {                return $.map(this.option("items"), $.proxy(function(item) {                        var locations = item.location || {};                        locations = $.isPlainObject(locations) ? [locations] : locations;                        return $.map(this._filterByScreen(locations), function(location) {                                return {                                        item: item,                                        location: $.extend({                                            rowspan: 1,                                            colspan: 1                                        }, location)                                    }                            })                    }, this))            },            _occupyCells: function(itemCell, itemInfo) {                if (!itemCell || this._isItemCellOccupied(itemCell, itemInfo))                    return;                $.extend(itemCell, itemInfo);                this._markSpanningCell(itemCell)            },            _isItemCellOccupied: function(itemCell, itemInfo) {                if (!$.isEmptyObject(itemCell.item))                    return true;                var result = false;                this._loopOverSpanning(itemInfo.location, function(cell) {                    result = result || !$.isEmptyObject(cell.item)                });                return result            },            _loopOverSpanning: function(location, callback) {                var rowEnd = location.row + location.rowspan - 1;                var colEnd = location.col + location.colspan - 1;                var boundRowEnd = Math.min(rowEnd, this._rows.length - 1);                var boundColEnd = Math.min(colEnd, this._cols.length - 1);                location.rowspan -= rowEnd - boundRowEnd;                location.colspan -= colEnd - boundColEnd;                for (var rowIndex = location.row; rowIndex <= boundRowEnd; rowIndex++)                    for (var colIndex = location.col; colIndex <= boundColEnd; colIndex++)                        if (rowIndex !== location.row || colIndex !== location.col)                            callback(this._grid[rowIndex][colIndex])            },            _markSpanningCell: function(itemCell) {                this._loopOverSpanning(itemCell.location, function(cell) {                    $.extend(cell, {                        item: itemCell.item,                        spanningCell: itemCell                    })                })            },            _linkNodeToItem: function() {                $.each(this._itemElements(), function(_, itemNode) {                    var $item = $(itemNode),                        item = $item.data(BOX_ITEM_DATA_KEY);                    if (!item.box)                        item.node = $item.children()                })            },            _layoutItems: function() {                var rowsCount = this._grid.length;                var colsCount = rowsCount && this._grid[0].length;                if (!rowsCount && !colsCount)                    return;                var result = this._layoutBlock({                        direction: "col",                        row: {                            start: 0,                            end: rowsCount - 1                        },                        col: {                            start: 0,                            end: colsCount - 1                        }                    });                var rootBox = this._prepareBoxConfig(result.box || {                        direction: "col",                        items: [result]                    });                $.extend(rootBox, this._rootBoxConfig());                this._$root = $("<div>").appendTo(this._itemContainer());                this._createComponent(this._$root, "dxBox", rootBox)            },            _rootBoxConfig: function(config) {                return {                        width: "100%",                        height: "100%",                        itemTemplate: this.option("itemTemplate"),                        itemHoldTimeout: this.option("itemHoldTimeout"),                        onItemHold: this.option("onItemHold"),                        onItemClick: this.option("onItemClick"),                        onItemContextMenu: this.option("onItemContextMenu"),                        onItemRendered: this.option("onItemRendered")                    }            },            _prepareBoxConfig: function(config) {                return $.extend(config || {}, {crossAlign: "stretch"})            },            _layoutBlock: function(options) {                if (this._isSingleItem(options))                    return this._itemByCell(options.row.start, options.col.start);                return this._layoutDirection(options)            },            _isSingleItem: function(options) {                var firstCellLocation = this._grid[options.row.start][options.col.start].location;                var isItemRowSpanned = options.row.end - options.row.start === firstCellLocation.rowspan - 1;                var isItemColSpanned = options.col.end - options.col.start === firstCellLocation.colspan - 1;                return isItemRowSpanned && isItemColSpanned            },            _itemByCell: function(rowIndex, colIndex) {                var itemCell = this._grid[rowIndex][colIndex];                return itemCell.spanningCell ? null : itemCell.item            },            _layoutDirection: function(options) {                var items = [];                var direction = options.direction;                var crossDirection = this._crossDirection(direction);                var block;                while (block = this._nextBlock(options)) {                    if (this._isBlockIndivisible(options.prevBlockOptions, block))                        throw DX.Error("E1025");                    var item = this._layoutBlock({                            direction: crossDirection,                            row: block.row,                            col: block.col,                            prevBlockOptions: options                        });                    if (item) {                        $.extend(item, this._blockSize(block, crossDirection));                        items.push(item)                    }                    options[crossDirection].start = block[crossDirection].end + 1                }                return {box: this._prepareBoxConfig({                            direction: direction,                            items: items                        })}            },            _isBlockIndivisible: function(options, block) {                return options && options.col.start === block.col.start && options.col.end === block.col.end && options.row.start === block.row.start && options.row.end === block.row.end            },            _crossDirection: function(direction) {                return direction === "col" ? "row" : "col"            },            _nextBlock: function(options) {                var direction = options.direction;                var crossDirection = this._crossDirection(direction);                var startIndex = options[direction].start;                var endIndex = options[direction].end;                var crossStartIndex = options[crossDirection].start;                if (crossStartIndex > options[crossDirection].end)                    return null;                var crossSpan = 1;                for (var crossIndex = crossStartIndex; crossIndex < crossStartIndex + crossSpan; crossIndex++) {                    var lineCrossSpan = 1;                    for (var index = startIndex; index <= endIndex; index++) {                        var cell = this._cellByDirection(direction, index, crossIndex);                        lineCrossSpan = Math.max(lineCrossSpan, cell.location[crossDirection + "span"])                    }                    var lineCrossEndIndex = crossIndex + lineCrossSpan;                    var crossEndIndex = crossStartIndex + crossSpan;                    if (lineCrossEndIndex > crossEndIndex)                        crossSpan += lineCrossEndIndex - crossEndIndex                }                var result = {};                result[direction] = {                    start: startIndex,                    end: endIndex                };                result[crossDirection] = {                    start: crossStartIndex,                    end: crossStartIndex + crossSpan - 1                };                return result            },            _cellByDirection: function(direction, index, crossIndex) {                return direction === "col" ? this._grid[crossIndex][index] : this._grid[index][crossIndex]            },            _blockSize: function(block, direction) {                var sizeConfigs = direction === "row" ? this._rows : this._cols;                var result = {                        ratio: 0,                        baseSize: 0,                        minSize: 0,                        maxSize: 0                    };                for (var index = block[direction].start; index <= block[direction].end; index++) {                    var sizeConfig = sizeConfigs[index];                    result.ratio += sizeConfig.ratio;                    result.baseSize += sizeConfig.baseSize;                    result.minSize += sizeConfig.minSize;                    result.maxSize += sizeConfig.maxSize                }                result.minSize = result.minSize ? result.minSize : "auto";                result.maxSize = result.maxSize ? result.maxSize : "auto";                this._isSingleColumnScreen() && (result.baseSize = 'auto');                return result            },            _update: function() {                var $existingRoot = this._$root;                this._renderItems();                $existingRoot.remove()            },            _dispose: function() {                clearTimeout(this._updateTimer);                this.callBase.apply(this, arguments)            },            _optionChanged: function(args) {                switch (args.name) {                    case"rows":                    case"cols":                    case"screenByWidth":                    case"singleColumnScreen":                        this._invalidate();                        break;                    case"width":                    case"height":                        this.callBase(args);                        this._update();                        break;                    default:                        this.callBase(args)                }            },            _dimensionChanged: function() {                this._update()            },            repaint: function() {                this._update()            }        }))    })(jQuery, DevExpress);    /*! Module widgets-base, file ui.button.js */    (function($, DX, undefined) {        var ui = DX.ui,            events = ui.events,            utils = DX.utils;        var BUTTON_CLASS = "dx-button",            BUTTON_CONTENT_CLASS = "dx-button-content",            BUTTON_HAS_TEXT_CLASS = "dx-button-has-text",            BUTTON_HAS_ICON_CLASS = "dx-button-has-icon",            TEMPLATE_WRAPPER_CLASS = "dx-template-wrapper",            BUTTON_FEEDBACK_HIDE_TIMEOUT = 100;        DX.registerComponent("dxButton", ui, ui.Widget.inherit({            _supportedKeys: function() {                var that = this,                    click = function(e) {                        e.preventDefault();                        that._executeClickAction(e)                    };                return $.extend(this.callBase(), {                        space: click,                        enter: click                    })            },            _setDeprecatedOptions: function() {                this.callBase();                $.extend(this._deprecatedOptions, {                    clickAction: {                        since: "14.2",                        alias: "onClick"                    },                    iconSrc: {                        since: "15.1",                        alias: "icon"                    }                })            },            _setDefaultOptions: function() {                this.callBase();                this.option({                    onClick: null,                    type: "normal",                    text: "",                    icon: "",                    validationGroup: undefined,                    activeStateEnabled: true,                    template: "content"                })            },            _defaultOptionsRules: function() {                return this.callBase().concat([{                            device: function(device) {                                return DX.devices.real().generic && !DX.devices.isSimulator()                            },                            options: {                                hoverStateEnabled: true,                                focusStateEnabled: true                            }                        }])            },            _init: function() {                this.callBase();                this._feedbackHideTimeout = BUTTON_FEEDBACK_HIDE_TIMEOUT            },            _render: function() {                this.callBase();                this.element().addClass(BUTTON_CLASS);                this._renderType();                this._renderClick();                this.setAria("role", "button");                this._updateAriaLabel()            },            _renderContentImpl: function() {                var $content = $("<div>").addClass(BUTTON_CONTENT_CLASS),                    data = this._getContentData();                this.element().empty();                this.element().append($content);                this.element().toggleClass(BUTTON_HAS_ICON_CLASS, !!data.icon);                this.element().toggleClass(BUTTON_HAS_TEXT_CLASS, !!data.text);                var template = this._getTemplateByOption("template");                var $result = template.render(data, $content);                if ($result.hasClass(TEMPLATE_WRAPPER_CLASS)) {                    $content.replaceWith($result);                    $content = $result;                    $content.addClass(BUTTON_CONTENT_CLASS)                }            },            _getContentData: function() {                var icon = this.option("icon"),                    text = this.option("text"),                    back = this.option("type") === "back";                if (back && !icon)                    icon = "back";                if (back && !text)                    text = DX.localization.localizeString("@Back");                return {                        icon: icon,                        text: text                    }            },            _renderClick: function() {                var that = this,                    eventName = events.addNamespace("dxclick", this.NAME);                this._clickAction = this._createActionByOption("onClick");                this.element().off(eventName).on(eventName, function(e) {                    that._executeClickAction(e)                })            },            _executeClickAction: function(e) {                this._clickAction({                    jQueryEvent: e,                    validationGroup: DX.validationEngine.getGroupConfig(this._findGroup())                })            },            _updateAriaLabel: function() {                var icon = this.option("icon"),                    text = this.option("text");                icon = utils.getImageSourceType(icon) === "image" ? icon.replace(/.+\/([^\.]+)\..+$/, "$1") : icon;                var ariaLabel = text || icon;                this.setAria("label", $.trim(ariaLabel))            },            _renderType: function() {                var type = this.option("type");                if (type)                    this.element().addClass("dx-button-" + type)            },            _refreshType: function(prevType) {                var type = this.option("type");                prevType && this.element().removeClass("dx-button-" + prevType).addClass("dx-button-" + type);                if (!this.element().hasClass("dx-button-has-icon") && type === "back")                    this._renderContentImpl()            },            _optionChanged: function(args) {                switch (args.name) {                    case"onClick":                        this._renderClick();                        break;                    case"icon":                    case"text":                        this._renderContentImpl();                        this._updateAriaLabel();                        break;                    case"type":                        this._refreshType(args.previousValue);                        this._updateAriaLabel();                        break;                    case"template":                        this._renderContentImpl();                        break;                    default:                        this.callBase(args)                }            },            _findGroup: DX.ui.validation.findGroup        }))    })(jQuery, DevExpress);    /*! Module widgets-base, file ui.checkBox.js */    (function($, DX, undefined) {        var ui = DX.ui,            events = ui.events;        var CHECKBOX_CLASS = "dx-checkbox",            CHECKBOX_ICON_CLASS = "dx-checkbox-icon",            CHECKBOX_CHECKED_CLASS = "dx-checkbox-checked",            CHECKBOX_CONTAINER_CLASS = "dx-checkbox-container",            CHECKBOX_CONTAINER_SELECTOR = ".dx-checkbox-container",            CHECKBOX_TEXT_CLASS = "dx-checkbox-text",            CHECKBOX_TEXT_SELECTOR = ".dx-checkbox-text",            CHECKBOX_HAS_TEXT_CLASS = "dx-checkbox-has-text",            CHECKBOX_INDETERMINATE_CLASS = "dx-checkbox-indeterminate",            CHECKBOX_FEEDBACK_HIDE_TIMEOUT = 100,            CHECKBOX_DXCLICK_EVENT_NAME = events.addNamespace("dxclick", "dxCheckBox");        DX.registerComponent("dxCheckBox", ui, ui.Editor.inherit({            _supportedKeys: function() {                var click = function(e) {                        e.preventDefault();                        this._clickAction({jQueryEvent: e})                    };                return $.extend(this.callBase(), {space: click})            },            _setDefaultOptions: function() {                this.callBase();                this.option({                    value: false,                    text: ""                })            },            _defaultOptionsRules: function() {                return this.callBase().concat([{                            device: function(device) {                                return DX.devices.real().generic && !DX.devices.isSimulator()                            },                            options: {                                hoverStateEnabled: true,                                focusStateEnabled: true                            }                        }])            },            _init: function() {                this.callBase();                this._feedbackHideTimeout = CHECKBOX_FEEDBACK_HIDE_TIMEOUT            },            _render: function() {                this.callBase();                this.element().addClass(CHECKBOX_CLASS).append($("<div>").addClass(CHECKBOX_CONTAINER_CLASS));                this.setAria("role", "checkbox");                this._$container = this.element().find(CHECKBOX_CONTAINER_SELECTOR);                this._renderClick();                this._renderValue();                this._renderIcon();                this._renderText()            },            _renderDimensions: function() {                this.callBase()            },            _renderIcon: function() {                this._$icon = $("<span>").addClass(CHECKBOX_ICON_CLASS).prependTo(this._$container)            },            _renderText: function() {                this._$text = this._$container.find(CHECKBOX_TEXT_SELECTOR);                if (!this.option("text")) {                    if (this._$text) {                        this._$text.remove();                        this.element().removeClass(CHECKBOX_HAS_TEXT_CLASS)                    }                    return                }                if (!this._$text.length)                    this._$text = $("<span>").addClass(CHECKBOX_TEXT_CLASS);                this._$text.text(this.option("text"));                this._$container.append(this._$text);                this.element().addClass(CHECKBOX_HAS_TEXT_CLASS)            },            _renderClick: function() {                this._clickAction = this._createAction(this._clickHandler);                this.element().off(CHECKBOX_DXCLICK_EVENT_NAME).on(CHECKBOX_DXCLICK_EVENT_NAME, $.proxy(function(e) {                    this._clickAction({jQueryEvent: e})                }, this))            },            _clickHandler: function(args) {                var that = args.component;                that._saveValueChangeEvent(args.jQueryEvent);                that.option("value", !that.option("value"))            },            _renderValue: function() {                var $element = this.element(),                    checked = this.option("value"),                    indeterminate = checked === undefined;                $element.toggleClass(CHECKBOX_CHECKED_CLASS, Boolean(checked));                $element.toggleClass(CHECKBOX_INDETERMINATE_CLASS, indeterminate);                this.setAria("checked", indeterminate ? "mixed" : checked || "false")            },            _optionChanged: function(args) {                switch (args.name) {                    case"value":                        this._renderValue();                        this.callBase(args);                        break;                    case"text":                        this._renderText();                        this._renderDimensions();                        break;                    default:                        this.callBase(args)                }            }        }))    })(jQuery, DevExpress);    /*! Module widgets-base, file ui.switch.js */    (function($, DX, undefined) {        var ui = DX.ui,            events = ui.events,            fx = DX.fx;        var SWITCH_CLASS = "dx-switch",            SWITCH_WRAPPER_CLASS = SWITCH_CLASS + "-wrapper",            SWITCH_CONTAINER_CLASS = SWITCH_CLASS + "-container",            SWITCH_INNER_CLASS = SWITCH_CLASS + "-inner",            SWITCH_HANDLE_CLASS = SWITCH_CLASS + "-handle",            SWITCH_ON_VALUE_CLASS = SWITCH_CLASS + "-on-value",            SWITCH_ON_CLASS = SWITCH_CLASS + "-on",            SWITCH_OFF_CLASS = SWITCH_CLASS + "-off",            SWITCH_ANIMATION_DURATION = 100;        DX.registerComponent("dxSwitch", ui, ui.Editor.inherit({            _supportedKeys: function() {                var isRTL = this.option("rtlEnabled");                var click = function(e) {                        e.preventDefault();                        this._clickAction({jQueryEvent: e})                    },                    move = function(value, e) {                        e.preventDefault();                        e.stopPropagation();                        this._animateValue(value)                    };                return $.extend(this.callBase(), {                        space: click,                        enter: click,                        leftArrow: $.proxy(move, this, isRTL ? true : false),                        rightArrow: $.proxy(move, this, isRTL ? false : true)                    })            },            _setDefaultOptions: function() {                this.callBase();                this.option({                    onText: Globalize.localize("dxSwitch-onText"),                    offText: Globalize.localize("dxSwitch-offText"),                    value: false                })            },            _defaultOptionsRules: function() {                return this.callBase().concat([{                            device: function(device) {                                return DX.devices.real().generic && !DX.devices.isSimulator()                            },                            options: {                                hoverStateEnabled: true,                                focusStateEnabled: true                            }                        }])            },            _init: function() {                this.callBase();                this._animating = false;                this._animationDuration = SWITCH_ANIMATION_DURATION            },            _render: function() {                var element = this.element();                this._$switchInner = $("<div>").addClass(SWITCH_INNER_CLASS);                this._$handle = $("<div>").addClass(SWITCH_HANDLE_CLASS).appendTo(this._$switchInner);                this._$labelOn = $("<div>").addClass(SWITCH_ON_CLASS).prependTo(this._$switchInner);                this._$labelOff = $("<div>").addClass(SWITCH_OFF_CLASS).appendTo(this._$switchInner);                this._$switchContainer = $("<div>").addClass(SWITCH_CONTAINER_CLASS).append(this._$switchInner);                this._$switchWrapper = $("<div>").addClass(SWITCH_WRAPPER_CLASS).append(this._$switchContainer);                element.addClass(SWITCH_CLASS).append(this._$switchWrapper);                this.setAria("role", "button");                this._createComponent(element, "dxSwipeable", {                    elastic: false,                    immediate: true,                    onStart: $.proxy(this._swipeStartHandler, this),                    onUpdated: $.proxy(this._swipeUpdateHandler, this),                    onEnd: $.proxy(this._swipeEndHandler, this)                });                this._renderLabels();                this.callBase();                this._updateMarginBound();                this._renderValue();                this._renderClick()            },            _updateMarginBound: function() {                this._marginBound = this._$switchContainer.outerWidth(true) - this._$handle.outerWidth()            },            _marginDirection: function() {                return this.option("rtlEnabled") ? "Right" : "Left"            },            _offsetDirection: function() {                return this.option("rtlEnabled") ? -1 : 1            },            _renderPosition: function(state, swipeOffset) {                var stateInt = state ? 1 : 0,                    marginDirection = this._marginDirection(),                    resetMarginDirection = marginDirection === "Left" ? "Right" : "Left";                this._$switchInner.css("margin" + marginDirection, this._marginBound * (stateInt + swipeOffset - 1));                this._$switchInner.css("margin" + resetMarginDirection, 0)            },            _validateValue: function() {                var check = this.option("value");                if (typeof check !== "boolean")                    this._options["value"] = !!check            },            _renderClick: function() {                var eventName = events.addNamespace("dxclick", this.NAME);                this._clickAction = this._createAction($.proxy(this._clickHandler, this));                this.element().off(eventName).on(eventName, $.proxy(function(e) {                    this._clickAction({jQueryEvent: e})                }, this))            },            _clickHandler: function(args) {                var e = args.jQueryEvent;                this._saveValueChangeEvent(e);                if (this._animating || this._swiping)                    return;                this._animateValue(!this.option("value"))            },            _animateValue: function(value) {                var startValue = this.option("value"),                    endValue = value;                if (startValue === endValue)                    return;                this._animating = true;                var that = this,                    marginDirection = this._marginDirection(),                    resetMarginDirection = marginDirection === "Left" ? "Right" : "Left",                    fromConfig = {},                    toConfig = {};                this._$switchInner.css("margin" + resetMarginDirection, 0);                fromConfig["margin" + marginDirection] = (Number(startValue) - 1) * this._marginBound;                toConfig["margin" + marginDirection] = (Number(endValue) - 1) * this._marginBound;                fx.animate(this._$switchInner, {                    from: fromConfig,                    to: toConfig,                    duration: this._animationDuration,                    complete: function() {                        that._animating = false;                        that.option("value", endValue)                    }                })            },            _swipeStartHandler: function(e) {                var state = this.option("value"),                    rtlEnabled = this.option("rtlEnabled"),                    maxOffOffset = rtlEnabled ? 0 : 1,                    maxOnOffset = rtlEnabled ? 1 : 0;                e.jQueryEvent.maxLeftOffset = state ? maxOffOffset : maxOnOffset;                e.jQueryEvent.maxRightOffset = state ? maxOnOffset : maxOffOffset;                this._swiping = true;                this._toggleActiveState(this.element(), true)            },            _swipeUpdateHandler: function(e) {                this._renderPosition(this.option("value"), this._offsetDirection() * e.jQueryEvent.offset)            },            _swipeEndHandler: function(e) {                var that = this,                    offsetDirection = this._offsetDirection(),                    toConfig = {};                toConfig["margin" + this._marginDirection()] = this._marginBound * (that.option("value") + offsetDirection * e.jQueryEvent.targetOffset - 1);                fx.animate(this._$switchInner, {                    to: toConfig,                    duration: that._animationDuration,                    complete: function() {                        that._swiping = false;                        var pos = that.option("value") + offsetDirection * e.jQueryEvent.targetOffset;                        that.option("value", Boolean(pos));                        that._toggleActiveState(that.element(), false)                    }                })            },            _renderValue: function() {                this._validateValue();                var val = this.option("value");                this._renderPosition(val, 0);                this.element().toggleClass(SWITCH_ON_VALUE_CLASS, val);                this.setAria({                    pressed: val,                    label: val ? this.option("onText") : this.option("offText")                })            },            _renderLabels: function() {                this._$labelOn.text(this.option("onText"));                this._$labelOff.text(this.option("offText"))            },            _visibilityChanged: function(visible) {                if (visible)                    this.repaint()            },            _optionChanged: function(args) {                switch (args.name) {                    case"visible":                    case"width":                        this._refresh();                        break;                    case"onText":                    case"offText":                        this._renderLabels();                        break;                    case"value":                        this._renderValue();                        this.callBase(args);                        break;                    default:                        this.callBase(args)                }            }        }))    })(jQuery, DevExpress);    /*! Module widgets-base, file ui.textEditor.js */    (function($, DX, undefined) {        var ui = DX.ui,            events = ui.events,            inflector = DX.inflector;        var TEXTEDITOR_CLASS = "dx-texteditor",            TEXTEDITOR_INPUT_CLASS = "dx-texteditor-input",            TEXTEDITOR_INPUT_SELECTOR = "." + TEXTEDITOR_INPUT_CLASS,            TEXTEDITOR_CONTAINER_CLASS = "dx-texteditor-container",            TEXTEDITOR_BUTTONS_CONTAINER_CLASS = "dx-texteditor-buttons-container",            TEXTEDITOR_PLACEHOLDER_CLASS = "dx-placeholder",            TEXTEDITOR_SHOW_CLEAR_BUTTON_CLASS = "dx-show-clear-button",            TEXTEDITOR_ICON_CLASS = "dx-icon",            TEXTEDITOR_CLEAR_ICON_CLASS = "dx-icon-clear",            TEXTEDITOR_CLEAR_BUTTON_CLASS = "dx-clear-button-area",            TEXTEDITOR_EMPTY_INPUT_CLASS = "dx-texteditor-empty",            TEXTEDITOR_STATE_FOCUSED_CLASS = "dx-state-focused",            EVENTS_LIST = ["keyDown", "keyPress", "keyUp", "change", "cut", "copy", "paste", "input"];        DX.registerComponent("dxTextEditor", ui, ui.Editor.inherit({            _supportedKeys: function() {                var stop = function(e) {                        e.stopPropagation()                    };                return {                        space: stop,                        enter: stop,                        leftArrow: stop,                        rightArrow: stop                    }            },            _setDeprecatedOptions: function() {                this.callBase();                $.extend(this._deprecatedOptions, {                    keyDownAction: {                        since: "14.2",                        alias: "onKeyDown"                    },                    keyPressAction: {                        since: "14.2",                        alias: "onKeyPress"                    },                    keyUpAction: {                        since: "14.2",                        alias: "onKeyUp"                    },                    cutAction: {                        since: "14.2",                        alias: "onCut"                    },                    copyAction: {                        since: "14.2",                        alias: "onCopy"                    },                    pasteAction: {                        since: "14.2",                        alias: "onPaste"                    },                    changeAction: {                        since: "14.2",                        alias: "onChange"                    },                    inputAction: {                        since: "14.2",                        alias: "onInput"                    },                    focusInAction: {                        since: "14.2",                        alias: "onFocusIn"                    },                    focusOutAction: {                        since: "14.2",                        alias: "onFocusOut"                    },                    enterKeyAction: {                        since: "14.2",                        alias: "onEnterKey"                    }                })            },            _setDefaultOptions: function() {                this.callBase();                this.option({                    value: "",                    spellcheck: false,                    showClearButton: false,                    valueChangeEvent: "change",                    placeholder: "",                    attr: {},                    onFocusIn: null,                    onFocusOut: null,                    onKeyDown: null,                    onKeyPress: null,                    onKeyUp: null,                    onChange: null,                    onInput: null,                    onCut: null,                    onCopy: null,                    onPaste: null,                    onEnterKey: null,                    mode: "text",                    hoverStateEnabled: true,                    focusStateEnabled: true,                    text: undefined,                    valueFormat: function(value) {                        return value                    }                })            },            _input: function() {                return this.element().find(TEXTEDITOR_INPUT_SELECTOR).first()            },            _inputWrapper: function() {                return this.element()            },            _buttonsContainer: function() {                return this._inputWrapper().find("." + TEXTEDITOR_BUTTONS_CONTAINER_CLASS)            },            _render: function() {                this.element().addClass(TEXTEDITOR_CLASS);                this._renderInput();                this._renderInputType();                this._renderValue();                this._renderProps();                this._renderPlaceholder();                this._renderEvents();                this._renderEnterKeyAction();                this._renderEmptinessEvent();                this.callBase()            },            _renderInput: function() {                $("<div>").addClass(TEXTEDITOR_CONTAINER_CLASS).append(this._createInput()).append($("<div>").addClass(TEXTEDITOR_BUTTONS_CONTAINER_CLASS)).appendTo(this.element())            },            _createInput: function() {                return $("<input>").addClass(TEXTEDITOR_INPUT_CLASS).attr("autocomplete", "off").attr(this.option("attr"))            },            _renderValue: function() {                this._renderInputValue();                this._renderInputAddons()            },            _renderInputValue: function() {                var text = this.option("text"),                    value = this.option("value"),                    displayValue = this.option("displayValue"),                    valueFormat = this.option("valueFormat");                if (displayValue !== undefined)                    text = valueFormat(displayValue);                else if (!DX.utils.isDefined(text))                    text = valueFormat(value);                if (this._input().val() !== (DX.utils.isDefined(text) ? text : ""))                    this._renderDisplayText(text)            },            _renderDisplayText: function(text) {                this._input().val(text);                this._toggleEmptinessEventHandler()            },            _isValueValid: function() {                var validity = this._input().get(0).validity;                if (validity)                    return validity.valid;                return true            },            _toggleEmptiness: function(isEmpty) {                this.element().toggleClass(TEXTEDITOR_EMPTY_INPUT_CLASS, isEmpty);                this._togglePlaceholder(isEmpty)            },            _togglePlaceholder: function(isEmpty) {                if (!this._$placeholder)                    return;                if (DX.browser["msie"])                    this._$placeholder.toggle(!this._input().is(":focus") && isEmpty);                else                    this._$placeholder.toggle(isEmpty)            },            _renderProps: function() {                this._toggleDisabledState(this.option("disabled"));                this._toggleReadOnlyState(this._readOnlyPropValue());                this._toggleSpellcheckState()            },            _toggleDisabledState: function() {                this.callBase.apply(this, arguments);                var $input = this._input();                if (this.option("disabled"))                    $input.attr("disabled", true).attr("tabindex", -1);                else                    $input.removeAttr("disabled").removeAttr("tabindex")            },            _toggleReadOnlyState: function(value) {                this._input().prop("readOnly", value);                this.callBase()            },            _readOnlyPropValue: function() {                return this.option("readOnly")            },            _toggleSpellcheckState: function() {                this._input().prop("spellcheck", this.option("spellcheck"))            },            _renderPlaceholder: function() {                if (this._$placeholder) {                    this._$placeholder.remove();                    this._$placeholder = null                }                var that = this,                    $input = that._input(),                    placeholderText = that.option("placeholder"),                    $placeholder = this._$placeholder = $('<div>').attr("data-dx_placeholder", placeholderText),                    startEvent = events.addNamespace("dxpointerup", this.NAME);                $placeholder.on(startEvent, function() {                    $input.focus()                });                $placeholder.insertAfter($input);                $placeholder.addClass(TEXTEDITOR_PLACEHOLDER_CLASS)            },            _placeholder: function() {                return this._$placeholder || $()            },            _renderInputAddons: function() {                this._renderClearButton()            },            _checkIfClearButtonShouldBeRendered: function() {                return this.option("showClearButton") && !this.option("readOnly")            },            _renderClearButton: function() {                var shouldClearButtonBeRendered = this._checkIfClearButtonShouldBeRendered();                this.element().toggleClass(TEXTEDITOR_SHOW_CLEAR_BUTTON_CLASS, shouldClearButtonBeRendered);                if (!shouldClearButtonBeRendered) {                    this._$clearButton && this._$clearButton.remove();                    this._$clearButton = null;                    return                }                if (this._$clearButton)                    return;                this._$clearButton = this._createClearButton()            },            _createClearButton: function() {                return $("<span>").addClass(TEXTEDITOR_CLEAR_BUTTON_CLASS).append($("<span>").addClass(TEXTEDITOR_ICON_CLASS).addClass(TEXTEDITOR_CLEAR_ICON_CLASS)).prependTo(this._buttonsContainer()).on(events.addNamespace("dxpointerdown", this.NAME), function(e) {                        e.preventDefault();                        e.dxPreventBlur = true                    }).on(events.addNamespace("dxclick", this.NAME), $.proxy(this._clearValueHandler, this))            },            _clearValueHandler: function(e) {                var $input = this._input();                e.stopPropagation();                this.reset();                if ($input.is(":focus")) {                    $input.val("");                    this._toggleEmptinessEventHandler()                }                else                    $input.focus()            },            _renderEvents: function() {                var that = this,                    $input = that._input();                that._renderValueChangeEvent();                that._attachFocusEvents();                $.each(EVENTS_LIST, function(_, event) {                    var eventName = events.addNamespace(event.toLowerCase(), that.NAME),                        action = that._createActionByOption("on" + inflector.camelize(event, true), {excludeValidators: ["readOnly"]});                    $input.off(eventName).on(eventName, function(e) {                        action({jQueryEvent: e})                    })                })            },            _keyUpHandler: function(e) {                this.option("text", this._input().val())            },            _renderValueChangeEvent: function() {                var eventNamespace = this.NAME + "ValueChange";                var keyUpNamespace = events.addNamespace(this._renderValueEventName(), this.NAME + "TextChange");                this._input().off(keyUpNamespace).on(keyUpNamespace, $.proxy(this._keyUpHandler, this));                var valueChangeEventNamespace = events.addNamespace(this.option("valueChangeEvent"), eventNamespace);                this._input().off("." + eventNamespace).on(valueChangeEventNamespace, $.proxy(this._valueChangeEventHandler, this)).on("paste", $.proxy(this._pasteHandler, this))            },            _renderValueEventName: function() {                return "input change keyup"            },            _focusTarget: function() {                return this._input()            },            _pasteHandler: function(e) {                clearTimeout(this._pasteTimer);                this._pasteTimer = setTimeout($.proxy(this._valueChangeEventHandler, this, e))            },            _focusInHandler: function(e) {                e.stopPropagation();                this.element().addClass(TEXTEDITOR_STATE_FOCUSED_CLASS)            },            _focusOutHandler: function(e) {                e.stopPropagation();                this.element().removeClass(TEXTEDITOR_STATE_FOCUSED_CLASS)            },            _renderEmptinessEvent: function() {                var $input = this._input();                $input.on("input blur", $.proxy(this._toggleEmptinessEventHandler, this));                this._toggleEmptinessEventHandler()            },            _toggleEmptinessEventHandler: function(value) {                var text = this._input().val(),                    isEmpty = (text === "" || text === null) && this._isValueValid();                this._toggleEmptiness(isEmpty)            },            _valueChangeEventHandler: function(e, formattedValue) {                this._saveValueChangeEvent(e);                this.option("value", arguments.length > 1 ? formattedValue : this._input().val())            },            _renderEnterKeyAction: function() {                if (this.option("onEnterKey")) {                    this._enterKeyAction = this._createActionByOption("onEnterKey", {excludeValidators: ["readOnly"]});                    this._input().on("keyup.onEnterKey.dxTextEditor", $.proxy(this._enterKeyHandlerUp, this))                }                else {                    this._input().off("keyup.onEnterKey.dxTextEditor");                    this._enterKeyAction = undefined                }            },            _enterKeyHandlerUp: function(e) {                if (e.which === 13)                    this._enterKeyAction({jQueryEvent: e})            },            _updateValue: function() {                this.option("text", undefined);                this._renderValue()            },            _clean: function() {                if (this._$placeholder) {                    this._$placeholder.remove();                    delete this._$placeholder                }                delete this._$clearButton;                this.callBase()            },            _dispose: function() {                clearTimeout(this._pasteTimer);                this.callBase()            },            _optionChanged: function(args) {                var name = args.name;                if ($.inArray(inflector.camelize(name.replace("on", "")), EVENTS_LIST) > -1) {                    this._renderEvents();                    return                }                switch (name) {                    case"valueChangeEvent":                        this._renderValueChangeEvent();                        break;                    case"onValueChanged":                        this._createValueChangeAction();                        break;                    case"readOnly":                        this._toggleReadOnlyState(args.value);                        this.callBase(args);                        this._renderInputAddons();                        break;                    case"spellcheck":                        this._toggleSpellcheckState();                        break;                    case"mode":                        this._renderInputType();                        break;                    case"onEnterKey":                        this._renderEnterKeyAction();                        break;                    case"placeholder":                        this._invalidate();                        break;                    case"showClearButton":                        this._renderInputAddons();                        break;                    case"text":                        break;                    case"value":                        this._updateValue();                        this.callBase(args);                        break;                    case"attr":                        this._input().attr(args.value);                        break;                    case"valueFormat":                        this._invalidate();                        break;                    default:                        this.callBase(args)                }            },            _renderInputType: function() {                this._setInputType(this.option("mode"))            },            _setInputType: function(type) {                var input = this._input();                if (type === "search")                    type = "text";                try {                    input.prop("type", type)                }                catch(e) {                    input.prop("type", "text")                }            },            focus: function() {                this._input().focus()            },            blur: function() {                if (this._input().is(document.activeElement))                    DX.utils.resetActiveElement()            },            reset: function() {                this.option("value", "")            }        }))    })(jQuery, DevExpress);    /*! Module widgets-base, file ui.textEditor.mask.js */    (function($, DX, undefined) {        var ui = DX.ui,            events = ui.events,            utils = DX.utils;        var EMPTY_CHAR = " ";        var EMPTY_CHAR_CODE = 32;        var TEXTEDITOR_MASKED_CLASS = "dx-texteditor-masked";        var MASK_EVENT_NAMESPACE = "dxMask";        var FORWARD_DIRECTION = "forward";        var BACKWARD_DIRECTION = "backward";        var buildInMaskRules = {                "0": /[0-9]/,                "9": /[0-9\s]/,                "#": /[-+0-9\s]/,                L: /[a-zA-Z]/,                l: /[a-zA-Z\s]/,                C: /\S/,                c: /./,                A: /[0-9a-zA-Z]/,                a: /[0-9a-zA-Z\s]/            };        var CONTROL_KEYS = {                35: "end",                36: "home",                37: "leftArrow",                38: "upArrow",                39: "rightArrow",                40: "downArrow"            };        DX.registerComponent("dxTextEditor", ui, ui.dxTextEditor.inherit({            _setDefaultOptions: function() {                this.callBase();                this.option({                    mask: "",                    maskChar: "_",                    maskRules: {},                    maskInvalidMessage: Globalize.localize("validation-mask")                })            },            _supportedKeys: function() {                var that = this;                var keyHandlerMap = {                        backspace: that._maskBackspaceHandler,                        del: that._maskDelHandler,                        enter: that._changeHandler                    };                var result = that.callBase();                $.each(keyHandlerMap, function(key, callback) {                    var parentHandler = result[key];                    result[key] = function(e) {                        that.option("mask") && callback.call(that, e);                        parentHandler && parentHandler(e)                    }                });                return result            },            _render: function() {                this.callBase();                this._renderMask()            },            _renderMask: function() {                this.element().removeClass(TEXTEDITOR_MASKED_CLASS);                this._maskRulesChain = null;                if (!this.option("mask"))                    return;                this.element().addClass(TEXTEDITOR_MASKED_CLASS);                this._attachMaskEventHandlers();                this._parseMask();                this._renderMaskedValue()            },            _attachMaskEventHandlers: function() {                this._input().off("." + MASK_EVENT_NAMESPACE).on(events.addNamespace("focus", MASK_EVENT_NAMESPACE), $.proxy(this._maskFocusHandler, this)).on(events.addNamespace("keypress", MASK_EVENT_NAMESPACE), $.proxy(this._maskKeyPressHandler, this)).on(events.addNamespace("paste", MASK_EVENT_NAMESPACE), $.proxy(this._maskPasteHandler, this)).on(events.addNamespace("cut", MASK_EVENT_NAMESPACE), $.proxy(this._maskCutHandler, this)).on(events.addNamespace("drop", MASK_EVENT_NAMESPACE), $.proxy(this._maskDragHandler, this));                this._attachChangeEventHandlers()            },            _attachChangeEventHandlers: function() {                if ($.inArray("change", this.option("valueChangeEvent").split(" ")) === -1)                    return;                this._input().on(events.addNamespace("blur", MASK_EVENT_NAMESPACE), $.proxy(this._changeHandler, this))            },            _changeHandler: function(e) {                this._valueChangeEventHandler(events.createEvent(e, {type: "change"}))            },            _parseMask: function() {                this._maskRules = $.extend({}, buildInMaskRules, this.option("maskRules"));                this._maskRulesChain = this._parseMaskRule(0)            },            _parseMaskRule: function(index) {                var mask = this.option("mask");                if (index >= mask.length)                    return new ui.dxTextEditor.EmptyMaskRule;                var result = this._getMaskRule(mask[index]);                result.next(this._parseMaskRule(index + 1));                return result            },            _getMaskRule: function(pattern) {                var ruleConfig;                $.each(this._maskRules, function(rulePattern, allowedChars) {                    if (rulePattern === pattern) {                        ruleConfig = {                            pattern: rulePattern,                            allowedChars: allowedChars                        };                        return false                    }                });                return utils.isDefined(ruleConfig) ? new ui.dxTextEditor.MaskRule($.extend({maskChar: this.option("maskChar")}, ruleConfig)) : new ui.dxTextEditor.StubMaskRule({maskChar: pattern})            },            _renderMaskedValue: function() {                if (!this._maskRulesChain)                    return;                var value = this.option("value");                this._maskRulesChain.clear();                this._handleChain({                    value: value,                    length: value.length                });                this._displayMask()            },            _displayMask: function() {                var caret = this._caret();                this._renderValue();                this._caret(caret)            },            _renderValue: function() {                if (this._maskRulesChain)                    this.option("text", this._maskRulesChain.text());                this.callBase()            },            _valueChangeEventHandler: function(e) {                if (this._maskRulesChain) {                    this._saveValueChangeEvent(e);                    this.option("value", (this._value || "").replace(/\s+$/, ""));                    return                }                this.callBase.apply(this, arguments)            },            _maskFocusHandler: function() {                this._direction(FORWARD_DIRECTION);                this._adjustCaret()            },            _maskKeyPressHandler: function(e) {                if (this._isControlKeyFired(e))                    return;                this._maskKeyHandler(e, function() {                    this._handleKey(e.which);                    return true                })            },            _isControlKeyFired: function(e) {                return CONTROL_KEYS[e.keyCode] && !e.which || e.metaKey            },            _maskBackspaceHandler: function(e) {                this._maskKeyHandler(e, function() {                    if (this._hasSelection())                        return true;                    if (this._tryMoveCaretBackward())                        return false;                    this._handleKey(EMPTY_CHAR_CODE, BACKWARD_DIRECTION);                    return true                })            },            _maskDelHandler: function(e) {                this._maskKeyHandler(e, function() {                    !this._hasSelection() && this._handleKey(EMPTY_CHAR_CODE);                    return true                })            },            _maskPasteHandler: function(e) {                var caret = this._caret();                this._maskKeyHandler(e, function() {                    var pastingText = utils.clipboardText(e);                    var restText = this._maskRulesChain.text().substring(caret.end);                    var accepted = this._handleChain({                            text: pastingText,                            start: caret.start,                            length: pastingText.length                        });                    var newCaret = caret.start + accepted;                    this._handleChain({                        text: restText,                        start: newCaret,                        length: restText.length                    });                    this._caret({                        start: newCaret,                        end: newCaret                    });                    return true                })            },            _handleChain: function(args) {                var handledCount = this._maskRulesChain.handle(args);                this._value = this._maskRulesChain.value();                return handledCount            },            _maskCutHandler: function(e) {                var caret = this._caret();                var selectedText = this._input().val().substring(caret.start, caret.end);                this._maskKeyHandler(e, function() {                    utils.clipboardText(e, selectedText);                    return true                })            },            _maskDragHandler: function() {                this._clearDragTimer();                this._dragTimer = setTimeout($.proxy(function() {                    this.option("value", this._convertToValue(this._input().val()))                }, this))            },            _convertToValue: function(text) {                return text.replace(new RegExp(this.option("maskChar"), "g"), EMPTY_CHAR)            },            _maskKeyHandler: function(e, tryHandleKeyCallback) {                this._direction(FORWARD_DIRECTION);                e.preventDefault();                this._handleSelection();                if (!tryHandleKeyCallback.call(this))                    return;                this._direction(FORWARD_DIRECTION);                this._adjustCaret();                this._displayMask();                this._maskRulesChain.reset()            },            _handleKey: function(keyCode, direction) {                var char = String.fromCharCode(keyCode);                this._direction(direction || FORWARD_DIRECTION);                this._adjustCaret(char);                this._handleKeyChain(char);                this._moveCaret()            },            _handleSelection: function() {                if (!this._hasSelection())                    return;                var caret = this._caret();                var emptyChars = new Array(caret.end - caret.start + 1).join(EMPTY_CHAR);                this._handleKeyChain(emptyChars)            },            _handleKeyChain: function(chars) {                var caret = this._caret();                var start = this._isForwardDirection() ? caret.start : caret.start - 1;                var end = this._isForwardDirection() ? caret.end : caret.end - 1;                var length = start === end ? 1 : end - start;                this._handleChain({                    text: chars,                    start: start,                    length: length                })            },            _tryMoveCaretBackward: function() {                this._direction(BACKWARD_DIRECTION);                var currentCaret = this._caret().start;                this._adjustCaret();                return !currentCaret || currentCaret !== this._caret().start            },            _adjustCaret: function(char) {                var caret = this._maskRulesChain.adjustedCaret(this._caret().start, this._isForwardDirection(), char);                this._caret({                    start: caret,                    end: caret                })            },            _moveCaret: function() {                var currentCaret = this._caret().start;                var maskRuleIndex = currentCaret + (this._isForwardDirection() ? 0 : -1);                var caret = this._maskRulesChain.isAccepted(maskRuleIndex) ? currentCaret + (this._isForwardDirection() ? 1 : -1) : currentCaret;                this._caret({                    start: caret,                    end: caret                })            },            _caret: function(position) {                if (!arguments.length)                    return utils.caret(this._input());                utils.caret(this._input(), position)            },            _hasSelection: function() {                var caret = this._caret();                return caret.start !== caret.end            },            _direction: function(direction) {                if (!arguments.length)                    return this._typingDirection;                this._typingDirection = direction            },            _isForwardDirection: function() {                return this._direction() === FORWARD_DIRECTION            },            _clearDragTimer: function() {                clearTimeout(this._dragTimer)            },            _clean: function() {                this._clearDragTimer();                this.callBase()            },            _validateMask: function() {                if (!this._maskRulesChain)                    return;                var isValid = this._maskRulesChain.isValid();                this.option({                    isValid: isValid,                    validationError: isValid ? null : {                        editorSpecific: true,                        message: this.option("maskInvalidMessage")                    }                })            },            _optionChanged: function(args) {                switch (args.name) {                    case"mask":                    case"maskChar":                    case"maskRules":                        this._renderMask();                        this._validateMask();                        break;                    case"value":                        this._renderMaskedValue();                        this._validateMask();                        this.callBase(args);                        break;                    case"maskInvalidMessage":                        break;                    default:                        this.callBase(args)                }            }        }))    })(jQuery, DevExpress);    /*! Module widgets-base, file ui.textEditor.mask.rule.js */    (function($, DX, undefined) {        var ui = DX.ui;        var EMPTY_CHAR = " ";        var BaseMaskRule = DX.Class.inherit({                ctor: function(config) {                    this._value = EMPTY_CHAR;                    $.extend(this, config)                },                next: function(rule) {                    if (!arguments.length)                        return this._next;                    this._next = rule                },                text: $.noop,                value: $.noop,                rawValue: $.noop,                handle: $.noop,                _prepareHandlingArgs: function(args, config) {                    var handlingProperty = args.hasOwnProperty("value") ? "value" : "text";                    args[handlingProperty] = DX.utils.isDefined(config.str) ? config.str : args[handlingProperty];                    args.start = DX.utils.isDefined(config.start) ? config.start : args.start;                    args.length = DX.utils.isDefined(config.length) ? config.length : args.length;                    return args                },                reset: $.noop,                clear: $.noop,                isAccepted: function() {                    return false                },                adjustedCaret: function(caret, isForwardDirection, char) {                    return isForwardDirection ? this._adjustedForward(caret, 0, char) : this._adjustedBackward(caret, 0, char)                },                _adjustedForward: $.noop,                _adjustedBackward: $.noop,                isValid: $.noop            });        var EmptyMaskRule = BaseMaskRule.inherit({                next: $.noop,                handle: function() {                    return 0                },                text: function() {                    return ""                },                value: function() {                    return ""                },                rawValue: function() {                    return ""                },                adjustedCaret: function() {                    return 0                },                isValid: function() {                    return true                }            });        var MaskRule = BaseMaskRule.inherit({                text: function() {                    return (this._value !== EMPTY_CHAR ? this._value : this.maskChar) + this.next().text()                },                value: function() {                    return this._value + this.next().value()                },                rawValue: function() {                    return this._value + this.next().rawValue()                },                handle: function(args) {                    var str = args.hasOwnProperty("value") ? args.value : args.text;                    if (!str.length || !args.length)                        return 0;                    if (args.start)                        return this.next().handle(this._prepareHandlingArgs(args, {start: args.start - 1}));                    var char = str[0];                    var rest = str.substring(1);                    this._tryAcceptChar(char);                    return this._accepted() ? this.next().handle(this._prepareHandlingArgs(args, {                            str: rest,                            length: args.length - 1                        })) + 1 : this.handle(this._prepareHandlingArgs(args, {                            str: rest,                            length: args.length - 1                        }))                },                clear: function() {                    this._tryAcceptChar(EMPTY_CHAR);                    this.next().clear()                },                reset: function() {                    this._accepted(false);                    this.next().reset()                },                _tryAcceptChar: function(char) {                    this._accepted(false);                    if (!this._isAllowed(char))                        return;                    this._accepted(true);                    this._value = char                },                _accepted: function(value) {                    if (!arguments.length)                        return !!this._isAccepted;                    this._isAccepted = !!value                },                _isAllowed: function(char) {                    if (char === EMPTY_CHAR)                        return true;                    return this._isValid(char)                },                _isValid: function(char) {                    var allowedChars = this.allowedChars;                    if (allowedChars instanceof RegExp)                        return allowedChars.test(char);                    if ($.isFunction(allowedChars))                        return allowedChars(char);                    if ($.isArray(allowedChars))                        return $.inArray(char, allowedChars) > -1;                    return allowedChars === char                },                isAccepted: function(caret) {                    return caret === 0 ? this._accepted() : this.next().isAccepted(caret - 1)                },                _adjustedForward: function(caret, index, char) {                    if (index >= caret)                        return index;                    return this.next()._adjustedForward(caret, index + 1, char) || index + 1                },                _adjustedBackward: function(caret, index) {                    if (index >= caret - 1)                        return caret;                    return this.next()._adjustedBackward(caret, index + 1) || index + 1                },                isValid: function() {                    return this._isValid(this._value) && this.next().isValid()                }            });        var StubMaskRule = MaskRule.inherit({                value: function() {                    return this.next().value()                },                handle: function(args) {                    var hasValueProperty = args.hasOwnProperty("value");                    var str = hasValueProperty ? args.value : args.text;                    if (!str.length || !args.length)                        return 0;                    if (args.start || hasValueProperty)                        return this.next().handle(this._prepareHandlingArgs(args, {start: args.start && args.start - 1}));                    var char = str[0];                    var rest = str.substring(1);                    this._tryAcceptChar(char);                    var nextArgs = this._isAllowed(char) ? this._prepareHandlingArgs(args, {                            str: rest,                            length: args.length - 1                        }) : args;                    return this.next().handle(nextArgs) + 1                },                clear: function() {                    this._accepted(false);                    this.next().clear()                },                _tryAcceptChar: function(char) {                    this._accepted(this._isValid(char))                },                _isValid: function(char) {                    return char === this.maskChar                },                _adjustedForward: function(caret, index, char) {                    if (index >= caret && char === this.maskChar)                        return index;                    if (caret === index + 1 && this._accepted())                        return caret;                    return this.next()._adjustedForward(caret, index + 1, char)                },                _adjustedBackward: function(caret, index) {                    if (index >= caret - 1)                        return 0;                    return this.next()._adjustedBackward(caret, index + 1)                },                isValid: function() {                    return this.next().isValid()                }            });        $.extend(ui.dxTextEditor, {            MaskRule: MaskRule,            StubMaskRule: StubMaskRule,            EmptyMaskRule: EmptyMaskRule        })    })(jQuery, DevExpress);    /*! Module widgets-base, file ui.textBox.js */    (function($, DX, undefined) {        var ui = DX.ui,            events = ui.events,            devices = DX.devices,            ua = window.navigator.userAgent,            ignoreCode = [8, 9, 13, 33, 34, 35, 36, 37, 38, 39, 40, 46],            TEXTBOX_CLASS = "dx-textbox",            SEARCHBOX_CLASS = "dx-searchbox",            ICON_CLASS = "dx-icon",            SEARCH_ICON_CLASS = "dx-icon-search";        DX.registerComponent("dxTextBox", ui, ui.dxTextEditor.inherit({            ctor: function(element, options) {                if (options)                    this._showClearButton = options.showClearButton;                this.callBase.apply(this, arguments)            },            _setDefaultOptions: function() {                this.callBase();                this.option({                    mode: "text",                    maxLength: null                })            },            _render: function() {                this.callBase();                this.element().addClass(TEXTBOX_CLASS);                this.setAria("role", "textbox");                this._renderMaxLengthHandlers()            },            _renderInputType: function() {                this.callBase();                this._renderSearchMode()            },            _renderMaxLengthHandlers: function() {                if (this._isAndroid())                    this._input().on(events.addNamespace("keydown", this.NAME), $.proxy(this._onKeyDownAndroidHandler, this)).on(events.addNamespace("change", this.NAME), $.proxy(this._onChangeAndroidHandler, this))            },            _getAriaTarget: function() {                return this._input()            },            _renderProps: function() {                this.callBase();                this._toggleMaxLengthProp()            },            _toggleMaxLengthProp: function() {                if (this._isAndroid())                    return;                var maxLength = this.option("maxLength");                if (maxLength > 0)                    this._input().attr("maxLength", maxLength);                else                    this._input().removeAttr("maxLength")            },            _renderSearchMode: function() {                var $element = this._$element;                if (this.option("mode") === "search") {                    $element.addClass(SEARCHBOX_CLASS);                    this._renderSearchIcon();                    if (this._showClearButton === undefined) {                        this._showClearButton = this.option("showClearButton");                        this.option("showClearButton", true)                    }                }                else {                    $element.removeClass(SEARCHBOX_CLASS);                    this._$searchIcon && this._$searchIcon.remove();                    this.option("showClearButton", this._showClearButton === undefined ? this.option("showClearButton") : this._showClearButton);                    delete this._showClearButton                }            },            _renderSearchIcon: function() {                var $searchIcon = $("<div>").addClass(ICON_CLASS).addClass(SEARCH_ICON_CLASS);                $searchIcon.prependTo(this._input().parent());                this._$searchIcon = $searchIcon            },            _optionChanged: function(args) {                switch (args.name) {                    case"maxLength":                        this._toggleMaxLengthProp();                        this._renderMaxLengthHandlers();                        break;                    default:                        this.callBase(args)                }            },            _onKeyDownAndroidHandler: function(e) {                var maxLength = this.option("maxLength");                if (maxLength) {                    var $input = $(e.target),                        code = e.keyCode;                    this._cutOffExtraChar($input);                    return $input.val().length < maxLength || $.inArray(code, ignoreCode) !== -1 || window.getSelection().toString() !== ""                }                else                    return true            },            _onChangeAndroidHandler: function(e) {                var $input = $(e.target);                if (this.option("maxLength"))                    this._cutOffExtraChar($input)            },            _cutOffExtraChar: function($input) {                var maxLength = this.option("maxLength"),                    textInput = $input.val();                if (textInput.length > maxLength)                    $input.val(textInput.substr(0, maxLength))            },            _isAndroid: function() {                var realDevice = devices.real();                var version = realDevice.version.join(".");                return realDevice.platform === "android" && version && /^(2\.|4\.1)/.test(version) && !/chrome/i.test(ua)            }        }));        ui.dxTextBox.__internals = {            uaAccessor: function(value) {                if (!arguments.length)                    return ui;                ua = value            },            SEARCHBOX_CLASS: SEARCHBOX_CLASS,            SEARCH_ICON_CLASS: SEARCH_ICON_CLASS        }    })(jQuery, DevExpress);    /*! Module widgets-base, file ui.dropDownEditor.js */    (function($, DX, undefined) {        var ui = DX.ui,            events = ui.events,            DROP_DOWN_EDITOR_CLASS = "dx-dropdowneditor",            DROP_DOWN_EDITOR_READONLY_CLASS = "dx-dropdowneditor-readonly",            DROP_DOWN_EDITOR_INPUT_WRAPPER_CLASS = "dx-dropdowneditor-input-wrapper",            DROP_DOWN_EDITOR_BUTTON_CLASS = "dx-dropdowneditor-button",            DROP_DOWN_EDITOR_BUTTON_ICON = "dx-dropdowneditor-icon",            DROP_DOWN_EDITOR_OVERLAY = "dx-dropdowneditor-overlay",            DROP_DOWN_EDITOR_OVERLAY_FLIPPED = "dx-dropdowneditor-overlay-flipped",            DROP_DOWN_EDITOR_ACTIVE = "dx-dropdowneditor-active",            DROP_DOWN_EDITOR_BUTTON_VISIBLE = "dx-dropdowneditor-button-visible",            DROP_DOWN_EDITOR_FIELD_CLICKABLE = "dx-dropdowneditor-field-clickable",            DROP_DOWN_EDITOR = "dxDropDownEditor",            CLICK_EVENT_NAME = events.addNamespace("dxclick", DROP_DOWN_EDITOR);        DX.registerComponent(DROP_DOWN_EDITOR, ui, ui.dxTextBox.inherit({            _supportedKeys: function() {                return $.extend(this.callBase(), {                        escape: function(e) {                            if (this.option("opened"))                                e.preventDefault();                            this.close()                        },                        upArrow: function(e) {                            e.preventDefault();                            e.stopPropagation();                            if (e.altKey) {                                this.close();                                return false                            }                            return true                        },                        downArrow: function(e) {                            e.preventDefault();                            e.stopPropagation();                            if (e.altKey) {                                this._validatedOpening();                                return false                            }                            return true                        },                        enter: function(e) {                            if (this.option("opened")) {                                e.preventDefault();                                this._valueChangeEventHandler(e)                            }                            return true                        }                    })            },            _setDeprecatedOptions: function() {                this.callBase();                $.extend(this._deprecatedOptions, {                    openAction: {                        since: "14.2",                        alias: "onOpened"                    },                    closeAction: {                        since: "14.2",                        alias: "onClosed"                    },                    shownAction: {                        since: "14.2",                        alias: "onOpened"                    },                    hiddenAction: {                        since: "14.2",                        alias: "onClosed"                    },                    editEnabled: {                        since: "14.2",                        alias: "fieldEditEnabled"                    }                })            },            _setDefaultOptions: function() {                this.callBase();                this.option({                    value: null,                    onOpened: null,                    onClosed: null,                    opened: false,                    fieldEditEnabled: true,                    applyValueMode: "instantly",                    fieldTemplate: null,                    contentTemplate: null,                    openOnFieldClick: false,                    deferRendering: true,                    showDropButton: true,                    dropPosition: this._getDefaultDropPosition(),                    applyButtonText: Globalize.localize("OK"),                    cancelButtonText: Globalize.localize("Cancel"),                    buttonsLocation: "default",                    showPopupTitle: false                })            },            _getDefaultDropPosition: function() {                var position = this.option("rtlEnabled") ? "right" : "left";                return {                        offset: {                            h: 0,                            v: -1                        },                        my: position + " top",                        at: position + " bottom",                        collision: "flip flip"                    }            },            _defaultOptionsRules: function() {                return this.callBase().concat([{                            device: {platform: "generic"},                            options: {dropPosition: {offset: {v: 0}}}                        }])            },            _inputWrapper: function() {                return this.element().find("." + DROP_DOWN_EDITOR_INPUT_WRAPPER_CLASS)            },            _init: function() {                this.callBase();                this._initVisibilityActions()            },            _initVisibilityActions: function() {                this._openAction = this._createActionByOption("onOpened");                this._closeAction = this._createActionByOption("onClosed")            },            _render: function() {                this.callBase();                this._renderOpenHandler();                this.element().addClass(DROP_DOWN_EDITOR_CLASS);                this._renderOpenedState();                this.setAria("role", "combobox")            },            _renderContentImpl: function() {                if (!this.option("deferRendering"))                    this._createPopup()            },            _renderInput: function() {                this.callBase();                this.element().wrapInner($("<div>").addClass(DROP_DOWN_EDITOR_INPUT_WRAPPER_CLASS));                this._$container = this.element().children().eq(0);                this.setAria({                    haspopup: "true",                    autocomplete: "list"                })            },            _readOnlyPropValue: function() {                return !this.option("fieldEditEnabled") || this.callBase()            },            _renderField: function() {                var fieldTemplate = this._getTemplateByOption("fieldTemplate");                if (!(fieldTemplate && this.option("fieldTemplate")))                    return;                var isFocused = this._input().is(":focus");                isFocused && this._input().focusout();                this._cleanFocusState();                var $container = this._$container;                var data = this._fieldRenderData();                $container.empty();                this._$dropButton = null;                this._$clearButton = null;                fieldTemplate.render(data, $container);                if (!this._input().length)                    throw DX.Error("E1010");                this._renderFocusState();                isFocused && this._input().focus()            },            _fieldRenderData: function() {                return this.option("value")            },            _renderInputAddons: function() {                this._renderField();                this.callBase();                this._renderDropButton()            },            _renderDropButton: function(hideButton) {                var dropButtonVisible = this.option("showDropButton");                this.element().toggleClass(DROP_DOWN_EDITOR_BUTTON_VISIBLE, dropButtonVisible);                if (!dropButtonVisible) {                    this._$dropButton && this._$dropButton.remove();                    this._$dropButton = null;                    return                }                if (!this._$dropButton)                    this._$dropButton = this._createDropButton().addClass(DROP_DOWN_EDITOR_BUTTON_CLASS);                this._$dropButton.prependTo(this._buttonsContainer())            },            _createDropButton: function() {                var $button = $("<div>");                this._createComponent($button, "dxButton", {                    focusStateEnabled: false,                    disabled: this.option("readOnly"),                    _templates: {}                });                var $buttonIcon = $("<div>").addClass(DROP_DOWN_EDITOR_BUTTON_ICON);                $button.append($buttonIcon).removeClass("dx-button").on("mousedown", function(e) {                    e.preventDefault()                });                $button.find(".dx-button-content").remove();                return $button            },            _renderOpenHandler: function() {                var $inputWrapper = this.element().find(".dx-dropdowneditor-input-wrapper");                $inputWrapper.off(CLICK_EVENT_NAME);                var openOnFieldClick = this.option("openOnFieldClick");                this.element().toggleClass(DROP_DOWN_EDITOR_FIELD_CLICKABLE, openOnFieldClick);                if (openOnFieldClick) {                    $inputWrapper.on(events.addNamespace("mousedown", this.NAME), function(e) {                        DX.devices.real().platform !== "generic" && e.preventDefault()                    });                    $inputWrapper.on(CLICK_EVENT_NAME, $.proxy(this._openHandler, this));                    return                }                if (this.option("showDropButton"))                    this._$dropButton.dxButton("option", "onClick", $.proxy(this._openHandler, this))            },            _openHandler: function() {                this._toggleOpenState()            },            _keyboardEventBindingTarget: function() {                return this._input()            },            _toggleOpenState: function(isVisible) {                if (this.option("disabled"))                    return;                this._input().focus();                if (!this.option("readOnly")) {                    isVisible = arguments.length ? isVisible : !this.option("opened");                    this.option("opened", isVisible)                }            },            _renderOpenedState: function() {                var opened = this.option("opened");                if (opened)                    this._createPopup();                this.element().toggleClass(DROP_DOWN_EDITOR_ACTIVE, opened);                this._setPopupOption("visible", opened);                this.setAria("expanded", opened)            },            _createPopup: function() {                if (this._$popup)                    return;                this._$popup = $("<div>").addClass(DROP_DOWN_EDITOR_OVERLAY).addClass(this.option("customOverlayCssClass")).appendTo(this.element());                this._renderPopup();                this._renderPopupContent()            },            _renderPopup: function() {                this._popup = this._createComponent(this._$popup, "dxPopup", this._popupConfig());                this._popup.on({                    showing: $.proxy(this._popupShowingHandler, this),                    shown: $.proxy(this._popupShownHandler, this),                    hiding: $.proxy(this._popupHidingHandler, this),                    hidden: $.proxy(this._popupHiddenHandler, this)                });                this._popup.option("onContentReady", $.proxy(this._contentReadyHandler, this));                this._contentReadyHandler()            },            _contentReadyHandler: $.noop,            _popupConfig: function() {                return {                        position: $.extend(this.option("dropPosition"), {of: this.element()}),                        showTitle: this.option("showPopupTitle"),                        width: "auto",                        height: "auto",                        shading: false,                        closeOnTargetScroll: true,                        closeOnOutsideClick: $.proxy(this._closeOutsideDropDownHandler, this),                        animation: {                            show: {                                type: "fade",                                duration: 0,                                from: 0,                                to: 1                            },                            hide: {                                type: "fade",                                duration: 400,                                from: 1,                                to: 0                            }                        },                        deferRendering: false,                        focusStateEnabled: false,                        showCloseButton: false,                        buttons: this._getPopupButtons(),                        onPositioned: $.proxy(this._popupPositionedHandler, this)                    }            },            _popupPositionedHandler: function(e) {                this._popup.overlayContent().toggleClass(DROP_DOWN_EDITOR_OVERLAY_FLIPPED, e.position.v.flip)            },            _popupShowingHandler: $.noop,            _popupHidingHandler: function() {                this.option("opened", false)            },            _popupShownHandler: function() {                this._openAction();                if (this._$validationMessage)                    this._$validationMessage.dxTooltip("option", "position", this._getValidationTooltipPosition())            },            _popupHiddenHandler: function() {                this._closeAction();                if (this._$validationMessage)                    this._$validationMessage.dxTooltip("option", "position", this._getValidationTooltipPosition())            },            _getValidationTooltipPosition: function() {                var positionRequest = "below";                if (this._popup && this._popup.option("visible")) {                    var myTop = DX.position(this.element()).top,                        popupTop = DX.position(this._popup.content()).top;                    positionRequest = myTop + this.option("dropPosition").offset.v > popupTop ? "below" : "above"                }                return this.callBase(positionRequest)            },            _renderPopupContent: function() {                var contentTemplate = this._getTemplateByOption("contentTemplate");                if (!(contentTemplate && this.option("contentTemplate")))                    return;                var $popupContent = this._popup.content();                $popupContent.empty();                contentTemplate.render($popupContent)            },            _closeOutsideDropDownHandler: function(e) {                var $target = $(e.target);                var isInputClicked = !!$target.closest(this.element()).length;                var isDropButtonClicked = !!$target.closest(this._$dropButton).length;                var isOutsideClick = !isInputClicked && !isDropButtonClicked;                return isOutsideClick            },            _clean: function() {                delete this._$dropButton;                if (this._$popup) {                    this._$popup.remove();                    delete this._$popup;                    delete this._popup                }                this.callBase()            },            _setPopupOption: function(optionName, value) {                this._setWidgetOption("_popup", arguments)            },            _validatedOpening: function() {                if (!this.option("readOnly"))                    this._toggleOpenState(true)            },            _getAriaTarget: function() {                return this._input()            },            _getPopupButtons: function() {                return this.option("applyValueMode") === "useButtons" ? this._popupButtonsConfig() : []            },            _popupButtonsConfig: function() {                var buttonsConfig = [{                            shortcut: "done",                            options: {                                onClick: $.proxy(this._applyButtonHandler, this),                                text: this.option("applyButtonText")                            }                        }, {                            shortcut: "cancel",                            options: {                                onClick: $.proxy(this._cancelButtonHandler, this),                                text: this.option("cancelButtonText")                            }                        }];                return this._applyButtonsLocation(buttonsConfig)            },            _applyButtonsLocation: function(buttonsConfig) {                var buttonsLocation = this.option("buttonsLocation"),                    resultConfig = buttonsConfig;                if (buttonsLocation !== "default") {                    var position = DX.utils.splitPair(buttonsLocation);                    $.each(resultConfig, function(_, element) {                        $.extend(element, {                            toolbar: position[0],                            location: position[1]                        })                    })                }                return resultConfig            },            _applyButtonHandler: function() {                this.close();                this.option("focusStateEnabled") && this.focus()            },            _cancelButtonHandler: function() {                this.close();                this.option("focusStateEnabled") && this.focus()            },            _optionChanged: function(args) {                switch (args.name) {                    case"opened":                        this._renderOpenedState();                        break;                    case"onOpened":                    case"onClosed":                        this._initVisibilityActions();                        break;                    case"fieldTemplate":                    case"fieldRender":                        this._renderInputAddons();                        break;                    case"showDropButton":                    case"contentTemplate":                    case"contentRender":                    case"fieldEditEnabled":                    case"openOnFieldClick":                        this._invalidate();                        break;                    case"dropPosition":                    case"deferRendering":                        break;                    case"applyValueMode":                    case"applyButtonText":                    case"cancelButtonText":                    case"buttonsLocation":                        this._setPopupOption("buttons", this._getPopupButtons());                        break;                    case"showPopupTitle":                        this._setPopupOption("showTitle", args.value);                        break;                    default:                        this.callBase(args)                }            },            open: function() {                this.option("opened", true)            },            close: function() {                this.option("opened", false)            },            reset: function() {                this.option("value", null)            },            field: function() {                return this._input()            },            content: function() {                return this._popup ? this._popup.content() : null            }        }));        ui.dxDropDownEditor.__internals = {            DROP_DOWN_EDITOR_CLASS: DROP_DOWN_EDITOR_CLASS,            DROP_DOWN_EDITOR_READONLY_CLASS: DROP_DOWN_EDITOR_READONLY_CLASS,            DROP_DOWN_EDITOR_BUTTON_ICON: DROP_DOWN_EDITOR_BUTTON_ICON,            DROP_DOWN_EDITOR_INPUT_WRAPPER_CLASS: DROP_DOWN_EDITOR_INPUT_WRAPPER_CLASS,            DROP_DOWN_EDITOR_BUTTON_CLASS: DROP_DOWN_EDITOR_BUTTON_CLASS,            DROP_DOWN_EDITOR_OVERLAY: DROP_DOWN_EDITOR_OVERLAY,            DROP_DOWN_EDITOR_ACTIVE: DROP_DOWN_EDITOR_ACTIVE,            DROP_DOWN_EDITOR_BUTTON_VISIBLE: DROP_DOWN_EDITOR_BUTTON_VISIBLE        }    })(jQuery, DevExpress);    /*! Module widgets-base, file ui.dropDownList.js */    (function($, DX, undefined) {        var ui = DX.ui,            utils = DX.utils;        var LIST_ITEM_SELECTOR = ".dx-list-item",            LIST_ITEM_DATA_KEY = "dxListItemData",            DROPDOWNLIST_SELECTED_CLASS = "dx-dropdownlist-selected",            DROPDOWNLIST_POPUP_WRAPPER_CLASS = "dx-dropdownlist-popup-wrapper",            SEARCH_MODES = ["startswith", "contains", "endwith", "notcontains"];        DX.registerComponent("dxDropDownList", ui, ui.dxDropDownEditor.inherit({            _supportedKeys: function() {                return $.extend(this.callBase(), {                        tab: function(e) {                            if (this.option("opened") === true) {                                var $focusedItem = this._list.option("focusedElement");                                if ($focusedItem) {                                    var $selectedItem = this._listSelectedItemElements();                                    this._changeSelectedItem($selectedItem, $focusedItem);                                    this.option("value", this._selectedItemValue())                                }                                this.close()                            }                            else                                this._focusTarget().focusout()                        },                        space: $.noop,                        home: $.noop,                        end: $.noop                    })            },            _setDeprecatedOptions: function() {                this.callBase();                $.extend(this._deprecatedOptions, this._dataExpressionDeprecatedOptions(), {pagingEnabled: {                        since: "15.1",                        message: "Use the 'dataSource.paginate' option instead"                    }})            },            _setDefaultOptions: function() {                this.callBase();                this.option($.extend(this._dataExpressionDefaultOptions(), {                    displayValue: undefined,                    searchEnabled: false,                    searchMode: "contains",                    searchTimeout: 500,                    minSearchLength: 0,                    searchExpr: null,                    valueChangeEvent: "change keyup",                    selectedItem: null,                    pagingEnabled: undefined,                    noDataText: Globalize.localize("dxCollectionWidget-noDataText"),                    onSelectionChanged: null,                    onItemClick: $.noop,                    dropPosition: {                        my: "left top",                        at: "left bottom",                        offset: {                            h: 0,                            v: 0                        },                        collision: "flip"                    },                    popupWidthExtension: 0                }))            },            _defaultOptionsRules: function() {                return this.callBase().concat([{                            device: {platform: "win8"},                            options: {dropPosition: {offset: {v: -6}}}                        }, {                            device: function(device) {                                return device.platform === "android"                            },                            options: {popupWidthExtension: 32}                        }])            },            _setOptionsByReference: function() {                this.callBase();                $.extend(this._optionsByReference, {                    value: true,                    selectedItem: true,                    displayValue: true                })            },            _init: function() {                this.callBase();                this._initDataExpressions();                this._initActions();                this._setListDataSource();                this._validateSearchMode();                this._clearSelectedItem()            },            _initActions: function() {                this._initContentReadyAction();                this._initSelectionChangedAction();                this._initItemClickAction()            },            _initContentReadyAction: function() {                this._contentReadyAction = this._createActionByOption("onContentReady")            },            _initSelectionChangedAction: function() {                this._selectionChangedAction = this._createActionByOption("onSelectionChanged", {excludeValidators: ["disabled", "readOnly"]})            },            _initItemClickAction: function() {                this._itemClickAction = this._createActionByOption("onItemClick")            },            _renderContentImpl: function() {                this.callBase();                if (this.option("deferRendering"))                    this._loadDataSource()            },            _renderField: function() {                this.callBase();                this._input().on("input", $.proxy(this._setFocusPolicy, this))            },            _preventFocusOnPopup: function(e) {                if (this._list && this._list.initialOption("focusStateEnabled"))                    e.preventDefault()            },            _createPopup: function() {                this.callBase();                this._popup._wrapper().addClass(this._popupWrapperClass());                this._popup.content().off("mousedown").on("mousedown", $.proxy(this._preventFocusOnPopup, this))            },            _popupWrapperClass: function() {                return DROPDOWNLIST_POPUP_WRAPPER_CLASS            },            _renderInputValue: function() {                var callBase = $.proxy(this.callBase, this);                return this._loadItem(this.option("value")).always($.proxy(function(item) {                        this._setSelectedItem(item);                        this._refreshSelected();                        callBase()                    }, this))            },            _loadItem: function(value) {                var selectedItem = $.grep(this.option("items") || [], $.proxy(function(item) {                        return this._isValueEquals(this._valueGetter(item), value)                    }, this))[0];                return selectedItem !== undefined ? $.Deferred().resolve(selectedItem).promise() : this._loadValue(value)            },            _setSelectedItem: function(item) {                var displayValue = this._displayValue(item);                this.option("selectedItem", item);                this.option("displayValue", displayValue)            },            _displayValue: function(item) {                return this._displayGetter(item)            },            _refreshSelected: function() {                this._listItemElements().each($.proxy(function(_, itemElement) {                    var $itemElement = $(itemElement);                    var itemValue = this._valueGetter($itemElement.data(LIST_ITEM_DATA_KEY));                    var isItemSelected = this._isSelectedValue(itemValue);                    $itemElement.toggleClass(this._selectedItemClass(), isItemSelected);                    if (isItemSelected)                        this._list.selectItem($itemElement);                    else                        this._list.unselectItem($itemElement)                }, this))            },            _popupShownHandler: function() {                this.callBase();                this._setFocusPolicy()            },            _setFocusPolicy: function() {                if (!this.option("focusStateEnabled") || !this._list)                    return;                this._list.option("focusedElement", null)            },            _isSelectedValue: function(value) {                return this._isValueEquals(value, this.option("value"))            },            _validateSearchMode: function() {                var searchMode = this.option("searchMode"),                    normalizedSearchMode = searchMode.toLowerCase();                if ($.inArray(normalizedSearchMode, SEARCH_MODES) < 0)                    throw DX.Error("E1019", searchMode);            },            _clearSelectedItem: function() {                this.option("selectedItem", null)            },            _processDataSourceChanging: function() {                this._setListDataSource();                this._renderInputValue().fail($.proxy(this.reset, this))            },            reset: function() {                this.option("value", null);                this._clearSelectedItem()            },            _selectedItemClass: function() {                return DROPDOWNLIST_SELECTED_CLASS            },            _listItemElements: function() {                return this._$list ? this._$list.find(LIST_ITEM_SELECTOR) : $()            },            _listSelectedItemElements: function() {                return this._$list ? this._$list.find("." + this._selectedItemClass()) : $()            },            _popupConfig: function() {                return $.extend(this.callBase(), {width: this.option("width")})            },            _renderPopupContent: function() {                this._renderList()            },            _attachChildKeyboardEvents: function() {                this._childKeyboardProcessor = this._keyboardProcessor.attachChildProcessor();                this._setListOption("_keyboardProcessor", this._childKeyboardProcessor)            },            _fireContentReadyAction: $.noop,            _renderList: function() {                var listId = (new DevExpress.data.Guid)._value,                    $list = this._$list = $("<div>", {id: listId}).appendTo(this._popup.content());                this._list = this._createComponent($list, "dxList", this._listConfig());                this.setAria({                    activedescendant: this._list.getFocusedItemId(),                    owns: listId                });                this._refreshList()            },            _refreshList: function() {                if (this._list && this._shouldRefreshDataSource())                    this._setListDataSource()            },            _shouldRefreshDataSource: function() {                var dataSourceProvided = !!this._list.option("dataSource");                return dataSourceProvided !== this._isMinFilterLengthExceeded()            },            _refreshActiveDescendant: function() {                this.setAria("activedescendant", "");                this.setAria("activedescendant", this._list.getFocusedItemId())            },            _listConfig: function() {                return {                        _templates: this.option("_templates"),                        templateProvider: this.option("templateProvider"),                        noDataText: this.option("noDataText"),                        onContentReady: $.proxy(this._listContentReadyHandler, this),                        itemTemplate: this._getTemplateByOption("itemTemplate"),                        indicateLoading: false,                        tabIndex: -1,                        onItemClick: $.proxy(this._listItemClickAction, this),                        dataSource: this._isMinFilterLengthExceeded() ? this._dataSource : null,                        _keyboardProcessor: this._childKeyboardProcessor,                        onOptionChanged: $.proxy(function(args) {                            if (args.name === "focusedElement")                                this._refreshActiveDescendant()                        }, this)                    }            },            _dataSourceOptions: function() {                this._suppressDeprecatedWarnings();                var pagingEnabled = this.option("pagingEnabled");                this._resumeDeprecatedWarnings();                return {paginate: utils.ensureDefined(pagingEnabled, false)}            },            _listContentReadyHandler: function() {                this._list = this._list || this._$list.dxList("instance");                this.option().items = this._list.option("items");                this._refreshSelected();                this._dimensionChanged();                this._contentReadyAction()            },            _setListOption: function(optionName, value) {                this._setWidgetOption("_list", arguments)            },            _listItemClickAction: function(e) {                this._listItemClickHandler(e);                this._itemClickAction(e)            },            _listItemClickHandler: $.noop,            _setListDataSource: function() {                if (!this._list)                    return;                var isMinFilterLengthExceeded = this._isMinFilterLengthExceeded();                this._setListOption("dataSource", isMinFilterLengthExceeded ? this._dataSource : null);                if (!isMinFilterLengthExceeded)                    this._setListOption("items", [])            },            _isMinFilterLengthExceeded: function() {                return this._searchValue().toString().length >= this.option("minSearchLength")            },            _searchValue: function() {                return this._input().val() || ""            },            _search: function() {                if (!this._isMinFilterLengthExceeded()) {                    this._searchCanceled();                    return                }                var searchTimeout = this.option("searchTimeout");                if (searchTimeout) {                    if (!this._searchTimer)                        this._searchTimer = setTimeout($.proxy(this._searchDataSource, this), searchTimeout)                }                else                    this._searchDataSource()            },            _searchCanceled: function() {                this._clearSearchTimer();                this._refreshList()            },            _searchDataSource: function() {                this._filterDataSource(this._searchValue())            },            _filterDataSource: function(searchValue) {                var dataSource = this._dataSource;                dataSource.searchExpr(this.option("searchExpr") || this._displayGetterExpr());                dataSource.searchOperation(this.option("searchMode"));                dataSource.searchValue(searchValue);                dataSource.pageIndex(0);                return dataSource.load().done($.proxy(this._dataSourceFiltered, this))            },            _clearFilter: function() {                this._dataSource.searchValue("")            },            _dataSourceFiltered: function() {                this._clearSearchTimer();                this._refreshList();                this._refreshPopupVisibility()            },            _refreshPopupVisibility: function() {                this.option("opened", this._hasItemsToShow());                if (this.option("opened"))                    this._dimensionChanged()            },            _hasItemsToShow: function() {                var resultItems = this._dataSource && this._dataSource.items() || [];                var resultAmount = resultItems.length;                var isMinFilterLengthExceeded = this._isMinFilterLengthExceeded();                return isMinFilterLengthExceeded && resultAmount && this.element().hasClass("dx-state-focused")            },            _clearSearchTimer: function() {                clearTimeout(this._searchTimer);                delete this._searchTimer            },            _popupShowingHandler: function() {                this._dimensionChanged()            },            _dimensionChanged: function() {                this._popup && this._updatePopupDimensions()            },            _updatePopupDimensions: function() {                this._updatePopupWidth();                this._updatePopupHeight()            },            _updatePopupWidth: function() {                this._setPopupOption("width", this.element().outerWidth() + this.option("popupWidthExtension"))            },            _updatePopupHeight: function() {                var popupPadding = this._popup.overlayContent().outerHeight() - this._popup.content().height();                var listMargin = this._list ? this._list.element().outerHeight() - this._list.clientHeight() : 0;                var listHeight = this._list ? this._list.scrollHeight() + listMargin : 0;                var popupHeight = Math.min(listHeight + popupPadding, this._getMaxHeight());                this._setPopupOption("height", popupHeight);                this._list && this._list.updateDimensions()            },            _getMaxHeight: function() {                var $element = this.element(),                    offset = $element.offset(),                    windowHeight = $(window).height(),                    maxHeight = Math.max(offset.top, windowHeight - offset.top - $element.outerHeight());                return Math.min(windowHeight * 0.5, maxHeight)            },            _changeSelectedItem: function($selectedItem, $newItem) {                var selectedItemClass = this._selectedItemClass();                $selectedItem.removeClass(selectedItemClass);                $newItem.addClass(selectedItemClass)            },            _selectedItemValue: function() {                var $selectedItem = this._listSelectedItemElements();                return this._valueGetter($selectedItem.data(LIST_ITEM_DATA_KEY))            },            _valueChangeArgs: function() {                return $.extend(this.callBase.apply(this, arguments), {                        selectedItem: this.option("selectedItem"),                        itemData: this.option("selectedItem")                    })            },            _clean: function() {                if (this._list)                    delete this._list;                this.callBase()            },            _dispose: function() {                this._clearSearchTimer();                this.callBase()            },            _setCollectionWidgetOption: function() {                this._setListOption.apply(this, arguments)            },            _optionChanged: function(args) {                this._dataExpressionOptionChanged(args);                switch (args.name) {                    case"items":                        if (!this.option("dataSource"))                            this._processDataSourceChanging();                        break;                    case"dataSource":                        this._processDataSourceChanging();                        break;                    case"valueExpr":                    case"displayExpr":                        this._renderValue();                        break;                    case"searchMode":                        this._validateSearchMode();                        break;                    case"minSearchLength":                        this._refreshList();                        break;                    case"searchEnabled":                    case"searchExpr":                    case"pagingEnabled":                        this._invalidate();                        break;                    case"onContentReady":                        this._initContentReadyAction();                        break;                    case"onSelectionChanged":                        this._initSelectionChangedAction();                        break;                    case"onItemClick":                        this._initItemClickAction();                        break;                    case"noDataText":                        this._setListOption("noDataText");                        break;                    case"displayValue":                        this.option("text", args.value);                        break;                    case"itemTemplate":                    case"searchTimeout":                    case"popupWidthExtension":                        break;                    case"selectedItem":                        this._selectionChangedAction({selectedItem: args.value});                        break;                    default:                        this.callBase(args)                }            }        }).include(ui.DataExpressionMixin))    })(jQuery, DevExpress);    /*! Module widgets-base, file ui.textArea.js */    (function($, DX, undefined) {        var ui = DX.ui,            events = ui.events;        var TEXTAREA_CLASS = "dx-textarea",            TEXTEDITOR_INPUT_CLASS = "dx-texteditor-input";        DX.registerComponent("dxTextArea", ui, ui.dxTextBox.inherit({            _setDefaultOptions: function() {                this.callBase();                this.option({spellcheck: true})            },            _render: function() {                this.callBase();                this.element().addClass(TEXTAREA_CLASS);                this.setAria("multiline", "true")            },            _renderInput: function() {                this.callBase();                this._renderScrollHandler()            },            _createInput: function() {                return $("<textarea>").addClass(TEXTEDITOR_INPUT_CLASS)            },            _renderScrollHandler: function() {                var $input = this._input(),                    eventY = 0;                $input.on(events.addNamespace("dxpointerdown", this.NAME), function(e) {                    eventY = events.eventData(e).y                });                $input.on(events.addNamespace("dxpointermove", this.NAME), function(e) {                    var scrollTopPos = $input.scrollTop(),                        scrollBottomPos = $input.prop("scrollHeight") - $input.prop("clientHeight") - scrollTopPos;                    if (scrollTopPos === 0 && scrollBottomPos === 0)                        return;                    var currentEventY = events.eventData(e).y;                    var isScrollFromTop = scrollTopPos === 0 && eventY >= currentEventY,                        isScrollFromBottom = scrollBottomPos === 0 && eventY <= currentEventY,                        isScrollFromMiddle = scrollTopPos > 0 && scrollBottomPos > 0;                    if (isScrollFromTop || isScrollFromBottom || isScrollFromMiddle)                        e.isScrollingEvent = true;                    eventY = currentEventY                })            },            _renderInputType: $.noop        }))    })(jQuery, DevExpress);    /*! Module widgets-base, file ui.numberBox.js */    (function($, DX, undefined) {        var ui = DX.ui,            math = Math,            events = ui.events,            WIDGET_CLASS = "dx-numberbox",            SPIN_CLASS = "dx-numberbox-spin",            SPIN_CONTAINER_CLASS = "dx-numberbox-spin-container",            SPIN_UP_CLASS = "dx-numberbox-spin-up",            SPIN_DOWN_CLASS = "dx-numberbox-spin-down",            SPIN_BUTTON_CLASS = "dx-numberbox-spin-button",            SPIN_BUTTON_SELECTOR = ".dx-numberbox-spin-button",            SPIN_TOUCH_FRIENDLY_CLASS = "dx-numberbox-spin-touch-friendly",            SPIN_HOLD_DELAY = 100,            CONTROL_KEYS = ["Tab", "Del", "Delete", "Backspace", "Left", "ArrowLeft", "Right", "ArrowRight", "Home", "End"],            NUMBER_BOX = 'dxNumberBox',            MOUSEWHEEL_EVENT_NAME = events.addNamespace("dxmousewheel", NUMBER_BOX),            POINTERDOWN_EVENT_NAME = events.addNamespace("dxpointerdown", NUMBER_BOX),            POINTERUP_EVENT_NAME = events.addNamespace("dxpointerup", NUMBER_BOX),            POINTERCANCEL_EVENT_NAME = events.addNamespace("dxpointercancel", NUMBER_BOX);        var androidNativeBrowser = DX.devices.real().android && navigator.userAgent.indexOf("Chrome") === -1;        var dxSpinButton = ui.Widget.inherit({                _setDefaultOptions: function() {                    this.callBase();                    this.option({                        direction: "up",                        onChange: null,                        activeStateEnabled: true,                        hoverStateEnabled: false                    })                },                _render: function() {                    this.callBase();                    var $element = this.element(),                        direction = SPIN_CLASS + "-" + this.option("direction");                    $element.addClass(SPIN_BUTTON_CLASS).addClass(direction).off(POINTERDOWN_EVENT_NAME).on(POINTERDOWN_EVENT_NAME, $.proxy(this._spinDownHandler, this));                    this._spinIcon = $("<div>").addClass(direction + "-icon").appendTo(this.element());                    this._spinChangeHandler = this._createActionByOption("onChange")                },                _spinDownHandler: function(e) {                    e.preventDefault();                    this._clearTimer();                    $(document).on("dxhold", $.proxy(function() {                        this._feedBackDeferred = $.Deferred();                        ui.events.lockFeedback(this._feedBackDeferred);                        this._spinChangeHandler({jQueryEvent: e});                        this._holdTimer = setInterval(this._spinChangeHandler, SPIN_HOLD_DELAY, {jQueryEvent: e})                    }, this)).on(POINTERUP_EVENT_NAME, $.proxy(this._clearTimer, this)).on(POINTERCANCEL_EVENT_NAME, $.proxy(this._clearTimer, this));                    this._spinChangeHandler({jQueryEvent: e})                },                _dispose: function() {                    this._clearTimer();                    this.callBase()                },                _clearTimer: function(e) {                    $(document).off(POINTERUP_EVENT_NAME).off(POINTERCANCEL_EVENT_NAME).off("dxhold");                    if (this._feedBackDeferred)                        this._feedBackDeferred.resolve();                    if (this._holdTimer)                        clearInterval(this._holdTimer)                },                _optionChanged: function(args) {                    switch (args.name) {                        case"onChange":                        case"direction":                            this._invalidate();                            break;                        default:                            this.callBase(args)                    }                }            });        DX.registerComponent("dxNumberBox", ui, ui.dxTextEditor.inherit({            _activeStateUnit: SPIN_BUTTON_SELECTOR,            _supportedKeys: function() {                return $.extend(this.callBase(), {                        upArrow: function(e) {                            e.preventDefault();                            e.stopPropagation();                            this._spinUpChangeHandler()                        },                        downArrow: function(e) {                            e.preventDefault();                            e.stopPropagation();                            this._spinDownChangeHandler()                        },                        enter: function(e) {                            this._input().trigger(this.option("valueChangeEvent"))                        }                    })            },            _setDefaultOptions: function() {                this.callBase();                this.option({                    value: 0,                    min: undefined,                    max: undefined,                    step: 1,                    showSpinButtons: false,                    useTouchSpinButtons: true,                    mode: "number"                })            },            _defaultOptionsRules: function() {                return this.callBase().concat([{                            device: function(device) {                                return DX.devices.real().generic && !DX.devices.isSimulator()                            },                            options: {useTouchSpinButtons: false}                        }])            },            _render: function() {                this.callBase();                this.element().addClass(WIDGET_CLASS);                this.setAria("role", "spinbutton");                this._keyPressHandlerEvent();                this._renderMouseWheelHandler()            },            _keyPressHandlerEvent: function() {                var that = this;                this._input().keypress(function(e) {                    var ch = String.fromCharCode(e.which),                        validCharRegExp = /[\d.,eE\-+]/,                        isInputCharValid = validCharRegExp.test(ch);                    if (!isInputCharValid) {                        if (e.metaKey || e.ctrlKey || e.key && $.inArray(e.key, CONTROL_KEYS) >= 0)                            return;                        e.preventDefault();                        return false                    }                    that._isIncompleteValue = false;                    if (that._isValueIncomplete(that._input().val() + ch))                        that._isIncompleteValue = true                })            },            _isValueIncomplete: function(value) {                var expRegex = /\d+[eE]$/,                    dotRegex = /^[\.,]$/,                    negRegex = /^-$/;                return expRegex.test(value) || dotRegex.test(value) || negRegex.test(value)            },            _renderMouseWheelHandler: function(e) {                var mouseWheelAction = this._createAction($.proxy(function(e) {                        this._mouseWheelHandler(e.jQueryEvent)                    }, this));                this._input().off(MOUSEWHEEL_EVENT_NAME).on(MOUSEWHEEL_EVENT_NAME, function(e) {                    mouseWheelAction({jQueryEvent: e})                })            },            _mouseWheelHandler: function(e) {                if (!this._input().is(":focus"))                    return;                e.delta > 0 ? this._spinValueChange(1) : this._spinValueChange(-1);                e.preventDefault();                e.stopPropagation()            },            _renderValue: function() {                if (!this._input().val().length || Number(this._input().val()) !== this.option("value")) {                    this._forceValueRender();                    this._toggleEmptinessEventHandler()                }                this._renderInputAddons();                this.setAria("valuenow", this.option("value"))            },            _forceValueRender: function() {                var $input = this._input(),                    value = this.option("value"),                    valueFormat = this.option("valueFormat");                if (androidNativeBrowser) {                    var inputType = $input.attr("type");                    this._setInputType("text");                    $input.val(valueFormat(value));                    this._setInputType(inputType)                }                else                    $input.val(valueFormat(value))            },            _getAriaTarget: function() {                return this._input()            },            _renderProps: function() {                this.callBase();                this._input().prop({                    min: this.option("min"),                    max: this.option("max"),                    step: this.option("step")                });                this.setAria({                    valuemin: this.option("min") || "undefined",                    valuemax: this.option("max") || "undefined"                })            },            _renderInputAddons: function() {                this.callBase();                this._renderSpinButtons()            },            _renderSpinButtons: function() {                var spinButtonsVisible = this.option("showSpinButtons");                this.element().toggleClass(SPIN_CLASS, spinButtonsVisible);                this._toggleTouchFriendlyClass();                if (!spinButtonsVisible) {                    this._$spinContainer && this._$spinContainer.remove();                    this._$spinContainer = null;                    return                }                if (!this._$spinContainer)                    this._$spinContainer = this._createSpinButtons();                this._$spinContainer.prependTo(this._buttonsContainer())            },            _toggleTouchFriendlyClass: function() {                this.element().toggleClass(SPIN_TOUCH_FRIENDLY_CLASS, this.option("showSpinButtons") && this.option("useTouchSpinButtons"))            },            _createSpinButtons: function() {                var pointerDownAction = this._createAction($.proxy(this._spinButtonsPointerDownHandler, this));                var $spinContainer = $("<div>").addClass(SPIN_CONTAINER_CLASS).off(POINTERDOWN_EVENT_NAME).on(POINTERDOWN_EVENT_NAME, function(e) {                        pointerDownAction({jQueryEvent: e})                    });                this._$spinUp = $("<div>").appendTo($spinContainer);                this._createComponent(this._$spinUp, "dxSpinButton", {                    direction: "up",                    onChange: $.proxy(this._spinUpChangeHandler, this)                });                this._$spinDown = $("<div>").appendTo($spinContainer);                this._createComponent(this._$spinDown, "dxSpinButton", {                    direction: "down",                    onChange: $.proxy(this._spinDownChangeHandler, this)                });                return $spinContainer            },            _spinButtonsPointerDownHandler: function(e) {                e.dxPreventBlur = true;                var $input = this._input();                if (!this.option("useTouchSpinButtons") && document.activeElement !== $input[0])                    $input.trigger("focus")            },            _spinUpChangeHandler: function() {                if (!this.option("readOnly"))                    this._spinValueChange(1)            },            _spinDownChangeHandler: function() {                if (!this.option("readOnly"))                    this._spinValueChange(-1)            },            _spinValueChange: function(sign) {                var value = parseFloat(this._validationRequired() ? this._oldValue : this._normalizeInputValue()) || 0,                    step = parseFloat(this.option("step"));                value = this._correctRounding(value, step * sign);                this.option("value", value)            },            _correctRounding: function(value, step) {                var regex = /[,|.](.*)/;                var isFloatValue = regex.test(value),                    isFloatStep = regex.test(step);                if (isFloatValue || isFloatStep) {                    var valueAccuracy = isFloatValue ? regex.exec(value)[0].length : 0,                        stepAccuracy = isFloatStep ? regex.exec(step)[0].length : 0,                        accuracy = math.max(valueAccuracy, stepAccuracy);                    value = this._round(value + step, accuracy);                    return value                }                return value + step            },            _round: function(value, precision) {                precision = precision || 0;                var multiplier = Math.pow(10, precision);                value *= multiplier;                value = Math.round(value) / multiplier;                return value            },            _renderValueChangeEvent: function() {                this.callBase();                this._input().focusout($.proxy(this._forceRefreshInputValue, this))            },            _forceRefreshInputValue: function() {                var $input = this._input(),                    valueFormat = this.option("valueFormat");                $input.val(null);                $input.val(valueFormat(this.option("value")))            },            _valueChangeEventHandler: function(e) {                if (this._validationRequired()) {                    this._inputInvalidHandler();                    return                }                var $input = this._input(),                    value = this._normalizeInputValue(),                    valueFormat = this.option("valueFormat");                if (this._isIncompleteValue)                    return;                if (Number($input.val()) !== value)                    $input.val(valueFormat(this.option("value")), valueFormat(value));                this.callBase(e, value)            },            _validationRequired: function() {                return !this._isIncompleteValue && !this._validateValue(this._normalizeText())            },            _validateValue: function(value) {                var isValueValid = this._isValueValid();                if (!value && isValueValid) {                    this.option("value", null);                    return true                }                var isNumber = /^-?\d*\.?\d*$/.test(value),                    isExponent = /^-?\d+e[-+]?\d+$/.test(value);                this._oldValue = this.option("value");                if (!isNumber && !isExponent && !isValueValid)                    return false;                return true            },            _inputInvalidHandler: function() {                var $input = this._input(),                    isValueDefined = DX.utils.isDefined(this._oldValue);                this.option("value", isValueDefined ? this._oldValue : null);                isValueDefined && $input.val(this._oldValue);                this._oldValue = null            },            _normalizeInputValue: function() {                var value = this._normalizeValue();                return DX.utils.isDefined(value) ? value : this.option("value")            },            _normalizeValue: function(value) {                return this._parseValue(this._normalizeText(value))            },            _normalizeText: function(value) {                value = $.trim(DX.utils.isDefined(value) ? value : this._input().val());                return value.replace(",", ".")            },            _parseValue: function(value) {                var number = parseFloat(value);                if (this.option("min") !== undefined)                    number = math.max(number, this.option("min"));                if (this.option("max") !== undefined)                    number = math.min(number, this.option("max"));                return number            },            _setValue: function(value, prevValue) {                if (value == null || value === "") {                    this.option("value", null);                    if (value !== null)                        this._suppressValueChangeAction();                    return                }                var newValue = this._normalizeValue(value);                if (!newValue && newValue !== 0) {                    this.option("value", prevValue);                    this._suppressValueChangeAction();                    return                }                if (value !== newValue) {                    this.option("value", newValue);                    this._suppressValueChangeAction()                }            },            _clean: function() {                delete this._$spinContainer;                delete this._$spinUp;                delete this._$spinDown;                this.callBase()            },            _optionChanged: function(args) {                switch (args.name) {                    case"value":                        this._setValue(args.value, args.previousValue);                        this.callBase(args);                        this._resumeValueChangeAction();                        break;                    case"step":                    case"min":                    case"max":                        this._renderProps();                        break;                    case"showSpinButtons":                        this._renderInputAddons();                        break;                    case"useTouchSpinButtons":                        this._toggleTouchFriendlyClass();                        break;                    default:                        this.callBase(args)                }            }        }));        DX.registerComponent("dxSpinButton", ui.dxNumberBox, dxSpinButton);        ui.dxNumberBox.__internals = {            WIDGET_CLASS: WIDGET_CLASS,            SPIN_CLASS: SPIN_CLASS,            SPIN_CONTAINER_CLASS: SPIN_CONTAINER_CLASS,            SPIN_UP_CLASS: SPIN_UP_CLASS,            SPIN_DOWN_CLASS: SPIN_DOWN_CLASS        }    })(jQuery, DevExpress);    /*! Module widgets-base, file ui.radioButton.js */    (function($, DX, undefined) {        var ui = DX.ui,            events = ui.events;        var RADIO_BUTTON = "dxRadioButton",            RADIO_BUTTON_CLASS = "dx-radiobutton",            RADIO_BUTTON_ICON_CLASS = "dx-radiobutton-icon",            RADIO_BUTTON_ICON_DOT_CLASS = "dx-radiobutton-icon-dot",            RADIO_BUTTON_CHECKED_CLASS = "dx-radiobutton-checked",            RADIO_BUTTON_DXCLICK_EVENT_NAME = events.addNamespace("dxclick", RADIO_BUTTON);        DX.registerComponent(RADIO_BUTTON, ui, ui.Editor.inherit({            _supportedKeys: function() {                var click = function(e) {                        e.preventDefault();                        this._clickAction({jQueryEvent: e})                    };                return $.extend(this.callBase(), {space: click})            },            _setDefaultOptions: function() {                this.callBase();                this.option({value: false})            },            _defaultOptionsRules: function() {                return this.callBase().concat([{                            device: function(device) {                                return DX.devices.real().generic && !DX.devices.isSimulator()                            },                            options: {                                focusStateEnabled: true,                                hoverStateEnabled: true                            }                        }])            },            _init: function() {                this.callBase();                this.element().addClass(RADIO_BUTTON_CLASS)            },            _render: function() {                this.callBase();                this._renderIcon();                this._renderCheckedState(this.option("value"));                this._renderClick();                this.setAria("role", "radio")            },            _renderIcon: function() {                var $icon = $("<div>").addClass(RADIO_BUTTON_ICON_CLASS);                $("<div>").addClass(RADIO_BUTTON_ICON_DOT_CLASS).appendTo($icon);                this.element().append($icon)            },            _renderCheckedState: function(checked) {                this.element().toggleClass(RADIO_BUTTON_CHECKED_CLASS, checked);                this.setAria("checked", checked)            },            _renderClick: function() {                this._clickAction = this._createAction($.proxy(function(args) {                    this._clickHandler(args.jQueryEvent)                }, this));                this.element().off(RADIO_BUTTON_DXCLICK_EVENT_NAME).on(RADIO_BUTTON_DXCLICK_EVENT_NAME, $.proxy(function(e) {                    this._clickAction({jQueryEvent: e})                }, this))            },            _clickHandler: function(e) {                this._saveValueChangeEvent(e);                this.option("value", true)            },            _optionChanged: function(args) {                switch (args.name) {                    case"value":                        this._renderCheckedState(args.value);                        this.callBase(args);                        break;                    default:                        this.callBase(args)                }            }        }))    })(jQuery, DevExpress);    /*! Module widgets-base, file ui.radioGroup.js */    (function($, DX, undefined) {        var ui = DX.ui;        var RADIO_GROUP_CLASS = "dx-radiogroup",            RADIO_GROUP_VERTICAL_CLASS = "dx-radiogroup-vertical",            RADIO_GROUP_HORIZONTAL_CLASS = "dx-radiogroup-horizontal",            RADIO_BUTTON_CLASS = "dx-radiobutton",            RADIO_BUTTON_ICON_CLASS = "dx-radiobutton-icon",            RADIO_BUTTON_ICON_DOT_CLASS = "dx-radiobutton-icon-dot",            RADIO_VALUE_CONTAINER_CLASS = "dx-radio-value-container",            RADIO_BUTTON_CHECKED_CLASS = "dx-radiobutton-checked",            ITEM_DATA_KEY = "dxItemData",            RADIO_FEEDBACK_HIDE_TIMEOUT = 100;        var dxRadioCollection = ui.CollectionWidget.inherit({                _setDefaultOptions: function() {                    this.callBase();                    this.option($.extend(this._dataExpressionDefaultOptions(), {_itemAttributes: {role: "radio"}}))                },                _getAriaTarget: function() {                    return this._focusTarget()                },                _focusTarget: function() {                    return this.element().parent()                },                _keyboardEventBindingTarget: function() {                    return this._focusTarget()                }            });        DX.registerComponent("dxRadioGroup", ui, ui.Editor.inherit({            _activeStateUnit: "." + RADIO_BUTTON_CLASS,            _setDeprecatedOptions: function() {                this.callBase();                $.extend(this._deprecatedOptions, this._dataExpressionDeprecatedOptions())            },            _setDefaultOptions: function() {                this.callBase();                this.option($.extend(this._dataExpressionDefaultOptions(), {layout: "vertical"}))            },            _defaultOptionsRules: function() {                return this.callBase().concat([{                            device: {tablet: true},                            options: {layout: "horizontal"}                        }, {                            device: function(device) {                                return DX.devices.real().generic && !DX.devices.isSimulator()                            },                            options: {                                focusStateEnabled: true,                                hoverStateEnabled: true                            }                        }])            },            _setOptionsByReference: function() {                this.callBase();                $.extend(this._optionsByReference, {value: true})            },            _dataSourceOptions: function() {                return {paginate: false}            },            _init: function() {                this.callBase();                this._initDataExpressions();                this._feedbackHideTimeout = RADIO_FEEDBACK_HIDE_TIMEOUT            },            _render: function() {                this.element().addClass(RADIO_GROUP_CLASS);                this._renderRadios();                this.setAria("role", "radiogroup");                this.callBase();                this._renderLayout();                this._updateItemsSize()            },            _renderFocusState: $.noop,            _renderRadios: function() {                var $radios = $("<div>").appendTo(this.element());                this._radios = this._createComponent($radios, "dxRadioCollection", {                    dataSource: this._dataSource,                    onItemRendered: $.proxy(this._itemRenderedHandler, this),                    onItemClick: $.proxy(this._itemClickHandler, this),                    itemTemplate: this._getTemplateByOption("itemTemplate"),                    scrollingEnabled: false,                    focusStateEnabled: this.option("focusStateEnabled"),                    accessKey: this.option("accessKey"),                    tabIndex: this.option("tabIndex"),                    noDataText: "",                    disabled: this.option("disabled")                });                this._setCollectionWidgetOption("onContentReady", $.proxy(this._contentReadyHandler, this));                this._contentReadyHandler()            },            _contentReadyHandler: function() {                this.itemElements().addClass(RADIO_BUTTON_CLASS);                this._refreshSelected()            },            _itemRenderedHandler: function(e) {                if (e.itemData.html)                    return;                var $radio,                    $radioContainer;                $radio = $("<div>").addClass(RADIO_BUTTON_ICON_CLASS);                $("<div>").addClass(RADIO_BUTTON_ICON_DOT_CLASS).appendTo($radio);                $radioContainer = $("<div>").append($radio).addClass(RADIO_VALUE_CONTAINER_CLASS);                e.itemElement.prepend($radioContainer)            },            _itemClickHandler: function(e) {                this.option("value", this._getItemValue(e.itemData))            },            _getItemValue: function(item) {                return !!this._valueGetter ? this._valueGetter(item) : item.text            },            itemElements: function() {                return this._radios.itemElements()            },            _renderDimensions: function() {                this.callBase();                this._updateItemsSize()            },            _renderLayout: function() {                var layout = this.option("layout");                this.element().toggleClass(RADIO_GROUP_VERTICAL_CLASS, layout === "vertical");                this.element().toggleClass(RADIO_GROUP_HORIZONTAL_CLASS, layout === "horizontal")            },            _refreshSelected: function() {                var selectedValue = this.option("value");                this.itemElements().each($.proxy(function(_, item) {                    var $item = $(item);                    var itemValue = this._valueGetter($item.data(ITEM_DATA_KEY));                    $item.toggleClass(RADIO_BUTTON_CHECKED_CLASS, this._isValueEquals(itemValue, selectedValue));                    this.setAria("checked", this._isValueEquals(itemValue, selectedValue), $item)                }, this))            },            _updateItemsSize: function() {                if (this.option("layout") === "horizontal")                    this.itemElements().css("height", "auto");                else {                    var itemsCount = this.option("items").length;                    this.itemElements().css("height", 100 / itemsCount + "%")                }            },            _setCollectionWidgetOption: function() {                this._setWidgetOption("_radios", arguments)            },            _optionChanged: function(args) {                this._dataExpressionOptionChanged(args);                switch (args.name) {                    case"focusStateEnabled":                    case"accessKey":                    case"tabIndex":                        this._setCollectionWidgetOption(args.name, args.value);                        break;                    case"disabled":                        this.callBase(args);                        this._setCollectionWidgetOption(args.name, args.value);                        break;                    case"dataSource":                        this._setCollectionWidgetOption("dataSource");                        break;                    case"valueExpr":                        this._refreshSelected();                        break;                    case"value":                        this._refreshSelected();                        this.callBase(args);                        break;                    case"items":                    case"itemTemplate":                    case"displayExpr":                        break;                    case"layout":                        this._renderLayout();                        this._updateItemsSize();                        break;                    default:                        this.callBase(args)                }            }        }).include(ui.DataExpressionMixin));        DX.registerComponent("dxRadioCollection", ui.dxRadioGroup, dxRadioCollection)    })(jQuery, DevExpress);    /*! Module widgets-base, file ui.tabs.js */    (function($, DX, undefined) {        var ui = DX.ui,            events = ui.events,            TABS_CLASS = "dx-tabs",            TABS_WRAPPER_CLASS = "dx-indent-wrapper",            TABS_EXPANDED_CLASS = "dx-tabs-expanded",            TABS_SCROLLABLE_CLASS = "dx-scrollable-wrapper",            TABS_NAV_BUTTONS_CLASS = "dx-tabs-nav-buttons",            TABS_ITEM_CLASS = "dx-tab",            TABS_ITEM_SELECTOR = ".dx-tab",            TABS_ITEM_SELECTED_CLASS = "dx-tab-selected",            TABS_NAV_BUTTON_CLASS = "dx-tabs-nav-button",            TABS_LEFT_NAV_BUTTON_CLASS = "dx-tabs-nav-button-left",            TABS_RIGHT_NAV_BUTTON_CLASS = "dx-tabs-nav-button-right",            TABS_ITEM_DATA_KEY = "dxTabData",            FEEDBACK_HIDE_TIMEOUT = 100,            FEEDBACK_DURATION_INTERVAL = 5,            FEEDBACK_SCROLL_TIMEOUT = 300,            ACTIVE_STATE_CLASS = "dx-state-active",            TAB_OFFSET = 30;        DX.registerComponent("dxTabs", ui, ui.CollectionWidget.inherit({            _activeStateUnit: TABS_ITEM_SELECTOR,            _setDefaultOptions: function() {                this.callBase();                this.option({                    showNavButtons: false,                    scrollByContent: true,                    scrollingEnabled: true,                    wordWrap: false,                    selectionMode: "single",                    activeStateEnabled: true,                    selectionRequired: false,                    selectOnFocus: true,                    loopItemFocus: false                })            },            _defaultOptionsRules: function() {                return this.callBase().concat([{                            device: {platform: "win8"},                            options: {wordWrap: true}                        }, {                            device: {platform: "generic"},                            options: {                                showNavButtons: true,                                scrollByContent: false                            }                        }, {                            device: function(device) {                                return DX.devices.real().generic && !DX.devices.isSimulator()                            },                            options: {                                hoverStateEnabled: true,                                focusStateEnabled: true                            }                        }])            },            _init: function() {                this.callBase();                this._renderMultiple();                this.element().addClass(TABS_CLASS);                this._feedbackHideTimeout = FEEDBACK_HIDE_TIMEOUT            },            _itemClass: function() {                return TABS_ITEM_CLASS            },            _selectedItemClass: function() {                return TABS_ITEM_SELECTED_CLASS            },            _itemDataKey: function() {                return TABS_ITEM_DATA_KEY            },            _render: function() {                this.element().removeClass(TABS_EXPANDED_CLASS);                this.callBase();                this._renderWrapper();                if (this._allowScrolling()) {                    this._renderScrollable();                    this._renderNavButtons();                    this._updateNavButtons()                }                else {                    this.element().removeClass(TABS_NAV_BUTTONS_CLASS);                    this.element().addClass(TABS_EXPANDED_CLASS)                }                this.setAria("role", "tablist");                var that = this;                this.itemElements().each(function(_, item) {                    that.setAria("role", "tab", $(item))                });                this.element().addClass(ACTIVE_STATE_CLASS).removeClass(ACTIVE_STATE_CLASS)            },            _renderMultiple: function() {                if (this.option("selectionMode") === "multi")                    this.option("selectOnFocus", false)            },            _renderWrapper: function() {                this.element().wrapInner($("<div>").addClass(TABS_WRAPPER_CLASS))            },            _renderScrollable: function() {                var $itemContainer = this.element().wrapInner($("<div>").addClass(TABS_SCROLLABLE_CLASS)).children();                this._scrollable = this._createComponent($itemContainer, "dxScrollable", {                    direction: "horizontal",                    showScrollbar: false,                    useKeyboard: false,                    useNative: false,                    scrollByContent: this.option("scrollByContent"),                    onScroll: $.proxy(this._updateNavButtonsVisibility, this)                });                this.element().append(this._scrollable.element())            },            _allowScrolling: function() {                if (this.option("wordWrap"))                    return false;                if (!this.option("scrollingEnabled"))                    return false;                var tabItemsWidth = 0;                this.itemElements().each(function(_, tabItem) {                    tabItemsWidth += $(tabItem).outerWidth(true)                });                return tabItemsWidth - 1 > this.element().width()            },            _renderNavButtons: function() {                this.element().toggleClass(TABS_NAV_BUTTONS_CLASS, this.option("showNavButtons"));                if (this.option("showNavButtons")) {                    this._leftButton = this._createNavButton(-TAB_OFFSET, "chevronprev");                    var $leftButton = this._leftButton.element();                    $leftButton.addClass(TABS_LEFT_NAV_BUTTON_CLASS);                    this.element().prepend($leftButton);                    this._rightButton = this._createNavButton(TAB_OFFSET, "chevronnext");                    var $rightButton = this._rightButton.element();                    $rightButton.addClass(TABS_RIGHT_NAV_BUTTON_CLASS);                    this.element().append($rightButton);                    this._updateNavButtonsVisibility();                    this._scrollable.update();                    if (this.option("rtlEnabled"))                        this._scrollable.scrollTo({left: this._scrollable.scrollWidth() - this._scrollable.clientWidth()})                }            },            _updateNavButtonsVisibility: function() {                this._leftButton && this._leftButton.option("disabled", this._scrollable.scrollLeft() <= 0);                this._rightButton && this._rightButton.option("disabled", this._scrollable.scrollLeft() >= this._scrollable.scrollWidth() - this._scrollable.clientWidth())            },            _updateScrollPosition: function(offset, duration) {                this._scrollable.update();                this._scrollable.scrollBy(offset / duration)            },            _createNavButton: function(offset, icon) {                var that = this;                var holdAction = that._createAction(function() {                        that._holdInterval = setInterval(function() {                            that._updateScrollPosition(offset, FEEDBACK_DURATION_INTERVAL)                        }, FEEDBACK_DURATION_INTERVAL)                    }),                    holdEventName = events.addNamespace('dxhold', "dxButton"),                    pointerUpEventName = events.addNamespace('dxpointerup', "dxButton"),                    pointerOutEventName = events.addNamespace('dxpointerout', "dxButton");                var navButton = this._createComponent($("<div>").addClass(TABS_NAV_BUTTON_CLASS), "dxButton", {                        focusStateEnabled: false,                        icon: icon,                        onClick: function() {                            that._updateScrollPosition(offset, 1)                        },                        _templates: {}                    });                navButton.element().on(holdEventName, {timeout: FEEDBACK_SCROLL_TIMEOUT}, $.proxy(function(e) {                    holdAction({jQueryEvent: e})                }, this)).on(pointerUpEventName, function() {                    that._clearInterval()                }).on(pointerOutEventName, function() {                    that._clearInterval()                });                return navButton            },            _clearInterval: function() {                if (this._holdInterval)                    clearInterval(this._holdInterval)            },            _updateNavButtons: function() {                var $element = this.element(),                    tabsHeight = $element.height();                $element.find("." + TABS_LEFT_NAV_BUTTON_CLASS).css({height: tabsHeight});                $element.find("." + TABS_RIGHT_NAV_BUTTON_CLASS).css({                    height: tabsHeight,                    "margin-top": -tabsHeight                })            },            _renderSelection: function(addedSelection) {                this._scrollable && this._scrollable.scrollToElement(this.itemElements().eq(addedSelection[0]))            },            _visibilityChanged: function(visible) {                if (visible)                    this._dimensionChanged()            },            _dimensionChanged: function() {                this._refresh()            },            _itemSelectHandler: function(e) {                if (this.option("selectionMode") === "single" && this.isItemSelected(e.currentTarget))                    return;                this.callBase(e)            },            _optionChanged: function(args) {                switch (args.name) {                    case"wordWrap":                    case"scrollingEnabled":                    case"showNavButtons":                        this._invalidate();                        break;                    case"scrollByContent":                        this._scrollable && this._scrollable.option(args.name, args.value);                        break;                    case"selectionMode":                        this._renderMultiple();                        this.callBase(args);                        break;                    default:                        this.callBase(args)                }            }        }))    })(jQuery, DevExpress);    /*! Module widgets-base, file ui.navBar.js */    (function($, DX, undefined) {        var ui = DX.ui,            NAVBAR_CLASS = "dx-navbar",            ITEM_CLASS = "dx-item-content",            NAVBAR_ITEM_CLASS = "dx-nav-item",            NAVBAR_ITEM_CONTENT_CLASS = "dx-nav-item-content";        DX.registerComponent("dxNavBar", ui, ui.dxTabs.inherit({            _setDefaultOptions: function() {                this.callBase();                this.option({scrollingEnabled: false})            },            _render: function() {                this.callBase();                this.element().addClass(NAVBAR_CLASS)            },            _postprocessRenderItem: function(args) {                this.callBase(args);                var $itemElement = args.itemElement,                    itemData = args.itemData;                $itemElement.addClass(NAVBAR_ITEM_CLASS);                $itemElement.find("." + ITEM_CLASS).addClass(NAVBAR_ITEM_CONTENT_CLASS);                if (!itemData.icon && !itemData.iconSrc)                    $itemElement.addClass("dx-navbar-text-item")            }        }))    })(jQuery, DevExpress);    /*! Module widgets-base, file ui.toolbar.js */    (function($, DX, undefined) {        var ui = DX.ui,            fx = DX.fx,            translator = DX.translator;        var TOOLBAR_CLASS = "dx-toolbar",            TOOLBAR_BOTTOM_CLASS = "dx-toolbar-bottom",            TOOLBAR_MINI_CLASS = "dx-toolbar-mini",            TOOLBAR_ITEM_CLASS = "dx-toolbar-item",            TOOLBAR_LABEL_CLASS = "dx-toolbar-label",            TOOLBAR_BUTTON_CLASS = "dx-toolbar-button",            TOOLBAR_MENU_CONTAINER_CLASS = "dx-toolbar-menu-container",            TOOLBAR_MENU_BUTTON_CLASS = "dx-toolbar-menu-button",            TOOLBAR_ITEMS_CONTAINER_CLASS = "dx-toolbar-items-container",            TOOLBAR_LABEL_SELECTOR = "." + TOOLBAR_LABEL_CLASS,            TOOLBAR_ITEM_DATA_KEY = "dxToolbarItemDataKey",            SUBMENU_SWIPE_EASING = "easeOutCubic",            SUBMENU_HIDE_DURATION = 200,            SUBMENU_SHOW_DURATION = 400;        var slideSubmenu = function($element, position, isShowAnimation) {                var duration = isShowAnimation ? SUBMENU_SHOW_DURATION : SUBMENU_HIDE_DURATION;                fx.animate($element, {                    type: "slide",                    to: {top: position},                    easing: SUBMENU_SWIPE_EASING,                    duration: duration                })            };        DX.registerComponent("dxToolbar", ui, ui.CollectionWidget.inherit({            _setDeprecatedOptions: function() {                this.callBase();                $.extend(this._deprecatedOptions, {menuItemRender: {                        since: "14.2",                        alias: "menuItemTemplate"                    }})            },            _setDefaultOptions: function() {                this.callBase();                this.option({                    menuItemTemplate: "menuItem",                    submenuType: "dxDropDownMenu",                    renderAs: "topToolbar"                })            },            _defaultOptionsRules: function() {                return this.callBase().concat([{                            device: {platform: "ios"},                            options: {submenuType: "dxActionSheet"}                        }, {                            device: {platform: "android"},                            options: {submenuType: "dxDropDownMenu"}                        }, {                            device: {platform: "win8"},                            options: {submenuType: "dxList"}                        }])            },            _itemContainer: function() {                return this._$toolbarItemsContainer.find([".dx-toolbar-before", ".dx-toolbar-center", ".dx-toolbar-after"].join(","))            },            _itemClass: function() {                return TOOLBAR_ITEM_CLASS            },            _itemDataKey: function() {                return TOOLBAR_ITEM_DATA_KEY            },            _dimensionChanged: function() {                if (this._menu)                    this._toggleMenuVisibility(false, true);                this._arrangeTitle()            },            _render: function() {                this._renderToolbar();                this._renderSections();                this.callBase();                this._renderMenu();                this._arrangeTitle();                this.setAria("role", "toolbar")            },            _renderToolbar: function() {                this.element().addClass(TOOLBAR_CLASS).toggleClass(TOOLBAR_BOTTOM_CLASS, this.option("renderAs") === "bottomToolbar");                this._$toolbarItemsContainer = $("<div>").appendTo(this.element());                this._$toolbarItemsContainer.addClass(TOOLBAR_ITEMS_CONTAINER_CLASS)            },            _renderSections: function() {                var $container = this._$toolbarItemsContainer,                    that = this;                $.each(["before", "center", "after"], function() {                    var sectionClass = "dx-toolbar-" + this,                        $section = $container.find("." + sectionClass);                    if (!$section.length)                        that["_$" + this + "Section"] = $section = $("<div>").addClass(sectionClass).appendTo($container)                })            },            _arrangeTitle: function() {                if (this.element().is(":hidden"))                    return;                var $section = this._$toolbarItemsContainer.find(TOOLBAR_LABEL_SELECTOR).eq(0).parent(),                    $label = $section.children(TOOLBAR_LABEL_SELECTOR).eq(0);                if (!$label.length)                    return;                var containerWidth = this._$toolbarItemsContainer.width(),                    labelOffset = this._$beforeSection.outerWidth() ? this._$beforeSection.outerWidth() : $label.position().left,                    widthBeforeSection = $section.hasClass("dx-toolbar-before") ? 0 : labelOffset,                    widthAfterSection = $section.hasClass("dx-toolbar-after") ? 0 : this._$afterSection.outerWidth(),                    elemsAtSectionWidth = 10;                $section.children().not(TOOLBAR_LABEL_SELECTOR).each(function() {                    elemsAtSectionWidth += $(this).outerWidth()                });                var maxLabelWidth = containerWidth - widthBeforeSection - widthAfterSection - elemsAtSectionWidth,                    labelLongerThanMax = $label.outerWidth() > maxLabelWidth;                $section.css({                    marginLeft: labelLongerThanMax ? widthBeforeSection : "",                    marginRight: labelLongerThanMax ? widthAfterSection : ""                });                $label.css("max-width", maxLabelWidth)            },            _renderItem: function(index, item) {                var location = item.location || "center",                    container = this._$toolbarItemsContainer.find(".dx-toolbar-" + location),                    itemHasTest = Boolean(item.text),                    itemElement = this.callBase(index, item, container);                itemElement.toggleClass(TOOLBAR_BUTTON_CLASS, !itemHasTest).toggleClass(TOOLBAR_LABEL_CLASS, itemHasTest);                return itemElement            },            _hasVisibleMenuItems: function() {                var menuItems = this._getMenuItems(),                    result = false;                var optionGetter = DevExpress.data.utils.compileGetter("visible");                $.each(menuItems, function(index, item) {                    var itemVisible = optionGetter(item, {functionsAsIs: true});                    if (itemVisible !== false)                        result = true                });                return result            },            _getToolbarItems: function() {                return $.grep(this.option("items") || [], function(item) {                        return item.location !== "menu"                    })            },            _getMenuItems: function() {                return $.grep(this.option("items") || [], function(item) {                        return item.location === "menu"                    })            },            _renderContentImpl: function() {                var items = this._getToolbarItems();                this.element().toggleClass(TOOLBAR_MINI_CLASS, items.length === 0);                if (this._renderedItemsCount)                    this._renderItems(items.slice(this._renderedItemsCount));                else                    this._renderItems(items)            },            _renderMenu: function() {                var that = this,                    itemClickAction = this._createActionByOption("onItemClick");                var options = {                        itemTemplate: function() {                            if (that._menuType === "dxActionSheet")                                return that._getTemplate("actionSheetItem");                            return that._getTemplateByOption("menuItemTemplate")                        },                        onItemClick: function(e) {                            that._toggleMenuVisibility(false, true);                            itemClickAction(e)                        }                    };                this._menuType = this.option("submenuType");                if (this._menuType === "dxList" && this.option("renderAs") === "topToolbar")                    this._menuType = "dxDropDownMenu";                switch (this._menuType) {                    case"dxActionSheet":                        this._renderActionSheet(options);                        break;                    case"dxDropDownMenu":                        this._renderDropDown(options);                        break;                    case"dxList":                        this._renderList(options);                        break                }            },            _renderMenuButton: function(options) {                var buttonOptions = $.extend({onClick: $.proxy(this._menuButtonClickHandler, this)}, options);                this._renderMenuButtonContainer();                this._$button = $("<div>").appendTo(this._$menuButtonContainer).addClass(TOOLBAR_MENU_BUTTON_CLASS);                this._createComponent(this._$button, "dxButton", buttonOptions)            },            _renderMenuButtonContainer: function() {                var $afterSection = this._$afterSection;                this._$menuButtonContainer = $("<div>").appendTo($afterSection).addClass(TOOLBAR_BUTTON_CLASS).addClass(TOOLBAR_MENU_CONTAINER_CLASS)            },            _renderDropDown: function(options) {                if (!this._hasVisibleMenuItems())                    return;                this._renderMenuButtonContainer();                var $menu = $("<div>").appendTo(this._$menuButtonContainer);                this._menu = this._createComponent($menu, "dxDropDownMenu", options);                this._renderMenuItems()            },            _renderActionSheet: function(options) {                if (!this._hasVisibleMenuItems())                    return;                this._renderMenuButton({icon: "overflow"});                var actionSheetOptions = $.extend({                        target: this._$button,                        showTitle: false                    }, options);                var $menu = $("<div>").appendTo(this.element());                this._menu = this._createComponent($menu, "dxActionSheet", actionSheetOptions);                this._renderMenuItems()            },            _renderList: function(options) {                this._renderMenuButton({                    activeStateEnabled: false,                    text: "..."                });                var listOptions = $.extend({                        width: "100%",                        indicateLoading: false                    }, options);                this._renderListOverlay();                this._renderContainerSwipe();                if (this._hasVisibleMenuItems()) {                    var $menu = $("<div>").appendTo(this._listOverlay.content());                    this._menu = this._createComponent($menu, "dxList", listOptions);                    this._renderMenuItems()                }                this._changeListVisible(this.option("visible"))            },            _renderMenuItems: function() {                this._menu.option("items", this._getMenuItems())            },            _getListHeight: function() {                var listHeight = this._listOverlay.content().find(".dx-list").height(),                    semiHiddenHeight = this._$toolbarItemsContainer.height() - this.element().height();                return listHeight + semiHiddenHeight            },            _renderListOverlay: function() {                var $listOverlay = $("<div>").appendTo(this.element());                this._listOverlay = this._createComponent($listOverlay, "dxOverlay", {                    container: false,                    deferRendering: false,                    shading: false,                    height: "auto",                    width: "100%",                    showTitle: false,                    closeOnOutsideClick: $.proxy(this._listOutsideClickHandler, this),                    position: null,                    animation: null,                    closeOnBackButton: false                })            },            _hideTopOverlayHandler: function() {                this._toggleMenuVisibility(false, true)            },            _toggleHideTopOverlayCallback: function() {                if (this._closeCallback)                    DX.hideTopOverlayCallback.remove(this._closeCallback);                if (this._menuShown) {                    this._closeCallback = $.proxy(this._hideTopOverlayHandler, this);                    DX.hideTopOverlayCallback.add(this._closeCallback)                }            },            _renderContainerSwipe: function() {                this._createComponent(this._$toolbarItemsContainer.appendTo(this._listOverlay.content()), "dxSwipeable", {                    elastic: false,                    onStart: $.proxy(this._swipeStartHandler, this),                    onUpdated: $.proxy(this._swipeUpdateHandler, this),                    onEnd: $.proxy(this._swipeEndHandler, this),                    itemSizeFunc: $.proxy(this._getListHeight, this),                    direction: "vertical"                })            },            _listOutsideClickHandler: function(e) {                if (!$(e.target).closest(this._listOverlay.content()).length)                    this._toggleMenuVisibility(false, true)            },            _calculatePixelOffset: function(offset) {                offset = (offset || 0) - 1;                var maxOffset = this._getListHeight();                return offset * maxOffset            },            _swipeStartHandler: function(e) {                e.jQueryEvent.maxTopOffset = this._menuShown ? 0 : 1;                e.jQueryEvent.maxBottomOffset = this._menuShown ? 1 : 0            },            _swipeUpdateHandler: function(e) {                var offset = this._menuShown ? e.jQueryEvent.offset : 1 + e.jQueryEvent.offset;                this._renderMenuPosition(offset, false)            },            _swipeEndHandler: function(e) {                var targetOffset = e.jQueryEvent.targetOffset;                targetOffset -= this._menuShown - 1;                this._toggleMenuVisibility(targetOffset === 0, true)            },            _renderMenuPosition: function(offset, animate) {                var pos = this._calculatePixelOffset(offset),                    element = this._listOverlay.content();                if (animate)                    slideSubmenu(element, pos, this._menuShown);                else                    translator.move(element, {top: pos})            },            _menuButtonClickHandler: function() {                this._toggleMenuVisibility(!this._menuShown, true)            },            _toggleMenuVisibility: function(visible, animate) {                this._menuShown = visible;                switch (this._menuType) {                    case"dxList":                        this._toggleHideTopOverlayCallback();                        this._renderMenuPosition(this._menuShown ? 0 : 1, animate);                        break;                    case"dxActionSheet":                        this._menu.toggle(this._menuShown);                        this._menuShown = false;                        break                }            },            _renderEmptyMessage: $.noop,            _clean: function() {                this._$toolbarItemsContainer.children().empty();                this.element().empty()            },            _changeMenuOption: function(name, value) {                if (this._menu)                    this._menu.option(name, value)            },            _changeListVisible: function(value) {                if (this._listOverlay) {                    this._listOverlay.option("visible", value);                    this._toggleMenuVisibility(false, false)                }            },            _visibilityChanged: function(visible) {                if (visible)                    this._arrangeTitle()            },            _renderDimensions: function() {                this.callBase();                this._arrangeTitle()            },            _optionChanged: function(args) {                var name = args.name;                var value = args.value;                switch (name) {                    case"renderAs":                    case"submenuType":                        this._invalidate();                        break;                    case"visible":                        this.callBase.apply(this, arguments);                        this._changeListVisible(value);                        break;                    case"menuItemTemplate":                        this._changeMenuOption("itemTemplate", this._getTemplate(value));                        break;                    case"onItemClick":                        this._changeMenuOption(name, value);                        this.callBase.apply(this, arguments);                        break;                    default:                        this.callBase.apply(this, arguments)                }            }        }))    })(jQuery, DevExpress);    /*! Module widgets-base, file ui.list.js */    (function($, DX, undefined) {        var ui = DX.ui,            events = ui.events,            utils = DX.utils;        var LIST_CLASS = "dx-list",            LIST_ITEM_CLASS = "dx-list-item",            LIST_ITEM_SELECTOR = "." + LIST_ITEM_CLASS,            LIST_GROUP_CLASS = "dx-list-group",            LIST_GROUP_HEADER_CLASS = "dx-list-group-header",            LIST_GROUP_BODY_CLASS = "dx-list-group-body",            LIST_COLLAPSIBLE_GROUPS_CLASS = "dx-list-collapsible-groups",            LIST_GROUP_COLLAPSED_CLASS = "dx-list-group-collapsed",            LIST_HAS_NEXT_CLASS = "dx-has-next",            LIST_NEXT_BUTTON_CLASS = "dx-list-next-button",            LIST_ITEM_DATA_KEY = "dxListItemData",            LIST_FEEDBACK_SHOW_TIMEOUT = 70;        var groupItemsGetter = DX.data.utils.compileGetter("items");        DX.registerComponent("dxList", ui, ui.CollectionWidget.inherit({            _activeStateUnit: LIST_ITEM_SELECTOR,            _supportedKeys: function() {                var that = this;                var moveFocusPerPage = function(direction) {                        var $item = getEdgeVisibleItem(direction),                            isFocusedItem = $item.is(that.option("focusedElement"));                        if (isFocusedItem) {                            scrollListTo($item, direction);                            $item = getEdgeVisibleItem(direction)                        }                        that.option("focusedElement", $item);                        that.scrollToItem($item)                    };                var getEdgeVisibleItem = function(direction) {                        var scrollTop = that.scrollTop(),                            containerHeight = that.element().height();                        var $item = that.option("focusedElement"),                            isItemVisible = true;                        if (!$item)                            return;                        while (isItemVisible) {                            var $nextItem = $item[direction]();                            if (!$nextItem.length)                                break;                            var nextItemLocation = $nextItem.position().top + $nextItem.outerHeight() / 2;                            isItemVisible = nextItemLocation < containerHeight + scrollTop && nextItemLocation > scrollTop;                            if (isItemVisible)                                $item = $nextItem                        }                        return $item                    };                var scrollListTo = function($item, direction) {                        var resultPosition = $item.position().top;                        if (direction === "prev")                            resultPosition = $item.position().top - that.element().height() + $item.outerHeight();                        that.scrollTo(resultPosition)                    };                return $.extend(this.callBase(), {                        leftArrow: $.noop,                        rightArrow: $.noop,                        pageUp: function() {                            moveFocusPerPage("prev");                            return false                        },                        pageDown: function() {                            moveFocusPerPage("next");                            return false                        }                    })            },            _setDeprecatedOptions: function() {                this.callBase();                $.extend(this._deprecatedOptions, {                    itemSwipeAction: {                        since: "14.2",                        alias: "onItemSwipe"                    },                    scrollAction: {                        since: "14.2",                        alias: "onScroll"                    },                    pullRefreshAction: {                        since: "14.2",                        alias: "onPullRefresh"                    },                    pageLoadingAction: {                        since: "14.2",                        alias: "onPageLoading"                    },                    groupRender: {                        since: "14.2",                        alias: "groupTemplate"                    },                    autoPagingEnabled: {                        since: "15.1",                        message: "Use the 'pageLoadMode' option instead"                    },                    showNextButton: {                        since: "15.1",                        message: "Use the 'pageLoadMode' option instead"                    }                })            },            _setDefaultOptions: function() {                this.callBase();                this.option({                    pullRefreshEnabled: false,                    scrollingEnabled: true,                    showScrollbar: "onScroll",                    useNative: true,                    bounceEnabled: true,                    scrollByContent: true,                    scrollByThumb: false,                    pullingDownText: Globalize.localize("dxList-pullingDownText"),                    pulledDownText: Globalize.localize("dxList-pulledDownText"),                    refreshingText: Globalize.localize("dxList-refreshingText"),                    pageLoadingText: Globalize.localize("dxList-pageLoadingText"),                    onScroll: null,                    onPullRefresh: null,                    onPageLoading: null,                    pageLoadMode: "scrollBottom",                    nextButtonText: Globalize.localize("dxList-nextButtonText"),                    onItemSwipe: null,                    grouped: false,                    onGroupRendered: null,                    collapsibleGroups: false,                    groupTemplate: "group",                    indicateLoading: true,                    activeStateEnabled: true,                    _itemAttributes: {role: "option"}                })            },            _defaultOptionsRules: function() {                return this.callBase().concat(ui.dxScrollable.deviceDependentOptions(), [{                            device: function(device) {                                return !DX.support.nativeScrolling && !DX.devices.isSimulator() && DX.devices.real().platform === "generic" && device.platform === "generic"                            },                            options: {                                showScrollbar: "onHover",                                pageLoadMode: "nextButton"                            }                        }, {                            device: function(device) {                                return DX.devices.real().generic && !DX.devices.isSimulator()                            },                            options: {                                hoverStateEnabled: true,                                focusStateEnabled: true                            }                        }])            },            _getOptionAliases: function() {                return $.extend(this.callBase(), {useNative: "useNativeScrolling"})            },            _itemClass: function() {                return LIST_ITEM_CLASS            },            _itemDataKey: function() {                return LIST_ITEM_DATA_KEY            },            _itemContainer: function() {                return this._$container            },            _allowDinamicItemsAppend: function() {                return true            },            _init: function() {                this.callBase();                this._$container = this.element();                this._initScrollView();                this._feedbackShowTimeout = LIST_FEEDBACK_SHOW_TIMEOUT;                this._createGroupRenderAction()            },            _dataSourceOptions: function() {                this._suppressDeprecatedWarnings();                var pagingEnabled = this.option("autoPagingEnabled");                pagingEnabled = utils.isDefined(this.option("showNextButton")) ? pagingEnabled || this.option("showNextButton") : pagingEnabled;                this._resumeDeprecatedWarnings();                return $.extend(this.callBase(), {paginate: utils.isDefined(pagingEnabled) ? pagingEnabled : true})            },            _initScrollView: function() {                this._suppressDeprecatedWarnings();                var scrollingEnabled = this.option("scrollingEnabled"),                    pullRefreshEnabled = scrollingEnabled && this.option("pullRefreshEnabled"),                    autoPagingEnabled = scrollingEnabled && utils.ensureDefined(this.option("autoPagingEnabled"), this.option("pageLoadMode") === "scrollBottom") && !!this._dataSource;                this._resumeDeprecatedWarnings();                this._scrollView = this._createComponent(this.element(), "dxScrollView", {                    disabled: this.option("disabled") || !scrollingEnabled,                    onScroll: $.proxy(this._scrollHandler, this),                    onPullDown: pullRefreshEnabled ? $.proxy(this._pullDownHandler, this) : null,                    onReachBottom: autoPagingEnabled ? $.proxy(this._scrollBottomHandler, this) : null,                    showScrollbar: this.option("showScrollbar"),                    useNative: this.option("useNativeScrolling"),                    bounceEnabled: this.option("bounceEnabled"),                    scrollByContent: this.option("scrollByContent"),                    scrollByThumb: this.option("scrollByThumb"),                    pullingDownText: this.option("pullingDownText"),                    pulledDownText: this.option("pulledDownText"),                    refreshingText: this.option("refreshingText"),                    reachBottomText: this.option("pageLoadingText"),                    useKeyboard: false                });                this._$container = this._scrollView.content();                this._createScrollViewActions()            },            _createScrollViewActions: function() {                this._scrollAction = this._createActionByOption("onScroll");                this._pullRefreshAction = this._createActionByOption("onPullRefresh");                this._pageLoadingAction = this._createActionByOption("onPageLoading")            },            _scrollHandler: function(e) {                this._scrollAction(e)            },            _updateLoadingState: function(tryLoadMore) {                this._suppressDeprecatedWarnings();                var isDataLoaded = !tryLoadMore || this._isLastPage(),                    autoPagingEnabled = utils.ensureDefined(this.option("autoPagingEnabled"), this.option("pageLoadMode") === "scrollBottom"),                    stopLoading = isDataLoaded || !autoPagingEnabled,                    hideLoadIndicator = stopLoading && !this._isDataSourceLoading();                this._resumeDeprecatedWarnings();                if (stopLoading || this._scrollViewIsFull()) {                    this._scrollView.release(hideLoadIndicator);                    this._toggleNextButton(this._shouldRenderNextButton() && !isDataLoaded);                    this._loadIndicationSuppressed(false)                }                else                    this._infiniteDataLoading()            },            _shouldRenderNextButton: function() {                this._suppressDeprecatedWarnings();                var result = utils.ensureDefined(this.option("showNextButton"), this.option("pageLoadMode") === "nextButton") && this._dataSource && this._dataSource.isLoaded();                this._resumeDeprecatedWarnings();                return result            },            _dataSourceLoadingChangedHandler: function(isLoading) {                if (this._loadIndicationSuppressed())                    return;                if (isLoading && this.option("indicateLoading"))                    this._showLoadingIndicatorTimer = setTimeout($.proxy(function() {                        this._scrollView && this._scrollView.startLoading()                    }, this));                else {                    clearTimeout(this._showLoadingIndicatorTimer);                    this._scrollView && this._scrollView.finishLoading()                }            },            _hideLoadingIfLoadIndicationOff: function() {                if (!this.option("indicateLoading"))                    this._dataSourceLoadingChangedHandler(false)            },            _loadIndicationSuppressed: function(value) {                if (!arguments.length)                    return this._isLoadIndicationSuppressed;                this._isLoadIndicationSuppressed = value            },            _scrollViewIsFull: function() {                return !this._scrollView || this._scrollView.isFull()            },            _pullDownHandler: function(e) {                this._pullRefreshAction(e);                if (this._dataSource && !this._isDataSourceLoading()) {                    this._dataSource.pageIndex(0);                    this._dataSource.load()                }                else                    this._updateLoadingState()            },            _infiniteDataLoading: function() {                if (!this._scrollViewIsFull() && !this._isDataSourceLoading() && !this._isLastPage()) {                    clearTimeout(this._loadNextPageTimer);                    this._loadNextPageTimer = setTimeout($.proxy(this._loadNextPage, this))                }            },            _scrollBottomHandler: function(e) {                this._pageLoadingAction(e);                if (!this._isDataSourceLoading())                    this._loadNextPage();                else                    this._updateLoadingState()            },            _renderItems: function(items) {                if (this.option("grouped")) {                    $.each(items, $.proxy(this._renderGroup, this));                    this._attachGroupCollapseEvent();                    this._renderEmptyMessage()                }                else                    this.callBase.apply(this, arguments);                this._updateLoadingState(true)            },            _attachGroupCollapseEvent: function() {                var eventName = events.addNamespace("dxclick", this.NAME),                    selector = "." + LIST_GROUP_HEADER_CLASS,                    $element = this.element(),                    collapsibleGroups = this.option("collapsibleGroups");                $element.toggleClass(LIST_COLLAPSIBLE_GROUPS_CLASS, collapsibleGroups);                $element.off(eventName, selector);                if (collapsibleGroups)                    $element.on(eventName, selector, $.proxy(function(e) {                        this._createAction($.proxy(function(e) {                            this._collapseGroupHandler($(e.jQueryEvent.currentTarget).parent())                        }, this), {validatingTargetName: "element"})({jQueryEvent: e})                    }, this))            },            _collapseGroupHandler: function($group, toggle) {                var deferred = $.Deferred(),                    $groupBody = $group.children("." + LIST_GROUP_BODY_CLASS);                $group.toggleClass(LIST_GROUP_COLLAPSED_CLASS, toggle);                var slideMethod = "slideToggle";                if (toggle === true)                    slideMethod = "slideUp";                if (toggle === false)                    slideMethod = "slideDown";                $groupBody[slideMethod]({                    duration: 200,                    complete: $.proxy(function() {                        this.updateDimensions();                        deferred.resolve()                    }, this)                });                return deferred.promise()            },            _dataSourceLoadErrorHandler: function() {                this._forgetNextPageLoading();                if (this._initialized) {                    this._renderEmptyMessage();                    this._updateLoadingState()                }            },            _render: function() {                this.element().addClass(LIST_CLASS);                this.callBase();                this.setAria("role", "listbox")            },            _postprocessRenderItem: function(args) {                this.callBase.apply(this, arguments);                if (this.option("onItemSwipe"))                    this._attachSwipeEvent($(args.itemElement))            },            _attachSwipeEvent: function($itemElement) {                var endEventName = events.addNamespace("dxswipeend", this.NAME);                $itemElement.on(endEventName, $.proxy(this._itemSwipeEndHandler, this))            },            _itemSwipeEndHandler: function(e) {                this._itemJQueryEventHandler(e, "onItemSwipe", {direction: e.offset < 0 ? "left" : "right"})            },            _nextButtonHandler: function() {                var source = this._dataSource;                if (source && !source.isLoading()) {                    this._scrollView.toggleLoading(true);                    this._$nextButton.detach();                    this._loadIndicationSuppressed(true);                    this._loadNextPage()                }            },            _renderGroup: function(index, group) {                var $groupElement = $("<div>").addClass(LIST_GROUP_CLASS).appendTo(this._itemContainer());                var $groupHeaderElement = $("<div>").addClass(LIST_GROUP_HEADER_CLASS).appendTo($groupElement);                var groupTemplateName = this.option("groupTemplate"),                    groupTemplate = this._getTemplate(group.template || groupTemplateName, group, index, $groupHeaderElement),                    renderArgs = {                        index: index,                        item: group,                        container: $groupHeaderElement                    };                this._createItemByTemplate(groupTemplate, renderArgs);                this._renderingGroupIndex = index;                var $groupBody = $("<div>").addClass(LIST_GROUP_BODY_CLASS).appendTo($groupElement);                $.each(groupItemsGetter(group) || [], $.proxy(function(index, item) {                    this._renderItem(index, item, $groupBody)                }, this));                this._groupRenderAction({                    groupElement: $groupElement,                    groupIndex: index,                    groupData: group                })            },            _createGroupRenderAction: function() {                this._groupRenderAction = this._createActionByOption("onGroupRendered")            },            _clean: function() {                if (this._$nextButton) {                    this._$nextButton.remove();                    this._$nextButton = null                }                this.callBase.apply(this, arguments)            },            _dispose: function() {                clearTimeout(this._holdTimer);                clearTimeout(this._loadNextPageTimer);                clearTimeout(this._showLoadingIndicatorTimer);                this.callBase()            },            _toggleDisabledState: function(value) {                this.callBase(value);                this._scrollView.option("disabled", value || !this.option("scrollingEnabled"))            },            _toggleNextButton: function(value) {                var dataSource = this._dataSource,                    $nextButton = this._getNextButton();                this.element().toggleClass(LIST_HAS_NEXT_CLASS, value);                if (value && dataSource && dataSource.isLoaded())                    $nextButton.appendTo(this._itemContainer());                if (!value)                    $nextButton.detach()            },            _getNextButton: function() {                if (!this._$nextButton)                    this._$nextButton = this._createNextButton();                return this._$nextButton            },            _createNextButton: function() {                var $result = $("<div>").addClass(LIST_NEXT_BUTTON_CLASS);                var $button = $("<div>").appendTo($result);                this._createComponent($button, "dxButton", {                    text: this.option("nextButtonText"),                    onClick: $.proxy(this._nextButtonHandler, this),                    _templates: {}                });                return $result            },            _moveFocus: function(location) {                this.callBase.apply(this, arguments);                this.scrollToItem(this.option("focusedElement"))            },            _optionChanged: function(args) {                switch (args.name) {                    case"pageLoadMode":                        this._toggleNextButton(args.value);                        this._initScrollView();                        break;                    case"showNextButton":                        this._toggleNextButton(args.value);                        break;                    case"dataSource":                        this.callBase(args);                        this._initScrollView();                        break;                    case"pullingDownText":                    case"pulledDownText":                    case"refreshingText":                    case"pageLoadingText":                    case"useNative":                    case"showScrollbar":                    case"bounceEnabled":                    case"scrollByContent":                    case"scrollByThumb":                    case"scrollingEnabled":                    case"pullRefreshEnabled":                    case"autoPagingEnabled":                        this._initScrollView();                        break;                    case"nextButtonText":                    case"onItemSwipe":                        this._invalidate();                        break;                    case"onScroll":                    case"onPullRefresh":                    case"onPageLoading":                        this._createScrollViewActions();                        this._invalidate();                        break;                    case"grouped":                    case"collapsibleGroups":                    case"groupTemplate":                        this._invalidate();                        break;                    case"onGroupRendered":                        this._createGroupRenderAction();                        break;                    case"items":                        this._invalidate();                        break;                    case"width":                    case"height":                        this.callBase(args);                        this._scrollView.update();                        break;                    case"indicateLoading":                        this._hideLoadingIfLoadIndicationOff();                        break;                    case"visible":                        this.callBase(args);                        this._scrollView.update();                        break;                    case"rtlEnabled":                        this._initScrollView();                        this.callBase(args);                        break;                    default:                        this.callBase(args)                }            },            _extendActionArgs: function($itemElement) {                if (!this.option("grouped"))                    return this.callBase($itemElement);                var $group = $itemElement.closest("." + LIST_GROUP_CLASS);                var $item = $group.find("." + LIST_ITEM_CLASS);                return $.extend(this.callBase($itemElement), {itemIndex: {                            group: $group.index(),                            item: $item.index($itemElement)                        }})            },            expandGroup: function(groupIndex) {                var deferred = $.Deferred(),                    $group = this._itemContainer().find("." + LIST_GROUP_CLASS).eq(groupIndex);                this._collapseGroupHandler($group, false).done($.proxy(function() {                    deferred.resolveWith(this)                }, this));                return deferred.promise()            },            collapseGroup: function(groupIndex) {                var deferred = $.Deferred(),                    $group = this._itemContainer().find("." + LIST_GROUP_CLASS).eq(groupIndex);                this._collapseGroupHandler($group, true).done($.proxy(function() {                    deferred.resolveWith(this)                }, this));                return deferred            },            updateDimensions: function() {                var that = this,                    deferred = $.Deferred();                if (that._scrollView)                    that._scrollView.update().done(function() {                        deferred.resolveWith(that)                    });                else                    deferred.resolveWith(that);                return deferred.promise()            },            reload: function() {                this.scrollTo(0);                this._pullDownHandler()            },            scrollTop: function() {                return this._scrollView.scrollOffset().top            },            clientHeight: function() {                return this._scrollView.clientHeight()            },            scrollHeight: function() {                return this._scrollView.scrollHeight()            },            scrollBy: function(distance) {                this._scrollView.scrollBy(distance)            },            scrollTo: function(location) {                this._scrollView.scrollTo(location)            },            scrollToItem: function(itemElement) {                var $item = this._editStrategy.getItemElement(itemElement);                this._scrollView.scrollToElement($item)            }        }))    })(jQuery, DevExpress);    /*! Module widgets-base, file ui.list.edit.js */    (function($, DX, undefined) {        var ui = DX.ui;        var LIST_ITEM_SELECTED_CLASS = "dx-list-item-selected",            LIST_ITEM_RESPONSE_WAIT_CLASS = "dx-list-item-response-wait";        DX.registerComponent("dxList", ui, ui.dxList.inherit({            _supportedKeys: function() {                var that = this,                    parent = this.callBase();                var deleteFocusedItem = function(e) {                        if (that.option("allowItemDeleting")) {                            e.preventDefault();                            that.deleteItem(that.option("focusedElement"))                        }                    };                var moveFocusedItemUp = function(e) {                        if (e.shiftKey && that.option("allowItemReordering")) {                            e.preventDefault();                            var focusedItemIndex = that._editStrategy.getNormalizedIndex(that.option("focusedElement")),                                $prevItem = that._editStrategy.getItemElement(focusedItemIndex - 1);                            that.reorderItem(that.option("focusedElement"), $prevItem);                            that.scrollToItem(that.option("focusedElement"))                        }                        else                            parent.upArrow(e)                    };                var moveFocusedItemDown = function(e) {                        if (e.shiftKey && that.option("allowItemReordering")) {                            e.preventDefault();                            var focusedItemIndex = that._editStrategy.getNormalizedIndex(that.option("focusedElement")),                                $nextItem = that._editStrategy.getItemElement(focusedItemIndex + 1);                            that.reorderItem(that.option("focusedElement"), $nextItem);                            that.scrollToItem(that.option("focusedElement"))                        }                        else                            parent.downArrow(e)                    };                return $.extend({}, parent, {                        del: deleteFocusedItem,                        upArrow: moveFocusedItemUp,                        downArrow: moveFocusedItemDown                    })            },            _setDeprecatedOptions: function() {                this.callBase();                $.extend(this._deprecatedOptions, {                    itemDeleteAction: {                        since: "14.2",                        alias: "onItemDeleted"                    },                    itemReorderAction: {                        since: "14.2",                        alias: "onItemReordered"                    },                    itemUnselectAction: {                        since: "14.2",                        message: "Use the 'onSelectionChanged' option instead"                    }                })            },            _setDefaultOptions: function() {                this.callBase();                this.option({                    showSelectionControls: false,                    selectionMode: 'none',                    selectAllText: Globalize.localize("dxList-selectAll"),                    menuItems: [],                    menuMode: "context",                    allowItemDeleting: false,                    itemDeleteMode: "toggle",                    allowItemReordering: false                })            },            _defaultOptionsRules: function() {                return this.callBase().concat([{                            device: function(device) {                                return device.platform === "ios"                            },                            options: {                                menuMode: "slide",                                itemDeleteMode: "slideItem"                            }                        }, {                            device: {platform: "android"},                            options: {itemDeleteMode: "swipe"}                        }, {                            device: {platform: "win8"},                            options: {itemDeleteMode: "context"}                        }, {                            device: {platform: "generic"},                            options: {itemDeleteMode: "static"}                        }])            },            _init: function() {                this.callBase();                this._initEditProvider()            },            _initEditProvider: function() {                this._editProvider = new ui.dxList.EditProvider(this)            },            _disposeEditProvider: function() {                if (this._editProvider)                    this._editProvider.dispose()            },            _refreshEditProvider: function() {                this._disposeEditProvider();                this._initEditProvider()            },            _initEditStrategy: function(grouped) {                if (this.option("grouped"))                    this._editStrategy = new ui.dxList.GroupedEditStrategy(this);                else                    this.callBase()            },            _render: function() {                this._refreshEditProvider();                this.callBase()            },            _renderItems: function() {                this.callBase.apply(this, arguments);                this._editProvider.afterItemsRendered()            },            _selectedItemClass: function() {                return LIST_ITEM_SELECTED_CLASS            },            _itemResponseWaitClass: function() {                return LIST_ITEM_RESPONSE_WAIT_CLASS            },            _itemClickHandler: function(e) {                var $itemElement = $(e.currentTarget);                if ($itemElement.is(".dx-state-disabled, .dx-state-disabled *"))                    return;                var handledByEditProvider = this._editProvider.handleClick($itemElement, e);                if (handledByEditProvider)                    return;                this.callBase.apply(this, arguments)            },            _shouldAttachContextMenuEvent: function() {                return this.callBase.apply(this, arguments) || this._editProvider.contextMenuHandlerExists()            },            _itemHoldHandler: function(e) {                var $itemElement = $(e.currentTarget);                if ($itemElement.is(".dx-state-disabled, .dx-state-disabled *"))                    return;                var isTouchEvent = ui.events.isTouchEvent(e),                    handledByEditProvider = isTouchEvent && this._editProvider.handleContextMenu($itemElement, e);                if (handledByEditProvider) {                    e.handledByEditProvider = true;                    return                }                this.callBase.apply(this, arguments)            },            _itemContextMenuHandler: function(e) {                var $itemElement = $(e.currentTarget);                if ($itemElement.is(".dx-state-disabled, .dx-state-disabled *"))                    return;                var handledByEditProvider = !e.handledByEditProvider && this._editProvider.handleContextMenu($itemElement, e);                if (handledByEditProvider)                    return;                this.callBase.apply(this, arguments)            },            _postprocessRenderItem: function(args) {                this.callBase.apply(this, arguments);                this._editProvider.modifyItemElement(args)            },            _clean: function() {                this._disposeEditProvider();                this.callBase()            },            _optionChanged: function(args) {                switch (args.name) {                    case"items":                        this._clearSelectedItems();                        this.callBase(args);                        break;                    case"grouped":                        this._clearSelectedItems();                        delete this._renderingGroupIndex;                        this._initEditStrategy(args.value);                        this.callBase(args);                        break;                    case"showSelectionControls":                    case"menuItems":                    case"menuMode":                    case"allowItemDeleting":                    case"itemDeleteMode":                    case"allowItemReordering":                    case"selectAllText":                        this._invalidate();                        break;                    default:                        this.callBase(args)                }            },            getFlatIndexByItemElement: function(itemElement) {                return this._itemElements().index(itemElement)            },            getItemElementByFlatIndex: function(flatIndex) {                var $itemElements = this._itemElements();                if (flatIndex < 0 || flatIndex >= $itemElements.length)                    return $();                return $itemElements.eq(flatIndex)            },            getItemByIndex: function(index) {                return this._getItemData(this._itemElements().eq(index))            }        }))    })(jQuery, DevExpress);    /*! Module widgets-base, file ui.list.edit.strategy.grouped.js */    (function($, DX, undefined) {        var ui = DX.ui;        var LIST_ITEM_CLASS = "dx-list-item",            LIST_GROUP_CLASS = "dx-list-group";        var SELECTION_SHIFT = 20,            SELECTION_MASK = 0x8FF;        var combineIndex = function(indices) {                return (indices.group << SELECTION_SHIFT) + indices.item            };        var splitIndex = function(combinedIndex) {                return {                        group: combinedIndex >> SELECTION_SHIFT,                        item: combinedIndex & SELECTION_MASK                    }            };        var createGroupSelection = function(group, selectedItems) {                var groupItems = group.items,                    groupSelection = {                        key: group.key,                        items: []                    };                $.each(selectedItems, function(_, itemIndex) {                    groupSelection.items.push(groupItems[itemIndex])                });                return groupSelection            };        var groupByKey = function(groups, key) {                var length = groups.length;                for (var i = 0; i < length; i++)                    if (groups[i].key === key)                        return groups[i]            };        ui.dxList.GroupedEditStrategy = ui.CollectionWidget.EditStrategy.inherit({            _groupElements: function() {                return this._collectionWidget._itemContainer().find("." + LIST_GROUP_CLASS)            },            _groupItemElements: function($group) {                return $group.find("." + LIST_ITEM_CLASS)            },            getIndexByItemData: function(itemData) {                return null            },            getItemDataByIndex: function(index) {                return null            },            deleteItemAtIndex: function(index) {                var indices = splitIndex(index),                    itemGroup = this._collectionWidget.option("items")[indices.group].items;                itemGroup.splice(indices.item, 1)            },            updateSelectionAfterDelete: function(fromIndex) {                var deletedIndices = splitIndex(fromIndex),                    selectedItemIndices = this._collectionWidget._selectedItemIndices;                $.each(selectedItemIndices, function(i, index) {                    var indices = splitIndex(index);                    if (indices.group === deletedIndices.group && indices.item > deletedIndices.item)                        selectedItemIndices[i] -= 1                })            },            fetchSelectedItems: function(indices) {                indices = indices || this._collectionWidget._selectedItemIndices;                var items = this._collectionWidget.option("items"),                    selectedItems = [];                indices.sort(function(a, b) {                    return a - b                });                var currentGroupIndex = 0,                    groupSelectedIndices = [];                $.each(indices, function(_, combinedIndex) {                    var index = splitIndex(combinedIndex);                    if (index.group !== currentGroupIndex && groupSelectedIndices.length) {                        selectedItems.push(createGroupSelection(items[currentGroupIndex], groupSelectedIndices));                        groupSelectedIndices.length = 0                    }                    currentGroupIndex = index.group;                    groupSelectedIndices.push(index.item)                });                if (groupSelectedIndices.length)                    selectedItems.push(createGroupSelection(items[currentGroupIndex], groupSelectedIndices));                return selectedItems            },            selectedItemIndices: function() {                var selectedIndices = [],                    items = this._collectionWidget.option("items"),                    selected = this._collectionWidget.option("selectedItems");                $.each(selected, function(_, selectionInGroup) {                    var group = groupByKey(items, selectionInGroup.key),                        groupIndex = $.inArray(group, items);                    if (!group) {                        DX.log("W1003", selectionInGroup.key);                        return                    }                    $.each(selectionInGroup.items, function(_, selectedGroupItem) {                        var itemIndex = $.inArray(selectedGroupItem, group.items);                        if (itemIndex !== -1)                            selectedIndices.push(combineIndex({                                group: groupIndex,                                item: itemIndex                            }));                        else                            DX.log("W1004", selectedGroupItem, selectionInGroup.key)                    })                });                return selectedIndices            },            moveItemAtIndexToIndex: function(movingIndex, destinationIndex) {                var items = this._collectionWidget.option("items"),                    movingIndices = splitIndex(movingIndex),                    destinationIndices = splitIndex(destinationIndex),                    movingItemGroup = items[movingIndices.group].items,                    destinationItemGroup = items[destinationIndices.group].items,                    movedItemData = movingItemGroup[movingIndices.item];                movingItemGroup.splice(movingIndices.item, 1);                destinationItemGroup.splice(destinationIndices.item, 0, movedItemData)            },            getSelectedItemsAfterReorderItem: function(movingIndex, destinationIndex) {                if (this._itemsFromSameParent(movingIndex, destinationIndex) || $.inArray(movingIndex, this._collectionWidget._selectedItemIndices))                    return this.callBase();                var items = this._collectionWidget.option("items"),                    selectedItems = this._collectionWidget.option("selectedItems"),                    movingIndices = splitIndex(movingIndex),                    destinationIndices = splitIndex(destinationIndex),                    movingSelectedItemGroup = selectedItems[movingIndices.group].items,                    destinationSelectedItemGroup = selectedItems[destinationIndices.group].items,                    movedItemData = items[movingIndices.group].items[movingIndices.item],                    movedItemSelectedIndex = $.inArray(movedItemData, movingSelectedItemGroup);                movingSelectedItemGroup.splice(movedItemSelectedIndex, 1);                destinationSelectedItemGroup.push(movedItemData);                return selectedItems            },            _isItemIndex: function(index) {                return $.isNumeric(index.group) && $.isNumeric(index.item)            },            _getNormalizedItemIndex: function(itemElement) {                var $item = $(itemElement),                    $group = $item.closest("." + LIST_GROUP_CLASS);                return combineIndex({                        group: this._groupElements().index($group),                        item: this._groupItemElements($group).index($item)                    })            },            _normalizeItemIndex: function(index) {                return combineIndex(index)            },            _denormalizeItemIndex: function(index) {                return splitIndex(index)            },            _getItemByNormalizedIndex: function(index) {                var indices = splitIndex(index),                    $group = this._groupElements().eq(indices.group);                return this._groupItemElements($group).eq(indices.item)            },            _itemsFromSameParent: function(firstIndex, secondIndex) {                return splitIndex(firstIndex).group === splitIndex(secondIndex).group            }        })    })(jQuery, DevExpress);    /*! Module widgets-base, file ui.list.edit.decorator.js */    (function($, DX, undefined) {        var ui = DX.ui,            events = ui.events;        ui.dxList.EditDecoratorsRegistry = {};        ui.dxList.registerEditDecorator = function(option, type, decoratorClass) {            var decoratorsRegistry = ui.dxList.EditDecoratorsRegistry;            var decoratorConfig = {};            decoratorConfig[option] = decoratorsRegistry[option] ? decoratorsRegistry[option] : {};            decoratorConfig[option][type] = decoratorClass;            decoratorsRegistry = $.extend(decoratorsRegistry, decoratorConfig)        };        var LIST_EDIT_DECORATOR = "dxListEditDecorator",            SWIPE_START_EVENT_NAME = events.addNamespace("dxswipestart", LIST_EDIT_DECORATOR),            SWIPE_UPDATE_EVENT_NAME = events.addNamespace("dxswipe", LIST_EDIT_DECORATOR),            SWIPE_END_EVENT_NAME = events.addNamespace("dxswipeend", LIST_EDIT_DECORATOR);        ui.dxList.EditDecorator = DX.Class.inherit({            ctor: function(list) {                this._list = list;                this._init()            },            _init: $.noop,            _shouldHandleSwipe: false,            _attachSwipeEvent: function(config) {                var swipeConfig = {itemSizeFunc: $.proxy(function() {                            if (this._clearSwipeCache) {                                this._itemWidthCache = this._list.element().width();                                this._clearSwipeCache = false                            }                            return this._itemWidthCache                        }, this)};                config.$itemElement.on(SWIPE_START_EVENT_NAME, swipeConfig, $.proxy(this._itemSwipeStartHandler, this)).on(SWIPE_UPDATE_EVENT_NAME, $.proxy(this._itemSwipeUpdateHandler, this)).on(SWIPE_END_EVENT_NAME, $.proxy(this._itemSwipeEndHandler, this))            },            _itemSwipeStartHandler: function(e) {                var $itemElement = $(e.currentTarget);                if ($itemElement.is(".dx-state-disabled, .dx-state-disabled *")) {                    e.cancel = true;                    return                }                this._swipeStartHandler($itemElement, e)            },            _itemSwipeUpdateHandler: function(e) {                var $itemElement = $(e.currentTarget);                this._swipeUpdateHandler($itemElement, e)            },            _itemSwipeEndHandler: function(e) {                var $itemElement = $(e.currentTarget);                this._swipeEndHandler($itemElement, e);                this._clearSwipeCache = true            },            beforeBag: $.noop,            afterBag: $.noop,            _commonOptions: function() {                return {                        activeStateEnabled: this._list.option("activeStateEnabled"),                        hoverStateEnabled: this._list.option("hoverStateEnabled"),                        focusStateEnabled: this._list.option("focusStateEnabled")                    }            },            modifyElement: function(config) {                if (this._shouldHandleSwipe) {                    this._attachSwipeEvent(config);                    this._clearSwipeCache = true                }            },            afterRender: $.noop,            handleClick: $.noop,            handleContextMenu: $.noop,            _swipeStartHandler: $.noop,            _swipeUpdateHandler: $.noop,            _swipeEndHandler: $.noop,            visibilityChange: $.noop,            dispose: $.noop        })    })(jQuery, DevExpress);    /*! Module widgets-base, file ui.list.edit.decoratorMenuHelper.js */    (function($, DX, undefined) {        var ui = DX.ui;        ui.dxList.EditDecoratorMenuHelperMixin = {            _menuEnabled: function() {                return !!this._menuItems().length            },            _menuItems: function() {                return this._list.option("menuItems")            },            _deleteEnabled: function() {                return this._list.option("allowItemDeleting")            },            _fireMenuAction: function($itemElement, action) {                this._list._itemEventHandlerByHandler($itemElement, action, {}, {excludeValidators: ["disabled", "readOnly"]})            }        }    })(jQuery, DevExpress);    /*! Module widgets-base, file ui.list.edit.decorator.static.js */    (function($, DX, undefined) {        var ui = DX.ui;        var STATIC_DELETE_BUTTON_CONTAINER_CLASS = "dx-list-static-delete-button-container",            STATIC_DELETE_BUTTON_CLASS = "dx-list-static-delete-button";        ui.dxList.registerEditDecorator("delete", "static", ui.dxList.EditDecorator.inherit({            afterBag: function(config) {                var $itemElement = config.$itemElement,                    $container = config.$container;                var $button = $("<div>").addClass(STATIC_DELETE_BUTTON_CLASS);                this._list._createComponent($button, "dxButton", {                    icon: "remove",                    type: "danger",                    onClick: $.proxy(function(e) {                        this._deleteItem($itemElement)                    }, this),                    _templates: {}                });                $container.addClass(STATIC_DELETE_BUTTON_CONTAINER_CLASS).append($button)            },            _deleteItem: function($itemElement) {                if ($itemElement.is(".dx-state-disabled, .dx-state-disabled *"))                    return;                this._list.deleteItem($itemElement)            }        }))    })(jQuery, DevExpress);    /*! Module widgets-base, file ui.list.edit.decorator.switchable.js */    (function($, DX, undefined) {        var ui = DX.ui,            events = ui.events;        var LIST_EDIT_DECORATOR = "dxListEditDecorator",            POINTER_DOWN_EVENT_NAME = events.addNamespace("dxpointerdown", LIST_EDIT_DECORATOR),            LIST_ITEM_CONTENT_CLASS = "dx-list-item-content",            SWITCHABLE_DELETE_READY_CLASS = "dx-list-switchable-delete-ready",            SWITCHABLE_MENU_SHIELD_POSITIONING_CLASS = "dx-list-switchable-menu-shield-positioning",            SWITCHABLE_DELETE_TOP_SHIELD_CLASS = "dx-list-switchable-delete-top-shield",            SWITCHABLE_DELETE_BOTTOM_SHIELD_CLASS = "dx-list-switchable-delete-bottom-shield",            SWITCHABLE_MENU_ITEM_SHIELD_POSITIONING_CLASS = "dx-list-switchable-menu-item-shield-positioning",            SWITCHABLE_DELETE_ITEM_CONTENT_SHIELD_CLASS = "dx-list-switchable-delete-item-content-shield";        ui.dxList.SwitchableEditDecorator = ui.dxList.EditDecorator.inherit({            _init: function() {                this._$topShield = $("<div />").addClass(SWITCHABLE_DELETE_TOP_SHIELD_CLASS);                this._$bottomShield = $("<div />").addClass(SWITCHABLE_DELETE_BOTTOM_SHIELD_CLASS);                this._$itemContentShield = $("<div />").addClass(SWITCHABLE_DELETE_ITEM_CONTENT_SHIELD_CLASS);                this._$topShield.on(POINTER_DOWN_EVENT_NAME, $.proxy(this._cancelDeleteReadyItem, this));                this._$bottomShield.on(POINTER_DOWN_EVENT_NAME, $.proxy(this._cancelDeleteReadyItem, this));                this._list.element().append(this._$topShield.toggle(false)).append(this._$bottomShield.toggle(false))            },            handleClick: function($itemElement) {                return this._cancelDeleteReadyItem()            },            _cancelDeleteReadyItem: function() {                if (!this._$readyToDeleteItem)                    return false;                this._cancelDelete(this._$readyToDeleteItem);                return true            },            _cancelDelete: function($itemElement) {                this._toggleDeleteReady($itemElement, false)            },            _toggleDeleteReady: function($itemElement, readyToDelete) {                if (readyToDelete === undefined)                    readyToDelete = !this._isReadyToDelete($itemElement);                this._toggleShields($itemElement, readyToDelete);                this._toggleScrolling(readyToDelete);                this._cacheReadyToDeleteItem($itemElement, readyToDelete);                this._animateToggleDelete($itemElement, readyToDelete)            },            _isReadyToDelete: function($itemElement) {                return $itemElement.hasClass(SWITCHABLE_DELETE_READY_CLASS)            },            _toggleShields: function($itemElement, enabled) {                this._list.element().toggleClass(SWITCHABLE_MENU_SHIELD_POSITIONING_CLASS, enabled);                this._$topShield.toggle(enabled);                this._$bottomShield.toggle(enabled);                if (enabled)                    this._updateShieldsHeight($itemElement);                this._toggleContentShield($itemElement, enabled)            },            _updateShieldsHeight: function($itemElement) {                var $list = this._list.element(),                    listTopOffset = $list.offset().top,                    listHeight = $list.outerHeight(),                    itemTopOffset = $itemElement.offset().top,                    itemHeight = $itemElement.outerHeight(),                    dirtyTopShieldHeight = itemTopOffset - listTopOffset,                    dirtyBottomShieldHeight = listHeight - itemHeight - dirtyTopShieldHeight;                this._$topShield.height(Math.max(dirtyTopShieldHeight, 0));                this._$bottomShield.height(Math.max(dirtyBottomShieldHeight, 0))            },            _toggleContentShield: function($itemElement, enabled) {                if (enabled)                    $itemElement.find("." + LIST_ITEM_CONTENT_CLASS).append(this._$itemContentShield);                else                    this._$itemContentShield.detach()            },            _toggleScrolling: function(readyToDelete) {                var scrollView = this._list.element().dxScrollView("instance");                if (readyToDelete) {                    this._scrollViewDisabled = scrollView.option("disabled");                    scrollView.option("disabled", true)                }                else                    scrollView.option("disabled", this._scrollViewDisabled)            },            _cacheReadyToDeleteItem: function($itemElement, cache) {                if (cache)                    this._$readyToDeleteItem = $itemElement;                else                    delete this._$readyToDeleteItem            },            _animateToggleDelete: function($itemElement, readyToDelete) {                if (readyToDelete) {                    this._enablePositioning($itemElement);                    this._prepareDeleteReady($itemElement);                    this._animatePrepareDeleteReady($itemElement)                }                else {                    this._forgetDeleteReady($itemElement);                    this._animateForgetDeleteReady($itemElement).done($.proxy(this._disablePositioning, this, $itemElement))                }            },            _enablePositioning: function($itemElement) {                $itemElement.addClass(SWITCHABLE_MENU_ITEM_SHIELD_POSITIONING_CLASS)            },            _disablePositioning: function($itemElement) {                $itemElement.removeClass(SWITCHABLE_MENU_ITEM_SHIELD_POSITIONING_CLASS)            },            _prepareDeleteReady: function($itemElement) {                $itemElement.addClass(SWITCHABLE_DELETE_READY_CLASS)            },            _forgetDeleteReady: function($itemElement) {                $itemElement.removeClass(SWITCHABLE_DELETE_READY_CLASS)            },            _animatePrepareDeleteReady: DX.abstract,            _animateForgetDeleteReady: DX.abstract,            _deleteItem: function($itemElement) {                $itemElement = $itemElement || this._$readyToDeleteItem;                if ($itemElement.is(".dx-state-disabled, .dx-state-disabled *"))                    return;                this._list.deleteItem($itemElement).always($.proxy(this._cancelDelete, this, $itemElement))            },            _isRtlEnabled: function() {                return this._list.option("rtlEnabled")            },            dispose: function() {                if (this._$topShield)                    this._$topShield.remove();                if (this._$bottomShield)                    this._$bottomShield.remove();                this.callBase.apply(this, arguments)            }        })    })(jQuery, DevExpress);    /*! Module widgets-base, file ui.list.edit.decorator.switchable.button.js */    (function($, DX, undefined) {        var ui = DX.ui,            fx = DX.fx;        var SWITCHABLE_DELETE_BUTTON_CONTAINER_CLASS = "dx-list-switchable-delete-button-container",            SWITCHABLE_DELETE_BUTTON_WRAPPER_CLASS = "dx-list-switchable-delete-button-wrapper",            SWITCHABLE_DELETE_BUTTON_INNER_WRAPPER_CLASS = "dx-list-switchable-delete-button-inner-wrapper",            SWITCHABLE_DELETE_BUTTON_CLASS = "dx-list-switchable-delete-button",            SWITCHABLE_DELETE_BUTTON_ANIMATION_DURATION = 200;        ui.dxList.SwitchableButtonEditDecorator = ui.dxList.SwitchableEditDecorator.inherit({            _init: function() {                this.callBase.apply(this, arguments);                var $buttonContainer = $("<div >").addClass(SWITCHABLE_DELETE_BUTTON_CONTAINER_CLASS),                    $buttonWrapper = $("<div />").addClass(SWITCHABLE_DELETE_BUTTON_WRAPPER_CLASS),                    $buttonInnerWrapper = $("<div />").addClass(SWITCHABLE_DELETE_BUTTON_INNER_WRAPPER_CLASS),                    $button = $("<div />").addClass(SWITCHABLE_DELETE_BUTTON_CLASS);                this._list._createComponent($button, "dxButton", {                    text: Globalize.localize("dxListEditDecorator-delete"),                    type: "danger",                    onClick: $.proxy(function(e) {                        this._deleteItem();                        e.jQueryEvent.stopPropagation()                    }, this),                    _templates: {}                });                $buttonContainer.append($buttonWrapper);                $buttonWrapper.append($buttonInnerWrapper);                $buttonInnerWrapper.append($button);                this._$buttonContainer = $buttonContainer            },            _enablePositioning: function($itemElement) {                this.callBase.apply(this, arguments);                fx.stop(this._$buttonContainer, true);                this._$buttonContainer.appendTo($itemElement)            },            _disablePositioning: function() {                this.callBase.apply(this, arguments);                this._$buttonContainer.detach()            },            _animatePrepareDeleteReady: function() {                var rtl = this._isRtlEnabled(),                    listWidth = this._list.element().width(),                    buttonWidth = this._buttonWidth(),                    fromValue = rtl ? listWidth : -buttonWidth,                    toValue = rtl ? listWidth - buttonWidth : 0;                return fx.animate(this._$buttonContainer, {                        type: "custom",                        duration: SWITCHABLE_DELETE_BUTTON_ANIMATION_DURATION,                        from: {right: fromValue},                        to: {right: toValue}                    })            },            _animateForgetDeleteReady: function() {                var rtl = this._isRtlEnabled(),                    listWidth = this._list.element().width(),                    buttonWidth = this._buttonWidth(),                    fromValue = rtl ? listWidth - buttonWidth : 0,                    toValue = rtl ? listWidth : -buttonWidth;                return fx.animate(this._$buttonContainer, {                        type: "custom",                        duration: SWITCHABLE_DELETE_BUTTON_ANIMATION_DURATION,                        from: {right: fromValue},                        to: {right: toValue}                    })            },            _buttonWidth: function() {                if (!this._buttonContainerWidth)                    this._buttonContainerWidth = this._$buttonContainer.outerWidth();                return this._buttonContainerWidth            },            dispose: function() {                if (this._$buttonContainer)                    this._$buttonContainer.remove();                this.callBase.apply(this, arguments)            }        });        var TOGGLE_DELETE_SWITCH_CONTAINER_CLASS = "dx-list-toggle-delete-switch-container",            TOGGLE_DELETE_SWITCH_CLASS = "dx-list-toggle-delete-switch";        ui.dxList.registerEditDecorator("delete", "toggle", ui.dxList.SwitchableButtonEditDecorator.inherit({beforeBag: function(config) {                var $itemElement = config.$itemElement,                    $container = config.$container;                var $toggle = $("<div />").addClass(TOGGLE_DELETE_SWITCH_CLASS);                this._list._createComponent($toggle, "dxButton", {                    icon: "toggle-delete",                    onClick: $.proxy(function(e) {                        this._toggleDeleteReady($itemElement);                        e.jQueryEvent.stopPropagation()                    }, this),                    _templates: {}                });                $container.addClass(TOGGLE_DELETE_SWITCH_CONTAINER_CLASS);                $container.append($toggle)            }}));        ui.dxList.registerEditDecorator("delete", "slideButton", ui.dxList.SwitchableButtonEditDecorator.inherit({            _shouldHandleSwipe: true,            _swipeEndHandler: function($itemElement, args) {                if (args.targetOffset !== 0)                    this._toggleDeleteReady($itemElement);                return true            }        }))    })(jQuery, DevExpress);    /*! Module widgets-base, file ui.list.edit.decorator.switchable.slide.js */    (function($, DX, undefined) {        var ui = DX.ui,            events = ui.events,            translator = DX.translator,            fx = DX.fx;        var LIST_EDIT_DECORATOR = "dxListEditDecorator",            CLICK_EVENT_NAME = events.addNamespace("dxclick", LIST_EDIT_DECORATOR),            SLIDE_MENU_CLASS = "dx-list-slide-menu",            SLIDE_MENU_WRAPPER_CLASS = "dx-list-slide-menu-wrapper",            SLIDE_MENU_CONTENT_CLASS = "dx-list-slide-menu-content",            SLIDE_MENU_BUTTONS_CONTAINER_CLASS = "dx-list-slide-menu-buttons-container",            SLIDE_MENU_BUTTONS_CLASS = "dx-list-slide-menu-buttons",            SLIDE_MENU_BUTTON_CLASS = "dx-list-slide-menu-button",            SLIDE_MENU_BUTTON_MENU_CLASS = "dx-list-slide-menu-button-menu",            SLIDE_MENU_BUTTON_DELETE_CLASS = "dx-list-slide-menu-button-delete";        ui.dxList.registerEditDecorator("menu", "slide", ui.dxList.SwitchableEditDecorator.inherit({            _shouldHandleSwipe: true,            _init: function() {                this.callBase.apply(this, arguments);                this._$buttonsContainer = $("<div/>").addClass(SLIDE_MENU_BUTTONS_CONTAINER_CLASS);                this._$buttons = $("<div/>").addClass(SLIDE_MENU_BUTTONS_CLASS).appendTo(this._$buttonsContainer);                this._renderMenu();                this._renderDeleteButton()            },            _renderMenu: function() {                if (!this._menuEnabled())                    return;                var menuItems = this._menuItems();                if (menuItems.length === 1) {                    var menuItem = menuItems[0];                    this._renderMenuButton(menuItem.text, $.proxy(function() {                        this._fireAction(menuItem)                    }, this))                }                else {                    var $menu = $("<div />").addClass(SLIDE_MENU_CLASS);                    this._menu = this._list._createComponent($menu, "dxActionSheet", {                        showTitle: false,                        items: menuItems,                        onItemClick: $.proxy(function(args) {                            this._fireAction(args.itemData)                        }, this),                        _templates: {}                    });                    $menu.appendTo(this._list.element());                    var $menuButton = this._renderMenuButton(Globalize.localize("dxListEditDecorator-more"), $.proxy(this._menu.show, this._menu));                    this._menu.option("target", $menuButton)                }            },            _renderMenuButton: function(text, action) {                var $menuButton = $("<div/>").addClass(SLIDE_MENU_BUTTON_CLASS).addClass(SLIDE_MENU_BUTTON_MENU_CLASS).text(text);                this._$buttons.append($menuButton);                $menuButton.on(CLICK_EVENT_NAME, action);                return $menuButton            },            _renderDeleteButton: function() {                if (!this._deleteEnabled())                    return;                var $deleteButton = $("<div/>").addClass(SLIDE_MENU_BUTTON_CLASS).addClass(SLIDE_MENU_BUTTON_DELETE_CLASS).text(Globalize.localize("dxListEditDecorator-delete"));                $deleteButton.on(CLICK_EVENT_NAME, $.proxy(function() {                    this._deleteItem()                }, this));                this._$buttons.append($deleteButton)            },            _fireAction: function(menuItem) {                this._fireMenuAction($(this._cachedNode), menuItem.action);                this._cancelDeleteReadyItem()            },            modifyElement: function(config) {                this.callBase.apply(this, arguments);                var $itemElement = config.$itemElement;                $itemElement.addClass(SLIDE_MENU_WRAPPER_CLASS);                var $slideMenuContent = $("<div/>").addClass(SLIDE_MENU_CONTENT_CLASS);                $itemElement.wrapInner($slideMenuContent)            },            handleClick: function(_, e) {                if ($(e.target).closest("." + SLIDE_MENU_CONTENT_CLASS).length)                    return this.callBase.apply(this, arguments);                return false            },            _swipeStartHandler: function($itemElement) {                this._enablePositioning($itemElement);                this._cacheItemData($itemElement)            },            _swipeUpdateHandler: function($itemElement, args) {                var rtl = this._isRtlEnabled(),                    signCorrection = rtl ? -1 : 1,                    offset = this._cachedItemWidth * args.offset,                    startOffset = this._isReadyToDelete($itemElement) ? -this._cachedButtonWidth * signCorrection : 0,                    correctedOffset = (offset + startOffset) * signCorrection,                    contentPosition = correctedOffset < 0 ? offset + startOffset : 0,                    buttonPosition = correctedOffset < 0 ? correctedOffset : 0;                translator.move(this._$cachedContent, {left: contentPosition});                this._$buttonsContainer.css(rtl ? "right" : "left", Math.max(this._cachedItemWidth + buttonPosition, this._minButtonContainerLeftOffset()));                return true            },            _cacheItemData: function($itemElement) {                if ($itemElement[0] === this._cachedNode)                    return;                this._$cachedContent = $itemElement.find("." + SLIDE_MENU_CONTENT_CLASS);                this._cachedItemWidth = $itemElement.outerWidth();                this._cachedButtonWidth = this._cachedButtonWidth || $itemElement.find("." + SLIDE_MENU_BUTTONS_CLASS).outerWidth();                if (this._$cachedContent.length)                    this._cachedNode = $itemElement[0]            },            _minButtonContainerLeftOffset: function() {                return this._cachedItemWidth - this._cachedButtonWidth            },            _swipeEndHandler: function($itemElement, args) {                this._cacheItemData($itemElement);                var signCorrection = this._isRtlEnabled() ? 1 : -1,                    offset = this._cachedItemWidth * args.offset,                    endedAtReadyToDelete = !this._isReadyToDelete($itemElement) && offset * signCorrection > this._cachedButtonWidth * 0.2,                    readyToDelete = args.targetOffset === signCorrection || endedAtReadyToDelete;                this._toggleDeleteReady($itemElement, readyToDelete);                return true            },            _enablePositioning: function($itemElement) {                this.callBase.apply(this, arguments);                this._$buttonsContainer.appendTo($itemElement)            },            _disablePositioning: function($itemElement) {                this.callBase.apply(this, arguments);                this._$buttonsContainer.detach()            },            _animatePrepareDeleteReady: function() {                var rtl = this._isRtlEnabled(),                    directionCorrection = rtl ? 1 : -1;                this._$buttonsContainer.css(rtl ? "left" : "right", "0");                var contentAnimation = fx.animate(this._$cachedContent, {                        to: {left: this._cachedButtonWidth * directionCorrection},                        type: "slide",                        duration: 200                    });                var direction = rtl ? "right" : "left",                    buttonToAnimation = {};                buttonToAnimation[direction] = this._minButtonContainerLeftOffset();                var buttonAnimation = fx.animate(this._$buttonsContainer, {                        to: buttonToAnimation,                        duration: 200                    });                return $.when(contentAnimation, buttonAnimation).promise()            },            _animateForgetDeleteReady: function($itemElement) {                this._cacheItemData($itemElement);                var rtl = this._isRtlEnabled();                this._$buttonsContainer.css(rtl ? "left" : "right", "0");                var contentAnimation = fx.animate(this._$cachedContent, {                        to: {left: 0},                        type: "slide",                        duration: 200                    });                var direction = rtl ? "right" : "left",                    buttonToAnimation = {};                buttonToAnimation[direction] = this._cachedItemWidth;                var buttonAnimation = fx.animate(this._$buttonsContainer, {                        to: buttonToAnimation,                        duration: 200,                        complete: $.proxy(function() {                            this._$buttonsContainer.css(direction, "100%")                        }, this)                    });                return $.when(contentAnimation, buttonAnimation).promise()            },            dispose: function() {                if (this._menu)                    this._menu.element().remove();                if (this._$buttonsContainer)                    this._$buttonsContainer.remove();                this.callBase.apply(this, arguments)            }        }).include(ui.dxList.EditDecoratorMenuHelperMixin))    })(jQuery, DevExpress);    /*! Module widgets-base, file ui.list.edit.decorator.swipe.js */    (function($, DX, undefined) {        var ui = DX.ui,            translator = DX.translator,            fx = DX.fx;        ui.dxList.registerEditDecorator("delete", "swipe", ui.dxList.EditDecorator.inherit({            _shouldHandleSwipe: true,            _renderItemPosition: function($itemElement, offset, animate) {                var deferred = $.Deferred(),                    itemOffset = offset * this._itemElementWidth;                if (animate)                    fx.animate($itemElement, {                        to: {left: itemOffset},                        type: "slide",                        complete: function() {                            deferred.resolve($itemElement, offset)                        }                    });                else {                    translator.move($itemElement, {left: itemOffset});                    deferred.resolve()                }                return deferred.promise()            },            _swipeStartHandler: function($itemElement) {                this._itemElementWidth = $itemElement.width();                return true            },            _swipeUpdateHandler: function($itemElement, args) {                this._renderItemPosition($itemElement, args.offset);                return true            },            _swipeEndHandler: function($itemElement, args) {                var offset = args.targetOffset;                this._renderItemPosition($itemElement, offset, true).done($.proxy(function($itemElement, offset) {                    if (Math.abs(offset))                        this._list.deleteItem($itemElement).fail($.proxy(function() {                            this._renderItemPosition($itemElement, 0, true)                        }, this))                }, this));                return true            }        }))    })(jQuery, DevExpress);    /*! Module widgets-base, file ui.list.edit.decorator.context.js */    (function($, DX, undefined) {        var ui = DX.ui;        var CONTEXTMENU_CLASS = "dx-list-context-menu",            CONTEXTMENU_MENUCONTENT_CLASS = "dx-list-context-menucontent";        ui.dxList.registerEditDecorator("menu", "context", ui.dxList.EditDecorator.inherit({            _init: function() {                var $menu = $("<div/>").addClass(CONTEXTMENU_CLASS);                this._list.element().append($menu);                this._menu = this._renderOverlay($menu)            },            _renderOverlay: function($element) {                return this._list._createComponent($element, "dxOverlay", {                        shading: false,                        deferRendering: true,                        closeOnTargetScroll: true,                        closeOnOutsideClick: function(e) {                            return !$(e.target).closest("." + CONTEXTMENU_CLASS).length                        },                        animation: {                            show: {                                type: "slide",                                duration: 300,                                from: {                                    height: 0,                                    opacity: 1                                },                                to: {                                    height: $.proxy(function() {                                        return this._$menuList.outerHeight()                                    }, this),                                    opacity: 1                                }                            },                            hide: {                                type: "slide",                                duration: 0,                                from: {opacity: 1},                                to: {opacity: 0}                            }                        },                        height: $.proxy(function() {                            return this._$menuList ? this._$menuList.outerHeight() : 0                        }, this),                        width: $.proxy(function() {                            return this._list.element().outerWidth()                        }, this),                        onContentReady: $.proxy(this._renderMenuContent, this)                    })            },            _renderMenuContent: function(e) {                var $overlayContent = e.component.content();                var items = this._menuItems().slice();                if (this._deleteEnabled())                    items.push({                        text: Globalize.localize("dxListEditDecorator-delete"),                        action: $.proxy(this._deleteItem, this)                    });                this._$menuList = $("<div>");                this._list._createComponent(this._$menuList, "dxList", {                    items: items,                    onItemClick: $.proxy(this._menuItemClickHandler, this),                    height: "auto",                    _templates: {}                });                $overlayContent.addClass(CONTEXTMENU_MENUCONTENT_CLASS);                $overlayContent.append(this._$menuList)            },            _menuItemClickHandler: function(args) {                this._menu.hide();                this._fireMenuAction(this._$itemWithMenu, args.itemData.action)            },            _deleteItem: function() {                this._list.deleteItem(this._$itemWithMenu)            },            handleContextMenu: function($itemElement) {                this._$itemWithMenu = $itemElement;                this._menu.option({position: {                        my: "top",                        at: "bottom",                        of: $itemElement,                        collision: "flip"                    }});                this._menu.show();                return true            },            dispose: function() {                if (this._menu)                    this._menu.element().remove();                this.callBase.apply(this, arguments)            }        }).include(ui.dxList.EditDecoratorMenuHelperMixin))    })(jQuery, DevExpress);    /*! Module widgets-base, file ui.list.edit.decorator.selection.js */    (function($, DX, undefined) {        var ui = DX.ui,            events = ui.events;        var SELECT_DECORATOR_ENABLED_CLASS = "dx-list-select-decorator-enabled",            SELECT_DECORATOR_SELECT_ALL_CLASS = "dx-list-select-all",            SELECT_DECORATOR_SELECT_ALL_CHECKBOX_CLASS = "dx-list-select-all-checkbox",            SELECT_DECORATOR_SELECT_ALL_LABEL_CLASS = "dx-list-select-all-label",            SELECT_CHECKBOX_CONTAINER_CLASS = "dx-list-select-checkbox-container",            SELECT_CHECKBOX_CLASS = "dx-list-select-checkbox",            SELECT_RADIO_BUTTON_CONTAINER_CLASS = "dx-list-select-radiobutton-container",            SELECT_RADIO_BUTTON_CLASS = "dx-list-select-radiobutton";        var CLICK_EVENT_NAME = events.addNamespace("dxclick", "dxListEditDecorator");        ui.dxList.registerEditDecorator("selection", "default", ui.dxList.EditDecorator.inherit({            _init: function() {                this.callBase.apply(this, arguments);                var selectionMode = this._list.option("selectionMode");                this._singleStrategy = selectionMode === "single";                this._containerClass = this._singleStrategy ? SELECT_RADIO_BUTTON_CONTAINER_CLASS : SELECT_CHECKBOX_CONTAINER_CLASS;                this._controlClass = this._singleStrategy ? SELECT_RADIO_BUTTON_CLASS : SELECT_CHECKBOX_CLASS;                this._controlWidget = this._singleStrategy ? "dxRadioButton" : "dxCheckBox";                this._list.element().addClass(SELECT_DECORATOR_ENABLED_CLASS)            },            beforeBag: function(config) {                var $itemElement = config.$itemElement,                    $container = config.$container;                var $control = $("<div />").addClass(this._controlClass);                $control[this._controlWidget]($.extend(this._commonOptions(), {                    value: this._isSelected($itemElement),                    focusStateEnabled: false,                    hoverStateEnabled: false,                    onValueChanged: $.proxy(function(e) {                        this._processCheckedState($itemElement, e.value);                        e.jQueryEvent && e.jQueryEvent.stopPropagation()                    }, this)                }));                $container.addClass(this._containerClass);                $container.append($control)            },            modifyElement: function(config) {                this.callBase.apply(this, arguments);                var $itemElement = config.$itemElement,                    control = $itemElement.find("." + this._controlClass)[this._controlWidget]("instance");                $itemElement.on("stateChanged", $.proxy(function() {                    control.option("value", this._isSelected($itemElement));                    this._updateSelectAllState()                }, this))            },            _updateSelectAllState: function() {                if (!this._$selectAll)                    return;                var items = this._list.option("items");                var selectedItems = this._list.option("selectedItems");                var isSelectedAll = items.length === selectedItems.length ? true : selectedItems.length === 0 ? false : undefined;                this._selectAllCheckBox.option("value", isSelectedAll)            },            afterRender: function() {                if (this._list.option("selectionMode") !== "all")                    return;                if (!this._$selectAll)                    this._renderSelectAll();                if (this._selectAllCheckBox.option("value"))                    this._selectAllItems()            },            _renderSelectAll: function() {                var $selectAll = this._$selectAll = $("<div>").addClass(SELECT_DECORATOR_SELECT_ALL_CLASS);                this._selectAllCheckBox = this._list._createComponent($("<div>").addClass(SELECT_DECORATOR_SELECT_ALL_CHECKBOX_CLASS).appendTo($selectAll), "dxCheckBox");                $("<div>").addClass(SELECT_DECORATOR_SELECT_ALL_LABEL_CLASS).text(this._list.option("selectAllText")).appendTo($selectAll);                this._list.itemsContainer().prepend($selectAll);                this._updateSelectAllState();                this._attachSelectAllHandler()            },            _attachSelectAllHandler: function() {                this._selectAllCheckBox.option("onValueChanged", $.proxy(this._selectAllHandler, this));                this._$selectAll.off(CLICK_EVENT_NAME).on(CLICK_EVENT_NAME, $.proxy(this._selectAllClickHandler, this))            },            _selectAllHandler: function(e) {                var isSelectedAll = this._selectAllCheckBox.option("value");                if (isSelectedAll === true)                    this._selectAllItems();                else if (isSelectedAll === false)                    this._unselectAllItems();                e.jQueryEvent && e.jQueryEvent.stopPropagation()            },            _selectAllItems: function() {                this._list.option("selectedItems", this._list.option("items").slice())            },            _unselectAllItems: function() {                this._list.option("selectedItems", [])            },            _selectAllClickHandler: function() {                this._selectAllCheckBox.option("value", !this._selectAllCheckBox.option("value"))            },            _isSelected: function($itemElement) {                return this._list.isItemSelected($itemElement)            },            _processCheckedState: function($itemElement, checked) {                if (checked)                    this._list.selectItem($itemElement);                else                    this._list.unselectItem($itemElement)            },            dispose: function() {                this._disposeSelectAll();                this._list.element().removeClass(SELECT_DECORATOR_ENABLED_CLASS);                this.callBase.apply(this, arguments)            },            _disposeSelectAll: function() {                if (this._$selectAll) {                    this._$selectAll.remove();                    this._$selectAll = null                }            },            handleClick: function($itemElement) {                var newState = !this._isSelected($itemElement) || this._singleStrategy;                this._processCheckedState($itemElement, newState);                return true            }        }))    })(jQuery, DevExpress);    /*! Module widgets-base, file ui.list.edit.decorator.reorder.js */    (function($, DX, undefined) {        var ui = DX.ui,            events = ui.events,            translator = DX.translator,            fx = DX.fx,            support = DX.support,            utils = DX.utils,            fitIntoRange = utils.fitIntoRange;        var ReorderScrollAnimator = DX.Animator.inherit({                ctor: function(strategy) {                    this.callBase();                    this._strategy = strategy                },                _isFinished: function() {                    return this._strategy.scrollFinished()                },                _step: function() {                    this._strategy.scrollByStep()                }            });        var LIST_EDIT_DECORATOR = "dxListEditDecorator",            DRAG_START_EVENT_NAME = events.addNamespace("dxdragstart", LIST_EDIT_DECORATOR),            DRAG_UPDATE_EVENT_NAME = events.addNamespace("dxdrag", LIST_EDIT_DECORATOR),            DRAG_END_EVENT_NAME = events.addNamespace("dxdragend", LIST_EDIT_DECORATOR),            REORDER_HANDLE_CONTAINER_CLASS = "dx-list-reorder-handle-container",            REORDER_HANDLE_CLASS = "dx-list-reorder-handle",            REOREDERING_ITEM_CLASS = "dx-list-item-reordering",            REOREDERING_ITEM_GHOST_CLASS = "dx-list-item-ghost-reordering",            LIST_REORDER_COMPATIBILITY_MODE_CLASS = "dx-list-reorder-compatibility-mode";        ui.dxList.registerEditDecorator("reorder", "default", ui.dxList.EditDecorator.inherit({            _init: function() {                this._groupedEnabled = this._list.option("grouped");                this._initAnimator()            },            _initAnimator: function() {                this._scrollAnimator = new ReorderScrollAnimator(this)            },            _startAnimator: function() {                if (!this._scrollAnimator.inProgress())                    this._scrollAnimator.start()            },            _stopAnimator: function() {                this._scrollAnimator.stop()            },            afterBag: function(config) {                var $itemElement = config.$itemElement,                    $container = config.$container;                var $handle = $("<div>").addClass(REORDER_HANDLE_CLASS);                $handle.on(DRAG_START_EVENT_NAME, {                    direction: "vertical",                    immediate: true                }, $.proxy(this._dragStartHandler, this, $itemElement));                $handle.on(DRAG_UPDATE_EVENT_NAME, $.proxy(this._dragHandler, this, $itemElement));                $handle.on(DRAG_END_EVENT_NAME, $.proxy(this._dragEndHandler, this, $itemElement));                $container.addClass(REORDER_HANDLE_CONTAINER_CLASS);                $container.append($handle)            },            _dragStartHandler: function($itemElement, e) {                if ($itemElement.is(".dx-state-disabled, .dx-state-disabled *")) {                    e.cancel = true;                    return                }                this._stopPreviousAnimation();                e.targetElements = [];                this._cacheItemsPositions();                this._startPointerOffset = e.pageY - $itemElement.offset().top;                this._elementHeight = $itemElement.outerHeight();                var itemIndex = this._list.getFlatIndexByItemElement($itemElement);                this._startIndex = itemIndex;                this._lastIndex = itemIndex;                this._cacheScrollData();                this._createGhost($itemElement);                $itemElement.addClass(REOREDERING_ITEM_CLASS);                this._toggleCompatibilityMode(true)            },            _stopPreviousAnimation: function() {                fx.stop(this._$ghostItem, true)            },            _toggleCompatibilityMode: function(enabled) {                this._list.element().toggleClass(LIST_REORDER_COMPATIBILITY_MODE_CLASS, !support.transform && enabled)            },            _cacheItemsPositions: function() {                this._itemPositions = [];                $.each(this._list.itemElements(), $.proxy(function(index, item) {                    this._itemPositions.push($(item).position().top)                }, this))            },            _getDraggingElementPosition: function() {                return this._itemPositions[this._startIndex]            },            _getLastElementPosition: function() {                return this._itemPositions[this._lastIndex]            },            _cacheScrollData: function() {                this._list.updateDimensions();                this._startScrollTop = this._list.scrollTop();                this._scrollOffset = 0;                this._scrollHeight = this._list.scrollHeight();                this._clientHeight = this._list.clientHeight()            },            _scrollTop: function() {                return this._startScrollTop + this._scrollOffset            },            _createGhost: function($itemElement) {                this._$ghostItem = $itemElement.clone();                this._$ghostItem.addClass(REOREDERING_ITEM_GHOST_CLASS).appendTo(this._list.itemsContainer());                this._startGhostPosition = this._getDraggingElementPosition() - this._$ghostItem.position().top;                translator.move(this._$ghostItem, {top: this._startGhostPosition})            },            _dragHandler: function($itemElement, e) {                this._topOffset = e.offset.y;                this._updateItemPositions();                var pointerPosition = this._getPonterPosition();                this._toggleScroll(pointerPosition)            },            _getPonterPosition: function() {                return this._getDraggingElementPosition() + this._startPointerOffset + this._scrollOffset + this._topOffset            },            _toggleScroll: function(pointerPosition) {                if (this._scrollHeight <= this._clientHeight)                    return;                var minOffset = this._elementHeight * 0.7,                    topOffset = this._clientHeight - (pointerPosition - this._scrollTop()),                    topOffsetRatio = topOffset / minOffset,                    bottomOffset = pointerPosition - this._scrollTop(),                    bottomOffsetRatio = bottomOffset / minOffset;                if (topOffsetRatio < 1) {                    this._stepSize = this._adjustRationIntoRange(topOffsetRatio);                    this._startAnimator()                }                else if (bottomOffsetRatio < 1) {                    this._stepSize = -this._adjustRationIntoRange(bottomOffsetRatio);                    this._startAnimator()                }                else                    this._stopAnimator()            },            _adjustRationIntoRange: function(ratio) {                return fitIntoRange(Math.round(Math.abs(ratio - 1) * 7), 1, 7)            },            _updateItemPositions: function() {                this._updateGhostPosition();                this._updateOthersPositions()            },            _updateGhostPosition: function() {                translator.move(this._$ghostItem, {top: this._startGhostPosition + this._scrollOffset + this._topOffset})            },            _updateOthersPositions: function() {                var currentIndex = this._findItemIndexByPosition(this._getPonterPosition());                if (this._lastIndex === currentIndex || this._groupedEnabled && !this._sameParent(currentIndex))                    return;                var currentIndexOffset = currentIndex - this._startIndex,                    currentDirection = utils.sign(currentIndexOffset),                    minIndex = Math.min(currentIndex, this._lastIndex),                    maxIndex = Math.max(currentIndex, this._lastIndex);                for (var itemIndex = minIndex; itemIndex <= maxIndex; itemIndex++) {                    if (itemIndex === this._startIndex)                        continue;                    var $item = this._list.getItemElementByFlatIndex(itemIndex),                        itemIndexOffset = itemIndex - this._startIndex,                        itemDirection = utils.sign(itemIndexOffset),                        offsetsDifference = Math.abs(itemIndexOffset) <= Math.abs(currentIndexOffset),                        sameDirections = currentDirection === itemDirection,                        setupPosition = offsetsDifference && sameDirections,                        resetPosition = !offsetsDifference || !sameDirections;                    fx.stop($item);                    if (setupPosition)                        fx.animate($item, {                            type: "slide",                            to: {top: this._elementHeight * -currentDirection},                            duration: 300                        });                    if (resetPosition)                        fx.animate($item, {                            type: "slide",                            to: {top: 0},                            duration: 300                        })                }                this._lastIndex = currentIndex            },            _sameParent: function(index) {                var $dragging = this._list.getItemElementByFlatIndex(this._startIndex),                    $over = this._list.getItemElementByFlatIndex(index);                return $over.parent().get(0) === $dragging.parent().get(0)            },            scrollByStep: function() {                this._scrollOffset += this._stepSize;                this._list.scrollBy(this._stepSize);                this._updateItemPositions()            },            scrollFinished: function() {                var scrollTop = this._scrollTop(),                    rejectScrollTop = scrollTop <= 0 && this._stepSize < 0,                    rejectScrollBottom = scrollTop >= this._scrollHeight - this._clientHeight && this._stepSize > 0;                return rejectScrollTop || rejectScrollBottom            },            _dragEndHandler: function($itemElement) {                this._scrollAnimator.stop();                fx.animate(this._$ghostItem, {                    type: "slide",                    to: {top: this._startGhostPosition + this._getLastElementPosition() - this._getDraggingElementPosition()},                    duration: 300                }).done($.proxy(function() {                    $itemElement.removeClass(REOREDERING_ITEM_CLASS);                    this._resetPositions();                    this._list.reorderItem($itemElement, this._list.getItemElementByFlatIndex(this._lastIndex));                    this._deleteGhost();                    this._toggleCompatibilityMode(false)                }, this))            },            _deleteGhost: function() {                this._$ghostItem.remove()            },            _resetPositions: function() {                var minIndex = Math.min(this._startIndex, this._lastIndex),                    maxIndex = Math.max(this._startIndex, this._lastIndex);                for (var itemIndex = minIndex; itemIndex <= maxIndex; itemIndex++) {                    var $item = this._list.getItemElementByFlatIndex(itemIndex);                    translator.resetPosition($item)                }            },            _findItemIndexByPosition: function(position) {                var minIndex = 0;                var maxIndex = this._itemPositions.length - 1;                var currentIndex;                var currentPosition;                while (minIndex <= maxIndex) {                    currentIndex = (minIndex + maxIndex) / 2 | 0;                    currentPosition = this._itemPositions[currentIndex];                    if (currentPosition < position)                        minIndex = currentIndex + 1;                    else if (currentPosition > position)                        maxIndex = currentIndex - 1;                    else                        return currentIndex                }                return fitIntoRange(minIndex, 0, Math.max(maxIndex, 0))            }        }))    })(jQuery, DevExpress);    /*! Module widgets-base, file ui.list.edit.provider.js */    (function($, DX, undefined) {        var ui = DX.ui;        var editOptionsRegistry = [];        var registerOption = function(enabledFunc, decoratorTypeFunc, decoratorSubTypeFunc) {                editOptionsRegistry.push({                    enabled: enabledFunc,                    decoratorType: decoratorTypeFunc,                    decoratorSubType: decoratorSubTypeFunc                })            };        registerOption(function() {            return this.option("menuItems").length        }, function() {            return "menu"        }, function() {            return this.option("menuMode")        });        registerOption(function() {            return !this.option("menuItems").length && this.option("allowItemDeleting")        }, function() {            var mode = this.option("itemDeleteMode");            return mode === "toggle" || mode === "slideButton" || mode === "swipe" || mode === "static" ? "delete" : "menu"        }, function() {            var mode = this.option("itemDeleteMode");            if (mode === "slideItem")                mode = "slide";            if (mode === "hold")                mode = "context";            return mode        });        registerOption(function() {            return this.option("selectionMode") !== "none" && this.option("showSelectionControls")        }, function() {            return "selection"        }, function() {            return "default"        });        registerOption(function() {            return this.option("allowItemReordering")        }, function() {            return "reorder"        }, function() {            return "default"        });        var LIST_ITEM_BEFORE_BAG_CLASS = "dx-list-item-before-bag",            LIST_ITEM_AFTER_BAG_CLASS = "dx-list-item-after-bag",            DECORATOR_BEFORE_BAG_CREATE_METHOD = "beforeBag",            DECORATOR_AFTER_BAG_CREATE_METHOD = "afterBag",            DECORATOR_MODIFY_ELEMENT_METHOD = "modifyElement",            DECORATOR_AFTER_RENDER_METHOD = "afterRender";        ui.dxList.EditProvider = DX.Class.inherit({            ctor: function(list) {                this._list = list;                this._fetchRequiredDecorators()            },            dispose: function() {                if (this._decorators && this._decorators.length)                    $.each(this._decorators, function(_, decorator) {                        decorator.dispose()                    })            },            _fetchRequiredDecorators: function() {                this._decorators = [];                $.each(editOptionsRegistry, $.proxy(function(_, option) {                    var optionEnabled = option.enabled.call(this._list);                    if (optionEnabled) {                        var decoratorType = option.decoratorType.call(this._list),                            decoratorSubType = option.decoratorSubType.call(this._list),                            decorator = this._createDecorator(decoratorType, decoratorSubType);                        this._decorators.push(decorator)                    }                }, this))            },            _createDecorator: function(type, subType) {                var decoratorClass = this._findDecorator(type, subType);                return new decoratorClass(this._list)            },            _findDecorator: function(type, subType) {                var foundDecorator = ui.dxList.EditDecoratorsRegistry[type][subType];                if (!foundDecorator)                    throw DX.Error("E1012", type, subType);                return foundDecorator            },            modifyItemElement: function(args) {                var $itemElement = $(args.itemElement);                var config = {$itemElement: $itemElement};                this._prependBeforeBags($itemElement, config);                this._appendAfterBags($itemElement, config);                this._applyDecorators(DECORATOR_MODIFY_ELEMENT_METHOD, config)            },            afterItemsRendered: function() {                this._applyDecorators(DECORATOR_AFTER_RENDER_METHOD)            },            _prependBeforeBags: function($itemElement, config) {                var $beforeBags = this._collectDecoratorsMarkup(DECORATOR_BEFORE_BAG_CREATE_METHOD, config, LIST_ITEM_BEFORE_BAG_CLASS);                $itemElement.prepend($beforeBags)            },            _appendAfterBags: function($itemElement, config) {                var $afterBags = this._collectDecoratorsMarkup(DECORATOR_AFTER_BAG_CREATE_METHOD, config, LIST_ITEM_AFTER_BAG_CLASS);                $itemElement.append($afterBags)            },            _collectDecoratorsMarkup: function(method, config, containerClass) {                var $collector = $("<div />");                $.each(this._decorators, function() {                    var $container = $("<div />").addClass(containerClass);                    this[method]($.extend({$container: $container}, config));                    if ($container.children().length)                        $collector.append($container)                });                return $collector.children()            },            _applyDecorators: function(method, config) {                $.each(this._decorators, function() {                    this[method](config)                })            },            _handlerExists: function(name) {                if (!this._decorators)                    return false;                var decorators = this._decorators,                    length = decorators.length;                for (var i = 0; i < length; i++)                    if (decorators[i][name] !== $.noop)                        return true;                return false            },            _eventHandler: function(name, $itemElement, e) {                if (!this._decorators)                    return false;                var response = false,                    decorators = this._decorators,                    length = decorators.length;                for (var i = 0; i < length; i++) {                    response = decorators[i][name]($itemElement, e);                    if (response)                        break                }                return response            },            handleClick: function($itemElement, e) {                return this._eventHandler("handleClick", $itemElement, e)            },            contextMenuHandlerExists: function() {                return this._handlerExists("handleContextMenu")            },            handleContextMenu: function($itemElement, e) {                return this._eventHandler("handleContextMenu", $itemElement, e)            }        })    })(jQuery, DevExpress);    /*! Module widgets-base, file ui.tileView.js */    (function($, DX, undefined) {        var ui = DX.ui;        var TILEVIEW_CLASS = "dx-tileview",            TILEVIEW_CONTAINER_CLASS = "dx-tileview-wrapper",            TILEVIEW_ITEM_CLASS = "dx-tile",            TILEVIEW_ITEM_SELECTOR = "." + TILEVIEW_ITEM_CLASS,            TILEVIEW_ITEM_DATA_KEY = "dxTileData";        DX.registerComponent("dxTileView", ui, ui.CollectionWidget.inherit({            _activeStateUnit: TILEVIEW_ITEM_SELECTOR,            _setDefaultOptions: function() {                this.callBase();                this.option({                    items: null,                    showScrollbar: false,                    height: 500,                    baseItemWidth: 100,                    baseItemHeight: 100,                    itemMargin: 20,                    activeStateEnabled: true,                    indicateLoading: true                })            },            _defaultOptionsRules: function() {                return this.callBase().concat([{                            device: function(device) {                                return DX.devices.real().generic && !DX.devices.isSimulator()                            },                            options: {                                hoverStateEnabled: true,                                focusStateEnabled: true                            }                        }])            },            _itemClass: function() {                return TILEVIEW_ITEM_CLASS            },            _itemDataKey: function() {                return TILEVIEW_ITEM_DATA_KEY            },            _itemContainer: function() {                return this._$container            },            _init: function() {                this.callBase();                this._initScrollView()            },            _dataSourceLoadingChangedHandler: function(isLoading) {                var scrollView = this._scrollView;                if (!scrollView)                    return;                if (isLoading && this.option("indicateLoading"))                    scrollView.startLoading();                else                    scrollView.finishLoading()            },            _hideLoadingIfLoadIndicationOff: function() {                if (!this.option("indicateLoading"))                    this._dataSourceLoadingChangedHandler(false)            },            _initScrollView: function() {                this._scrollView = this._createComponent(this.element(), "dxScrollView", {                    direction: "horizontal",                    scrollByContent: true,                    useKeyboard: false,                    showScrollbar: this.option("showScrollbar"),                    disabled: this.option("disabled")                });                this._$container = this._scrollView.content();                this._$container.addClass(TILEVIEW_CONTAINER_CLASS);                this._scrollView.option("onUpdated", $.proxy(this._renderGeometry, this))            },            _render: function() {                this.callBase();                this.element().addClass(TILEVIEW_CLASS);                this.cellsPerColumn = 1;                this._updateScrollView();                this._fireContentReadyAction()            },            _renderContent: function() {                this._renderContentImpl()            },            _updateScrollView: function() {                this._scrollView.option("rtlEnabled", this.option("rtlEnabled"));                this._renderGeometry();                this._scrollView.update();                this._indicateLoadingIfAlreadyStarted()            },            _indicateLoadingIfAlreadyStarted: function() {                if (this._isDataSourceLoading())                    this._dataSourceLoadingChangedHandler(true)            },            _renderGeometry: function() {                var items = this.option("items") || [],                    maxItemHeight = Math.max.apply(Math, $.map(items || [], function(item) {                        return Math.round(item.heightRatio || 1)                    }));                this.cellsPerColumn = Math.floor(this.element().height() / (this.option("baseItemHeight") + this.option("itemMargin")));                this.cellsPerColumn = Math.max(this.cellsPerColumn, maxItemHeight);                this.cells = [];                this.cells.push(new Array(this.cellsPerColumn));                this._arrangeItems(items);                this._$container.width(this.cells.length * this.option("baseItemWidth") + (this.cells.length + 1) * this.option("itemMargin"))            },            _arrangeItems: function(items) {                var that = this;                this._itemsPositions = [];                $.each(items, function(index, item) {                    var currentItem = {};                    currentItem.widthRatio = item.widthRatio || 1;                    currentItem.heightRatio = item.heightRatio || 1;                    currentItem.index = index;                    currentItem.widthRatio = currentItem.widthRatio <= 0 ? 0 : Math.round(currentItem.widthRatio);                    currentItem.heightRatio = currentItem.heightRatio <= 0 ? 0 : Math.round(currentItem.heightRatio);                    var itemPosition = that._getItemPosition(currentItem);                    if (itemPosition.x === -1)                        itemPosition.x = that.cells.push(new Array(that.cellsPerColumn)) - 1;                    that._occupyCells(currentItem, itemPosition);                    that._arrangeItem(currentItem, itemPosition);                    that._itemsPositions.push(itemPosition)                })            },            _getItemPosition: function(item) {                var position = {                        x: -1,                        y: 0                    };                for (var col = 0; col < this.cells.length; col++) {                    for (var row = 0; row < this.cellsPerColumn; row++)                        if (this._itemFit(col, row, item)) {                            position.x = col;                            position.y = row;                            break                        }                    if (position.x > -1)                        break                }                return position            },            _itemFit: function(column, row, item) {                var result = true;                if (row + item.heightRatio > this.cellsPerColumn)                    return false;                for (var columnIndex = column; columnIndex < column + item.widthRatio; columnIndex++)                    for (var rowIndex = row; rowIndex < row + item.heightRatio; rowIndex++)                        if (this.cells.length - 1 < columnIndex)                            this.cells.push(new Array(this.cellsPerColumn));                        else if (this.cells[columnIndex][rowIndex] !== undefined) {                            result = false;                            break                        }                return result            },            _occupyCells: function(item, itemPosition) {                for (var i = itemPosition.x; i < itemPosition.x + item.widthRatio; i++)                    for (var j = itemPosition.y; j < itemPosition.y + item.heightRatio; j++)                        this.cells[i][j] = item.index            },            _arrangeItem: function(item, itemPosition) {                var baseItemHeight = this.option("baseItemHeight"),                    baseItemWidth = this.option("baseItemWidth"),                    itemMargin = this.option("itemMargin"),                    leftOffset,                    offsetCorrection = this.option("rtlEnabled") ? this._$container.width() : 0,                    $item = this._itemElements().eq(item.index);                if (!offsetCorrection)                    leftOffset = itemPosition.x * baseItemWidth + (itemPosition.x + 1) * itemMargin;                else {                    var startOffsetPosition = itemPosition.x * baseItemWidth,                        itemBasePartWidth = baseItemWidth + itemMargin,                        itemWidth = itemBasePartWidth * item.widthRatio,                        subitemMarginsWidth = itemPosition.x * itemMargin;                    leftOffset = offsetCorrection - (startOffsetPosition + itemWidth + subitemMarginsWidth)                }                $item.css({                    height: item.heightRatio * baseItemHeight + (item.heightRatio - 1) * itemMargin,                    width: item.widthRatio * baseItemWidth + (item.widthRatio - 1) * itemMargin,                    top: itemPosition.y * baseItemHeight + (itemPosition.y + 1) * itemMargin,                    left: leftOffset,                    display: item.widthRatio <= 0 || item.heightRatio <= 0 ? "none" : ""                })            },            _moveFocus: function(location) {                var FOCUS_UP = "up",                    FOCUS_DOWN = "down",                    FOCUS_LEFT = this.option("rtlEnabled") ? "right" : "left",                    FOCUS_RIGHT = this.option("rtlEnabled") ? "left" : "right",                    FOCUS_PAGE_UP = "pageup",                    FOCUS_PAGE_DOWN = "pagedown";                var cells = this.cells,                    index = this.option("focusedElement").index(),                    newTargetCol = this._itemsPositions[index].x,                    targetRow = this._itemsPositions[index].y,                    newTargetIndex;                switch (location) {                    case FOCUS_PAGE_UP:                    case FOCUS_UP:                        while (targetRow > 0 && index === cells[newTargetCol][targetRow])                            targetRow--;                        if (targetRow < 0)                            targetRow = 0;                        break;                    case FOCUS_PAGE_DOWN:                    case FOCUS_DOWN:                        while (targetRow < cells[0].length && index === cells[newTargetCol][targetRow])                            targetRow++;                        if (targetRow === cells[0].length)                            targetRow = cells[0].length - 1;                        break;                    case FOCUS_RIGHT:                        while (newTargetCol < cells.length && index === cells[newTargetCol][targetRow])                            newTargetCol++;                        if (newTargetCol === cells.length)                            newTargetCol = cells.length - 1;                        break;                    case FOCUS_LEFT:                        while (newTargetCol >= 0 && index === cells[newTargetCol][targetRow])                            newTargetCol--;                        if (newTargetCol < 0)                            newTargetCol = 0;                        break;                    default:                        this.callBase.apply(this, arguments);                        return                }                newTargetIndex = cells[newTargetCol][targetRow];                var $newTarget = this._itemElements().eq(newTargetIndex);                this.option("focusedElement", $newTarget);                this._scrollToItem($newTarget)            },            _scrollToItem: function($itemElement) {                if (!$itemElement.length)                    return;                var itemPosition = $itemElement.position().left,                    itemWidth = $itemElement.outerWidth(),                    itemRight = itemPosition + itemWidth,                    scrollLeft = this._scrollView.scrollLeft(),                    clientWidht = this._scrollView.element().outerWidth();                if (scrollLeft <= itemPosition && itemRight <= scrollLeft + clientWidht)                    return;                if (scrollLeft > itemPosition)                    this._scrollView.scrollTo(itemPosition - this.option("itemMargin"));                else                    this._scrollView.scrollTo(itemPosition + itemWidth - clientWidht + this.option("itemMargin"))            },            _optionChanged: function(args) {                switch (args.name) {                    case"showScrollbar":                        this._initScrollView();                        break;                    case"disabled":                        this._scrollView.option("disabled", args.value);                        break;                    case"baseItemWidth":                    case"baseItemHeight":                    case"itemMargin":                        this._renderGeometry();                        break;                    case"height":                        this.callBase(args);                        this._renderGeometry();                        this._scrollView.update();                        break;                    case"indicateLoading":                        this._hideLoadingIfLoadIndicationOff();                        break;                    default:                        this.callBase(args)                }            },            scrollPosition: function() {                return this._scrollView.scrollOffset().left            }        }))    })(jQuery, DevExpress);    /*! Module widgets-base, file ui.trackBar.js */    (function($, DX, undefined) {        var ui = DX.ui,            fx = DX.fx;        var TRACKBAR_CLASS = "dx-trackbar",            TRACKBAR_CONTAINER_CLASS = "dx-trackbar-container",            TRACKBAR_RANGE_CLASS = "dx-trackbar-range",            TRACKBAR_WRAPPER_CLASS = "dx-trackbar-wrapper";        DX.registerComponent("dxTrackBar", ui, ui.Editor.inherit({            _setDefaultOptions: function() {                this.callBase();                this.option({                    min: 0,                    max: 100,                    value: 0                })            },            _render: function() {                this.element().addClass(TRACKBAR_CLASS);                this._renderWrapper();                this._renderContainer();                this._renderRange();                this.callBase();                this._renderValue()            },            _renderWrapper: function() {                this._$wrapper = $("<div>").addClass(TRACKBAR_WRAPPER_CLASS).appendTo(this.element())            },            _renderContainer: function() {                this._$bar = $("<div>").addClass(TRACKBAR_CONTAINER_CLASS).appendTo(this._$wrapper)            },            _renderRange: function() {                this._$range = $("<div>").addClass(TRACKBAR_RANGE_CLASS).appendTo(this._$bar)            },            _renderValue: function() {                var val = this.option("value"),                    min = this.option("min"),                    max = this.option("max");                if (min > max)                    return;                if (val < min) {                    this.option("value", min);                    this._currentRatio = 0;                    return                }                if (val > max) {                    this.option("value", max);                    this._currentRatio = 1;                    return                }                var ratio = min === max ? 0 : (val - min) / (max - min);                this._animateRange({width: ratio * 100 + "%"});                this.setAria({                    valuemin: this.option("min"),                    valuemax: max,                    valuenow: val                });                this._currentRatio = ratio            },            _animateRange: function(configTo) {                fx.stop(this._$range);                if (!this._needPreventAnimation)                    fx.animate(this._$range, {                        type: "custom",                        duration: 100,                        to: configTo,                        complete: $.proxy(this._rangeAnimationCompleteHandler, this)                    })            },            _rangeAnimationCompleteHandler: $.noop,            _optionChanged: function(args) {                switch (args.name) {                    case"value":                        this._renderValue();                        this.callBase(args);                        break;                    case"max":                    case"min":                        this._renderValue();                        break;                    default:                        this.callBase(args)                }            },            _dispose: function() {                fx.stop(this._$range);                this.callBase()            }        }))    })(jQuery, DevExpress);    /*! Module widgets-base, file ui.progressBar.js */    (function($, DX, undefined) {        var ui = DX.ui;        var PROGRESSBAR_CLASS = "dx-progressbar",            PROGRESSBAR_CONTAINER_CLASS = "dx-progressbar-container",            PROGRESSBAR_RANGE_CONTAINER_CLASS = "dx-progressbar-range-container",            PROGRESSBAR_RANGE_CLASS = "dx-progressbar-range",            PROGRESSBAR_WRAPPER_CLASS = "dx-progressbar-wrapper",            PROGRESSBAR_STATUS_CLASS = "dx-progressbar-status",            PROGRESSBAR_INDETERMINATE_SEGMENT_CONTAINER = "dx-progressbar-animating-container",            PROGRESSBAR_INDETERMINATE_SEGMENT = "dx-progressbar-animating-segment";        DX.registerComponent("dxProgressBar", ui, ui.dxTrackBar.inherit({            _setDefaultOptions: function() {                this.callBase();                this.option({                    statusFormat: function(ratio, value) {                        return "Progress: " + Math.round(ratio * 100) + "%"                    },                    showStatus: true,                    onComplete: null,                    activeStateEnabled: false,                    statusPosition: "bottom left",                    _animatingSegmentCount: 0                })            },            _defaultOptionsRules: function() {                return this.callBase().concat([{                            device: [{platform: "win8"}],                            options: {_animatingSegmentCount: 5}                        }, {                            device: function(device) {                                return device.platform === "android"                            },                            options: {_animatingSegmentCount: 2}                        }])            },            _init: function() {                this.callBase()            },            _render: function() {                this._createCompleteAction();                this._renderStatus();                this.callBase();                this.element().addClass(PROGRESSBAR_CLASS);                this.setAria("role", "progressbar");                this._$wrapper.addClass(PROGRESSBAR_WRAPPER_CLASS);                this._$bar.addClass(PROGRESSBAR_CONTAINER_CLASS);                $("<div>").addClass(PROGRESSBAR_RANGE_CONTAINER_CLASS).appendTo(this._$wrapper).append(this._$bar);                this._$range.addClass(PROGRESSBAR_RANGE_CLASS);                this._toggleStatus(this.option("showStatus"))            },            _createCompleteAction: function() {                this._completeAction = this._createActionByOption("onComplete")            },            _renderStatus: function() {                this._$status = $("<div>").addClass(PROGRESSBAR_STATUS_CLASS)            },            _renderIndeterminateState: function() {                this._$segmentContainer = $("<div>").addClass(PROGRESSBAR_INDETERMINATE_SEGMENT_CONTAINER);                var segments = this.option("_animatingSegmentCount");                for (var i = 0; i < segments; i++)                    $("<div>").addClass(PROGRESSBAR_INDETERMINATE_SEGMENT).addClass(PROGRESSBAR_INDETERMINATE_SEGMENT + "-" + (i + 1)).appendTo(this._$segmentContainer);                this._$segmentContainer.appendTo(this._$wrapper)            },            _toggleStatus: function(value) {                var splittedPosition = this.option("statusPosition").split(" ");                if (value)                    if (splittedPosition[0] === "top" || splittedPosition[0] === "left")                        this._$status.prependTo(this._$wrapper);                    else                        this._$status.appendTo(this._$wrapper);                else                    this._$status.detach();                this._togglePositionClass()            },            _togglePositionClass: function() {                var position = this.option("statusPosition"),                    splittedPosition = position.split(" ");                this._$wrapper.removeClass("dx-position-top-left dx-position-top-right dx-position-bottom-left dx-position-bottom-right dx-position-left dx-position-right");                var positionClass = "dx-position-" + splittedPosition[0];                if (splittedPosition[1])                    positionClass += "-" + splittedPosition[1];                this._$wrapper.addClass(positionClass)            },            _toggleIndeterminateState: function(value) {                if (value) {                    this._renderIndeterminateState();                    this._$bar.toggle(false)                }                else {                    this._$bar.toggle(true);                    this._$segmentContainer.remove();                    delete this._$segmentContainer                }            },            _renderValue: function() {                var val = this.option("value"),                    max = this.option("max");                if (!val && val !== 0) {                    this._toggleIndeterminateState(true);                    return                }                if (this._$segmentContainer)                    this._toggleIndeterminateState(false);                if (val === max)                    this._completeAction();                this.callBase();                this._setStatus()            },            _setStatus: function() {                var format = this.option("statusFormat");                if ($.isFunction(format))                    format = $.proxy(format, this);                else                    format = function(value) {                        return value                    };                var statusText = format(this._currentRatio, this.option("value"));                this._$status.text(statusText)            },            _dispose: function() {                this._$status.remove();                this.callBase()            },            _optionChanged: function(args) {                switch (args.name) {                    case"statusFormat":                        this._setStatus();                        break;                    case"showStatus":                        this._toggleStatus(args.value);                        break;                    case"statusPosition":                        this._toggleStatus(this.option("showStatus"));                        break;                    case"onComplete":                        this._createCompleteAction();                        break;                    case"_animatingSegmentCount":                        break;                    default:                        this.callBase(args)                }            }        }))    })(jQuery, DevExpress);    /*! Module widgets-base, file ui.slider.js */    (function($, DX, undefined) {        var ui = DX.ui,            events = ui.events,            translator = DX.translator,            transionEndEventName = DX.support.transitionEndEventName;        var SLIDER_CLASS = "dx-slider",            SLIDER_WRAPPER_CLASS = "dx-slider-wrapper",            SLIDER_HANDLE_CLASS = "dx-slider-handle",            SLIDER_HANDLE_SELECTOR = ".dx-slider-handle",            SLIDER_BAR_CLASS = "dx-slider-bar",            SLIDER_RANGE_CLASS = "dx-slider-range",            SLIDER_RANGE_VISIBLE_CLASS = "dx-slider-range-visible",            SLIDER_LABEL_CLASS = "dx-slider-label",            SLIDER_LABEL_POSITION_CLASS_PREFIX = "dx-slider-label-position-",            SLIDER_TOOLTIP_POSITION_CLASS_PREFIX = "dx-slider-tooltip-position-";        var dxSliderHandle = ui.Widget.inherit({                _setDefaultOptions: function() {                    this.callBase();                    this.option({                        hoverStateEnabled: false,                        value: 50,                        tooltipEnabled: false,                        tooltipFormat: function(v) {                            return v                        },                        tooltipPosition: "top",                        tooltipShowMode: "onHover",                        tooltipFitIn: null                    })                },                _render: function() {                    this.callBase();                    this.element().addClass(SLIDER_HANDLE_CLASS);                    this._renderTooltip();                    this.setAria({                        role: "slider",                        valuenow: this.option("value")                    })                },                _renderTooltip: function() {                    if (this.option("tooltipEnabled")) {                        if (!this._$tooltip) {                            this._$tooltip = $("<div>").appendTo(this.element());                            this._tooltip = this._createComponent(this._$tooltip, "dxTooltip", {                                visible: true,                                height: undefined,                                target: this.element(),                                closeOnOutsideClick: false,                                container: this.element(),                                closeOnBackButton: false,                                closeOnTargetScroll: false,                                animation: null,                                arrowPosition: null                            })                        }                        this._renderTooltipPosition();                        this._renderTooltipShowMode();                        this._renderValue()                    }                    else                        this._removeTooltip()                },                _visibilityChanged: function() {                    this._dimensionChanged()                },                _dimensionChanged: function() {                    this._repaintTooltip()                },                _removeTooltip: function() {                    if (!this._$tooltip)                        return;                    this._$tooltip.remove();                    delete this._$tooltip;                    delete this._tooltip                },                _renderTooltipPosition: function() {                    if (!this._tooltip)                        return;                    var position = this.option("tooltipPosition");                    if ($.type(position) === "string")                        position = position + "None";                    this._tooltip.option("position", position)                },                _repaintTooltip: function() {                    if (this._tooltip)                        this._tooltip.repaint()                },                _renderValue: function() {                    if (!this._tooltip)                        return;                    var format = this.option("tooltipFormat"),                        value = format(this.option("value"));                    this._tooltip.content().html(value);                    this._fitTooltipPosition()                },                _renderTooltipShowMode: function() {                    this.element().toggleClass("dx-slider-tooltip-on-hover", /^onhover$/i.test(this.option("tooltipShowMode")))                },                _fitTooltipPosition: function() {                    if (!this._$tooltip)                        return;                    var $tooltipContent = this._tooltip.content().parent(),                        tooltipWidth = $tooltipContent.outerWidth(),                        $boundElement = this.option("tooltipFitIn"),                        boundElementWidth = $boundElement.outerWidth(),                        boundElementLeft = $boundElement.offset().left,                        boundElementRight = boundElementLeft + boundElementWidth,                        $element = this.element(),                        elementWidth = $element.outerWidth(),                        elementLeft = $element.offset().left,                        elementRight = elementLeft + elementWidth,                        idealOffset = Math.round(elementWidth / 2 - tooltipWidth / 2),                        minOffset = Math.ceil(boundElementLeft - elementLeft),                        maxOffset = Math.floor(boundElementRight - elementRight) + idealOffset * 2,                        newOffset = Math.min(Math.max(minOffset, idealOffset), maxOffset);                    translator.move($tooltipContent, {left: newOffset})                },                _clean: function() {                    this.callBase();                    delete this._$tooltip;                    delete this._tooltip                },                _optionChanged: function(args) {                    switch (args.name) {                        case"tooltipFormat":                            this._renderValue();                            break;                        case"value":                            this._renderValue();                            this.setAria("valuenow", args.value);                            break;                        case"tooltipEnabled":                            this._renderTooltip();                            break;                        case"tooltipPosition":                            this._renderTooltipPosition();                            break;                        case"tooltipShowMode":                            this._renderTooltipShowMode();                            break;                        case"tooltipFitIn":                            this._fitTooltipPosition();                            break;                        case"_templates":                        case"templateProvider":                            break;                        default:                            this.callBase(args)                    }                },                fitTooltipPosition: function() {                    this._fitTooltipPosition()                },                repaint: function() {                    this._repaintTooltip();                    this._renderTooltipPosition();                    this._fitTooltipPosition()                }            });        DX.registerComponent("dxSlider", ui, ui.dxTrackBar.inherit({            _activeStateUnit: SLIDER_HANDLE_SELECTOR,            _supportedKeys: function() {                var isRTL = this.option("rtlEnabled");                var that = this,                    moveHandleRight = function(step) {                        var val = that.option("value");                        step = that._valueStep(step);                        val = isRTL ? val - step : val + step;                        that.option("value", val)                    },                    moveHandleLeft = function(step) {                        var val = that.option("value");                        step = that._valueStep(step);                        val = isRTL ? val + step : val - step;                        that.option("value", val)                    };                return $.extend(this.callBase(), {                        leftArrow: function(e) {                            e.preventDefault();                            e.stopPropagation();                            moveHandleLeft(this.option("step"))                        },                        rightArrow: function(e) {                            e.preventDefault();                            e.stopPropagation();                            moveHandleRight(this.option("step"))                        },                        pageUp: function(e) {                            e.preventDefault();                            e.stopPropagation();                            moveHandleRight(this.option("step") * this.option("keyStep"))                        },                        pageDown: function(e) {                            e.preventDefault();                            e.stopPropagation();                            moveHandleLeft(this.option("step") * this.option("keyStep"))                        },                        home: function(e) {                            e.preventDefault();                            e.stopPropagation();                            var min = this.option("min");                            this.option("value", min)                        },                        end: function(e) {                            e.preventDefault();                            e.stopPropagation();                            var max = this.option("max");                            this.option("value", max)                        }                    })            },            _setDefaultOptions: function() {                this.callBase();                this.option({                    step: 1,                    value: 50,                    showRange: true,                    tooltip: {                        enabled: false,                        format: function(value) {                            return value                        },                        position: "top",                        showMode: "onHover"                    },                    label: {                        visible: false,                        position: "bottom",                        format: function(value) {                            return value                        }                    },                    keyStep: 1                })            },            _defaultOptionsRules: function() {                return this.callBase().concat([{                            device: function(device) {                                return DX.devices.real().generic && !DX.devices.isSimulator()                            },                            options: {                                focusStateEnabled: true,                                hoverStateEnabled: true                            }                        }])            },            _render: function() {                this.element().addClass(SLIDER_CLASS);                this.callBase();                this._renderLabels();                this._renderStartHandler();                this._renderAriaMinAndMax()            },            _visibilityChanged: function() {                this.repaint()            },            _renderWrapper: function() {                this.callBase();                this._$wrapper.addClass(SLIDER_WRAPPER_CLASS);                this._createComponent(this._$wrapper, "dxSwipeable", {                    elastic: false,                    immediate: true,                    onStart: $.proxy(this._swipeStartHandler, this),                    onUpdated: $.proxy(this._swipeUpdateHandler, this),                    onEnd: $.proxy(this._swipeEndHandler, this),                    itemSizeFunc: $.proxy(this._itemWidthFunc, this)                })            },            _renderContainer: function() {                this.callBase();                this._$bar.addClass(SLIDER_BAR_CLASS);                this._$bar.off(transionEndEventName + "." + this.NAME).on(transionEndEventName, $.proxy(this._fitHandleTooltipPosition, this))            },            _renderRange: function() {                this.callBase();                this._$range.addClass(SLIDER_RANGE_CLASS);                this._renderHandle();                this._renderRangeVisibility()            },            _renderRangeVisibility: function() {                this._$range.toggleClass(SLIDER_RANGE_VISIBLE_CLASS, Boolean(this.option("showRange")))            },            _renderHandle: function() {                this._$handle = this._renderHandleImpl(this.option("value"), this._$handle)            },            _renderHandleImpl: function(value, $element) {                var $handle = $element || $("<div>").appendTo(this._$range),                    format = this._normalizeFormat(this.option("tooltip.format")),                    tooltipEnabled = this.option("tooltip.enabled"),                    tooltipPosition = this.option("tooltip.position");                this.element().toggleClass(SLIDER_TOOLTIP_POSITION_CLASS_PREFIX + "bottom", tooltipEnabled && tooltipPosition === "bottom").toggleClass(SLIDER_TOOLTIP_POSITION_CLASS_PREFIX + "top", tooltipEnabled && tooltipPosition === "top");                this._createComponent($handle, "dxSliderHandle", {                    value: value,                    tooltipEnabled: tooltipEnabled,                    tooltipPosition: tooltipPosition,                    tooltipFormat: format,                    tooltipShowMode: this.option("tooltip.showMode"),                    tooltipFitIn: this.element()                });                return $handle            },            _renderAriaMinAndMax: function() {                this.setAria({                    valuemin: this.option("min"),                    valuemax: this.option("max")                }, this._$handle)            },            _renderLabels: function() {                this.element().removeClass(SLIDER_LABEL_POSITION_CLASS_PREFIX + "bottom").removeClass(SLIDER_LABEL_POSITION_CLASS_PREFIX + "top");                if (this.option("label.visible")) {                    var min = this.option("min"),                        max = this.option("max"),                        position = this.option("label.position"),                        format = this._normalizeFormat(this.option("label.format"));                    if (!this._$minLabel)                        this._$minLabel = $("<div>").addClass(SLIDER_LABEL_CLASS).appendTo(this._$wrapper);                    this._$minLabel.html(format(min));                    if (!this._$maxLabel)                        this._$maxLabel = $("<div>").addClass(SLIDER_LABEL_CLASS).appendTo(this._$wrapper);                    this._$maxLabel.html(format(max));                    this.element().addClass(SLIDER_LABEL_POSITION_CLASS_PREFIX + position)                }                else {                    if (this._$minLabel) {                        this._$minLabel.remove();                        delete this._$minLabel                    }                    if (this._$maxLabel) {                        this._$maxLabel.remove();                        delete this._$maxLabel                    }                }            },            _normalizeFormat: function(formatSource) {                var format = formatSource;                if (typeof formatSource === "string")                    format = function(value) {                        return Globalize.format(value, formatSource)                    };                else if ($.isFunction(formatSource))                    format = $.proxy(format, this);                else                    format = function(value) {                        return value                    };                return format            },            _renderDimensions: function() {                this.callBase();                if (this._$bar) {                    var barMarginWidth = this._$bar.outerWidth(true) - this._$bar.outerWidth();                    this._$bar.width(this.option("width") - barMarginWidth)                }            },            _renderStartHandler: function() {                var pointerDownEventName = events.addNamespace("dxpointerdown", this.NAME),                    clickEventName = events.addNamespace("dxclick", this.NAME),                    startAction = this._createAction($.proxy(this._startHandler, this));                this.element().off(pointerDownEventName).on(pointerDownEventName, function(e) {                    if (events.isMouseEvent(e))                        startAction({jQueryEvent: e})                }).off(clickEventName).on(clickEventName, $.proxy(function(e) {                    var handle = this._activeHandle();                    handle && handle.focusin() && handle.focus();                    startAction({jQueryEvent: e})                }, this))            },            _itemWidthFunc: function() {                return this.element().width() / this._swipePixelRatio()            },            _swipeStartHandler: function(e) {                var rtlEnabled = this.option("rtlEnabled"),                    startOffset,                    endOffset;                if (events.isTouchEvent(e.jQueryEvent))                    this._createAction($.proxy(this._startHandler, this))({jQueryEvent: e.jQueryEvent});                this._feedbackDeferred = $.Deferred();                ui.events.lockFeedback(this._feedbackDeferred);                this._toggleActiveState(this._activeHandle(), true);                this._startOffset = this._currentRatio;                startOffset = this._startOffset * this._swipePixelRatio();                endOffset = (1 - this._startOffset) * this._swipePixelRatio();                e.jQueryEvent.maxLeftOffset = rtlEnabled ? endOffset : startOffset;                e.jQueryEvent.maxRightOffset = rtlEnabled ? startOffset : endOffset;                this._needPreventAnimation = true            },            _swipeEndHandler: function(e) {                this._feedbackDeferred.resolve();                this._toggleActiveState(this._activeHandle(), false);                var offsetDirection = this.option("rtlEnabled") ? -1 : 1;                delete this._needPreventAnimation;                this._changeValueOnSwipe(this._startOffset + offsetDirection * e.jQueryEvent.targetOffset / this._swipePixelRatio());                delete this._startOffset;                this._renderValue()            },            _activeHandle: function() {                return this._$handle            },            _swipeUpdateHandler: function(e) {                this._saveValueChangeEvent(e);                this._updateHandlePosition(e)            },            _updateHandlePosition: function(e) {                var offsetDirection = this.option("rtlEnabled") ? -1 : 1;                var newRatio = this._startOffset + offsetDirection * e.jQueryEvent.offset / this._swipePixelRatio();                this._$range.width(newRatio * 100 + "%");                this._changeValueOnSwipe(newRatio)            },            _swipePixelRatio: function() {                var min = this.option("min"),                    max = this.option("max"),                    step = this._valueStep(this.option("step"));                return (max - min) / step            },            _valueStep: function(step) {                if (!step || isNaN(step))                    step = 1;                step = parseFloat(step.toFixed(5));                if (step === 0)                    step = 0.00001;                return step            },            _changeValueOnSwipe: function(ratio) {                var min = this.option("min"),                    max = this.option("max"),                    step = this._valueStep(this.option("step")),                    newChange = ratio * (max - min),                    newValue = min + newChange;                if (step < 0)                    return;                if (newValue === max || newValue === min)                    this.option("value", newValue);                else {                    var stepExponent = (step + "").split(".")[1];                    var minExponent = (min + "").split(".")[1];                    var exponentLength = Math.max(stepExponent && stepExponent.length || 0, minExponent && minExponent.length || 0);                    var stepCount = Math.round((newValue - min) / step);                    newValue = Number((stepCount * step + min).toFixed(exponentLength));                    this.option("value", Math.max(Math.min(newValue, max), min))                }            },            _startHandler: function(args) {                var e = args.jQueryEvent;                this._currentRatio = (ui.events.eventData(e).x - this._$bar.offset().left) / this._$bar.width();                if (this.option("rtlEnabled"))                    this._currentRatio = 1 - this._currentRatio;                this._saveValueChangeEvent(e);                this._changeValueOnSwipe(this._currentRatio)            },            _renderValue: function() {                this.callBase();                this._activeHandle().dxSliderHandle("option", "value", this.option("value"))            },            _rangeAnimationCompleteHandler: function() {                this._fitHandleTooltipPosition()            },            _fitHandleTooltipPosition: function() {                if (this._activeHandle())                    this._activeHandle().dxSliderHandle("fitTooltipPosition")            },            _repaintHandle: function() {                this._$handle.dxSliderHandle("repaint")            },            _optionChanged: function(args) {                switch (args.name) {                    case"visible":                        this.callBase(args);                        this._renderHandle();                        this._repaintHandle();                        DX.utils.triggerShownEvent(this.element());                        break;                    case"min":                    case"max":                        this._renderLabels();                        this._renderAriaMinAndMax();                        this.callBase(args);                        break;                    case"step":                        this._renderValue();                        break;                    case"keyStep":                        break;                    case"showRange":                        this._renderRangeVisibility();                        break;                    case"tooltip":                        this._renderHandle();                        break;                    case"label":                        this._renderLabels();                        break;                    case"rtlEnabled":                        this._toggleRTLDirection();                        this._renderValue();                        break;                    default:                        this.callBase(args)                }            },            _refresh: function() {                this._renderDimensions();                this._renderValue();                this._renderHandle();                this._repaintHandle()            }        }));        DX.registerComponent("dxSliderHandle", ui.dxSlider, dxSliderHandle)    })(jQuery, DevExpress);    /*! Module widgets-base, file ui.rangeSlider.js */    (function($, DX, undefined) {        var ui = DX.ui,            utils = DX.utils,            events = ui.events;        var RANGE_SLIDER_CLASS = "dx-rangeslider",            RANGE_SLIDER_START_HANDLE_CLASS = RANGE_SLIDER_CLASS + "-start-handle",            RANGE_SLIDER_END_HANDLE_CLASS = RANGE_SLIDER_CLASS + "-end-handle";        DX.registerComponent("dxRangeSlider", ui, ui.dxSlider.inherit({            _supportedKeys: function() {                var isRTL = this.option("rtlEnabled");                var that = this,                    _changeHandle = function(e, capturedHandle) {                        if (that.option("start") === that.option("end")) {                            that._capturedHandle = capturedHandle;                            e.target = that._capturedHandle;                            that._capturedHandle.focus()                        }                    },                    _setHandleValue = function(e, step, sign) {                        var isStart = $(e.target).hasClass(RANGE_SLIDER_START_HANDLE_CLASS),                            valueOption = isStart ? "start" : "end",                            val = that.option(valueOption);                        step = that._valueStep(step);                        val += sign * (isRTL ? -step : step);                        that.option(valueOption, val)                    },                    moveHandleRight = function(e, step) {                        _changeHandle(e, isRTL ? that._$handleStart : that._$handleEnd);                        _setHandleValue(e, step, 1)                    },                    moveHandleLeft = function(e, step) {                        _changeHandle(e, isRTL ? that._$handleEnd : that._$handleStart);                        _setHandleValue(e, step, -1)                    };                return $.extend(this.callBase(), {                        leftArrow: function(e) {                            e.preventDefault();                            e.stopPropagation();                            moveHandleLeft(e, this.option("step"))                        },                        rightArrow: function(e) {                            e.preventDefault();                            e.stopPropagation();                            moveHandleRight(e, this.option("step"))                        },                        pageUp: function(e) {                            e.preventDefault();                            e.stopPropagation();                            moveHandleRight(e, this.option("step") * this.option("keyStep"))                        },                        pageDown: function(e) {                            e.preventDefault();                            e.stopPropagation();                            moveHandleLeft(e, this.option("step") * this.option("keyStep"))                        },                        home: function(e) {                            e.preventDefault();                            e.stopPropagation();                            var isStart = $(e.target).hasClass(RANGE_SLIDER_START_HANDLE_CLASS),                                valueOption = isStart ? "start" : "end",                                startOption = isStart ? "min" : "start",                                val = this.option(startOption);                            this.option(valueOption, val)                        },                        end: function(e) {                            e.preventDefault();                            e.stopPropagation();                            var isStart = $(e.target).hasClass(RANGE_SLIDER_START_HANDLE_CLASS),                                valueOption = isStart ? "start" : "end",                                endOption = isStart ? "end" : "max",                                val = this.option(endOption);                            this.option(valueOption, val)                        }                    })            },            _setDefaultOptions: function() {                this.callBase();                this.option({                    start: 40,                    end: 60                })            },            _render: function() {                this.callBase();                this.element().addClass(RANGE_SLIDER_CLASS)            },            _renderHandle: function() {                this._$handleStart = this._renderHandleImpl(this.option("start"), this._$handleStart).addClass(RANGE_SLIDER_START_HANDLE_CLASS);                this._$handleEnd = this._renderHandleImpl(this.option("end"), this._$handleEnd).addClass(RANGE_SLIDER_END_HANDLE_CLASS);                this._updateHandleAriaLabels()            },            _startHandler: function(args) {                var e = args.jQueryEvent,                    $range = this._$range,                    rangeWidth = $range.width(),                    eventOffsetX = events.eventData(e).x - this._$bar.offset().left,                    startHandleX = $range.position().left,                    endHandleX = $range.position().left + rangeWidth,                    rtlEnabled = this.option("rtlEnabled"),                    startHandleIsClosest = (rtlEnabled ? -1 : 1) * ((startHandleX + endHandleX) / 2 - eventOffsetX) > 0;                this._capturedHandle = startHandleIsClosest ? this._$handleStart : this._$handleEnd;                this.callBase(args)            },            _updateHandleAriaLabels: function() {                this.setAria("label", utils.stringFormat(Globalize.localize("dxRangeSlider-ariaFrom"), this.option("start")), this._$handleStart);                this.setAria("label", utils.stringFormat(Globalize.localize("dxRangeSlider-ariaTill"), this.option("end")), this._$handleEnd)            },            _activeHandle: function() {                return this._capturedHandle            },            _updateHandlePosition: function(e) {                var rtlEnabled = this.option("rtlEnabled"),                    offsetDirection = rtlEnabled ? -1 : 1,                    max = this.option("max"),                    min = this.option("min");                var newRatio = this._startOffset + offsetDirection * e.jQueryEvent.offset / this._swipePixelRatio();                newRatio = newRatio.toPrecision(12);                var newValue = newRatio * (max - min) + min;                this._updateSelectedRangePosition(newRatio, newRatio);                this._changeValueOnSwipe(newRatio);                var startValue = this.option("start"),                    endValue = this.option("end"),                    $nextHandle;                if (startValue === endValue) {                    if (newValue < startValue)                        $nextHandle = this._$handleStart;                    else                        $nextHandle = this._$handleEnd;                    $nextHandle.focus();                    if ($nextHandle && $nextHandle !== this._capturedHandle) {                        this._updateSelectedRangePosition((startValue - min) / (max - min), (endValue - min) / (max - min));                        this._toggleActiveState(this._activeHandle(), false);                        this._toggleActiveState($nextHandle, true);                        this._capturedHandle = $nextHandle                    }                    this._updateSelectedRangePosition(newRatio, newRatio);                    this._changeValueOnSwipe(newRatio)                }            },            _updateSelectedRangePosition: function(leftRatio, rightRatio) {                var rtlEnabled = this.option("rtlEnabled"),                    moveRight = this._capturedHandle === this._$handleStart && rtlEnabled || this._capturedHandle === this._$handleEnd && !rtlEnabled;                var prop = moveRight ? "right" : "left";                if (rtlEnabled ^ moveRight)                    this._$range.css(prop, 100 - rightRatio * 100 + "%");                else                    this._$range.css(prop, leftRatio * 100 + "%")            },            _changeValueOnSwipe: function(ratio) {                this._suppressValueChangeAction();                this.callBase(ratio);                this._resumeValueChangeAction();                var option = this._capturedHandle === this._$handleStart ? "start" : "end",                    start = this.option("start"),                    end = this.option("end"),                    newValue = this.option("value"),                    max = this.option("max"),                    min = this.option("min");                if (start > max) {                    start = max;                    this.option("start", max)                }                if (start < min) {                    start = min;                    this.option("start", min)                }                if (end > max) {                    end = max;                    this.option("end", max)                }                if (newValue > end && option === "start")                    newValue = end;                if (newValue < start && option === "end")                    newValue = start;                this.option(option, newValue)            },            _renderValue: function() {                var valStart = this.option("start"),                    valEnd = this.option("end"),                    min = this.option("min"),                    max = this.option("max"),                    rtlEnabled = this.option("rtlEnabled");                valStart = Math.max(min, Math.min(valStart, max));                valEnd = Math.max(valStart, Math.min(valEnd, max));                this.option("start", valStart);                this.option("end", valEnd);                var ratio1 = max === min ? 0 : (valStart - min) / (max - min),                    ratio2 = max === min ? 0 : (valEnd - min) / (max - min);                var startOffset = parseFloat((ratio1 * 100).toPrecision(12)) + "%",                    endOffset = parseFloat(((1 - ratio2) * 100).toPrecision(12)) + "%";                this._animateRange({                    right: rtlEnabled ? startOffset : endOffset,                    left: rtlEnabled ? endOffset : startOffset                });                this._renderHandle()            },            _repaintHandle: function() {                this._$handleStart.dxSliderHandle("repaint");                this._$handleEnd.dxSliderHandle("repaint")            },            _optionChanged: function(args) {                switch (args.name) {                    case"start":                    case"end":                        this._renderValue();                        this._createActionByOption("onValueChanged")({                            start: this.option("start"),                            end: this.option("end"),                            jQueryEvent: this._valueChangeEventInstance                        });                        this._saveValueChangeEvent(undefined);                        break;                    default:                        this.callBase(args)                }            }        }))    })(jQuery, DevExpress);    /*! Module widgets-base, file ui.gallery.js */    (function($, DX, undefined) {        var ui = DX.ui,            events = ui.events,            fx = DX.fx,            translator = DX.translator,            GALLERY_CLASS = "dx-gallery",            GALLERY_WRAPPER_CLASS = GALLERY_CLASS + "-wrapper",            GALLERY_LOOP_CLASS = "dx-gallery-loop",            GALLERY_ITEM_CONTAINER_CLASS = GALLERY_CLASS + "-container",            GALLERY_ACTIVE_CLASS = GALLERY_CLASS + "-active",            GALLERY_ITEM_CLASS = GALLERY_CLASS + "-item",            GALLERY_LOOP_ITEM_CLASS = GALLERY_ITEM_CLASS + "-loop",            GALLERY_ITEM_SELECTOR = "." + GALLERY_ITEM_CLASS,            GALLERY_ITEM_SELECTED_CLASS = GALLERY_ITEM_CLASS + "-selected",            GALLERY_INDICATOR_CLASS = GALLERY_CLASS + "-indicator",            GALLERY_INDICATOR_ITEM_CLASS = GALLERY_INDICATOR_CLASS + "-item",            GALLERY_INDICATOR_ITEM_SELECTOR = "." + GALLERY_INDICATOR_ITEM_CLASS,            GALLERY_INDICATOR_ITEM_SELECTED_CLASS = GALLERY_INDICATOR_ITEM_CLASS + "-selected",            GALLERY_ITEM_DATA_KEY = "dxGalleryItemData";        var dxGalleryNavButton = ui.Widget.inherit({                _supportedKeys: function() {                    return $.extend(this.callBase(), {                            pageUp: $.noop,                            pageDown: $.noop                        })                },                _setDefaultOptions: function() {                    this.callBase();                    this.option({                        direction: "next",                        onClick: null,                        hoverStateEnabled: true,                        activeStateEnabled: true                    })                },                _render: function() {                    this.callBase();                    var that = this,                        $element = this.element(),                        eventName = events.addNamespace("dxclick", this.NAME);                    $element.addClass(GALLERY_CLASS + "-nav-button-" + this.option("direction")).off(eventName).on(eventName, function(e) {                        that._createActionByOption("onClick")({jQueryEvent: e})                    })                },                _optionChanged: function(args) {                    switch (args.name) {                        case"onClick":                        case"direction":                            this._invalidate();                            break;                        default:                            this.callBase(args)                    }                }            });        DX.registerComponent("dxGallery", ui, ui.CollectionWidget.inherit({            _activeStateUnit: GALLERY_ITEM_SELECTOR,            _setDefaultOptions: function() {                this.callBase();                this.option({                    activeStateEnabled: false,                    animationDuration: 400,                    animationEnabled: true,                    loop: false,                    swipeEnabled: true,                    indicatorEnabled: true,                    showIndicator: true,                    selectedIndex: 0,                    slideshowDelay: 0,                    showNavButtons: false,                    wrapAround: false,                    initialItemWidth: undefined,                    stretchImages: false,                    _itemAttributes: {role: "option"},                    loopItemFocus: false,                    selectOnFocus: true,                    selectionMode: "single",                    selectionRequired: true,                    selectionByClick: false                })            },            _defaultOptionsRules: function() {                return this.callBase().concat([{                            device: function(device) {                                return DX.devices.real().generic && !DX.devices.isSimulator()                            },                            options: {focusStateEnabled: true}                        }])            },            _init: function() {                this.callBase();                this.option("loopItemFocus", this.option("loop"))            },            _dataSourceOptions: function() {                return {paginate: false}            },            _itemContainer: function() {                return this._$container            },            _itemClass: function() {                return GALLERY_ITEM_CLASS            },            _itemDataKey: function() {                return GALLERY_ITEM_DATA_KEY            },            _itemWidth: function() {                if (!this._itemWidthCache)                    this._itemWidthCache = this.option("initialItemWidth") || this.element().outerWidth();                return this._itemWidthCache            },            _actualItemWidth: function() {                var itemPerPage = this.option("wrapAround") ? this._itemsPerPage() + 1 : this._itemsPerPage();                if (this.option("stretchImages"))                    return this.element().outerWidth() / itemPerPage;                if (this.option("wrapAround"))                    return this._itemWidth() * this._itemsPerPage() / (this._itemsPerPage() + 1);                return this._itemWidth()            },            _itemsPerPage: function() {                var itemsPerPage = Math.floor(this.element().outerWidth() / this._itemWidth()) || 1;                return Math.min(itemsPerPage, this._itemsCount())            },            _pagesCount: function() {                return Math.ceil(this._itemsCount() / this._itemsPerPage())            },            _clearItemWidthCache: function() {                delete this._itemWidthCache            },            _itemsCount: function() {                return (this.option("items") || []).length            },            _offsetDirection: function() {                return this.option("rtlEnabled") ? -1 : 1            },            _render: function() {                this.element().addClass(GALLERY_CLASS);                this.element().toggleClass(GALLERY_LOOP_CLASS, this.option("loop"));                this._renderDragHandler();                this._renderWrapper();                this._renderItemsContainer();                this.callBase();                this._renderContainerPosition();                this._renderItemSizes();                this._renderItemPositions();                this._renderNavButtons();                this._renderIndicator();                this._renderSelectedItem();                this._renderUserInteraction();                this._setupSlideShow();                this._reviseDimensions();                this.setAria({                    role: "listbox",                    label: "gallery"                })            },            _dimensionChanged: function() {                var selectedIndex = this.option("selectedIndex") || 0;                this._clearItemWidthCache();                this._renderDuplicateItems();                this._renderItemSizes();                this._renderItemPositions();                this._renderIndicator();                this._renderContainerPosition(this._calculateIndexOffset(selectedIndex))            },            _renderDragHandler: function() {                var eventName = events.addNamespace("dragstart", this.NAME);                this.element().off(eventName).on(eventName, "img", function() {                    return false                })            },            _renderWrapper: function() {                if (this._$wrapper)                    return;                this._$wrapper = $("<div />").addClass(GALLERY_WRAPPER_CLASS).appendTo(this.element())            },            _renderItems: function(items) {                this.callBase(items);                this._loadNextPageIfNeeded()            },            _renderItemsContainer: function() {                if (this._$container)                    return;                this._$container = $("<div>").addClass(GALLERY_ITEM_CONTAINER_CLASS).appendTo(this._$wrapper)            },            _renderDuplicateItems: function() {                if (!this.option("loop"))                    return;                var items = this.option("items") || [],                    itemsCount = items.length,                    lastItemIndex = itemsCount - 1,                    i;                if (!itemsCount)                    return;                this.element().find("." + GALLERY_LOOP_ITEM_CLASS).remove();                var duplicateCount = Math.min(this._itemsPerPage(), itemsCount);                for (i = 0; i < duplicateCount; i++)                    this._renderItem(0, items[i]).addClass(GALLERY_LOOP_ITEM_CLASS);                for (i = 0; i < duplicateCount; i++)                    this._renderItem(0, items[lastItemIndex - i]).addClass(GALLERY_LOOP_ITEM_CLASS)            },            _renderItemSizes: function(startIndex) {                var $items = this._itemElements(),                    itemWidth = this._actualItemWidth();                if (startIndex !== undefined)                    $items = $items.slice(startIndex);                $items.each(function(index) {                    $($items[index]).outerWidth(itemWidth)                })            },            _renderItemPositions: function() {                var itemWidth = this._actualItemWidth(),                    itemsCount = this._itemsCount(),                    itemsPerPage = this._itemsPerPage(),                    loopItemsCount = this.element().find("." + GALLERY_LOOP_ITEM_CLASS).length,                    lastItemDuplicateIndex = itemsCount + loopItemsCount - 1,                    offsetDirection = this._offsetDirection(),                    offsetRatio = this.option("wrapAround") ? 0.5 : 0,                    freeSpace = this._itemFreeSpace();                this._itemElements().each(function(index) {                    var realIndex = index;                    if (index > itemsCount + itemsPerPage - 1)                        realIndex = lastItemDuplicateIndex - realIndex - itemsPerPage;                    var itemPosition = offsetDirection * itemWidth * (realIndex + offsetRatio) + freeSpace * (realIndex + 1 - offsetRatio);                    translator.move($(this), {left: itemPosition})                });                this._relocateItems(this.option("selectedIndex"), this.option("selectedIndex"), true)            },            _itemFreeSpace: function() {                var itemsPerPage = this._itemsPerPage();                if (this.option("wrapAround"))                    itemsPerPage = itemsPerPage + 1;                return (this.element().outerWidth() - this._actualItemWidth() * itemsPerPage) / (itemsPerPage + 1)            },            _renderContainerPosition: function(offset, animate) {                offset = offset || 0;                var that = this,                    itemWidth = this._actualItemWidth(),                    targetIndex = offset,                    targetPosition = this._offsetDirection() * targetIndex * (itemWidth + this._itemFreeSpace()),                    positionReady;                if (DX.utils.isDefined(this._animationOverride)) {                    animate = this._animationOverride;                    delete this._animationOverride                }                if (animate) {                    that._startSwipe();                    positionReady = that._animate(targetPosition).done($.proxy(that._endSwipe, that))                }                else {                    translator.move(this._$container, {left: targetPosition});                    positionReady = $.Deferred().resolveWith(that)                }                if (this._deferredAnimate)                    positionReady.done(function() {                        that._deferredAnimate.resolveWith(that)                    });                return positionReady.promise()            },            _startSwipe: function() {                this.element().addClass(GALLERY_ACTIVE_CLASS)            },            _endSwipe: function() {                this.element().removeClass(GALLERY_ACTIVE_CLASS)            },            _animate: function(targetPosition, extraConfig) {                var that = this,                    animationComplete = $.Deferred();                fx.animate(this._$container, $.extend({                    type: "slide",                    to: {left: targetPosition},                    duration: that.option("animationDuration"),                    complete: function() {                        if (that._needMoveContainerForward())                            translator.move(that._$container, {left: 0});                        if (that._needMoveContainerBack())                            translator.move(that._$container, {left: that._maxContainerOffset()});                        animationComplete.resolveWith(that)                    }                }, extraConfig || {}));                return animationComplete            },            _needMoveContainerForward: function() {                return this._$container.position().left * this._offsetDirection() <= -this._maxItemWidth() * this._itemsCount()            },            _needMoveContainerBack: function() {                return this._$container.position().left * this._offsetDirection() >= this._actualItemWidth()            },            _maxContainerOffset: function() {                return -this._maxItemWidth() * (this._itemsCount() - this._itemsPerPage()) * this._offsetDirection()            },            _maxItemWidth: function() {                return this._actualItemWidth() + this._itemFreeSpace()            },            _reviseDimensions: function() {                var that = this,                    $firstItem = that._itemElements().first().find(".dx-item-content");                if (!$firstItem || $firstItem.is(":hidden"))                    return;                if (!that.option("height"))                    that.option("height", $firstItem.outerHeight());                if (!that.option("width"))                    that.option("width", $firstItem.outerWidth());                this._dimensionChanged()            },            _renderIndicator: function() {                this._cleanIndicators();                if (!this.option("showIndicator"))                    return;                var indicator = this._$indicator = $("<div>").addClass(GALLERY_INDICATOR_CLASS).appendTo(this._$wrapper);                for (var i = 0; i < this._pagesCount(); i++)                    $("<div>").addClass(GALLERY_INDICATOR_ITEM_CLASS).appendTo(indicator);                this._renderSelectedPageIndicator()            },            _cleanIndicators: function() {                if (this._$indicator)                    this._$indicator.remove()            },            _renderSelectedItem: function() {                var selectedIndex = this.option("selectedIndex");                this._itemElements().removeClass(GALLERY_ITEM_SELECTED_CLASS).eq(selectedIndex).addClass(GALLERY_ITEM_SELECTED_CLASS)            },            _renderSelectedPageIndicator: function() {                if (!this._$indicator)                    return;                var itemIndex = this.option("selectedIndex"),                    lastIndex = this._pagesCount() - 1,                    pageIndex = Math.ceil(itemIndex / this._itemsPerPage());                pageIndex = Math.min(lastIndex, pageIndex);                this._$indicator.find(GALLERY_INDICATOR_ITEM_SELECTOR).removeClass(GALLERY_INDICATOR_ITEM_SELECTED_CLASS).eq(pageIndex).addClass(GALLERY_INDICATOR_ITEM_SELECTED_CLASS)            },            _renderUserInteraction: function() {                var that = this,                    rootElement = that.element(),                    swipeEnabled = that.option("swipeEnabled") && this._itemsCount() > 1;                this._createComponent(rootElement, "dxSwipeable", {                    disabled: this.option("disabled") || !swipeEnabled,                    onStart: $.proxy(that._swipeStartHandler, that),                    onUpdated: $.proxy(that._swipeUpdateHandler, that),                    onEnd: $.proxy(that._swipeEndHandler, that),                    itemSizeFunc: $.proxy(that._actualItemWidth(), that)                });                var indicatorSelectAction = this._createAction(this._indicatorSelectHandler);                rootElement.off(events.addNamespace("dxclick", this.NAME), GALLERY_INDICATOR_ITEM_SELECTOR).on(events.addNamespace("dxclick", this.NAME), GALLERY_INDICATOR_ITEM_SELECTOR, function(e) {                    indicatorSelectAction({jQueryEvent: e})                })            },            _indicatorSelectHandler: function(args) {                var e = args.jQueryEvent,                    instance = args.component;                if (!instance.option("indicatorEnabled"))                    return;                var indicatorIndex = $(e.target).index(),                    itemIndex = instance._fitPaginatedIndex(indicatorIndex * instance._itemsPerPage());                instance._needLongMove = true;                instance.option("selectedIndex", itemIndex);                instance._loadNextPageIfNeeded(itemIndex)            },            _renderNavButtons: function() {                var that = this;                if (!that.option("showNavButtons")) {                    that._cleanNavButtons();                    return                }                that._prevNavButton = $("<div>").appendTo(this._$wrapper);                that._createComponent(that._prevNavButton, "dxGalleryNavButton", {                    direction: "prev",                    onClick: function() {                        that._prevPage()                    }                });                that._nextNavButton = $("<div>").appendTo(this._$wrapper);                that._createComponent(that._nextNavButton, "dxGalleryNavButton", {                    direction: "next",                    onClick: function() {                        that._nextPage()                    }                });                this._renderNavButtonsVisibility()            },            _prevPage: function() {                var visiblePageSize = this._itemsPerPage(),                    newSelectedIndex = this.option("selectedIndex") - visiblePageSize;                if (newSelectedIndex === -visiblePageSize && visiblePageSize === this._itemsCount())                    return this._relocateItems(newSelectedIndex, 0);                else                    return this.goToItem(this._fitPaginatedIndex(newSelectedIndex))            },            _nextPage: function() {                var visiblePageSize = this._itemsPerPage(),                    newSelectedIndex = this.option("selectedIndex") + visiblePageSize;                if (newSelectedIndex === visiblePageSize && visiblePageSize === this._itemsCount())                    return this._relocateItems(newSelectedIndex, 0);                else                    return this.goToItem(this._fitPaginatedIndex(newSelectedIndex)).done(this._loadNextPageIfNeeded)            },            _loadNextPageIfNeeded: function(selectedIndex) {                selectedIndex = selectedIndex === undefined ? this.option("selectedIndex") : selectedIndex;                if (this._dataSource && this._dataSource.paginate() && this._shouldLoadNextPage(selectedIndex) && !this._isDataSourceLoading() && !this._isLastPage())                    this._loadNextPage().done($.proxy(function() {                        this._renderIndicator();                        this._renderItemPositions();                        this._renderNavButtonsVisibility();                        this._renderItemSizes(selectedIndex)                    }, this))            },            _shouldLoadNextPage: function(selectedIndex) {                var visiblePageSize = this._itemsPerPage();                return selectedIndex + 2 * visiblePageSize > this.option("items").length            },            _allowDinamicItemsAppend: function() {                return true            },            _fitPaginatedIndex: function(itemIndex) {                var itemsPerPage = this._itemsPerPage();                var restItemsCount = itemIndex < 0 ? itemsPerPage + itemIndex : this._itemsCount() - itemIndex;                if (itemIndex > this._itemsCount() - 1) {                    itemIndex = 0;                    this._goToGhostItem = true                }                else if (restItemsCount < itemsPerPage && restItemsCount > 0)                    if (itemIndex > 0)                        itemIndex = itemIndex - (itemsPerPage - restItemsCount);                    else                        itemIndex = itemIndex + (itemsPerPage - restItemsCount);                return itemIndex            },            _cleanNavButtons: function() {                if (this._prevNavButton) {                    this._prevNavButton.remove();                    delete this._prevNavButton                }                if (this._nextNavButton) {                    this._nextNavButton.remove();                    delete this._nextNavButton                }            },            _renderNavButtonsVisibility: function() {                if (!this.option("showNavButtons") || !this._prevNavButton || !this._nextNavButton)                    return;                var selectedIndex = this.option("selectedIndex"),                    loop = this.option("loop"),                    itemsCount = this._itemsCount();                this._prevNavButton.show();                this._nextNavButton.show();                if (loop)                    return;                var nextHidden = selectedIndex === itemsCount - this._itemsPerPage(),                    prevHidden = itemsCount < 2 || selectedIndex === 0;                if (this._dataSource && this._dataSource.paginate())                    nextHidden = nextHidden && this._isLastPage();                else                    nextHidden = nextHidden || itemsCount < 2;                if (prevHidden)                    this._prevNavButton.hide();                if (nextHidden)                    this._nextNavButton.hide()            },            _setupSlideShow: function() {                var that = this,                    slideshowDelay = that.option("slideshowDelay");                clearTimeout(that._slideshowTimer);                if (!slideshowDelay)                    return;                that._slideshowTimer = setTimeout(function() {                    if (that._userInteraction) {                        that._setupSlideShow();                        return                    }                    that.nextItem(true).done(that._setupSlideShow)                }, slideshowDelay)            },            _swipeStartHandler: function(e) {                var itemsCount = this._itemsCount();                if (!itemsCount) {                    e.jQueryEvent.cancel = true;                    return                }                this._stopItemAnimations();                this._startSwipe();                this._userInteraction = true;                if (!this.option("loop")) {                    var selectedIndex = this.option("selectedIndex"),                        startOffset = itemsCount - selectedIndex - this._itemsPerPage(),                        endOffset = selectedIndex,                        rtlEnabled = this.option("rtlEnabled");                    e.jQueryEvent.maxLeftOffset = rtlEnabled ? endOffset : startOffset;                    e.jQueryEvent.maxRightOffset = rtlEnabled ? startOffset : endOffset                }            },            _stopItemAnimations: function() {                fx.stop(this._$container, true)            },            _swipeUpdateHandler: function(e) {                var wrapAroundRatio = this.option("wrapAround") ? 1 : 0;                var offset = this._offsetDirection() * e.jQueryEvent.offset * (this._itemsPerPage() + wrapAroundRatio) - this.option("selectedIndex");                if (offset < 0)                    this._loadNextPageIfNeeded(Math.ceil(Math.abs(offset)));                this._renderContainerPosition(offset)            },            _swipeEndHandler: function(e) {                var targetOffset = e.jQueryEvent.targetOffset * this._offsetDirection() * this._itemsPerPage(),                    selectedIndex = this.option("selectedIndex"),                    newIndex = this._fitIndex(selectedIndex - targetOffset),                    paginatedIndex = this._fitPaginatedIndex(newIndex);                if (Math.abs(targetOffset) < this._itemsPerPage()) {                    this._relocateItems(selectedIndex);                    return                }                if (this._itemsPerPage() === this._itemsCount()) {                    if (targetOffset > 0)                        this._relocateItems(-targetOffset);                    else                        this._relocateItems(0);                    return                }                this.option("selectedIndex", paginatedIndex)            },            _setFocusOnSelect: function() {                this._userInteraction = true;                var selectedItem = this.itemElements().filter("." + GALLERY_ITEM_SELECTED_CLASS);                this.option("focusedElement", selectedItem);                this._userInteraction = false            },            _flipIndex: function(index) {                var itemsCount = this._itemsCount();                index = index % itemsCount;                if (index > (itemsCount + 1) / 2)                    index -= itemsCount;                if (index < -(itemsCount - 1) / 2)                    index += itemsCount;                return index            },            _fitIndex: function(index) {                if (!this.option("loop"))                    return index;                var itemsCount = this._itemsCount();                if (index >= itemsCount || index < 0)                    this._goToGhostItem = true;                if (index >= itemsCount)                    index = itemsCount - index;                index = index % itemsCount;                if (index < 0)                    index += itemsCount;                return index            },            _clean: function() {                this.callBase();                this._cleanIndicators();                this._cleanNavButtons()            },            _dispose: function() {                clearTimeout(this._slideshowTimer);                this.callBase()            },            _updateSelection: function(addedSelection, removedSelection) {                this._stopItemAnimations();                this._renderNavButtonsVisibility();                this._renderSelectedItem();                this._relocateItems(addedSelection[0], removedSelection[0]);                this._renderSelectedPageIndicator()            },            _relocateItems: function(newIndex, prevIndex, withoutAnimation) {                if (prevIndex === undefined)                    prevIndex = newIndex;                var indexOffset = this._calculateIndexOffset(newIndex, prevIndex);                this._renderContainerPosition(indexOffset, this.option("animationEnabled") && !withoutAnimation).done(function() {                    this._setFocusOnSelect();                    this._userInteraction = false;                    this._setupSlideShow()                })            },            _focusInHandler: function(e) {                if (fx.isAnimating(this._$container) || this._userInteraction)                    return;                this.callBase.apply(this, arguments)            },            _focusOutHandler: function(e) {                if (fx.isAnimating(this._$container) || this._userInteraction)                    return;                this.callBase.apply(this, arguments)            },            _selectFocusedItem: $.noop,            _moveFocus: function(location) {                this._stopItemAnimations();                this.callBase.apply(this, arguments);                var index = this.itemElements().index(this.option("focusedElement"));                this.goToItem(index, this.option("animationEnabled"))            },            _visibilityChanged: function(visible) {                if (visible)                    this._reviseDimensions()            },            _calculateIndexOffset: function(newIndex, lastIndex) {                if (lastIndex === undefined)                    lastIndex = newIndex;                var indexOffset = lastIndex - newIndex;                if (this.option("loop") && !this._needLongMove && this._goToGhostItem) {                    if (this._isItemOnFirstPage(newIndex) && this._isItemOnLastPage(lastIndex))                        indexOffset = -this._itemsPerPage();                    else if (this._isItemOnLastPage(newIndex) && this._isItemOnFirstPage(lastIndex))                        indexOffset = this._itemsPerPage();                    this._goToGhostItem = false                }                this._needLongMove = false;                indexOffset = indexOffset - lastIndex;                return indexOffset            },            _isItemOnLastPage: function(itemIndex) {                return itemIndex >= this._itemsCount() - this._itemsPerPage()            },            _isItemOnFirstPage: function(itemIndex) {                return itemIndex <= this._itemsPerPage()            },            _optionChanged: function(args) {                var value = args.value;                switch (args.name) {                    case"width":                    case"initialItemWidth":                        this.callBase.apply(this, arguments);                        this._dimensionChanged();                        break;                    case"animationDuration":                        this._renderNavButtonsVisibility();                        break;                    case"animationEnabled":                        break;                    case"loop":                        this.option("loopItemFocus", value);                        this.element().toggleClass(GALLERY_LOOP_CLASS, value);                        this._renderDuplicateItems();                        this._renderItemPositions();                        this._renderNavButtonsVisibility();                        return;                    case"showIndicator":                        this._renderIndicator();                        return;                    case"showNavButtons":                        this._renderNavButtons();                        return;                    case"slideshowDelay":                        this._setupSlideShow();                        return;                    case"wrapAround":                    case"stretchImages":                        this._renderItemSizes();                        this._renderItemPositions();                        break;                    case"swipeEnabled":                    case"indicatorEnabled":                        this._renderUserInteraction();                        return;                    default:                        this.callBase(args)                }            },            goToItem: function(itemIndex, animation) {                var selectedIndex = this.option("selectedIndex"),                    itemsCount = this._itemsCount();                if (animation !== undefined)                    this._animationOverride = animation;                itemIndex = this._fitIndex(itemIndex);                this._deferredAnimate = $.Deferred();                if (itemIndex > itemsCount - 1 || itemIndex < 0 || selectedIndex === itemIndex)                    return this._deferredAnimate.resolveWith(this).promise();                this.option("selectedIndex", itemIndex);                return this._deferredAnimate.promise()            },            prevItem: function(animation) {                return this.goToItem(this.option("selectedIndex") - 1, animation)            },            nextItem: function(animation) {                return this.goToItem(this.option("selectedIndex") + 1, animation)            }        }));        DX.registerComponent("dxGalleryNavButton", ui.dxGallery, dxGalleryNavButton)    })(jQuery, DevExpress);    /*! Module widgets-base, file ui.overlay.js */    (function($, DX, undefined) {        var ui = DX.ui,            utils = DX.utils,            events = ui.events,            fx = DX.fx,            translator = DX.translator;        var OVERLAY_CLASS = "dx-overlay",            OVERLAY_WRAPPER_CLASS = "dx-overlay-wrapper",            OVERLAY_CONTENT_CLASS = "dx-overlay-content",            OVERLAY_SHADER_CLASS = "dx-overlay-shader",            OVERLAY_MODAL_CLASS = "dx-overlay-modal",            ANONYMOUS_TEMPLATE_NAME = "content",            RTL_DIRECTION_CLASS = "dx-rtl",            ACTIONS = ["onShowing", "onShown", "onHiding", "onHidden", "onPositioning", "onPositioned"],            FIRST_Z_INDEX = 1000,            Z_INDEX_STACK = [],            DISABLED_STATE_CLASS = "dx-state-disabled",            TAB_KEY = 9;        var realDevice = DX.devices.real(),            realVersion = realDevice.version,            iOS7_0andBelow = realDevice.platform === "ios" && DX.compareVersions(realVersion, [7, 1]) < 0,            android4_0nativeBrowser = realDevice.platform === "android" && DX.compareVersions(realVersion, [4, 0], 2) === 0 && navigator.userAgent.indexOf("Chrome") === -1;        var forceRepaint = function($element) {                if (iOS7_0andBelow)                    $element.width();                if (android4_0nativeBrowser) {                    var $parents = $element.parents(),                        inScrollView = $parents.is(".dx-scrollable-native");                    if (!inScrollView) {                        $parents.css("backface-visibility", "hidden");                        $parents.css("backface-visibility");                        $parents.css("backface-visibility", "visible")                    }                }            };        var getElement = function(value) {                return value && $(value instanceof $.Event ? value.target : value)            };        DX.registerComponent("dxOverlay", ui, ui.Widget.inherit({            _supportedKeys: function() {                var offsetSize = 5,                    move = function(top, left, e) {                        if (!this.option("dragEnabled"))                            return;                        e.preventDefault();                        e.stopPropagation();                        var offset = {                                top: top,                                left: left                            };                        this._changePosition(offset)                    };                return $.extend(this.callBase(), {                        escape: function(e) {                            this.hide()                        },                        downArrow: $.proxy(move, this, offsetSize, 0),                        upArrow: $.proxy(move, this, -offsetSize, 0),                        leftArrow: $.proxy(move, this, 0, -offsetSize),                        rightArrow: $.proxy(move, this, 0, offsetSize)                    })            },            _setDeprecatedOptions: function() {                this.callBase();                $.extend(this._deprecatedOptions, {                    shownAction: {                        since: "14.2",                        alias: "onShown"                    },                    showingAction: {                        since: "14.2",                        alias: "onShowing"                    },                    hidingAction: {                        since: "14.2",                        alias: "onHiding"                    },                    hiddenAction: {                        since: "14.2",                        alias: "onHidden"                    }                })            },            _setDefaultOptions: function() {                this.callBase();                this.option({                    activeStateEnabled: false,                    visible: false,                    deferRendering: true,                    shading: true,                    shadingColor: "",                    position: {                        my: "center",                        at: "center"                    },                    width: function() {                        return $(window).width() * 0.8                    },                    height: function() {                        return $(window).height() * 0.8                    },                    animation: {                        show: {                            type: "pop",                            duration: 400                        },                        hide: {                            type: "pop",                            duration: 400,                            to: {                                opacity: 0,                                scale: 0                            },                            from: {                                opacity: 1,                                scale: 1                            }                        }                    },                    closeOnOutsideClick: false,                    closeOnBackButton: true,                    onShowing: null,                    onShown: null,                    onHiding: null,                    onHidden: null,                    contentTemplate: "content",                    dragEnabled: false,                    resizeEnabled: false,                    target: undefined,                    container: undefined,                    hideTopOverlayHandler: undefined,                    closeOnTargetScroll: false,                    onPositioning: null,                    onPositioned: null,                    boundaryOffset: {                        h: 0,                        v: 0                    }                })            },            _defaultOptionsRules: function() {                return this.callBase().concat([{                            device: function(device) {                                var realDevice = DX.devices.real(),                                    realPlatform = realDevice.platform,                                    realVersion = realDevice.version;                                return realPlatform === "android" && DX.compareVersions(realVersion, [4, 2]) < 0                            },                            options: {animation: {                                    show: {                                        type: "fade",                                        duration: 400                                    },                                    hide: {                                        type: "fade",                                        duration: 400,                                        to: {opacity: 0},                                        from: {opacity: 1}                                    }                                }}                        }])            },            _setOptionsByReference: function() {                this.callBase();                $.extend(this._optionsByReference, {animation: true})            },            _getAnonimousTemplateName: function() {                return ANONYMOUS_TEMPLATE_NAME            },            _wrapper: function() {                return this._$wrapper            },            _container: function() {                return this._$content            },            _init: function() {                this.callBase();                this._initActions();                this._initCloseOnOutsideClickHandler();                this._$wrapper = $("<div>").addClass(OVERLAY_WRAPPER_CLASS);                this._$content = $("<div>").addClass(OVERLAY_CONTENT_CLASS);                var $element = this.element();                this._$wrapper.addClass($element.attr("class"));                $element.addClass(OVERLAY_CLASS);                this._$wrapper.attr("data-bind", "dxControlsDescendantBindings: true");                this._$wrapper.on("MSPointerDown", $.noop);                this._toggleViewPortSubscriptiion(true)            },            _initOptions: function(options) {                this._initTarget(options.target);                this._initContainer(options.container);                this._initHideTopOverlayHandler(options.hideTopOverlayHandler);                this.callBase(options)            },            _initTarget: function(target) {                if (!utils.isDefined(target))                    return;                var options = this.option();                $.each(["position.of", "animation.show.from.position.of", "animation.show.to.position.of", "animation.hide.from.position.of", "animation.hide.to.position.of"], function(_, path) {                    var pathParts = path.split(".");                    var option = options;                    while (option)                        if (pathParts.length === 1) {                            if ($.isPlainObject(option))                                option[pathParts.shift()] = target;                            break                        }                        else                            option = option[pathParts.shift()]                })            },            _initContainer: function(container) {                container = container === undefined ? DX.viewPort() : container;                var $element = this.element(),                    $container = $element.closest(container);                if (!$container.length)                    $container = $(container).first();                this._$container = $container.length ? $container : $element.parent()            },            _initHideTopOverlayHandler: function(handler) {                this._hideTopOverlayHandler = handler !== undefined ? handler : $.proxy(this._defaultHideTopOverlayHandler, this)            },            _defaultHideTopOverlayHandler: function() {                this.hide()            },            _initActions: function() {                this._actions = {};                $.each(ACTIONS, $.proxy(function(_, action) {                    this._actions[action] = this._createActionByOption(action) || $.noop                }, this))            },            _initCloseOnOutsideClickHandler: function() {                this._proxiedDocumentDownHandler = $.proxy(function() {                    this._documentDownHandler.apply(this, arguments)                }, this)            },            _documentDownHandler: function(e) {                if (!this._isTopOverlay())                    return;                var closeOnOutsideClick = this.option("closeOnOutsideClick");                if ($.isFunction(closeOnOutsideClick))                    closeOnOutsideClick = closeOnOutsideClick(e);                if (closeOnOutsideClick) {                    var $container = this._$content,                        outsideClick = !$container.is(e.target) && !$.contains($container.get(0), e.target);                    if (outsideClick) {                        if (this.option("shading"))                            e.preventDefault();                        this.hide()                    }                }            },            _isTopOverlay: function() {                var zIndexStack = this._zIndexStack();                return zIndexStack[zIndexStack.length - 1] === this._zIndex            },            _zIndexStack: function() {                return Z_INDEX_STACK            },            _zIndexInitValue: function() {                return FIRST_Z_INDEX            },            _toggleViewPortSubscriptiion: function(toggle) {                DX.viewPortChanged.remove(this._viewPortChangeHandle);                if (toggle) {                    this._viewPortChangeHandle = $.proxy(this._viewPortChangeHandler, this);                    DX.viewPortChanged.add(this._viewPortChangeHandle)                }            },            _viewPortChangeHandler: function() {                this._initContainer(this.option("container"));                this._refresh()            },            _renderVisibilityAnimate: function() {                var visible = this.option("visible");                this._stopAnimation();                if (visible)                    return this._show();                else                    return this._hide()            },            _normalizePosition: function() {                this._position = this.option("position")            },            _show: function() {                if (this._isParentHidden())                    return $.Deferred().resolve();                this._normalizePosition();                var that = this,                    deferred = $.Deferred(),                    animation = that.option("animation") || {},                    showAnimation = this._normalizeAnimation(animation.show, "to"),                    completeShowAnimation = showAnimation && showAnimation.complete || $.noop;                if (this._isHidingActionCancelled) {                    delete this._isHidingActionCancelled;                    deferred.resolve()                }                else {                    this._toggleVisibility(true);                    this._animate(showAnimation, function() {                        if (that.option("focusStateEnabled"))                            that._focusTarget().focus();                        completeShowAnimation.apply(this, arguments);                        that._actions.onShown();                        deferred.resolve()                    })                }                return deferred.promise()            },            _normalizeAnimation: function(animation, prop) {                if (animation && animation[prop]) {                    animation = $.extend({type: "slide"}, animation);                    $.extend(animation[prop], {position: this._position})                }                return animation            },            _hide: function() {                var that = this,                    deferred = $.Deferred(),                    animation = this.option("animation") || {},                    hideAnimation = this._normalizeAnimation(animation.hide, "from"),                    completeHideAnimation = hideAnimation && hideAnimation.complete || $.noop,                    hidingArgs = {cancel: false};                this._actions.onHiding(hidingArgs);                if (hidingArgs.cancel) {                    this._isHidingActionCancelled = true;                    this.option("visible", true);                    deferred.resolve()                }                else {                    this._toggleShading(false);                    this._animate(hideAnimation, function() {                        that._toggleVisibility(false);                        completeHideAnimation.apply(this, arguments);                        that._actions.onHidden();                        deferred.resolve()                    })                }                return deferred.promise()            },            _animate: function(animation, completeCallback) {                if (animation) {                    var startCallback = animation.start || $.noop,                        $content = this._$content;                    fx.animate(this._$content, $.extend({}, animation, {                        start: function() {                            $content.css("pointer-events", "none");                            startCallback.apply(this, arguments)                        },                        complete: function() {                            $content.css("pointer-events", "");                            completeCallback.apply(this, arguments)                        }                    }))                }                else                    completeCallback()            },            _stopAnimation: function() {                fx.stop(this._$content, true)            },            _toggleVisibility: function(visible) {                if (visible && this._isParentHidden())                    return;                this._stopAnimation();                if (!visible)                    utils.triggerHidingEvent(this._$content);                this.callBase.apply(this, arguments);                this._$content.toggle(visible);                this._updateZIndexStackPosition(visible);                if (visible) {                    this._renderContent();                    this._actions.onShowing();                    this._moveToContainer();                    this._renderGeometry();                    utils.triggerShownEvent(this._$content)                }                else                    this._moveFromContainer();                this._toggleShading(visible);                this._toggleSubscriptions(visible)            },            _updateZIndexStackPosition: function(pushToStack) {                var zIndexStack = this._zIndexStack();                if (pushToStack) {                    if (!this._zIndex) {                        var length = zIndexStack.length;                        this._zIndex = (length ? zIndexStack[length - 1] : this._zIndexInitValue()) + 1;                        zIndexStack.push(this._zIndex)                    }                    this._$wrapper.css("z-index", this._zIndex);                    this._$content.css("z-index", this._zIndex)                }                else if (this._zIndex) {                    var index = $.inArray(this._zIndex, zIndexStack);                    zIndexStack.splice(index, 1);                    delete this._zIndex                }            },            _toggleShading: function(visible) {                this._$wrapper.toggleClass(OVERLAY_MODAL_CLASS, this.option("shading") && !this.option("container"));                this._$wrapper.toggleClass(OVERLAY_SHADER_CLASS, visible && this.option("shading"));                this._$wrapper.css("background-color", this.option("shading") ? this.option("shadingColor") : "");                this._toggleTabTerminator(visible && this.option("shading"))            },            _toggleTabTerminator: function(enabled) {                var eventName = events.addNamespace("keydown", this.NAME);                if (enabled)                    $(document).on(eventName, $.proxy(this._tabKeyHandler, this));                else                    $(document).off(eventName)            },            _tabKeyHandler: function(e) {                if (e.keyCode !== TAB_KEY)                    return;                var tabbableElements = this._$wrapper.find(":dx-tabbable"),                    $firstTabbable = tabbableElements.first(),                    $lastTabbable = tabbableElements.last(),                    isTabOnLast = !e.shiftKey && e.target === $lastTabbable.get(0),                    isShiftTabOnFirst = e.shiftKey && e.target === $firstTabbable.get(0),                    isEmptyTabList = tabbableElements.length === 0,                    isOutsideTarget = $.inArray(e.target, tabbableElements) === -1;                if (isTabOnLast || isShiftTabOnFirst || isEmptyTabList || isOutsideTarget) {                    e.preventDefault();                    (e.shiftKey ? $lastTabbable : $firstTabbable).focusin().focus()                }            },            _toggleSubscriptions: function(enabled) {                this._toggleHideTopOverlayCallback(enabled);                this._toggleDocumentDownHandler(enabled);                this._toggleParentsScrollSubscription(enabled)            },            _toggleHideTopOverlayCallback: function(subscribe) {                if (!this._hideTopOverlayHandler)                    return;                if (subscribe && this.option("closeOnBackButton"))                    DX.hideTopOverlayCallback.add(this._hideTopOverlayHandler);                else                    DX.hideTopOverlayCallback.remove(this._hideTopOverlayHandler)            },            _toggleDocumentDownHandler: function(enabled) {                var eventName = events.addNamespace("dxpointerdown", this.NAME);                if (enabled)                    $(document).on(eventName, this._proxiedDocumentDownHandler);                else                    $(document).off(eventName, this._proxiedDocumentDownHandler)            },            _toggleParentsScrollSubscription: function(subscribe) {                if (!this._position)                    return;                var that = this,                    target = that._position.of || $(),                    closeOnScroll = this.option("closeOnTargetScroll"),                    $parents = getElement(target).parents();                if (DX.devices.real().platform === "generic")                    $parents = $parents.add(window);                $().add(this._$prevTargetParents).off(events.addNamespace("scroll dxscroll", that.NAME));                if (subscribe && closeOnScroll) {                    $parents.on(events.addNamespace("scroll dxscroll", that.NAME), function(e) {                        if (e.overlayProcessed)                            return;                        e.overlayProcessed = true;                        var closeHandled = false;                        if ($.isFunction(closeOnScroll))                            closeHandled = closeOnScroll(e);                        if (!closeHandled)                            that.hide()                    });                    this._$prevTargetParents = $parents                }            },            _renderContent: function() {                var shouldDeferRendering = !this.option("visible") && this.option("deferRendering");                var isParentHidden = this.option("visible") && this._isParentHidden();                if (this._contentAlreadyRendered || shouldDeferRendering || isParentHidden)                    return;                this._contentAlreadyRendered = true;                this.callBase()            },            _isParentHidden: function() {                var $parent = this.element().parent();                if ($parent.is(":visible"))                    return false;                var isHidden = false;                $parent.add($parent.parents()).each(function() {                    var $element = $(this);                    if ($element.css("display") === "none") {                        isHidden = true;                        return false                    }                });                return isHidden || !$.contains(document, $parent.get(0))            },            _renderContentImpl: function() {                var $element = this.element();                this._$content.appendTo($element);                var contentTemplate = this._getTemplate(this.option("contentTemplate"));                contentTemplate && contentTemplate.render(this.content());                this._renderDrag();                this._renderResize();                this._renderScrollTerminator()            },            _renderDrag: function() {                var $dragTarget = this._getDragTarget();                if (!$dragTarget)                    return;                var startEventName = events.addNamespace("dxdragstart", this.NAME),                    updateEventName = events.addNamespace("dxdrag", this.NAME);                $dragTarget.off(startEventName).off(updateEventName);                if (!this.option("dragEnabled"))                    return;                $dragTarget.on(startEventName, $.proxy(this._dragStartHandler, this)).on(updateEventName, $.proxy(this._dragUpdateHandler, this))            },            _renderResize: function() {                this._createComponent(this._$content, "dxResizable", {                    handles: this.option("resizeEnabled") ? "all" : "none",                    onResizeEnd: $.proxy(this._resizeEndHandler, this),                    minHeight: 100,                    minWidth: 100,                    area: this._$container                })            },            _resizeEndHandler: function() {                this._geometryChangeHandled = true            },            _renderScrollTerminator: function() {                var $scrollTerminator = this._wrapper();                var scrollEventName = events.addNamespace("dxscroll", this.NAME);                $scrollTerminator.off(scrollEventName).on(scrollEventName, {                    validate: function() {                        return true                    },                    getDirection: function() {                        return "both"                    },                    _togglePointerAddons: $.noop,                    _clearSelection: $.noop,                    isNative: true                }, function(e) {                    if (e.originalEvent.originalEvent.type !== "mousemove")                        e.preventDefault()                })            },            _getDragTarget: function() {                return this.content()            },            _dragStartHandler: function(e) {                e.targetElements = [];                this._prevOffset = {                    x: 0,                    y: 0                };                var position = translator.locate(this._$content),                    allowedOffsets = this._allowedOffsets();                var deltaSize = this._deltaSize();                var isAllowedDrag = deltaSize.height >= 0 && deltaSize.width >= 0;                this._geometryChangeHandled = isAllowedDrag;                e.maxLeftOffset = isAllowedDrag ? position.left + allowedOffsets.left : 0;                e.maxRightOffset = isAllowedDrag ? -position.left + allowedOffsets.right : 0;                e.maxTopOffset = isAllowedDrag ? position.top + allowedOffsets.top : 0;                e.maxBottomOffset = isAllowedDrag ? -position.top + allowedOffsets.bottom : 0            },            _deltaSize: function() {                var $content = this._$content,                    $container = this._$container;                var contentWidth = $content.outerWidth(),                    contentHeight = $content.outerHeight(),                    containerWidth = $container.width(),                    containerHeight = $container.height();                return {                        width: containerWidth - contentWidth,                        height: containerHeight - contentHeight                    }            },            _dragUpdateHandler: function(e) {                var offset = e.offset,                    prevOffset = this._prevOffset,                    targetOffset = {                        top: offset.y - prevOffset.y,                        left: offset.x - prevOffset.x                    };                this._changePosition(targetOffset);                this._prevOffset = offset            },            _changePosition: function(offset) {                var position = translator.locate(this._$content);                translator.move(this._$content, {                    left: position.left + offset.left,                    top: position.top + offset.top                })            },            _allowedOffsets: function() {                var deltaSize = this._deltaSize(),                    boundaryOffset = this.option("boundaryOffset");                return {                        top: boundaryOffset.v,                        bottom: deltaSize.height - boundaryOffset.v,                        left: boundaryOffset.h,                        right: deltaSize.width - boundaryOffset.h                    }            },            _fireContentReadyAction: function() {                if (this.option("visible"))                    this._moveToContainer();                this.callBase.apply(this, arguments)            },            _moveFromContainer: function() {                this._$content.appendTo(this.element());                this._detachWrapperToContainer()            },            _detachWrapperToContainer: function() {                this._$wrapper.detach()            },            _moveToContainer: function() {                this._attachWrapperToContainer();                this._$content.appendTo(this._$wrapper)            },            _attachWrapperToContainer: function() {                var $element = this.element();                if (this._$container && this._$container[0] !== $element.parent()[0])                    this._$wrapper.appendTo(this._$container);                else                    this._$wrapper.appendTo($element)            },            _renderGeometry: function() {                if (this.option("visible"))                    this._renderGeometryImpl()            },            _renderGeometryImpl: function() {                this._stopAnimation();                this._normalizePosition();                this._renderShading();                this._renderDimensions();                this._renderPosition()            },            _renderShading: function() {                var $wrapper = this._$wrapper,                    $container = this._getContainer();                $wrapper.css("position", this._isWindow($container) ? "fixed" : "absolute");                if (this.option("shading"))                    $wrapper.show();                this._renderShadingDimensions();                this._renderShadingPosition()            },            _renderShadingPosition: function() {                if (this.option("shading")) {                    var $container = this._getContainer();                    DX.position(this._$wrapper, {                        my: "top left",                        at: "top left",                        of: $container                    })                }            },            _renderShadingDimensions: function() {                if (this.option("shading")) {                    var $container = this._getContainer(),                        wrapperWidth = this._isWindow($container) ? "100%" : $container.outerWidth(),                        wrapperHeight = this._isWindow($container) ? "100%" : $container.outerHeight();                    this._$wrapper.css({                        width: wrapperWidth,                        height: wrapperHeight                    })                }            },            _isWindow: function($element) {                return !!$element && $.isWindow($element.get(0))            },            _getContainer: function() {                var position = this._position,                    container = this.option("container"),                    positionOf = position ? position.of || window : null;                return getElement(container || positionOf)            },            _renderDimensions: function() {                if (this._geometryChangeHandled) {                    var $content = this._$content,                        $container = this._$container;                    $content.outerWidth(Math.min($content.outerWidth(), $container.width())).outerHeight(Math.min($content.outerHeight(), $container.height()))                }                else                    this._$content.outerWidth(this.option("width")).outerHeight(this.option("height"))            },            _renderPosition: function() {                var position,                    containerPosition,                    allowedOffsets,                    $content;                if (this._geometryChangeHandled) {                    $content = this._$content;                    position = translator.locate($content);                    allowedOffsets = this._allowedOffsets();                    translator.move($content, {                        top: utils.fitIntoRange(position.top, -allowedOffsets.top, allowedOffsets.bottom),                        left: utils.fitIntoRange(position.left, -allowedOffsets.left, allowedOffsets.right)                    })                }                else {                    translator.resetPosition(this._$content);                    this._renderOverlayBoundaryOffset();                    position = this._position;                    containerPosition = DX.calculatePosition(this._$content, position);                    this._actions.onPositioning({position: containerPosition});                    var resultPosition = DX.position(this._$content, containerPosition);                    this._actions.onPositioned({position: resultPosition});                    forceRepaint(this._$content)                }            },            _renderOverlayBoundaryOffset: function() {                var boundaryOffset = this.option("boundaryOffset");                this._$content.css("margin", boundaryOffset.v + "px " + boundaryOffset.h + "px")            },            _focusTarget: function() {                return this._$content            },            _attachKeyboardEvents: function() {                this._keyboardProcessor = new ui.KeyboardProcessor({                    element: this._$content,                    handler: this._keyboardHandler,                    context: this                })            },            _keyboardHandler: function(options) {                var e = options.originalEvent,                    $target = $(e.target);                if ($target.is(this._$content))                    this.callBase.apply(this, arguments)            },            _visibilityChanged: function(visible) {                if (visible) {                    if (this.option("visible") && this._$content.is(":hidden"))                        this._show();                    this._dimensionChanged()                }                else if (this._$content.is(":visible"))                    this._hide()            },            _dimensionChanged: function() {                this._renderGeometry()            },            _clean: function() {                this._cleanFocusState()            },            _dispose: function() {                this._stopAnimation();                this._toggleViewPortSubscriptiion(false);                this._toggleSubscriptions(false);                this._updateZIndexStackPosition(false);                this._actions = null;                this.callBase();                this._$wrapper.remove();                this._$content.remove()            },            _toggleDisabledState: function(value) {                this.callBase.apply(this, arguments);                this._$content.toggleClass(DISABLED_STATE_CLASS, value)            },            _toggleRTLDirection: function(rtl) {                this._$content.toggleClass(RTL_DIRECTION_CLASS, rtl)            },            _optionChanged: function(args) {                var value = args.value;                if ($.inArray(args.name, ACTIONS) > -1) {                    this._initActions();                    return                }                switch (args.name) {                    case"dragEnabled":                        this._renderDrag();                        break;                    case"resizeEnabled":                        this._renderResize();                        break;                    case"resizeEnabled":                        this._invalidate();                        break;                    case"shading":                    case"shadingColor":                        this._toggleShading(this.option("visible"));                        break;                    case"width":                    case"height":                    case"position":                    case"boundaryOffset":                        this._renderGeometry();                        break;                    case"visible":                        delete this._geometryChangeHandled;                        this._renderVisibilityAnimate().done($.proxy(function() {                            if (!this._animateDeferred)                                return;                            this._animateDeferred.resolveWith(this)                        }, this));                        break;                    case"target":                        this._initTarget(value);                        this._invalidate();                        break;                    case"container":                        this._initContainer(value);                        this._invalidate();                        break;                    case"deferRendering":                    case"contentTemplate":                        this._invalidate();                        break;                    case"closeOnBackButton":                        this._toggleHideTopOverlayCallback(this.option("visible"));                        break;                    case"closeOnOutsideClick":                        this._toggleDocumentDownHandler(this.option("visible"));                        break;                    case"closeOnTargetScroll":                        this._toggleParentsScrollSubscription(this.option("visible"));                        break;                    case"animation":                        break;                    default:                        this.callBase(args)                }            },            toggle: function(showing) {                showing = showing === undefined ? !this.option("visible") : showing;                if (showing === this.option("visible"))                    return $.Deferred().resolve().promise();                var animateDeferred = $.Deferred();                this._animateDeferred = animateDeferred;                this.option("visible", showing);                return animateDeferred.promise().done($.proxy(function() {                        delete this._animateDeferred                    }, this))            },            show: function() {                return this.toggle(true)            },            hide: function() {                return this.toggle(false)            },            content: function() {                return this._$content            },            repaint: function() {                this._renderGeometry()            }        }));        DevExpress.ui.dxOverlay.baseZIndex = function(zIndex) {            FIRST_Z_INDEX = zIndex        };        ui.dxOverlay.__internals = {            OVERLAY_CLASS: OVERLAY_CLASS,            OVERLAY_WRAPPER_CLASS: OVERLAY_WRAPPER_CLASS,            OVERLAY_CONTENT_CLASS: OVERLAY_CONTENT_CLASS,            OVERLAY_SHADER_CLASS: OVERLAY_SHADER_CLASS,            OVERLAY_MODAL_CLASS: OVERLAY_MODAL_CLASS        }    })(jQuery, DevExpress);    /*! Module widgets-base, file ui.toast.js */    (function($, DX, undefined) {        var ui = DX.ui;        var TOAST_CLASS = "dx-toast",            TOAST_CLASS_PREFIX = TOAST_CLASS + "-",            TOAST_WRAPPER_CLASS = TOAST_CLASS_PREFIX + "wrapper",            TOAST_CONTENT_CLASS = TOAST_CLASS_PREFIX + "content",            TOAST_MESSAGE_CLASS = TOAST_CLASS_PREFIX + "message",            TOAST_ICON_CLASS = TOAST_CLASS_PREFIX + "icon",            WIDGET_NAME = "dxToast",            toastTypes = ["info", "warning", "error", "success"],            Z_INDEX_STACK = [],            FIRST_Z_INDEX_OFFSET = 8000,            visibleToastInstance = null,            POSITION_ALIASES = {                top: {                    my: "top",                    at: "top",                    of: window,                    offset: "0 0"                },                bottom: {                    my: "bottom",                    at: "bottom",                    of: window,                    offset: "0 -20"                },                center: {                    my: "center",                    at: "center",                    of: window,                    offset: "0 0"                },                right: {                    my: "center right",                    at: "center right",                    of: window,                    offset: "0 0"                },                left: {                    my: "center left",                    at: "center left",                    of: window,                    offset: "0 0"                }            };        DX.registerComponent(WIDGET_NAME, ui, ui.dxOverlay.inherit({            _setDefaultOptions: function() {                this.callBase();                this.option({                    message: "",                    type: "info",                    displayTime: 2000,                    position: "bottom center",                    animation: {                        show: {                            type: "fade",                            duration: 400,                            from: 0,                            to: 1                        },                        hide: {                            type: "fade",                            duration: 400,                            to: 0                        }                    },                    shading: false,                    height: "auto",                    closeOnBackButton: false,                    resizeEnabled: false                })            },            _defaultOptionsRules: function() {                return this.callBase().concat([{                            device: {platform: "win8"},                            options: {                                position: "top center",                                width: function() {                                    return $(window).width()                                }                            }                        }, {                            device: function(device) {                                return device.platform === "android"                            },                            options: {                                closeOnOutsideClick: true,                                width: "auto",                                position: {                                    at: "bottom left",                                    my: "bottom left",                                    offset: "20 -20"                                }                            }                        }, {                            device: function(device) {                                return device.deviceType === "phone" && device.platform === "android"                            },                            options: {                                width: function() {                                    return $(window).width()                                },                                position: {                                    at: "bottom center",                                    my: "bottom center",                                    offset: "0 0"                                }                            }                        }])            },            _init: function() {                this.callBase();                this._posStringToObject()            },            _renderContentImpl: function() {                if (this.option("message"))                    this._message = $("<div>").addClass(TOAST_MESSAGE_CLASS).text(this.option("message")).appendTo(this.content());                this.setAria("role", "alert", this._message);                if ($.inArray(this.option("type").toLowerCase(), toastTypes) > -1)                    this.content().prepend($("<div>").addClass(TOAST_ICON_CLASS));                this.callBase()            },            _render: function() {                this.callBase();                this.element().addClass(TOAST_CLASS);                this._wrapper().addClass(TOAST_WRAPPER_CLASS);                this._$content.addClass(TOAST_CLASS_PREFIX + String(this.option("type")).toLowerCase());                this.content().addClass(TOAST_CONTENT_CLASS);                this._$content.off("dxswipe").on("dxswipe", $.proxy(this.hide, this))            },            _posStringToObject: function() {                if (!DX.utils.isString(this.option("position")))                    return;                var verticalPosition = this.option("position").split(" ")[0],                    horizontalPosition = this.option("position").split(" ")[1];                this.option("position", $.extend({}, POSITION_ALIASES[verticalPosition]));                switch (horizontalPosition) {                    case"center":                    case"left":                    case"right":                        this.option("position").at += " " + horizontalPosition;                        this.option("position").my += " " + horizontalPosition;                        break                }            },            _show: function() {                if (visibleToastInstance) {                    clearTimeout(visibleToastInstance._hideTimeout);                    visibleToastInstance.hide()                }                visibleToastInstance = this;                return this.callBase.apply(this, arguments).done($.proxy(function() {                        clearTimeout(this._hideTimeout);                        this._hideTimeout = setTimeout($.proxy(this.hide, this), this.option("displayTime"))                    }, this))            },            _hide: function() {                visibleToastInstance = null;                return this.callBase.apply(this, arguments)            },            _zIndexStack: function() {                return Z_INDEX_STACK            },            _zIndexInitValue: function() {                return this.callBase() + FIRST_Z_INDEX_OFFSET            },            _dispose: function() {                clearTimeout(this._hideTimeout);                visibleToastInstance = null;                this.callBase()            },            _optionChanged: function(args) {                switch (args.name) {                    case"type":                        this._$content.removeClass(TOAST_CLASS_PREFIX + args.previousValue);                        this._$content.addClass(TOAST_CLASS_PREFIX + String(args.value).toLowerCase());                        break;                    case"message":                        if (this._message)                            this._message.text(args.value);                        break;                    case"displayTime":                    case"position":                        break;                    default:                        this.callBase(args)                }            }        }));        ui.dxToast.__internals = {            TOAST_CLASS: TOAST_CLASS,            TOAST_WRAPPER_CLASS: TOAST_WRAPPER_CLASS,            TOAST_CONTENT_CLASS: TOAST_CONTENT_CLASS,            TOAST_MESSAGE_CLASS: TOAST_MESSAGE_CLASS,            TOAST_ICON_CLASS: TOAST_ICON_CLASS,            TOAST_CLASS_PREFIX: TOAST_CLASS_PREFIX,            WIDGET_NAME: WIDGET_NAME        }    })(jQuery, DevExpress);    /*! Module widgets-base, file ui.popup.js */    (function($, DX, undefined) {        var ui = DX.ui,            translator = DX.translator,            POPUP_CLASS = "dx-popup",            POPUP_WRAPPER_CLASS = "dx-popup-wrapper",            POPUP_FULL_SCREEN_CLASS = "dx-popup-fullscreen",            POPUP_FULL_SCREEN_WIDTH_CLASS = "dx-popup-fullscreen-width",            POPUP_NORMAL_CLASS = "dx-popup-normal",            POPUP_CONTENT_CLASS = "dx-popup-content",            POPUP_DRAGGABLE_CLASS = "dx-popup-draggable",            POPUP_TITLE_CLASS = "dx-popup-title",            POPUP_TITLE_CLOSEBUTTON_CLASS = "dx-closebutton",            POPUP_BOTTOM_CLASS = "dx-popup-bottom",            TEMPLATE_WRAPPER_CLASS = "dx-template-wrapper",            ALLOWED_BUTTON_ALIASES = ["cancel", "clear", "done"];        var getButtonPlace = function(name) {                var device = DX.devices.current(),                    platform = device.platform,                    toolbar = "bottom",                    location = "before";                if (platform === "ios")                    switch (name) {                        case"cancel":                            toolbar = "top";                            break;                        case"clear":                            toolbar = "top";                            location = "after";                            break;                        case"done":                            location = "after";                            break                    }                else if (platform === "win8")                    location = "after";                else if (platform === "android" && device.version && parseInt(device.version[0]) > 4)                    switch (name) {                        case"cancel":                            location = "after";                            break;                        case"done":                            location = "after";                            break                    }                else if (platform === "android")                    location = "center";                return {                        toolbar: toolbar,                        location: location                    }            };        DX.registerComponent("dxPopup", ui, ui.dxOverlay.inherit({            _setDefaultOptions: function() {                this.callBase();                this.option({                    fullScreen: false,                    title: "",                    showTitle: true,                    titleTemplate: "title",                    onTitleRendered: null,                    dragEnabled: false,                    buttons: [],                    showCloseButton: false,                    bottomTemplate: "bottom"                })            },            _defaultOptionsRules: function() {                return this.callBase().concat([{                            device: {platform: "win8"},                            options: {width: function() {                                    return $(window).width()                                }}                        }, {                            device: {                                platform: "win8",                                phone: true                            },                            options: {position: {                                    my: "top center",                                    at: "top center",                                    offset: "0 0"                                }}                        }, {                            device: {platform: "ios"},                            options: {animation: this._iosAnimation}                        }, {                            device: {platform: "generic"},                            options: {showCloseButton: true}                        }, {                            device: function(device) {                                return DX.devices.real().platform === "generic" && device.platform === "generic"                            },                            options: {dragEnabled: true}                        }, {                            device: function(device) {                                return DX.devices.real().generic && !DX.devices.isSimulator()                            },                            options: {focusStateEnabled: true}                        }])            },            _iosAnimation: {                show: {                    type: "slide",                    duration: 400,                    from: {position: {                            my: "top",                            at: "bottom"                        }},                    to: {position: {                            my: "center",                            at: "center"                        }}                },                hide: {                    type: "slide",                    duration: 400,                    from: {                        opacity: 1,                        position: {                            my: "center",                            at: "center"                        }                    },                    to: {                        opacity: 1,                        position: {                            my: "top",                            at: "bottom"                        }                    }                }            },            _init: function() {                this.callBase();                this.element().addClass(POPUP_CLASS);                this._wrapper().addClass(POPUP_WRAPPER_CLASS);                this._$popupContent = this._$content.wrapInner($("<div>").addClass(POPUP_CONTENT_CLASS)).children().eq(0)            },            _render: function() {                var isFullscreen = this.option("fullScreen");                this._$content.toggleClass(POPUP_DRAGGABLE_CLASS, this.option("dragEnabled")).toggleClass(POPUP_FULL_SCREEN_CLASS, isFullscreen).toggleClass(POPUP_NORMAL_CLASS, !isFullscreen);                this.callBase()            },            _renderContentImpl: function() {                this.callBase();                this._renderTitle();                this._renderBottom()            },            _renderTitle: function() {                var items = this._getToolbarItems("top"),                    titleText = this.option("title"),                    showTitle = this.option("showTitle");                if (showTitle && !!titleText)                    items.unshift({                        location: DX.devices.current().ios ? "center" : "before",                        text: titleText                    });                if (showTitle || items.length > 0) {                    this._$title && this._$title.remove();                    var $title = $("<div>").addClass(POPUP_TITLE_CLASS).prependTo(this._$content);                    this._$title = this._renderTemplateByType("titleTemplate", items, $title).addClass(POPUP_TITLE_CLASS);                    this._renderDrag();                    this._executeTitleRenderAction(this._$title)                }                else if (this._$title)                    this._$title.detach()            },            _renderTemplateByType: function(optionName, data, $container) {                var template = this._getTemplateByOption(optionName),                    toolbarTemplate = template.owner() === this.option("templateProvider"),                    $result;                if (toolbarTemplate) {                    $result = template.render(data, $container);                    $container.replaceWith($result);                    return $result                }                else {                    $result = template.render($container);                    if ($result.hasClass(TEMPLATE_WRAPPER_CLASS)) {                        $container.replaceWith($result);                        $container = $result                    }                    return $container                }            },            _executeTitleRenderAction: function(titleElement) {                this._getTitleRenderAction()({titleElement: titleElement})            },            _getTitleRenderAction: function() {                return this._titleRenderAction || this._createTitleRenderAction()            },            _createTitleRenderAction: function() {                return this._titleRenderAction = this._createActionByOption("onTitleRendered", {                        element: this.element(),                        excludeValidators: ["designMode", "disabled", "readOnly"]                    })            },            _getCloseButton: function() {                return {                        toolbar: "top",                        location: "after",                        template: this._getCloseButtonRenderer()                    }            },            _getCloseButtonRenderer: function() {                return $.proxy(function(_, __, $container) {                        var $button = $("<div>").addClass(POPUP_TITLE_CLOSEBUTTON_CLASS);                        this._createComponent($button, "dxButton", {                            icon: 'close',                            onClick: this._createButtonAction(undefined),                            _templates: {}                        });                        $container.append($button)                    }, this)            },            _getToolbarItems: function(toolbar) {                var buttons = this.option("buttons");                var toolbarsItems = [];                this._buttonsClasses = [];                var currentPlatform = DX.devices.current().platform,                    index = 0;                $.each(buttons, $.proxy(function(_, data) {                    var isShortcut = DX.utils.isDefined(data.shortcut),                        item = isShortcut ? getButtonPlace(data.shortcut) : data;                    if (isShortcut && currentPlatform === "ios" && index < 2) {                        item.toolbar = "top";                        index++                    }                    $.extend(item, DX.utils.isDefined(data.toolbar) ? {toolbar: data.toolbar} : {});                    if (item && item.toolbar === toolbar) {                        if (isShortcut)                            $.extend(item, {location: data.location}, this._getButtonByAlias(data));                        var isLTROrder = currentPlatform === "win8" || currentPlatform === "generic";                        if (data.shortcut === "done" && isLTROrder || data.shortcut === "cancel" && !isLTROrder)                            toolbarsItems.unshift(item);                        else                            toolbarsItems.push(item)                    }                }, this));                if (toolbar === "top" && this.option("showCloseButton"))                    toolbarsItems.push(this._getCloseButton());                return toolbarsItems            },            _getButtonByAlias: function(data) {                var buttonType = data.shortcut;                if ($.inArray(buttonType, ALLOWED_BUTTON_ALIASES) < 0)                    return false;                var buttonConfig = $.extend({                        text: Globalize.localize(DX.inflector.camelize(buttonType, true)),                        onClick: this._createButtonAction(data.onClick),                        _templates: {}                    }, data.options || {});                var buttonClass = POPUP_CLASS + "-" + buttonType;                this._buttonsClasses.push(buttonClass);                var $button = $("<div>").addClass(buttonClass);                this._createComponent($button, "dxButton", buttonConfig);                return {template: function(_, __, $container) {                            $container.append($button)                        }}            },            _createButtonAction: function(clickAction) {                return this._createAction(clickAction, {afterExecute: function(e) {                            e.component.hide()                        }})            },            _renderBottom: function() {                var items = this._getToolbarItems("bottom");                if (items.length) {                    this._$bottom && this._$bottom.remove();                    var $bottom = $("<div>").addClass(POPUP_BOTTOM_CLASS).appendTo(this._$content);                    this._$bottom = this._renderTemplateByType("bottomTemplate", items, $bottom).addClass(POPUP_BOTTOM_CLASS);                    this._toggleClasses()                }                else                    this._$bottom && this._$bottom.detach()            },            _toggleClasses: function() {                var aliases = ALLOWED_BUTTON_ALIASES;                $.each(aliases, $.proxy(function(_, alias) {                    var className = POPUP_CLASS + "-" + alias;                    if ($.inArray(className, this._buttonsClasses) >= 0) {                        this._wrapper().addClass(className + "-visible");                        this._$bottom.addClass(className)                    }                    else {                        this._wrapper().removeClass(className + "-visible");                        this._$bottom.removeClass(className)                    }                }, this))            },            _getDragTarget: function() {                return this._$title            },            _renderGeometryImpl: function() {                this._resetContentHeight();                this.callBase.apply(this, arguments);                this._setContentHeight()            },            _resetContentHeight: function() {                this._$popupContent.css({                    height: "auto",                    "max-height": "none"                })            },            _renderResize: function() {                this.callBase();                this._$content.dxResizable("option", "onResize", $.proxy(this._setContentHeight, this))            },            _setContentHeight: function() {                if (this.option("height") === "auto")                    return;                var contentHeight = this._$content.height();                if (this._$title)                    contentHeight -= this._$title.outerHeight(true) || 0;                if (this._$bottom)                    contentHeight -= this._$bottom.outerHeight(true) || 0;                this._$popupContent.css({                    height: "100%",                    "max-height": contentHeight                })            },            _renderDimensions: function() {                if (this.option("fullScreen"))                    this._$content.css({                        width: "100%",                        height: "100%"                    });                else                    this.callBase.apply(this, arguments);                this._renderFullscreenWidthClass()            },            _renderFullscreenWidthClass: function() {                this.overlayContent().toggleClass(POPUP_FULL_SCREEN_WIDTH_CLASS, this.overlayContent().outerWidth() === $(window).width())            },            _renderShadingDimensions: function() {                if (this.option("fullScreen"))                    this._wrapper().css({                        width: "100%",                        height: "100%"                    });                else                    this.callBase.apply(this, arguments)            },            _renderPosition: function() {                if (this.option("fullScreen"))                    translator.move(this._$content, {                        top: 0,                        left: 0                    });                else                    this.callBase.apply(this, arguments)            },            _optionChanged: function(args) {                switch (args.name) {                    case"showTitle":                    case"title":                    case"titleTemplate":                        this._renderTitle();                        this._renderGeometry();                        break;                    case"bottomTemplate":                        this._renderBottom();                        this._renderGeometry();                        break;                    case"onTitleRendered":                        this._createTitleRenderAction(args.value);                        break;                    case"buttons":                        this._renderTitle();                        this._renderBottom();                        this._renderGeometry();                        break;                    case"dragEnabled":                        this._renderDrag();                        break;                    case"fullScreen":                        this._$content.toggleClass(POPUP_FULL_SCREEN_CLASS, args.value);                        this._refresh();                        break;                    case"showCloseButton":                        this._renderTitle();                        break;                    default:                        this.callBase(args)                }            },            bottomToolbar: function() {                return this._$bottom            },            content: function() {                return this._$popupContent            },            overlayContent: function() {                return this._$content            }        }))    })(jQuery, DevExpress);    /*! Module widgets-base, file ui.popover.js */    (function($, DX, undefined) {        var ui = DX.ui,            fx = DX.fx;        var POPOVER_CLASS = "dx-popover",            POPOVER_WRAPPER_CLASS = "dx-popover-wrapper",            POPOVER_ARROW_CLASS = "dx-popover-arrow",            POPOVER_WITHOUT_TITLE_CLASS = "dx-popover-without-title",            POSITION_FLIP_MAP = {                left: "right",                top: "bottom",                right: "left",                bottom: "top",                center: "center"            },            WEIGHT_OF_SIDES = {                left: -1,                top: -1,                center: 0,                right: 1,                bottom: 1            },            POSITION_ALIASES = {                top: {                    my: "bottom center",                    at: "top center"                },                bottom: {                    my: "top center",                    at: "bottom center"                },                right: {                    my: "left center",                    at: "right center"                },                left: {                    my: "right center",                    at: "left center"                },                topNone: {                    my: "bottom center",                    at: "top center",                    collision: "none"                },                bottomNone: {                    my: "top center",                    at: "bottom center",                    collision: "none"                },                rightNone: {                    my: "left center",                    at: "right center",                    collision: "none"                },                leftNone: {                    my: "right center",                    at: "left center",                    collision: "none"                }            },            ARROW_OFFSET_CORRECTION = {                top: "0 -1",                bottom: "0 1",                left: "-1 0",                right: "1 0"            };        DX.registerComponent("dxPopover", ui, ui.dxPopup.inherit({            _setDefaultOptions: function() {                this.callBase();                this.option({                    target: window,                    shading: false,                    position: 'bottom',                    closeOnOutsideClick: true,                    animation: {                        show: {                            type: "fade",                            from: 0,                            to: 1                        },                        hide: {                            type: "fade",                            to: 0                        }                    },                    showTitle: false,                    width: "auto",                    height: "auto",                    dragEnabled: false,                    resizeEnabled: false,                    fullScreen: false,                    closeOnTargetScroll: true,                    arrowPosition: null,                    boundaryOffset: {                        h: 10,                        v: 10                    }                })            },            _defaultOptionsRules: function() {                return [{                            device: {platform: "ios"},                            options: {arrowPosition: {                                    boundaryOffset: {                                        h: 20,                                        v: -10                                    },                                    collision: "fit"                                }}                        }]            },            _init: function() {                this.callBase();                this._renderArrow();                this.element().addClass(POPOVER_CLASS);                this._wrapper().addClass(POPOVER_WRAPPER_CLASS)            },            _renderArrow: function() {                this._$arrow = $("<div>").addClass(POPOVER_ARROW_CLASS).appendTo(this._wrapper())            },            _documentDownHandler: function(e) {                if (this._isOutsideClick(e))                    this.callBase(e)            },            _isOutsideClick: function(e) {                return !$(e.target).closest(this.option("target")).length            },            _animate: function(animation) {                this._animateArrow(animation);                if (animation && animation.to)                    $.extend(animation.to, {position: this._contentPosition});                this.callBase.apply(this, arguments)            },            _animateArrow: function(animation) {                if (!animation)                    return;                DX.fx.animate(this._$arrow, $.extend({}, animation, {complete: $.noop}))            },            _stopAnimation: function() {                this.callBase.apply(this, arguments);                fx.stop(this._$arrow)            },            _renderTitle: function() {                this._wrapper().toggleClass(POPOVER_WITHOUT_TITLE_CLASS, !this.option("showTitle"));                this.callBase()            },            _renderPosition: function() {                this.callBase();                this._renderOverlayPosition();                this._renderArrowPosition()            },            _renderOverlayBoundaryOffset: $.noop,            _renderOverlayPosition: function() {                this._setContentHeight(true);                this._togglePositionClass("dx-position-" + this._positionSide);                DX.translator.move(this._$content, {                    left: 0,                    top: 0                });                var contentPosition = $.extend({}, this._position);                var containerPosition = this._getContainerPosition();                var containerLocation = DX.calculatePosition(this._$content, containerPosition);                var isFlippedByVertical = containerLocation.v.flip;                var isFlippedByHorizontal = containerLocation.h.flip;                this._updateContentSize(containerLocation);                if (this._position.collision === "flip")                    contentPosition.collision = "fit";                var positionClass = "dx-position-" + (isFlippedByVertical || isFlippedByHorizontal || this._isPopoverInside() ? POSITION_FLIP_MAP[this._positionSide] : this._positionSide);                this._togglePositionClass(positionClass);                this._toggleFlippedClass(isFlippedByVertical, isFlippedByHorizontal);                $.extend(contentPosition, this._applyFlip(contentPosition, isFlippedByVertical, isFlippedByHorizontal));                contentPosition.offset = this._updateContentOffset(isFlippedByVertical, isFlippedByHorizontal, contentPosition.offset);                DX.position(this._$content, contentPosition);                this._contentPosition = contentPosition            },            _isPopoverInside: function() {                var position = this._getPosition();                var my = DX.position.normalizeAlign(position.my);                var at = DX.position.normalizeAlign(position.at);                return my.h === at.h && my.v === at.v            },            _getPosition: function() {                var position = this.option("position");                if (DX.utils.isString(position))                    position = $.extend({}, POSITION_ALIASES[position]);                return position            },            _setContentHeight: function(fullUpdate) {                if (fullUpdate)                    this.callBase()            },            _updateContentSize: function(containerLocation) {                if (!this._$popupContent)                    return;                var positionAt = this._positionSide;                if (containerLocation.h.oversize > 0 && (positionAt === "left" || positionAt === "right")) {                    var newContainerWidth = this._$content.width() - containerLocation.h.oversize;                    this._$content.width(newContainerWidth)                }                if (containerLocation.v.oversize > 0 && (positionAt === "top" || positionAt === "bottom")) {                    var newOverlayContentHeight = this._$content.height() - containerLocation.v.oversize,                        newPopupContentHeight = this._$popupContent.height() - containerLocation.v.oversize;                    this._$content.height(newOverlayContentHeight);                    this._$popupContent.height(newPopupContentHeight)                }            },            _updateContentOffset: function(isFlippedByVertical, isFlippedByHorizontal, offsetString) {                var position = this._positionSide,                    offset = this._getOffsetObject(offsetString),                    signCorrectionH = isFlippedByHorizontal ? -1 : 1,                    signCorrectionV = isFlippedByVertical ? -1 : 1;                var offsetSignCorrection = this._isPopoverInside() ? -1 : 1;                var isTopPosition = position === "top" && !isFlippedByVertical || position === "bottom" && isFlippedByVertical,                    isBottomPosition = position === "bottom" && !isFlippedByVertical || position === "top" && isFlippedByVertical,                    isLeftPosition = position === "left" && !isFlippedByHorizontal || position === "right" && isFlippedByHorizontal,                    isRightPosition = position === "right" && !isFlippedByHorizontal || position === "left" && isFlippedByHorizontal;                if (isTopPosition)                    return offset.h + " " + (offset.v * signCorrectionV - offsetSignCorrection * (this._$arrow.height() - 1));                if (isBottomPosition)                    return offset.h + " " + (offset.v * signCorrectionV + offsetSignCorrection * (this._$arrow.height() - 1));                if (isLeftPosition)                    return offset.h * signCorrectionH - offsetSignCorrection * (this._$arrow.width() - 1) + " " + offset.v;                if (isRightPosition)                    return offset.h * signCorrectionH + offsetSignCorrection * (this._$arrow.width() - 1) + " " + offset.v            },            _getContainerPosition: function() {                var offset = this._getOffsetObject(this._position.offset || "");                var arrowConsideredOffset = this._$arrow.width() + offset.h + " " + (this._$arrow.height() + offset.v);                return $.extend({}, this._position, {offset: arrowConsideredOffset})            },            _applyFlip: function(position, isFlippedByVertical, isFlippedByHorizontal) {                var pairMy = DX.utils.splitPair(position.my),                    pairAt = DX.utils.splitPair(position.at);                var isVertical = function(location) {                        return location === "bottom" || location === "top"                    };                var isHorizontal = function(location) {                        return location === "left" || location === "right"                    };                var flipIfNeeded = function(location) {                        return isFlippedByVertical && isVertical(location) || isFlippedByHorizontal && isHorizontal(location) ? DX.position.inverseAlign(location) : location                    };                return {                        my: flipIfNeeded(pairMy[0]) + " " + flipIfNeeded(pairMy[1]),                        at: flipIfNeeded(pairAt[0]) + " " + flipIfNeeded(pairAt[1])                    }            },            _renderArrowPosition: function() {                DX.translator.move(this._$arrow, {                    left: 0,                    top: 0                });                var arrowPosition = this.option("arrowPosition"),                    position = $.extend({}, this._getDefaultArrowPosition(), arrowPosition);                var customPositionSpecified = arrowPosition && DX.utils.isDefined(arrowPosition.at) && DX.utils.isDefined(arrowPosition.my);                if (customPositionSpecified)                    $.extend(position, this._getCustomArrowPosition(arrowPosition));                DX.position(this._$arrow, position)            },            _getCustomArrowPosition: function(arrowPosition) {                var contentPositionAt = this._contentPosition.at.split(" ")[0],                    arrowPositionAt = arrowPosition.at,                    arrowPositionMy = arrowPosition.my,                    isFlipped = arrowPositionAt && arrowPositionAt.split(" ")[0] === contentPositionAt;                if (isFlipped) {                    var at = arrowPositionAt;                    arrowPositionAt = arrowPositionMy;                    arrowPositionMy = at                }                var correctedOffset = this._mergeOffsets(ARROW_OFFSET_CORRECTION[contentPositionAt], arrowPosition.offset);                return {                        my: arrowPositionMy,                        at: arrowPositionAt,                        of: this._$content,                        offset: correctedOffset                    }            },            _getDefaultArrowPosition: function() {                var popoverSide = this._getDisplaySide(this._contentPosition),                    flippedSide = POSITION_FLIP_MAP[popoverSide],                    that = this;                var flipIfInside = function(side) {                        return that._isPopoverInside() ? POSITION_FLIP_MAP[side] : side                    };                return this._isPopoverLargerThanTarget() ? {                        my: flipIfInside(flippedSide),                        at: popoverSide,                        of: $(this.option("target"))                    } : {                        my: flipIfInside(popoverSide),                        at: flipIfInside(flippedSide),                        of: this._$content,                        offset: ARROW_OFFSET_CORRECTION[flipIfInside(popoverSide)]                    }            },            _isPopoverLargerThanTarget: function() {                if (this._$content.is(':hidden'))                    return true;                if (this._position.of.target)                    return false;                var position = this._positionSide,                    $target = $(this._position.of),                    popoverSize,                    targetSize;                switch (position) {                    case"top":                    case"bottom":                        popoverSize = this._$content.width();                        targetSize = $target.outerWidth() + this._$arrow.width();                        break;                    case"left":                    case"right":                        popoverSize = this._$content.height();                        targetSize = $target.outerHeight() + this._$arrow.height();                        break                }                return popoverSize > targetSize            },            _mergeOffsets: function(baseOffset, additionalOffset) {                if (!additionalOffset)                    return baseOffset;                var base = this._getOffsetObject(baseOffset),                    addition = this._getOffsetObject(additionalOffset);                return base.h + addition.h + " " + (base.v + addition.v)            },            _renderShadingPosition: function() {                if (this.option("shading"))                    this._$wrapper.css({                        top: 0,                        left: 0                    })            },            _renderShadingDimensions: function() {                if (this.option("shading"))                    this._$wrapper.css({                        width: "100%",                        height: "100%"                    })            },            _togglePositionClass: function(positionClass) {                this._$wrapper.removeClass("dx-position-left dx-position-right dx-position-top dx-position-bottom").addClass(positionClass)            },            _toggleFlippedClass: function(isFlippedVertical, isFlippedHorizontal) {                this._$wrapper.toggleClass("dx-popover-flipped-vertical", isFlippedVertical).toggleClass("dx-popover-flipped-horizontal", isFlippedHorizontal)            },            _normalizePosition: function() {                var position = this._getPosition();                if (!position.of)                    position.of = this.option("target");                if (!position.collision)                    position.collision = "flip";                if (!position.boundaryOffset)                    position.boundaryOffset = this.option("boundaryOffset");                this._positionSide = this._getDisplaySide(position);                this._position = position            },            _getDisplaySide: function(position) {                var my = DX.position.normalizeAlign(position.my),                    at = DX.position.normalizeAlign(position.at);                var weightSign = WEIGHT_OF_SIDES[my.h] === WEIGHT_OF_SIDES[at.h] && WEIGHT_OF_SIDES[my.v] === WEIGHT_OF_SIDES[at.v] ? -1 : 1,                    horizontalWeight = Math.abs(WEIGHT_OF_SIDES[my.h] - weightSign * WEIGHT_OF_SIDES[at.h]),                    verticalWeight = Math.abs(WEIGHT_OF_SIDES[my.v] - weightSign * WEIGHT_OF_SIDES[at.v]);                return horizontalWeight > verticalWeight ? at.h : at.v            },            _getOffsetObject: function(offset) {                return DX.utils.stringPairToObject(offset)            },            _optionChanged: function(args) {                switch (args.name) {                    case"showTitle":                    case"title":                    case"titleTemplate":                        this.callBase(args);                        this._renderGeometry();                        break;                    case"target":                    case"boundaryOffset":                    case"arrowPosition":                        this._renderGeometry();                        break;                    case"fullScreen":                        if (args.value)                            this.option("fullScreen", false);                        break;                    default:                        this.callBase(args)                }            },            show: function(target) {                if (target)                    this.option("target", target);                return this.callBase()            }        }));        ui.dxPopover.__internals = {            POPOVER_CLASS: POPOVER_CLASS,            POPOVER_WRAPPER_CLASS: POPOVER_WRAPPER_CLASS,            POPOVER_ARROW_CLASS: POPOVER_ARROW_CLASS,            POPOVER_WITHOUT_TITLE_CLASS: POPOVER_WITHOUT_TITLE_CLASS        }    })(jQuery, DevExpress);    /*! Module widgets-base, file ui.tooltip.js */    (function($, DX, undefined) {        var ui = DX.ui,            TOOLTIP_CLASS = "dx-tooltip",            TOOLTIP_WRAPPER_CLASS = "dx-tooltip-wrapper",            Z_INDEX_STACK = [],            FIRST_Z_INDEX_OFFSET = -500;        DX.registerComponent("dxTooltip", ui, ui.dxPopover.inherit({            _setDefaultOptions: function() {                this.callBase();                this.option({                    showTitle: false,                    title: undefined,                    titleTemplate: undefined,                    bottomTemplate: undefined                })            },            _render: function() {                this.element().addClass(TOOLTIP_CLASS);                this._wrapper().addClass(TOOLTIP_WRAPPER_CLASS);                this.callBase()            },            _renderContent: function() {                this.callBase();                this._contentId = new DevExpress.data.Guid;                this._$content.attr({                    id: this._contentId,                    role: "tooltip"                });                this._toggleAriaDescription(true)            },            _toggleAriaDescription: function(showing) {                var $target = $(this.option("target")),                    label = showing ? this._contentId : undefined;                this.setAria("describedby", label, $target)            },            _zIndexStack: function() {                return Z_INDEX_STACK            },            _zIndexInitValue: function() {                return this.callBase() + FIRST_Z_INDEX_OFFSET            }        }));        ui.dxTooltip.__internals = {            TOOLTIP_CLASS: TOOLTIP_CLASS,            TOOLTIP_WRAPPER_CLASS: TOOLTIP_WRAPPER_CLASS        }    })(jQuery, DevExpress);    /*! Module widgets-base, file ui.dropDownMenu.js */    (function($, DX, undefined) {        var ui = DX.ui;        var DROP_DOWN_MENU_CLASS = "dx-dropdownmenu",            DROP_DOWN_MENU_POPUP_CLASS = "dx-dropdownmenu-popup",            DROP_DOWN_MENU_POPUP_WRAPPER_CLASS = DROP_DOWN_MENU_POPUP_CLASS + "-wrapper",            DROP_DOWN_MENU_LIST_CLASS = "dx-dropdownmenu-list",            DROP_DOWN_MENU_BUTTON_CLASS = "dx-dropdownmenu-button";        var POPUP_OPTION_MAP = {                popupWidth: "width",                popupHeight: "height"            };        var BUTTON_OPTION_MAP = {                buttonIcon: "icon",                buttonText: "text"            };        DX.registerComponent("dxDropDownMenu", ui, ui.Widget.inherit({            _supportedKeys: function() {                return $.extend(this.callBase(), {tab: function(e) {                            this._popup.hide()                        }})            },            _setDeprecatedOptions: function() {                this.callBase();                $.extend(this._deprecatedOptions, {                    itemClickAction: {                        since: "14.2",                        alias: "onItemClick"                    },                    buttonClickAction: {                        since: "14.2",                        alias: "onButtonClick"                    },                    itemRender: {                        since: "14.2",                        alias: "itemTemplate"                    },                    buttonIconSrc: {                        since: "15.1",                        alias: "buttonIcon"                    }                })            },            _setDefaultOptions: function() {                this.callBase();                this.option({                    items: [],                    onItemClick: null,                    dataSource: null,                    itemTemplate: "item",                    buttonText: "",                    buttonIcon: "overflow",                    onButtonClick: null,                    usePopover: false,                    popupWidth: "auto",                    popupHeight: "auto",                    hoverStateEnabled: true,                    opened: false,                    popupPosition: "bottom",                    popupAnimation: undefined                })            },            _defaultOptionsRules: function() {                return this.callBase().concat([{                            device: [{platform: "ios"}],                            options: {usePopover: true}                        }, {                            device: function(device) {                                return DX.devices.real().generic && !DX.devices.isSimulator()                            },                            options: {focusStateEnabled: true}                        }, {                            device: function(device) {                                return device.android && (device.version[0] >= 4 && device.version[1] >= 1 || device.version[0] >= 5)                            },                            options: {                                popupPosition: {                                    my: "top " + (this.option("rtlEnabled") ? "left" : "right"),                                    at: "top " + (this.option("rtlEnabled") ? "left" : "right")                                },                                popupAnimation: {                                    show: {                                        type: "pop",                                        duration: 200,                                        from: {scale: 0},                                        to: {scale: 1}                                    },                                    hide: {                                        type: "pop",                                        duration: 200,                                        from: {scale: 1},                                        to: {scale: 0}                                    }                                }                            }                        }])            },            _dataSourceOptions: function() {                return {paginate: false}            },            _init: function() {                this.callBase();                this._initDataSource();                this._initItemClickAction();                this._initButtonClickAction()            },            _initItemClickAction: function() {                this._itemClickAction = this._createActionByOption("onItemClick")            },            _initButtonClickAction: function() {                this._buttonClickAction = this._createActionByOption("onButtonClick")            },            _render: function() {                this.element().addClass(DROP_DOWN_MENU_CLASS);                this._renderButton();                this.callBase();                this.setAria({                    role: "menubar",                    haspopup: true,                    expanded: this.option("opened")                })            },            _clean: function() {                this._cleanFocusState();                this._popup.element().remove()            },            _renderContentImpl: function() {                this._renderPopup()            },            _renderButton: function() {                var that = this;                var $button = this.element().addClass(DROP_DOWN_MENU_BUTTON_CLASS);                this._button = this._createComponent($button, "dxButton", {                    text: this.option("buttonText"),                    icon: this.option("buttonIcon"),                    focusStateEnabled: false,                    onClick: function(e) {                        that.option("opened", !that.option("opened"));                        that._buttonClickAction(e)                    },                    _templates: {}                });                var keys = this._supportedKeys(),                    buttonKeys = this._button._supportedKeys();                this._supportedKeys = function() {                    return $.extend(keys, buttonKeys)                }            },            _toggleMenuVisibility: function(opened) {                var state = opened === undefined ? !this._popup.option("visible") : opened;                this._popup.toggle(state);                this.setAria("expanded", state)            },            _renderPopup: function() {                var $popup = this._$popup = $("<div>").appendTo(this.element());                var popupOptions = {                        onContentReady: $.proxy(this._popupContentReadyHandler, this),                        deferRendering: false,                        position: this.option("popupPosition"),                        animation: this.option("popupAnimation"),                        onOptionChanged: $.proxy(function(args) {                            if (args.name === "visible")                                this.option("opened", args.value)                        }, this)                    };                this._popup = this._createPopover($popup, popupOptions);                this._popup._wrapper().addClass(DROP_DOWN_MENU_POPUP_WRAPPER_CLASS);                this._popup._wrapper().toggleClass(DROP_DOWN_MENU_POPUP_CLASS, !this.option("usePopover"))            },            _popupContentReadyHandler: function() {                var popup = this._$popup.dxPopover("instance");                this._renderList(popup)            },            _createPopover: function($element, popupOptions) {                return this._createComponent($element, "dxPopover", $.extend(popupOptions, {                        target: this.element(),                        height: this.option("popupHeight"),                        width: this.option("popupWidth")                    }))            },            _renderList: function(instance) {                var $content = instance.content(),                    that = this;                $content.addClass(DROP_DOWN_MENU_LIST_CLASS);                that._list = that._createComponent($content, "dxList", {                    _keyboardProcessor: that._listProcessor,                    pageLoadMode: "scrollBottom",                    indicateLoading: false,                    noDataText: "",                    itemTemplate: that._getTemplateByOption("itemTemplate"),                    onItemClick: function(e) {                        that.option("opened", false);                        that._itemClickAction(e)                    },                    tabIndex: -1,                    focusStateEnabled: this.option("focusStateEnabled"),                    _itemAttributes: {role: "menuitem"}                });                that._list._getAriaTarget = function() {                    return that.element()                };                that._setListDataSource();                var listMaxHeight = $(window).height() * 0.5;                if ($content.height() > listMaxHeight)                    $content.height(listMaxHeight)            },            _setListDataSource: function() {                if (this._list)                    this._list.option("dataSource", this._dataSource || this.option("items"))            },            _attachKeyboardEvents: function() {                this.callBase.apply(this, arguments);                this._listProcessor = this._keyboardProcessor.attachChildProcessor();                if (this._list)                    this._list.option("_keyboardProcessor", this._listProcessor)            },            _cleanFocusState: function() {                this.callBase.apply(this, arguments);                delete this._listProcessor            },            _toggleVisibility: function(visible) {                this.callBase(visible);                this._button.option("visible", visible)            },            _optionChanged: function(args) {                var name = args.name;                var value = args.value;                switch (name) {                    case"items":                    case"dataSource":                        this._refreshDataSource();                        this._setListDataSource();                        break;                    case"itemTemplate":                        if (this._list)                            this._list.option(name, this._getTemplate(value));                        break;                    case"onItemClick":                        this._initItemClickAction();                        break;                    case"onButtonClick":                        this._buttonClickAction();                        break;                    case"buttonIcon":                    case"buttonText":                        this._button.option(BUTTON_OPTION_MAP[name], value);                        break;                    case"popupWidth":                    case"popupHeight":                        this._popup.option(POPUP_OPTION_MAP[name], value);                        break;                    case"usePopover":                        this._invalidate();                        break;                    case"focusStateEnabled":                        if (this._list)                            this._list.option(name, value);                        this.callBase(args);                        break;                    case"opened":                        this._toggleMenuVisibility(value);                        break;                    case"popupPosition":                        break;                    default:                        this.callBase(args)                }            },            open: function() {                this.option("opened", true)            },            close: function() {                this.option("opened", false)            }        }).include(ui.DataHelperMixin))    })(jQuery, DevExpress);    /*! Module widgets-base, file ui.dateUtils.js */    (function($, DX, undefined) {        var dateCopmotents = function() {                return ["year", "day", "month", "day"]            };        var dateUtils = DX.ui.dateUtils = {                SUPPORTED_FORMATS: ["date", "time", "datetime"],                DEFAULT_FORMATTER: function(value) {                    return value                },                DATE_COMPONENT_TEXT_FORMATTER: function(value, name) {                    var $container = $("<div>").addClass("dx-dateview-formatter-container");                    $("<span>").text(value).addClass("dx-dateview-value-formatter").appendTo($container);                    $("<span>").text(name).addClass("dx-dateview-name-formatter").appendTo($container);                    return $container                },                ONE_MINUTE: 1000 * 60,                ONE_DAY: 1000 * 60 * 60 * 24,                TEN_YEARS: 1000 * 60 * 60 * 24 * 365 * 10,                FORMATS_INFO: {                    date: {                        standardPattern: "yyyy-MM-dd",                        components: dateCopmotents()                    },                    time: {                        standardPattern: "HH:mm",                        components: ["hours", "minutes"]                    },                    datetime: {                        standardPattern: "yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'",                        components: dateCopmotents().concat(["hours", "minutes", "seconds", "milliseconds"])                    },                    "datetime-local": {                        standardPattern: "yyyy'-'MM'-'dd'T'HH':'mm",                        components: dateCopmotents().concat(["hours", "minutes", "seconds"])                    }                },                FORMATS_MAP: {                    date: "d",                    time: "t",                    datetime: "S",                    "datetime-local": "f"                },                toStandardDateFormat: function(date, mode, pattern) {                    pattern = pattern || dateUtils.FORMATS_INFO[mode].standardPattern;                    return Globalize.format(date, pattern)                },                fromStandardDateFormat: function(date) {                    return Globalize.parseDate(date, dateUtils.FORMATS_INFO["datetime"].standardPattern) || Globalize.parseDate(date, dateUtils.FORMATS_INFO["datetime-local"].standardPattern) || Globalize.parseDate(date, dateUtils.FORMATS_INFO["time"].standardPattern) || Globalize.parseDate(date, dateUtils.FORMATS_INFO["date"].standardPattern) || Date.parse && Date.parse(date) && new Date(Date.parse(date))                },                getMaxMonthDay: function(year, month) {                    return new Date(year, month + 1, 0).getDate()                },                mergeDates: function(target, source, format) {                    if (!source)                        return undefined;                    if (isNaN(target.getTime()))                        target = new Date(0, 0, 0, 0, 0, 0);                    var formatInfo = dateUtils.FORMATS_INFO[format];                    $.each(formatInfo.components, function() {                        var componentInfo = dateUtils.DATE_COMPONENTS_INFO[this];                        target[componentInfo.setter](source[componentInfo.getter]())                    });                    return target                },                getLongestCaptionIndex: function(captionArray) {                    var longestIndex = 0,                        longestCaptionLength = 0,                        i;                    for (i = 0; i < captionArray.length; ++i)                        if (captionArray[i].length > longestCaptionLength) {                            longestIndex = i;                            longestCaptionLength = captionArray[i].length                        }                    return longestIndex                },                expandPattern: function(pattern) {                    return pattern.length === 1 ? Globalize.culture().calendar.patterns[pattern] : pattern                },                formatUsesMonthName: function(format) {                    return dateUtils.expandPattern(format).indexOf("MMMM") !== -1                },                formatUsesDayName: function(format) {                    return dateUtils.expandPattern(format).indexOf("dddd") !== -1                },                getLongestDate: function(format, monthNames, dayNames) {                    var longestDate = new Date(1888, dateUtils.formatUsesMonthName(format) ? dateUtils.getLongestCaptionIndex(monthNames) : 9, 28 - 7, 23, 59, 59, 999);                    if (dateUtils.formatUsesDayName(format))                        longestDate.setDate(longestDate.getDate() - longestDate.getDay() + dateUtils.getLongestCaptionIndex(dayNames));                    return longestDate                },                calculateMaximumDateFormatWidth: function(format, customFontStyles, rootElement) {                    if (!rootElement || $(rootElement).is(":visible")) {                        var width,                            ieRoundingError = 2,                            longestTextDiv = $("<div>" + Globalize.format(dateUtils.getLongestDate(format, Globalize.culture().calendar.months.names, Globalize.culture().calendar.days.names), format) + "</div>").css({                                visibility: "hidden",                                "white-space": "nowrap",                                position: "absolute",                                float: "left"                            });                        if (customFontStyles)                            longestTextDiv.css(customFontStyles);                        longestTextDiv.appendTo(rootElement ? $(rootElement) : $("body"));                        width = longestTextDiv.width() + ieRoundingError;                        longestTextDiv.remove();                        return width                    }                }            };        dateUtils.DATE_COMPONENTS_INFO = {            year: {                getter: "getFullYear",                setter: "setFullYear",                possibleFormats: ["yy", "yyyy"],                formatter: dateUtils.DEFAULT_FORMATTER,                startValue: undefined,                endValue: undefined            },            day: {                getter: "getDate",                setter: "setDate",                possibleFormats: ["d", "dd"],                formatter: function(value, showNames, date) {                    if (!showNames)                        return value;                    var formatDate = new Date(date.getTime());                    formatDate.setDate(value);                    return dateUtils.DATE_COMPONENT_TEXT_FORMATTER(value, Globalize.culture().calendar.days.names[formatDate.getDay()])                },                startValue: 1,                endValue: undefined            },            month: {                getter: "getMonth",                setter: "setMonth",                possibleFormats: ["M", "MM", "MMM", "MMMM"],                formatter: function(value, showNames) {                    var monthName = Globalize.culture().calendar.months.names[value];                    return showNames ? dateUtils.DATE_COMPONENT_TEXT_FORMATTER(value + 1, monthName) : monthName                },                startValue: 0,                endValue: 11            },            hours: {                getter: "getHours",                setter: "setHours",                possibleFormats: ["H", "HH", "h", "hh"],                formatter: function(value) {                    return Globalize.format(new Date(0, 0, 0, value), "HH")                },                startValue: 0,                endValue: 23            },            minutes: {                getter: "getMinutes",                setter: "setMinutes",                possibleFormats: ["m", "mm"],                formatter: function(value) {                    return Globalize.format(new Date(0, 0, 0, 0, value), "mm")                },                startValue: 0,                endValue: 59            },            seconds: {                getter: "getSeconds",                setter: "setSeconds",                possibleFormats: ["s", "ss"],                formatter: function(value) {                    return Globalize.format(new Date(0, 0, 0, 0, 0, value), "ss")                },                startValue: 0,                endValue: 59            },            milliseconds: {                getter: "getMilliseconds",                setter: "setMilliseconds",                possibleFormats: ["f", "ff", "fff"],                formatter: function(value) {                    return Globalize.format(new Date(0, 0, 0, 0, 0, 0, value), "fff")                },                startValue: 0,                endValue: 999            }        };        (function androidFormatDetection() {            var androidFormatPattern = "yyyy'-'MM'-'dd'T'HH':'mm'Z'";            var $input = $("<input>").attr("type", "datetime");            $input.val(dateUtils.toStandardDateFormat(new Date, "datetime", androidFormatPattern));            if ($input.val())                dateUtils.FORMATS_INFO.datetime.standardPattern = androidFormatPattern        })()    })(jQuery, DevExpress);    /*! Module widgets-base, file ui.calendar.js */    (function($, DX, undefined) {        var ui = DX.ui,            fx = DX.fx,            utils = DX.utils,            CALENDAR_CLASS = "dx-calendar",            CALENDAR_BODY_CLASS = "dx-calendar-body",            CALENDAR_CELL_CLASS = "dx-calendar-cell",            CALENDAR_EMPTY_CELL_CLASS = "dx-calendar-empty-cell",            CALENDAR_FOOTER_CLASS = "dx-calendar-footer",            CALENDAR_TODAY_BUTTON_CLASS = "dx-calendar-today-button",            CALENDAR_HAS_FOOTER_CLASS = "dx-calendar-with-footer",            MONTH_VIEW_ANIMATION_DURATION = 300,            ANIMATION_DURATION_ILLEGAL_RANGE = 200,            ANIMATION_DURATION_SHOW_VIEW = 250,            POP_ANIMATION_FROM = 0.6,            POP_ANIMATION_TO = 1,            SHOT_SWIPE_OFFSET = 0.5,            CALENDAR_DATE_VALUE_KEY = "dxDateValueKey",            SWIPE_POSITION = {                left: -1,                right: 1            },            LEVEL_COMPARE_MAP = {                month: 3,                year: 2,                decade: 1,                century: 0            };        DX.registerComponent("dxCalendar", ui, ui.Editor.inherit({            _activeStateUnit: "." + CALENDAR_CELL_CLASS,            _supportedKeys: function() {                var isRTL = this.option("rtlEnabled"),                    offset = utils.getDifferenceInMonth(this.option("zoomLevel"));                return $.extend(this.callBase(), {                        rightArrow: function(e) {                            if (e.ctrlKey) {                                e.preventDefault();                                this._waitRenderView(offset, isRTL ? -1 : 1)                            }                            else {                                this._change = "key";                                return true                            }                        },                        leftArrow: function(e) {                            if (e.ctrlKey) {                                e.preventDefault();                                this._waitRenderView(offset, isRTL ? 1 : -1)                            }                            else {                                this._change = "key";                                return true                            }                        },                        upArrow: function(e) {                            if (e.ctrlKey) {                                e.preventDefault();                                this._navigateUp()                            }                            else {                                if (fx.isAnimating(this._view.element()))                                    return;                                this._change = "upDownArrow";                                return true                            }                        },                        downArrow: function(e) {                            if (e.ctrlKey) {                                e.preventDefault();                                this._navigateDown()                            }                            else {                                if (fx.isAnimating(this._view.element()))                                    return;                                this._change = "upDownArrow";                                return true                            }                        },                        pageUp: function(e) {                            e.preventDefault();                            this._waitRenderView(offset, -1)                        },                        pageDown: function(e) {                            e.preventDefault();                            this._waitRenderView(offset, 1)                        },                        tab: $.noop,                        enter: function(e) {                            if (!this._isMaxZoomLevel())                                this._navigateDown();                            else                                return true                        }                    })            },            _setDefaultOptions: function() {                this.callBase();                this.option({                    currentDate: new Date,                    min: new Date(1000, 0),                    max: new Date(3000, 0),                    firstDayOfWeek: undefined,                    zoomLevel: "month",                    maxZoomLevel: "month",                    minZoomLevel: "century",                    showTodayButton: false,                    cellTemplate: "cell",                    onCellClick: null,                    onContouredChanged: null                })            },            _defaultOptionsRules: function() {                return this.callBase().concat([{                            device: function() {                                return DX.devices.real().generic && !DX.devices.isSimulator()                            },                            options: {                                focusStateEnabled: true,                                hoverStateEnabled: true                            }                        }])            },            _init: function() {                this.callBase();                this._correctZoomLevel();                this._updateCurrentDate(this.option("value"));                this._initActions()            },            _initActions: function() {                this._cellClickOptionAction = this._createActionByOption("onCellClick")            },            _correctZoomLevel: function() {                var maxZoomLevel = this.option("maxZoomLevel"),                    minZoomLevel = this.option("minZoomLevel"),                    zoomLevel = this.option("zoomLevel");                if (LEVEL_COMPARE_MAP[maxZoomLevel] < LEVEL_COMPARE_MAP[minZoomLevel])                    return;                if (LEVEL_COMPARE_MAP[zoomLevel] > LEVEL_COMPARE_MAP[maxZoomLevel])                    this.option("zoomLevel", maxZoomLevel);                else if (LEVEL_COMPARE_MAP[zoomLevel] < LEVEL_COMPARE_MAP[minZoomLevel])                    this.option("zoomLevel", minZoomLevel)            },            _updateCurrentDate: function(value) {                var min = this.option("min"),                    max = this.option("max");                if (min && max && min > max) {                    this.option("currentDate", new Date);                    return                }                if (min)                    min = new Date(min);                if (max)                    max = new Date(max);                var date = value || new Date(this.option("currentDate")),                    normalizedDate = new Date(utils.normalizeDate(date, min, max));                normalizedDate.setDate(1);                this.option("currentDate", normalizedDate);                var zoomLevel = this.option("zoomLevel"),                    isNewView = this._view && !utils.sameView(zoomLevel, normalizedDate, this._view.option("date"));                if (isNewView) {                    this._view.element().remove();                    delete this._view;                    this._renderView()                }            },            _render: function() {                this.callBase();                this.element().addClass(CALENDAR_CLASS);                this._renderView();                this._renderFooter();                this.onContouredChanged = this._createActionByOption("onContouredChanged");                this.setAria({                    role: "listbox",                    label: Globalize.localize("dxCalendar-ariaWidgetName")                })            },            _renderView: function() {                this._change = "";                this._renderBody();                this._renderSpecificView();                this._renderNavigator();                this._renderSwipeable()            },            _renderBody: function() {                if (!this._body) {                    this._body = $("<div>").addClass(CALENDAR_BODY_CLASS);                    this.element().append(this._body)                }            },            _renderSwipeable: function() {                var that = this;                if (!this._swipeable)                    this._swipeable = this._createComponent(this.element(), "dxSwipeable", {                        elastic: false,                        onStart: function(e) {                            that._swipeStartHandler(e)                        },                        onUpdated: function(e) {                            that._swipeUpdateHandler(e)                        },                        onEnd: function(e) {                            that._swipeEndHandler(e)                        },                        itemWidthFunc: function() {                            return this.element().width()                        }                    })            },            _waitRenderView: function(offset, direction) {                if (this._alreadyViewRender)                    return;                this._alreadyViewRender = true;                this._change = "";                this._navigate(offset * direction);                setTimeout($.proxy(function() {                    this._alreadyViewRender = false                }, this))            },            _focusTarget: function() {                return this.element()            },            _focusOutHandler: function() {                this.callBase.apply(this, arguments);                this._view.option("contouredDate", undefined)            },            _focusInHandler: function() {                this.callBase.apply(this, arguments);                this._view.focusInHandler()            },            _attachKeyboardEvents: function() {                this.callBase.apply(this, arguments);                this._viewKeyboardProcessor = new ui.KeyboardProcessor;                this._keyboardProcessor.push(this._viewKeyboardProcessor)            },            _swipeStartHandler: function(e) {                if (this._viewsAnimating) {                    e.jQueryEvent.cancel = true;                    return                }                this._swipeInProgress = true;                this._viewsOnLeft = [this._view];                this._viewsOnRight = [this._view]            },            _swipeUpdateHandler: function(e) {                this._setOffset(e.jQueryEvent.offset);                if (this._swipeOffset >= 0)                    this._renderViews(this._viewsOnLeft, SWIPE_POSITION.right);                else                    this._renderViews(this._viewsOnRight, SWIPE_POSITION.left)            },            _setOffset: function(offset) {                var swipeDirection = offset > 0 ? SWIPE_POSITION.right : SWIPE_POSITION.left,                    prevOffset = this._swipeOffset || 0;                if (swipeDirection * (offset - prevOffset) <= 1)                    this._swipeOffset = offset            },            _renderViews: function(viewsArray, swipePosition) {                var arrayInsertIndex = Math.ceil(swipePosition * this._swipeOffset),                    zoomLevel = this.option("zoomLevel");                var offset = swipePosition * arrayInsertIndex;                offset *= utils.getDifferenceInMonth(zoomLevel);                offset = this.option("rtlEnabled") ? offset : -1 * offset;                this._initalizeViewDimensions();                if (!viewsArray[arrayInsertIndex]) {                    this._newDate = new Date(this.option("currentDate"));                    this._newDate.setMonth(this._newDate.getMonth() + offset);                    var $body = this._body,                        $view = $("<div>").appendTo($body);                    viewsArray[arrayInsertIndex] = new ui.dxCalendar.views[zoomLevel]($view, this._viewConfig())                }                this._translateViews(viewsArray, swipePosition)            },            _translateViews: function(viewsArray, swipePosition) {                var prevView = viewsArray[Math.floor(swipePosition * this._swipeOffset)],                    nextView = viewsArray[Math.ceil(swipePosition * this._swipeOffset)],                    localOffset = this._swipeOffset % 1;                this._normalizeViewsPosition();                DX.translator.move(prevView.element(), {left: this._correctionMovement * localOffset * this._viewWidth});                if (swipePosition * localOffset >= 0.05)                    DX.translator.move(nextView.element(), {left: this._correctionMovement * (localOffset - swipePosition) * this._viewWidth});                this._view = this._isInView(prevView, this._viewWidth / 2) ? prevView : nextView;                this._renderNavigator()            },            _normalizeViewsPosition: function() {                var i;                for (i = 0; i < this._viewsOnLeft.length; i++)                    DX.translator.move(this._viewsOnLeft[i].element(), {left: -this._correctionMovement * this._viewWidth});                for (i = 0; i < this._viewsOnRight.length; i++)                    DX.translator.move(this._viewsOnRight[i].element(), {left: this._correctionMovement * this._viewWidth})            },            _isDateInInvalidRange: function() {                if (this._view.isBoundary(this._newDate))                    return;                var min = this.option("min"),                    max = this.option("max"),                    normalizedDate = utils.normalizeDate(this._newDate, min, max);                return normalizedDate === min || normalizedDate === max            },            _trimUnusedViews: function(viewsArray) {                var animatedViews = viewsArray.slice(),                    indexCurrentView = $.inArray(this._view, animatedViews) + 1,                    boundaryIndex = this._getBoundaryIndexView(animatedViews);                animatedViews = animatedViews.splice(0, indexCurrentView + 1);                animatedViews.splice(0, boundaryIndex);                this._disposeUnusedViews(viewsArray, indexCurrentView);                return animatedViews            },            _cleanFocusState: function() {                this.callBase();                if (this._viewKeyboardProcessor)                    this._viewKeyboardProcessor.dispose()            },            _getBoundaryIndexView: function(arrayViews) {                var length = arrayViews.length;                for (var i = length - 1; i >= 0; i--) {                    if (!arrayViews[i])                        continue;                    if (this._view.isBoundary(arrayViews[i].option("date")))                        return i                }            },            _disposeUnusedViews: function(arrayViews, index) {                var length = arrayViews.length;                for (var i = length - 1; i > index; i--)                    arrayViews[i].element().remove()            },            _moveInRange: function(arrayViews, swipePosition) {                var length = arrayViews.length,                    startOffset = arrayViews[length - 1].element().position().left * swipePosition,                    summaryWidth = startOffset;                for (var i = length - 1; i >= 0; i--) {                    DX.translator.move(arrayViews[i].element(), {left: this._correctionMovement * summaryWidth * swipePosition});                    summaryWidth += arrayViews[i].element().width()                }                summaryWidth -= arrayViews[0].element().width();                return this._animateToBoundary(arrayViews, summaryWidth, swipePosition)            },            _animateToBoundary: function(arrayViews, summaryWidth, swipePosition) {                this._animation = $.Deferred();                var length = arrayViews.length;                for (var i = length - 1; i >= 0; i--) {                    var leftPosition = arrayViews[i].element().position().left;                    this._animateView(arrayViews[i], leftPosition - summaryWidth * swipePosition, ANIMATION_DURATION_ILLEGAL_RANGE * length)                }                return this._animation.promise()            },            _swipeEndHandler: function(e) {                var that = this,                    targetOffset = e.jQueryEvent.targetOffset;                this._viewsAnimating = true;                var animation,                    isShortSwipe = false;                if (Math.abs(e.jQueryEvent.offset) < SHOT_SWIPE_OFFSET)                    if (targetOffset === 1 || targetOffset === -1)                        isShortSwipe = true;                if (this._isDateInInvalidRange()) {                    this._toggleNavigatorDisabled(true);                    this._$footer && this._$footer.toggleClass("dx-state-disabled", true);                    if (this._swipeOffset > 0) {                        animation = this._animatedIllegalRange(that._viewsOnLeft, SWIPE_POSITION.right);                        this._newDate = new Date(this.option("min"))                    }                    else {                        animation = this._animatedIllegalRange(that._viewsOnRight, SWIPE_POSITION.left);                        this._newDate = new Date(this.option("max"))                    }                }                else                    animation = this._alignViews(isShortSwipe);                animation.done(function() {                    that._disposeViews();                    if (!that._isDateInInvalidRange())                        that.option("currentDate", that._view.option("date"));                    that._viewsAnimating = false;                    that._toggleNavigatorDisabled(false);                    that._$footer && that._$footer.toggleClass("dx-state-disabled", false);                    that._normalizedCircledDate(that._view.option("date"))                });                this._swipeInProgress = false;                this._swipeOffset = 0            },            _animatedIllegalRange: function(viewsArray, swipeDirection) {                var animatedViews = this._trimUnusedViews(viewsArray);                return this._moveInRange(animatedViews, swipeDirection)            },            _alignViews: function(isShortSwipe) {                this._animation = $.Deferred();                this._swipeOffset = this._swipeOffset || 0;                var firstVisibleView,                    secondVisibleView;                if (this._swipeOffset >= 0)                    firstVisibleView = this._viewsOnLeft[Math.floor(Math.abs(this._swipeOffset))],                    secondVisibleView = this._viewsOnLeft[Math.ceil(Math.abs(this._swipeOffset))];                else                    firstVisibleView = this._viewsOnRight[Math.ceil(Math.abs(this._swipeOffset))],                    secondVisibleView = this._viewsOnRight[Math.floor(Math.abs(this._swipeOffset))];                if (this._isInView(firstVisibleView, this._viewWidth / 2))                    if (isShortSwipe)                        this._arrangeViews(secondVisibleView, firstVisibleView, SWIPE_POSITION.right);                    else                        this._arrangeViews(firstVisibleView, secondVisibleView, SWIPE_POSITION.left);                else if (isShortSwipe)                    this._arrangeViews(firstVisibleView, secondVisibleView, SWIPE_POSITION.left);                else                    this._arrangeViews(secondVisibleView, firstVisibleView, SWIPE_POSITION.right);                this._renderNavigator();                return this._animation.promise()            },            _arrangeViews: function(firstView, secondView, swipePosition) {                this._centerView(firstView);                this._animateView(secondView, swipePosition * this._viewWidth, MONTH_VIEW_ANIMATION_DURATION)            },            _animateView: function(view, to, duration) {                var that = this;                fx.animate(view.element(), {                    type: "slide",                    from: {left: view.element().position().left},                    to: {left: to},                    duration: duration,                    complete: function() {                        that._animation.resolve()                    }                })            },            _centerView: function(view) {                this._animateView(view, 0, MONTH_VIEW_ANIMATION_DURATION);                this._view = view            },            _isInView: function(view, point) {                var $element = view.element(),                    left = $element.position().left;                return point > left && point <= left + $element.width()            },            _disposeViews: function() {                var i;                for (i = 0; i < this._viewsOnLeft.length; i++)                    if (this._viewsOnLeft[i] !== this._view)                        this._viewsOnLeft[i].element().remove();                for (i = 0; i < this._viewsOnRight.length; i++)                    if (this._viewsOnRight[i] !== this._view)                        this._viewsOnRight[i].element().remove();                this._viewsOnLeft = [];                this._viewsOnRight = []            },            _renderFooter: function() {                var that = this,                    showTodayButton = this.option("showTodayButton");                if (showTodayButton) {                    var $todayButton = this._createComponent($("<a>"), "dxButton", {                            focusStateEnabled: false,                            text: Globalize.localize("dxCalendar-todayButtonText"),                            onClick: function() {                                that._toTodayView()                            },                            _templates: {}                        }).element().addClass(CALENDAR_TODAY_BUTTON_CLASS);                    this._$footer = $("<div>").addClass(CALENDAR_FOOTER_CLASS).append($todayButton);                    this.element().append(this._$footer)                }                this.element().toggleClass(CALENDAR_HAS_FOOTER_CLASS, showTodayButton)            },            _toTodayView: function() {                var today = new Date;                if (!this._isMaxZoomLevel()) {                    this.option("currentDate", today);                    this.option("zoomLevel", this.option("maxZoomLevel"));                    this._animateShowView();                    this.option("value", today);                    return                }                var currentDate = this._view.option("date"),                    offset = 0;                offset += (today.getFullYear() - currentDate.getFullYear()) * 12;                offset += today.getMonth() - currentDate.getMonth();                if (!offset) {                    this.option("value", today);                    return                }                this._addPrevView(today);                this._animateNavigation(offset).done($.proxy(function() {                    this._clearPrevView();                    this.option("value", new Date)                }, this))            },            _isMaxZoomLevel: function() {                return this.option("zoomLevel") === this.option("maxZoomLevel")            },            _renderNavigator: function() {                if (!this._navigator) {                    var $navigator = $("<div>").prependTo(this.element());                    this._navigator = new ui.dxCalendar.Navigator($navigator, this._navigatorConfig())                }                this._navigator.option("text", this._view._getNavigatorCaption());                this._updateButtonsVisibility()            },            _updateButtonsVisibility: function() {                var viewType = this.option("zoomLevel"),                    isRTL = this.option("rtlEnabled"),                    difference = isRTL ? -1 * utils.getDifferenceInMonth(viewType) : 1 * utils.getDifferenceInMonth(viewType);                this._navigator.toggleButton("next", !this._view.canNavigate(difference));                this._navigator.toggleButton("prev", !this._view.canNavigate(-difference))            },            _navigatorConfig: function() {                return {                        text: this._view._getNavigatorCaption(),                        onClick: $.proxy(this._navigatorClickHandler, this),                        onCaptionClick: $.proxy(this._navigateUp, this),                        rtlEnabled: this.option("rtlEnabled")                    }            },            _navigatorClickHandler: function(e) {                var viewType = this.option("zoomLevel"),                    difference = utils.getDifferenceInMonth(viewType),                    deltaDifference = difference * e.direction;                this._navigate(deltaDifference)            },            _isMinZoomLevel: function(zoomLevel) {                var min = this.option("min"),                    max = this.option("max");                return utils.sameView(zoomLevel, min, max) || this.option("minZoomLevel") === zoomLevel            },            _navigateUp: function() {                var zoomLevel = this.option("zoomLevel"),                    nextView = utils.getViewUp(zoomLevel);                if (!nextView || this._isMinZoomLevel(zoomLevel))                    return;                this._contouredStack = this._contouredStack || [];                var contouredDate = this._view.option("contouredDate");                contouredDate && this._contouredStack.push(contouredDate);                this.option("currentDate", contouredDate || this._view.option("date"));                this.option("zoomLevel", nextView);                this._animateShowView()            },            _navigateDown: function(cell) {                var zoomLevel = this.option("zoomLevel");                if (this._isMaxZoomLevel())                    return;                var nextView = utils.getViewDown(zoomLevel);                if (!nextView)                    return;                var newCurrentDate = this._view.option("contouredDate") || this._view.option("date");                if (cell)                    newCurrentDate = $(cell).data(CALENDAR_DATE_VALUE_KEY);                this.option("currentDate", newCurrentDate);                this.option("zoomLevel", nextView);                this._animateShowView();                if (this._contouredStack && this._contouredStack.length > 0) {                    var circledDate = this._view.getCircledDate(newCurrentDate, this._contouredStack);                    this._normalizedCircledDate(circledDate);                    this._view.option("contouredDate", circledDate);                    return                }                this._normalizedCircledDate(newCurrentDate);                this._view.option("contouredDate", newCurrentDate)            },            _animateShowView: function() {                fx.stop(this._view.element(), true);                this._viewsAnimating = true;                this._popAnimationView(this._view, POP_ANIMATION_FROM, POP_ANIMATION_TO, ANIMATION_DURATION_SHOW_VIEW).done($.proxy(function() {                    this._viewsAnimating = false;                    this._view.moveContouredDate(0)                }, this))            },            _toggleNavigatorDisabled: function(state) {                this._navigator && this._navigator.option("disabled", state)            },            _popAnimationView: function(view, from, to, duration) {                return fx.animate(view.element(), {                        type: "pop",                        from: {                            scale: from,                            opacity: from                        },                        to: {                            scale: to,                            opacity: to                        },                        duration: duration                    })            },            _renderSpecificView: function() {                var specificView = ui.dxCalendar.views[this.option("zoomLevel")],                    $body = this._body,                    $view = $("<div>").appendTo($body);                this._view = new specificView($view, this._viewConfig());                this.element().addClass("dx-calendar-view-" + this.option("zoomLevel"));                this._correctionMovement = DX.browser.msie && this.option("rtlEnabled") ? -1 : 1            },            _viewConfig: function() {                return {                        date: this._swipeInProgress ? this._newDate : this.option("currentDate"),                        min: this.option("min"),                        max: this.option("max"),                        firstDayOfWeek: this.option("firstDayOfWeek"),                        value: this.option("value"),                        rtl: this.option("rtlEnabled"),                        disabled: this.option("disabled") || DevExpress.designMode,                        _keyboardProcessor: this._viewKeyboardProcessor,                        tabIndex: undefined,                        focusStateEnabled: this.option("focusStateEnabled"),                        hoverStateEnabled: this.option("hoverStateEnabled"),                        onValueChanged: $.proxy(this._viewValueChangedHandler, this),                        onContouredDateChanged: $.proxy(this._viewContouredChangedHandler, this),                        onCellClick: $.proxy(this._handlerOnCellClick, this),                        cellTemplate: this._getTemplateByOption("cellTemplate"),                        allowValueSelection: this._isMaxZoomLevel()                    }            },            _cellClickHandler: function(e) {                this._cellClickAction({jQueryEvent: e})            },            _handlerOnCellClick: function(e) {                var zoomLevel = this.option("zoomLevel"),                    nextView = utils.getViewDown(zoomLevel);                var _isMaxZoomLevel = this._isMaxZoomLevel();                if (nextView && !_isMaxZoomLevel) {                    var target = e.jQueryEvent.currentTarget;                    this._navigateDown(target)                }                else                    this._cellClickOptionAction(e)            },            _viewValueChangedHandler: function(e) {                if (this._isMaxZoomLevel())                    this.option("value", e.value)            },            _viewContouredChangedHandler: function(e) {                var date = e.value,                    currentDate = this.option("currentDate"),                    zoomLevel = this.option("zoomLevel"),                    isSameView = utils.sameView(zoomLevel, currentDate, date);                this.setAria("activedescendant", e.ariaId);                this.onContouredChanged && this.onContouredChanged(e.ariaId);                if (date && !isSameView && !this._isAlreadyNavigated && (this._isMaxZoomLevel() || this._change === "key" || this._change === "upDownArrow")) {                    var dir = utils.getFirstMonthDate(date) > currentDate ? 1 : -1,                        difference = utils.getDifferenceInMonth(zoomLevel) * dir;                    this._isAlreadyNavigated = true;                    this._navigate(difference)                }            },            _normalizedCircledDate: function(date) {                var $cell;                if (this._view.isBoundary(date)) {                    var zoomLevel = this.option("zoomLevel"),                        $cells = this._view.$body.find("." + CALENDAR_CELL_CLASS).not("." + CALENDAR_EMPTY_CELL_CLASS);                    var min = this.option("min"),                        max = this.option("max");                    if (utils.sameView(zoomLevel, min, max))                        $cell = Math.abs(min - date) > Math.abs(max - date) ? $cells.last() : $cells.first();                    else if (utils.sameView(zoomLevel, date, min))                        $cell = $cells.first();                    else if (utils.sameView(zoomLevel, date, max))                        $cell = $cells.last();                    date = $cell ? $cell.data(CALENDAR_DATE_VALUE_KEY) : date;                    this._view.option("contouredDate", date);                    return                }                var currentDate = this.option("currentDate");                $cell = this._view._getCellByDate(utils.getShortDate(date));                if (!$cell.length && !utils.dateInRange(date, this.option("min"), this.option("max"))) {                    this._view.option("contouredDate", currentDate);                    return                }                if (!$cell.hasClass(CALENDAR_EMPTY_CELL_CLASS)) {                    this._view.option("contouredDate", date);                    return                }                this._view.option("contouredDate", date)            },            _initalizeViewDimensions: function() {                this._viewWidth = this._viewWidth || this._body.width();                this._viewHeight = this._viewHeight || this._body.height()            },            _navigate: function(difference) {                if (this._view.canNavigate(difference)) {                    var currentDate = this.option("currentDate"),                        newDate = new Date(currentDate);                    var circledDate;                    newDate.setMonth(currentDate.getMonth() + difference);                    utils.fixTimezoneGap(currentDate, newDate);                    circledDate = this._view.getNextCircledDate(difference);                    if (this._change === "upDownArrow")                        circledDate = this._view.option("contouredDate");                    if (this._change === "key") {                        var zoomLevel = this.option("zoomLevel");                        circledDate = difference < 0 ? utils.getLastDateView(zoomLevel, newDate) : utils.getFirstDateView(zoomLevel, newDate)                    }                    this._changeView(newDate, difference);                    this._normalizedCircledDate(circledDate)                }            },            _changeView: function(newDate, difference) {                var that = this;                if (fx.isAnimating(this._view.element())) {                    this._stopCurrentAnimation();                    this._prevView && this._prevView.element().remove()                }                this._addPrevView(newDate);                this._animateNavigation(difference).done(function() {                    that._clearPrevView();                    that._isAlreadyNavigated = false                })            },            _clearPrevView: function() {                this._prevView.element().remove();                delete this._prevView            },            _addPrevView: function(date) {                var $view = $("<div>");                this._prevView = new ui.dxCalendar.views[this.option("zoomLevel")]($view, this._viewConfig());                this._body.append(this._prevView.element());                this.option("currentDate", date)            },            _stopCurrentAnimation: function() {                this._prevView && fx.stop(this._prevView.element(), true);                fx.stop(this._view.element(), true)            },            _animateNavigation: function(difference) {                this._animation = $.Deferred();                this._initalizeViewDimensions();                var navDirection = difference < 0 ? -1 : 1;                DX.translator.move(this._view.element(), {left: this._correctionMovement * navDirection * this._viewWidth});                this._animateView(this._view, 0, MONTH_VIEW_ANIMATION_DURATION);                this._animateView(this._prevView, -navDirection * this._viewWidth, MONTH_VIEW_ANIMATION_DURATION);                return this._animation.promise()            },            _clean: function() {                this.callBase();                delete this._body;                delete this._navigator;                delete this._$footer;                delete this._viewWidth;                delete this._viewHeight            },            _optionChanged: function(args) {                var value = args.value;                switch (args.name) {                    case"min":                    case"max":                    case"firstDayOfWeek":                        var date = this.option("value");                        date = date ? new Date(date) : new Date;                        this._updateCurrentDate(date);                        this._view.element().remove();                        this._renderView();                        break;                    case"currentDate":                        this._updateCurrentDate(value);                        break;                    case"zoomLevel":                        this.element().removeClass("dx-calendar-view-" + args.previousValue);                        this._correctZoomLevel();                        this._view.element().remove();                        delete this._view;                        this._renderView();                        this._updateButtonsVisibility();                        break;                    case"minZoomLevel":                    case"maxZoomLevel":                        this._correctZoomLevel();                        this._updateButtonsVisibility();                        break;                    case"value":                        this._updateCurrentDate(value ? new Date(value) : new Date);                        this._view.option("value", value ? new Date(value) : null);                        this.callBase(args);                        break;                    case"disabled":                        this._view.option("disabled", value);                        this.callBase(args);                        break;                    case"showTodayButton":                        this._invalidate();                        break;                    case"onCellClick":                        this._view.option("onCellClick", value);                        break;                    case"onContouredChanged":                        this.onContouredChanged = this._createActionByOption("onContouredChanged");                        break;                    case"cellTemplate":                        this._invalidate();                        break;                    default:                        this.callBase(args)                }            }        }))    })(jQuery, DevExpress);    /*! Module widgets-base, file ui.calendar.views.js */    (function($, DX, undefined) {        var ui = DX.ui,            events = ui.events,            utils = DX.utils,            CALENDAR_OTHER_MONTH_CLASS = "dx-calendar-other-month",            CALENDAR_OTHER_VIEW_CLASS = "dx-calendar-other-view",            CALENDAR_CELL_CLASS = "dx-calendar-cell",            CALENDAR_EMPTY_CELL_CLASS = "dx-calendar-empty-cell",            CALENDAR_TODAY_CLASS = "dx-calendar-today",            CALENDAR_SELECTED_DATE_CLASS = "dx-calendar-selected-date",            CALENDAR_CONTOURED_DATE_CLASS = "dx-calendar-contoured-date",            CALENDAR_DXCLICK_EVENT_NAME = events.addNamespace("dxclick", "dxCalendar"),            CALENDAR_DATE_VALUE_KEY = "dxDateValueKey",            CALENDAR_VIEW_NAME_PREFIX = "CalendarView";        ui.dxCalendar.BaseView = ui.Widget.inherit({            NAME: CALENDAR_VIEW_NAME_PREFIX + "Base",            _setDefaultOptions: function() {                this.callBase();                this.option({                    date: new Date,                    focusStateEnabled: false,                    cellTemplate: null,                    onCellClick: null,                    rowCount: 3,                    colCount: 4,                    allowValueSelection: true,                    onValueChanged: null,                    onContouredDateChanged: null                })            },            _init: function() {                this.callBase();                var value = this.option("value"),                    contouredDate = this.option("contouredDate");                if (contouredDate)                    this.option("contouredDate", this._calculateContouredDate(contouredDate));                this.option("value", new Date(value));                if (!this.option("value").valueOf())                    this.option("value", new Date(0, 0, 0, 0, 0, 0));                this._initActions()            },            _initActions: function() {                this._createCellClickOptionAction();                this._createCellClickAction();                this._valueChangedAction = this._createActionByOption("onValueChanged");                this._contouredDateChangedAction = this._createActionByOption("onContouredDateChanged")            },            _render: function() {                this.callBase();                this._renderImpl()            },            _renderImpl: function() {                this._$table = $("<table>");                this._renderBody();                this._renderContouredDate();                this._renderValue();                var cellClickAction = this._createAction($.proxy(function(e) {                        this._cellClickHandler(e.jQueryEvent)                    }, this));                this._$table.off(CALENDAR_DXCLICK_EVENT_NAME).on(CALENDAR_DXCLICK_EVENT_NAME, "td", function(e) {                    cellClickAction({jQueryEvent: e})                });                this.element().off("beforeactivate").on("beforeactivate", function(e) {                    e.preventDefault()                });                this.element().append(this._$table)            },            _renderBody: function() {                this.$body = $("<tbody>").appendTo(this._$table);                var that = this,                    cellTemplate = this.option("cellTemplate");                function renderCell(cellIndex) {                    var cellDate = that._getCellData(indexRow, cellIndex);                    var $cell = $("<td>").appendTo($row).addClass(CALENDAR_CELL_CLASS).toggleClass(CALENDAR_TODAY_CLASS, that._isTodayCell(cellDate)).toggleClass(CALENDAR_EMPTY_CELL_CLASS, that._isDateOutOfRange(cellDate)).toggleClass(CALENDAR_OTHER_VIEW_CLASS, that._isOtherView(cellDate)).attr("data-value", utils.getShortDate(cellDate)).data(CALENDAR_DATE_VALUE_KEY, cellDate);                    that.setAria({                        role: "option",                        label: that._getCellAriaLabel(cellDate)                    }, $cell);                    if (cellTemplate)                        cellTemplate.render({text: that._getCellText(cellDate)}, $cell, cellIndex);                    else                        $cell.text(that._getCellText(cellDate))                }                for (var indexRow = 0, len = this.option("rowCount"); indexRow < len; indexRow++) {                    var $row = $("<tr>").appendTo(this.$body);                    this._iterateCells(renderCell)                }            },            _iterateCells: function(delegate) {                var rtl = this.option("rtl"),                    colCount = this.option("colCount"),                    i = rtl ? colCount - 1 : 0;                while (rtl ? i >= 0 : i < colCount) {                    delegate(i);                    rtl ? --i : ++i                }            },            _isTodayCell: DX.abstract,            _isDateOutOfRange: DX.abstract,            _isOtherView: DX.abstract,            _getCellText: DX.abstract,            _getCellData: DX.abstract,            _supportedKeys: function() {                this._difference = utils.getDifferenceInMonthForCells(this._getViewName());                return $.extend(this.callBase(), {                        leftArrow: this._leftArrowHandler,                        rightArrow: this._rightArrowHandler,                        upArrow: this._upArrowHandler,                        downArrow: this._downArrowHandler,                        enter: this._enterHandler,                        home: this._homeHandler,                        end: this._endHandler                    })            },            _homeHandler: function(e) {                e.preventDefault();                var date = this.option("date"),                    currentView = this._getViewName();                if (utils[DX.inflector.camelize("same " + currentView)](date, new Date(this.option("min")))) {                    var $cell = this.$body.find("." + CALENDAR_CELL_CLASS).not("." + CALENDAR_EMPTY_CELL_CLASS).first();                    this.option("contouredDate", $cell.data(CALENDAR_DATE_VALUE_KEY))                }                else                    this.option("contouredDate", utils.getFirstDateView(currentView, date));                this._renderContouredDate()            },            _endHandler: function(e) {                e.preventDefault();                var date = this.option("date"),                    currentView = this._getViewName();                if (utils[DX.inflector.camelize("same " + currentView)](date, new Date(this.option("max")))) {                    var $cell = this.$body.find("." + CALENDAR_CELL_CLASS).not("." + CALENDAR_EMPTY_CELL_CLASS).last();                    this.option("contouredDate", $cell.data(CALENDAR_DATE_VALUE_KEY))                }                else                    this.option("contouredDate", utils.getLastDateView(currentView, date));                this._renderContouredDate()            },            _getViewName: function() {                var startPos = CALENDAR_VIEW_NAME_PREFIX.length,                    name = this.NAME;                name = name.substr(startPos, name.length);                return name.toLowerCase()            },            _leftArrowHandler: function(e) {                e.preventDefault();                this.moveContouredDate(this.option("rtl") ? 1 * this._difference : -1 * this._difference)            },            _rightArrowHandler: function(e) {                e.preventDefault();                this.moveContouredDate(this.option("rtl") ? -1 * this._difference : 1 * this._difference)            },            _upArrowHandler: function(e) {                e.preventDefault();                this.moveContouredDate(-this.option("colCount") * this._difference)            },            _downArrowHandler: function(e) {                e.preventDefault();                this.moveContouredDate(this.option("colCount") * this._difference)            },            _enterHandler: function() {                this.option("value", this.option("contouredDate"))            },            _renderContouredDate: function() {                if (!this.option("focusStateEnabled"))                    return;                var contouredDate = this.option("contouredDate"),                    $oldContouredCell = this._$table.find("." + CALENDAR_CONTOURED_DATE_CLASS),                    $newContouredCell = this._getCellByDate(contouredDate);                $oldContouredCell.removeClass(CALENDAR_CONTOURED_DATE_CLASS);                $newContouredCell.addClass(CALENDAR_CONTOURED_DATE_CLASS);                this._ariaId = new DevExpress.data.Guid;                this.setAria({                    id: undefined,                    selected: undefined                }, $oldContouredCell);                this.setAria({                    id: this._ariaId,                    selected: true                }, $newContouredCell)            },            _dispose: function() {                this._keyboardProcessor = undefined;                this.callBase()            },            _createCellClickOptionAction: function() {                this._cellClickOptionAction = this._createActionByOption("onCellClick")            },            _cellClickHandler: function(e) {                this._cellClickAction({jQueryEvent: e})            },            _createCellClickAction: function(e) {                this._cellClickAction = this._createAction($.proxy(function(e) {                    var $currentTarget = $(e.jQueryEvent.currentTarget);                    if (!$currentTarget.hasClass(CALENDAR_EMPTY_CELL_CLASS)) {                        var cellDate = $currentTarget.data(CALENDAR_DATE_VALUE_KEY);                        this._changeValue(cellDate);                        this._cellClickOptionAction(e)                    }                }, this))            },            _fitContouredCell: function(value, prevValue) {                var $cell = this._getCellByDate(utils.getShortDate(value));                if ($cell.hasClass(CALENDAR_EMPTY_CELL_CLASS))                    this.option("contouredDate", prevValue)            },            _changeValue: function(cellDate) {                if (cellDate) {                    var value = this.option("value"),                        newValue = value ? new Date(value) : new Date;                    newValue.setDate(cellDate.getDate());                    newValue.setMonth(cellDate.getMonth());                    newValue.setFullYear(cellDate.getFullYear());                    newValue.setDate(cellDate.getDate());                    this.option("value", newValue)                }                else                    this.option("value", null)            },            _renderValue: function() {                if (!this.option("allowValueSelection"))                    return;                var value = this.option("value"),                    selectedCell = this._getCellByDate(value);                if (this._selectedCell)                    this._selectedCell.removeClass(CALENDAR_SELECTED_DATE_CLASS);                selectedCell.addClass(CALENDAR_SELECTED_DATE_CLASS);                this._selectedCell = selectedCell            },            _getCellAriaLabel: $.noop,            getNextCircledDate: function(difference) {                var circledDate = this.option("contouredDate") && new Date(this.option("contouredDate"));                if (circledDate)                    circledDate.setMonth(circledDate.getMonth() + difference);                return circledDate            },            focusInHandler: DX.abstract,            canNavigate: DX.abstract,            moveContouredDate: DX.abstract,            isBoundary: DX.abstract,            _optionChanged: function(args) {                var name = args.name;                switch (name) {                    case"value":                        this.option("contouredDate", args.value);                        this._renderValue();                        this._valueChangedAction({                            jQueryEvent: undefined,                            value: args.value,                            previousValue: args.previousValue                        });                        break;                    case"contouredDate":                        this._fitContouredCell(args.value, args.previousValue);                        this._renderContouredDate();                        this._contouredDateChangedAction({                            jQueryEvent: undefined,                            value: args.value,                            previousValue: args.previousValue,                            ariaId: this._ariaId                        });                        break;                    case"onCellClick":                        this._createCellClickOptionAction();                        break;                    case"cellTemplate":                        this._invalidate();                        break;                    case"onValueChanged":                    case"onContouredDateChanged":                        break;                    default:                        this.callBase(args)                }            }        });        ui.dxCalendar.views = {            month: ui.dxCalendar.BaseView.inherit({                NAME: CALENDAR_VIEW_NAME_PREFIX + "Month",                _setDefaultOptions: function() {                    this.callBase();                    this.option({                        firstDayOfWeek: undefined,                        rowCount: 6,                        colCount: 7                    })                },                _renderImpl: function() {                    this.callBase();                    this._renderHeader()                },                _renderBody: function() {                    this.callBase();                    this._$table.find("." + CALENDAR_OTHER_VIEW_CLASS).addClass(CALENDAR_OTHER_MONTH_CLASS)                },                _renderFocusTarget: $.noop,                _getCellAriaLabel: function(date) {                    return Globalize.format(date, "D")                },                _renderHeader: function() {                    var that = this,                        $header = $("<thead>").prependTo(this._$table),                        $headerRow = $("<tr>").appendTo($header);                    this._iterateCells(function(i) {                        $("<th>").text(that._getDayCaption(that._getFirstDayOfWeek() + i)).appendTo($headerRow)                    })                },                _getNavigatorCaption: function() {                    var navigatorMonth = Globalize.culture().calendar.months.names[this.option("date").getMonth()],                        navigatorYear = this.option("date").getFullYear();                    return this.option("rtl") ? navigatorYear + " " + navigatorMonth : navigatorMonth + " " + navigatorYear                },                _isTodayCell: function(cellDate) {                    var today = new Date;                    return utils.sameMonthAndYear(cellDate, today) && cellDate.getDate() === today.getDate()                },                _isDateOutOfRange: function(cellDate) {                    var minDate = this.option("min"),                        maxDate = this.option("max");                    return !utils.dateInRange(cellDate, minDate, maxDate)                },                _isOtherView: function(cellDate) {                    return cellDate.getMonth() !== this.option("date").getMonth()                },                _getCellText: function(cellDate) {                    return cellDate.getDate()                },                _getDayCaption: function(day) {                    var daysInWeek = this.option("colCount");                    return Globalize.culture().calendar.days.namesAbbr[day % daysInWeek]                },                _getCellData: function(week, day) {                    var firstDay = utils.getFirstMonthDate(this.option("date")),                        firstMonthDayPosition = firstDay.getDay() - this._getFirstDayOfWeek(),                        daysInWeek = this.option("colCount"),                        firstWeekDay = daysInWeek * week - firstMonthDayPosition;                    firstWeekDay = firstMonthDayPosition < 0 ? firstWeekDay - daysInWeek : firstWeekDay;                    firstDay.setDate(firstDay.getDate() + firstWeekDay + day);                    return firstDay                },                _getFirstDayOfWeek: function() {                    return this.option("firstDayOfWeek") || Globalize.culture().calendar.firstDay                },                moveContouredDate: function(difference) {                    var circledDate = this.option("contouredDate"),                        contouredDate = circledDate || this._calculateContouredDate(circledDate),                        newContouredDate = new Date(contouredDate.getFullYear(), contouredDate.getMonth(), contouredDate.getDate() + difference);                    utils.fixTimezoneGap(contouredDate, newContouredDate);                    this.option("contouredDate", newContouredDate)                },                _calculateContouredDate: function(contouredDate) {                    var calculatedContouredDate = null,                        date = this.option("date"),                        value = this.option("value");                    if (utils.sameMonthAndYear(contouredDate, date))                        calculatedContouredDate = contouredDate;                    else if (utils.sameMonthAndYear(value, date))                        calculatedContouredDate = value;                    return calculatedContouredDate || utils.getFirstMonthDate(date)                },                focusInHandler: function() {                    this.option("contouredDate", this._calculateContouredDate(this.option("contouredDate")))                },                canNavigate: function(difference) {                    var date = new Date(this.option("date"));                    var testCurrentDate = difference < 0 ? new Date(date.getFullYear(), date.getMonth() + difference + 1, 0) : new Date(date.getFullYear(), date.getMonth() + difference, 1);                    return utils.dateInRange(testCurrentDate, this.option("min"), this.option("max"))                },                _getCellByDate: function(date) {                    return this._$table.find("td[data-value='" + utils.getShortDate(date) + "']")                },                isBoundary: function(date) {                    return utils.sameMonthAndYear(date, this.option("min")) || utils.sameMonthAndYear(date, this.option("max"))                },                getNextCircledDate: function(difference) {                    var circledDate = this.option("contouredDate") && new Date(this.option("contouredDate"));                    if (circledDate) {                        var currentDay = circledDate.getDate();                        circledDate.setDate(1);                        circledDate.setMonth(circledDate.getMonth() + difference);                        var lastDayMonth = utils.getLastMonthDate(circledDate).getDate();                        currentDay > lastDayMonth ? circledDate.setDate(lastDayMonth) : circledDate.setDate(currentDay)                    }                    return circledDate                },                getCircledDate: function(currentDate, contouredStack) {                    var lastContour = contouredStack.pop(),                        day = lastContour.getDate(),                        circled = new Date(currentDate);                    circled.setDate(day);                    return circled                }            }),            year: ui.dxCalendar.BaseView.inherit({                NAME: CALENDAR_VIEW_NAME_PREFIX + "Year",                _isTodayCell: function(cellDate) {                    return utils.sameMonthAndYear(cellDate, new Date)                },                _isDateOutOfRange: function(cellDate) {                    return !utils.dateInRange(cellDate, utils.getFirstMonthDate(this.option("min")), utils.getLastMonthDate(this.option("max")))                },                _isOtherView: function(cellDate) {                    return false                },                _getCellText: function(cellDate) {                    return Globalize.culture().calendar.months.names[cellDate.getMonth()].slice(0, 3)                },                _getCellData: function(indexRow, cellIndex) {                    var data = new Date(this.option("date")),                        colCount = this.option("colCount");                    data.setDate(1);                    data.setMonth(indexRow * colCount + cellIndex);                    return data                },                _getCellByDate: function(date) {                    var foundDate = new Date(date);                    foundDate.setDate(1);                    return this._$table.find("td[data-value='" + utils.getShortDate(foundDate) + "']")                },                _getCellAriaLabel: function(date) {                    return Globalize.format(date, "Y")                },                _getNavigatorCaption: function() {                    return this.option("date").getFullYear()                },                moveContouredDate: function(difference) {                    var contouredDate = this.option("contouredDate") || this.option("date"),                        newContouredDate = new Date(contouredDate.getFullYear(), contouredDate.getMonth() + difference, contouredDate.getDate());                    utils.fixTimezoneGap(contouredDate, newContouredDate);                    this.option("contouredDate", newContouredDate)                },                focusInHandler: function() {                    var date = this.option("date");                    this.option("contouredDate", new Date(date.getFullYear(), date.getMonth(), 1))                },                canNavigate: function(difference) {                    var date = new Date(this.option("date"));                    var testCurrentDate = difference < 0 ? new Date(date.getFullYear() - 1, 11, 31) : new Date(date.getFullYear() + 1, 1, 1);                    return utils.dateInRange(testCurrentDate, this.option("min"), this.option("max"))                },                isBoundary: function(date) {                    return utils.sameYear(date, this.option("min")) || utils.sameYear(date, this.option("max"))                },                getCircledDate: function(currentDate, contouredStack) {                    var lastContour = contouredStack.pop(),                        month = lastContour.getMonth(),                        circled = new Date(currentDate);                    circled.setMonth(month);                    circled.setDate(1);                    return circled                }            }),            decade: ui.dxCalendar.BaseView.inherit({                NAME: CALENDAR_VIEW_NAME_PREFIX + "Decade",                _isTodayCell: function(cellDate) {                    return utils.sameYear(cellDate, new Date)                },                _isDateOutOfRange: function(cellDate) {                    var min = this.option("min"),                        max = this.option("max");                    return !utils.dateInRange(cellDate.getFullYear(), min && min.getFullYear(), max && max.getFullYear())                },                _isOtherView: function(cellDate) {                    var date = new Date(cellDate);                    date.setMonth(1);                    return !utils.sameDecade(date, this.option("date"))                },                _getCellText: function(cellDate) {                    return cellDate.getFullYear()                },                _getCellData: function(indexRow, cellIndex) {                    var colCount = this.option("colCount"),                        year = utils.getFirstYearInDecade(this.option("date")) - 1 + indexRow * colCount + cellIndex;                    return new Date(year, 0, 1)                },                _getCellAriaLabel: function(date) {                    return this._getCellText(date)                },                _getNavigatorCaption: function() {                    var year = utils.getFirstYearInDecade(this.option("date"));                    return year + "-" + (year + 9)                },                moveContouredDate: function(difference) {                    var contouredDate = new Date(this.option("contouredDate") || this.option("date"));                    contouredDate.setMonth(0);                    var newContouredDate = new Date(contouredDate.getFullYear(), contouredDate.getMonth() + difference, contouredDate.getDate());                    utils.fixTimezoneGap(contouredDate, newContouredDate);                    this.option("contouredDate", newContouredDate)                },                focusInHandler: function() {                    var date = this.option("date");                    this.option("contouredDate", new Date(date.getFullYear(), 0, 1))                },                _getCellByDate: function(date) {                    var foundDate = new Date(date);                    foundDate.setDate(1);                    foundDate.setMonth(0);                    return this._$table.find("td[data-value='" + utils.getShortDate(foundDate) + "']")                },                canNavigate: function(difference) {                    var date = new Date(this.option("date"));                    var testCurrentDate = difference < 0 ? new Date(utils.getFirstYearInDecade(date) - 1, 11, 31) : new Date(utils.getFirstYearInDecade(date) + 10, 1, 1);                    return utils.dateInRange(testCurrentDate, this.option("min"), this.option("max"))                },                isBoundary: function(date) {                    return utils.sameDecade(date, this.option("min")) || utils.sameDecade(date, this.option("max"))                },                getCircledDate: function(currentDate, contouredStack) {                    var lastContour = contouredStack.pop(),                        year = lastContour.getFullYear(),                        circled = new Date(currentDate);                    circled.setFullYear(circled.getFullYear() + year % 10);                    circled.setMonth(0);                    circled.setDate(1);                    return circled                }            }),            century: ui.dxCalendar.BaseView.inherit({                NAME: CALENDAR_VIEW_NAME_PREFIX + "Century",                _isTodayCell: function(cellDate) {                    return utils.sameDecade(cellDate, new Date)                },                _isDateOutOfRange: function(cellDate) {                    var decade = utils.getFirstYearInDecade(cellDate),                        minDecade = utils.getFirstYearInDecade(this.option("min")),                        maxDecade = utils.getFirstYearInDecade(this.option("max"));                    return !utils.dateInRange(decade, minDecade, maxDecade)                },                _isOtherView: function(cellDate) {                    var date = new Date(cellDate);                    date.setMonth(1);                    return !utils.sameCentury(date, this.option("date"))                },                _getCellText: function(cellDate) {                    var decade = cellDate.getFullYear();                    return decade + " - " + (decade + 9)                },                _getCellData: function(indexRow, cellIndex) {                    var colCount = this.option("colCount"),                        decade = utils.getFirstDecadeInCentury(this.option("date")) + (-1 + indexRow * colCount + cellIndex) * 10;                    return new Date(decade, 0, 1)                },                _getCellAriaLabel: function(date) {                    return this._getCellText(date)                },                _getCellByDate: function(date) {                    var foundDate = new Date(date);                    foundDate.setDate(1);                    foundDate.setMonth(0);                    foundDate.setFullYear(utils.getFirstYearInDecade(foundDate));                    return this._$table.find("td[data-value='" + utils.getShortDate(foundDate) + "']")                },                _getNavigatorCaption: function() {                    var decade = utils.getFirstDecadeInCentury(this.option("date"));                    return decade + "-" + (decade + 99)                },                moveContouredDate: function(difference) {                    var contouredDate = this._calculateContouredDate(this.option("contouredDate")),                        newContouredDate = new Date(contouredDate.getFullYear(), contouredDate.getMonth() + difference, contouredDate.getDate());                    utils.fixTimezoneGap(contouredDate, newContouredDate);                    this.option("contouredDate", newContouredDate)                },                _calculateContouredDate: function(contouredDate) {                    var calculatedContouredDate = null;                    if (!utils.isDefined(contouredDate)) {                        var date = this.option("date");                        calculatedContouredDate = new Date(date);                        calculatedContouredDate.setFullYear(utils.getFirstYearInDecade(date));                        calculatedContouredDate.setDate(1)                    }                    else {                        calculatedContouredDate = new Date(contouredDate);                        calculatedContouredDate.setFullYear(utils.getFirstYearInDecade(this.option("contouredDate")))                    }                    calculatedContouredDate.setMonth(0);                    return calculatedContouredDate                },                focusInHandler: function() {                    var date = this.option("date");                    this.option("contouredDate", new Date(utils.getFirstYearInDecade(date), 0, 1))                },                canNavigate: function(difference) {                    var date = new Date(this.option("date"));                    var testCurrentDate = difference < 0 ? new Date(utils.getFirstDecadeInCentury(date) - 1, 11, 31) : new Date(utils.getFirstDecadeInCentury(date) + 100, 1, 1);                    return utils.dateInRange(testCurrentDate, this.option("min"), this.option("max"))                },                isBoundary: function(date) {                    return utils.sameCentury(date, this.option("min")) || utils.sameCentury(date, this.option("max"))                }            })        }    })(jQuery, DevExpress);    /*! Module widgets-base, file ui.calendar.navigator.js */    (function($, DX, undefined) {        var ui = DX.ui,            CALENDAR_NAVIGATOR_CLASS = "dx-calendar-navigator",            CALENDAR_NAVIGATOR_PREVIOUS_MONTH_CLASS = "dx-calendar-navigator-previous-month",            CALENDAR_NAVIGATOR_NEXT_MONTH_CLASS = "dx-calendar-navigator-next-month",            CALENDAR_NAVIGATOR_PREVIOUS_VIEW_CLASS = "dx-calendar-navigator-previous-view",            CALENDAR_NAVIGATOR_NEXT_VIEW_CLASS = "dx-calendar-navigator-next-view",            CALENDAR_NAVIGATOR_DISABLED_LINK_CLASS = "dx-calendar-disabled-navigator-link",            CALENDAR_NAVIGATOR_CAPTION_BUTTON_CLASS = "dx-calendar-caption-button";        ui.dxCalendar.Navigator = ui.Widget.inherit({            _setDefaultOptions: function() {                this.callBase();                this.option({                    onClick: null,                    onCaptionClick: null,                    text: ""                })            },            _init: function() {                this.callBase();                this._initActions()            },            _initActions: function() {                this._clickAction = this._createActionByOption("onClick");                this._captionClickAction = this._createActionByOption("onCaptionClick")            },            _render: function() {                this.callBase();                this.element().addClass(CALENDAR_NAVIGATOR_CLASS);                this._renderButtons();                this._renderCaption()            },            _renderButtons: function() {                var that = this,                    direction = this.option("rtlEnabled") ? -1 : 1;                this._prevButton = this._createComponent($("<a>"), "dxButton", {                    focusStateEnabled: false,                    icon: "chevronleft",                    onClick: function(e) {                        that._clickAction({                            direction: -direction,                            jQueryEvent: e                        })                    },                    _templates: {}                });                var $prevButton = this._prevButton.element().addClass(CALENDAR_NAVIGATOR_PREVIOUS_VIEW_CLASS).addClass(CALENDAR_NAVIGATOR_PREVIOUS_MONTH_CLASS);                this._nextButton = this._createComponent($("<a>"), "dxButton", {                    focusStateEnabled: false,                    icon: "chevronright",                    onClick: function(e) {                        that._clickAction({                            direction: direction,                            jQueryEvent: e                        })                    },                    _templates: {}                });                var $nextButton = this._nextButton.element().addClass(CALENDAR_NAVIGATOR_NEXT_VIEW_CLASS).addClass(CALENDAR_NAVIGATOR_NEXT_MONTH_CLASS);                this._caption = this._createComponent($("<a>").addClass(CALENDAR_NAVIGATOR_CAPTION_BUTTON_CLASS), "dxButton", {                    focusStateEnabled: false,                    onClick: function(e) {                        that._captionClickAction({jQueryEvent: e})                    },                    _templates: {}                });                var $caption = this._caption.element();                this.element().append($prevButton, $caption, $nextButton)            },            _renderCaption: function(caption) {                this._caption.option("text", this.option("text"))            },            toggleButton: function(buttonPrefix, value) {                var buttonName = "_" + buttonPrefix + "Button",                    button = this[buttonName];                if (button) {                    button.option("disabled", value);                    button.element().toggleClass(CALENDAR_NAVIGATOR_DISABLED_LINK_CLASS, value)                }            },            _optionChanged: function(args) {                var value = args.value;                switch (args.name) {                    case"text":                        this._renderCaption(value);                        break;                    default:                        this.callBase(args)                }            }        })    })(jQuery, DevExpress);    /*! Module widgets-base, file ui.timeView.js */    (function($, DX, undefined) {        var ui = DX.ui,            browser = DX.browser,            isBuggyIE = browser.msie && DX.compareVersions(browser.version, 9) < 0;        var TIMEVIEW_CLASS = "dx-timeview",            TIMEVIEW_CLOCK_CLASS = "dx-timeview-clock",            TIMEVIEW_FIELD_CLASS = "dx-timeview-field",            TIMEVIEW_HOURARROW_CLASS = "dx-timeview-hourarrow",            TIMEVIEW_MINUTEARROW_CLASS = "dx-timeview-minutearrow";        var rotateArrow = function($arrow, angle, offset) {                if (isBuggyIE)                    filterRotate($arrow, angle, offset);                else                    cssRotate($arrow, angle, offset)            };        var filterRotate = function($arrow, angle, offset) {                angle = angle / 180 * Math.PI;                var sin = Math.sin(angle),                    cos = Math.cos(angle);                $arrow.css("filter", "none");                var originalWidth = $arrow.width(),                    originalHeight = $arrow.height();                $arrow.css("filter", 'progid:DXImageTransform.Microsoft.Matrix' + '(sizingMethod="auto expand", M11 = ' + cos + ', M12 = ' + -sin + ', M21 = ' + sin + ', M22 = ' + cos + ')');                var width = $arrow.width(),                    height = $arrow.height();                var sx = (width - originalWidth) / 2,                    sy = (height - originalHeight) / 2;                $arrow.css("margin-left", -originalWidth / 2 + (originalHeight / 2 - offset) * sin - sx);                $arrow.css("margin-top", originalHeight / 2 - (originalHeight / 2 - offset) * cos - sy)            };        var cssRotate = function($arrow, angle, offset) {                $arrow.css("transform", "rotate(" + angle + "deg)" + " translate(0," + offset + "px)")            };        DX.registerComponent("dxTimeView", ui, ui.Editor.inherit({            _setDefaultOptions: function() {                this.callBase();                this.option({                    value: new Date($.now()),                    _arrowOffset: 0                })            },            _defaultOptionsRules: function() {                return this.callBase().concat([{                            device: {platform: "android"},                            options: {_arrowOffset: 15}                        }, {                            device: {platform: "generic"},                            options: {_arrowOffset: 5}                        }])            },            _getValue: function() {                return this.option("value") || new Date            },            _init: function() {                this.callBase();                this.element().addClass(TIMEVIEW_CLASS)            },            _render: function() {                this.callBase();                this._renderBox();                this._updateTime()            },            _renderBox: function() {                var $box = $("<div>").appendTo(this.element());                this._createComponent($box, "dxBox", {                    height: "100%",                    width: "100%",                    direction: "col",                    items: [{                            ratio: 1,                            shrink: 0,                            baseSize: "auto",                            template: $.proxy(this._renderClock, this)                        }, {                            ratio: 0,                            shrink: 0,                            baseSize: 50,                            template: $.proxy(this._renderField, this)                        }]                })            },            _renderClock: function(_, __, $container) {                this._$hourArrow = $("<div>").addClass(TIMEVIEW_HOURARROW_CLASS);                this._$minuteArrow = $("<div>").addClass(TIMEVIEW_MINUTEARROW_CLASS);                $container.addClass(TIMEVIEW_CLOCK_CLASS).append(this._$hourArrow).append(this._$minuteArrow);                this.setAria("role", "presentation", $container)            },            _updateClock: function() {                var time = this._getValue(),                    hourArrowAngle = time.getHours() / 12 * 360 + time.getMinutes() / 60 * 30,                    minuteArrowAngle = time.getMinutes() / 60 * 360;                rotateArrow(this._$hourArrow, hourArrowAngle, this.option("_arrowOffset"));                rotateArrow(this._$minuteArrow, minuteArrowAngle, this.option("_arrowOffset"))            },            _renderField: function() {                this._createHourBox();                this._createMinuteBox();                return this._createComponent($("<div>").addClass(TIMEVIEW_FIELD_CLASS), "dxBox", {                        direction: "row",                        align: "center",                        crossAlign: "center",                        items: [{                                ratio: 0,                                shrink: 0,                                baseSize: "auto",                                template: $.proxy(function() {                                    return this._hourBox.element()                                }, this)                            }, {                                ratio: 0,                                shrink: 0,                                baseSize: "auto",                                template: Globalize.culture().calendar[":"]                            }, {                                ratio: 0,                                shrink: 0,                                baseSize: "auto",                                template: $.proxy(function() {                                    return this._minuteBox.element()                                }, this)                            }]                    }).element()            },            _createHourBox: function() {                this._hourBox = this._createComponent($("<div>"), "dxNumberBox", $.extend({                    min: -1,                    max: 24,                    value: this._getValue().getHours(),                    onValueChanged: $.proxy(function(args) {                        var newHours = (24 + args.value) % 24;                        this._hourBox.option("value", newHours);                        var time = new Date(this._getValue());                        time.setHours(newHours);                        this.option("value", time)                    }, this)                }, this._getNumberBoxConfig()));                this._hourBox.setAria("label", "hours")            },            _createMinuteBox: function() {                this._minuteBox = this._createComponent($("<div>"), "dxNumberBox", $.extend({                    min: -1,                    max: 60,                    value: this._getValue().getMinutes(),                    onValueChanged: $.proxy(function(args) {                        var newMinutes = (60 + args.value) % 60;                        this._minuteBox.option("value", newMinutes);                        var time = new Date(this._getValue());                        time.setMinutes(newMinutes);                        this.option("value", time)                    }, this)                }, this._getNumberBoxConfig()));                this._minuteBox.setAria("label", "minutes")            },            _getNumberBoxConfig: function() {                return {                        showSpinButtons: true,                        disabled: this.option("disabled"),                        valueFormat: function(value) {                            return (value < 10 ? "0" : "") + value                        }                    }            },            _updateField: function() {                this._hourBox && this._hourBox.option("value", this._getValue().getHours());                this._minuteBox && this._minuteBox.option("value", this._getValue().getMinutes())            },            _updateTime: function() {                this._updateClock();                this._updateField()            },            _visibilityChanged: function(visible) {                if (visible)                    this._updateTime()            },            _toggleDisabledState: function(value) {                this._hourBox && this._hourBox.option("disabled", value);                this._minuteBox && this._minuteBox.option("disabled", value)            },            _optionChanged: function(args) {                switch (args.name) {                    case"value":                        this._updateTime();                        this.callBase(args);                        break;                    case"_arrowOffset":                        break;                    default:                        this.callBase(args)                }            }        }))    })(jQuery, DevExpress);    /*! Module widgets-base, file ui.dateView.js */    (function($, DX) {        var ui = DX.ui,            events = ui.events,            dateUtils = ui.dateUtils,            DATEVIEW_CLASS = "dx-dateview",            DATEVIEW_WRAPPER_CLASS = "dx-dateview-wrapper",            DATEVIEW_ROLLER_CONTAINER_CLASS = "dx-dateview-rollers",            DATEVIEW_ROLLER_CLASS = "dx-dateviewroller",            DATEVIEW_ROLLER_ACTIVE_CLASS = "dx-state-active",            DATEVIEW_ROLLER_CURRENT_CLASS = "dx-dateviewroller-current",            DATEVIEW_ROLLER_ITEM_CLASS = "dx-dateview-item",            DATEVIEW_ROLLER_ITEM_SELECTED_CLASS = "dx-dateview-item-selected",            DATEVIEW_ROLLER_ITEM_SELECTED_FRAME_CLASS = "dx-dateview-item-selected-frame",            DATEVIEW_ROLLER_ITEM_SELECTED_BORDER_CLASS = "dx-dateview-item-selected-border",            DATEVIEW_ROLLER_BUTTON_UP_CLASS = "dx-dateview-button-up",            DATEVIEW_ROLLER_BUTTON_DOWN_CLASS = "dx-dateview-button-down";        DX.registerComponent("dxDateViewRoller", ui, ui.dxScrollable.inherit({            _setDefaultOptions: function() {                this.callBase();                this.option({                    clickableItems: false,                    showScrollbar: false,                    useNative: false,                    selectedIndex: 0,                    bounceEnabled: false,                    items: [],                    onClick: null,                    showOnClick: false                })            },            _defaultOptionsRules: function() {                return this.callBase().concat([{                            device: {platform: "win8"},                            options: {                                clickableItems: true,                                showOnClick: true                            }                        }, {                            device: {platform: "generic"},                            options: {scrollByContent: true}                        }])            },            _init: function() {                this.callBase();                this._renderSelectedItemFrame();                this._renderControlButtons()            },            _render: function() {                this.callBase();                $.each(this._strategy._scrollers, function(index, scroller) {                    scroller._correctLocation = $.noop                });                this.element().addClass(DATEVIEW_ROLLER_CLASS);                this._renderContainerClick();                this._renderItems();                this._renderSelectedValue();                this._renderItemsClick();                this._wrapAction("_endAction", $.proxy(this._endActionHandler, this))            },            _renderContainerClick: function() {                if (!this.option("showOnClick"))                    return;                var eventName = events.addNamespace("dxclick", this.NAME);                var clickAction = this._createActionByOption("onClick");                this._$container.off(eventName).on(eventName, function(e) {                    clickAction({jQueryEvent: e})                })            },            _wrapAction: function(actionName, callback) {                var strategy = this._strategy,                    originalAction = strategy[actionName];                strategy[actionName] = function() {                    callback.apply(this, arguments);                    return originalAction.apply(this, arguments)                }            },            _renderItems: function() {                var items = this.option("items") || [],                    $items = $();                this._$content.empty();                $.each(items, function() {                    $items = $items.add($("<div>").addClass(DATEVIEW_ROLLER_ITEM_CLASS).append(this))                });                this._$content.append($items);                this._$items = $items;                this.update()            },            _renderSelectedItemFrame: function() {                $("<div>").addClass(DATEVIEW_ROLLER_ITEM_SELECTED_FRAME_CLASS).append($("<div>").addClass(DATEVIEW_ROLLER_ITEM_SELECTED_BORDER_CLASS)).appendTo(this._$container)            },            _renderControlButtons: function() {                this._createComponent($("<div>").addClass(DATEVIEW_ROLLER_BUTTON_UP_CLASS).insertAfter(this._$container), "dxButton", {                    onClick: $.proxy(this._upButtonClickHandler, this),                    _templates: {}                });                this._createComponent($("<div>").addClass(DATEVIEW_ROLLER_BUTTON_DOWN_CLASS).insertAfter(this._$container), "dxButton", {                    onClick: $.proxy(this._downButtonClickHandler, this),                    _templates: {}                })            },            _renderSelectedValue: function(selectedIndex) {                if (selectedIndex === undefined)                    selectedIndex = this.option("selectedIndex");                selectedIndex = this._fitIndex(selectedIndex);                var correctedPosition = this._getItemPosition(selectedIndex);                this.option().selectedIndex = selectedIndex;                this._moveTo({top: correctedPosition});                this._renderActiveStateItem()            },            _fitIndex: function(index) {                var items = this.option("items") || [],                    itemCount = items.length;                if (index >= itemCount)                    return itemCount - 1;                if (index < 0)                    return 0;                return index            },            _renderItemsClick: function() {                var itemSelector = "." + DATEVIEW_ROLLER_ITEM_CLASS,                    eventName = events.addNamespace("dxclick", this.NAME);                this.element().off(eventName, itemSelector);                if (this.option("clickableItems"))                    this.element().on(eventName, itemSelector, $.proxy(this._itemClickHandler, this))            },            _itemClickHandler: function(e) {                this._renderSelectedValue(this._itemElementIndex(this._closestItemElement(e)))            },            _itemElementIndex: function(itemElement) {                return this._itemElements().index(itemElement)            },            _closestItemElement: function(e) {                return e.currentTarget            },            _itemElements: function() {                return this.element().find("." + DATEVIEW_ROLLER_ITEM_CLASS)            },            _renderActiveStateItem: function() {                var selectedIndex = this.option("selectedIndex");                $.each(this._$items, function(index) {                    $(this).toggleClass(DATEVIEW_ROLLER_ITEM_SELECTED_CLASS, selectedIndex === index)                })            },            _upButtonClickHandler: function() {                this._animation = true;                this.option("selectedIndex", this.option("selectedIndex") - 1)            },            _downButtonClickHandler: function() {                this._animation = true;                this.option("selectedIndex", this.option("selectedIndex") + 1)            },            _getItemPosition: function(index) {                return Math.round(this._itemHeight() * index)            },            _moveTo: function(targetLocation) {                targetLocation = this._normalizeLocation(targetLocation);                var location = this._location(),                    delta = {                        x: -(location.left - targetLocation.left),                        y: -(location.top - targetLocation.top)                    };                if (this._isVisible() && (delta.x || delta.y)) {                    this._strategy._prepareDirections(true);                    if (this._animation) {                        DX.fx.stop(this._$content);                        DX.fx.animate(this._$content, {                            duration: 200,                            type: "slide",                            to: {top: targetLocation.top}                        });                        delete this._animation                    }                    else                        this._strategy.handleMove({delta: delta})                }            },            _validate: function(e) {                return this._strategy.validate(e)            },            _endActionHandler: function() {                if (this._changedByIndex) {                    this._changedByIndex = false;                    this._renderSelectedValue();                    return                }                var ratio = -this._location().top / this._itemHeight(),                    selectedIndex = Math.round(ratio);                this._animation = true;                this._renderSelectedValue(selectedIndex)            },            _itemHeight: function() {                var $item = this._$items.first(),                    height = $item.outerHeight() + parseFloat($item.css("margin-top") || 0);                return height            },            _toggleActive: function(state) {                this.element().toggleClass(DATEVIEW_ROLLER_ACTIVE_CLASS, state)            },            _isVisible: function() {                return this._$container.is(":visible")            },            _optionChanged: function(args) {                switch (args.name) {                    case"selectedIndex":                        this._renderSelectedValue();                        this._changedByIndex = true;                        this._strategy.handleEnd({velocity: {                                x: 0,                                y: 0                            }});                        break;                    case"items":                        this._renderItems();                        this._renderSelectedValue();                        break;                    case"clickableItems":                        this._renderItemsClick();                        break;                    case"onClick":                    case"showOnClick":                        this._renderContainerClick();                        break;                    default:                        this.callBase(args)                }            }        }), ui);        DX.registerComponent("dxDateView", ui, ui.Editor.inherit({            _valueOption: function() {                return new Date(this.option("value")) === "Invalid Date" ? new Date : new Date(this.option("value"))            },            _setDefaultOptions: function() {                this.callBase();                this.option({                    minDate: new Date(1),                    maxDate: new Date((new Date).setHours(23, 59, 59) + dateUtils.TEN_YEARS),                    format: "date",                    value: new Date,                    culture: Globalize.culture().name,                    activeStateEnabled: true,                    showNames: false                })            },            _defaultOptionsRules: function() {                return this.callBase().concat([{                            device: {platform: "win8"},                            options: {showNames: true}                        }])            },            _render: function() {                this.callBase();                this.element().addClass(DATEVIEW_CLASS);                this._toggleFormatClasses(this.option("format"))            },            _toggleFormatClasses: function(currentFormat, previousFormat) {                this.element().addClass(DATEVIEW_CLASS + "-" + currentFormat);                previousFormat && this.element().removeClass(DATEVIEW_CLASS + "-" + previousFormat)            },            _wrapper: function() {                return this._$wrapper            },            _renderContentImpl: function() {                this._$wrapper = $("<div>").appendTo(this.element()).addClass(DATEVIEW_WRAPPER_CLASS);                this._renderRollers()            },            _renderRollers: function() {                var that = this;                if (!that._$rollersContainer)                    that._$rollersContainer = $("<div>").appendTo(that._wrapper()).addClass(DATEVIEW_ROLLER_CONTAINER_CLASS);                that._$rollersContainer.empty();                that._createRollerConfigs();                that._rollers = {};                $.each(that._rollerConfigs, function(name) {                    var $roller = $("<div>").appendTo(that._$rollersContainer).addClass(DATEVIEW_ROLLER_CLASS + "-" + that._rollerConfigs[name].type);                    that._rollers[that._rollerConfigs[name].type] = that._createComponent($roller, "dxDateViewRoller", {                        items: that._rollerConfigs[name].displayItems,                        selectedIndex: that._rollerConfigs[name].selectedIndex,                        showScrollbar: false,                        onStart: function(e) {                            var roller = e.component;                            roller._toggleActive(true);                            that._setActiveRoller(that._rollerConfigs[name], roller.option("selectedIndex"))                        },                        onEnd: function(e) {                            var roller = e.component;                            that._setRollerState(that._rollerConfigs[name], roller.option("selectedIndex"));                            roller._toggleActive(false)                        },                        onClick: function(e) {                            var roller = e.component;                            roller._toggleActive(true);                            that._setActiveRoller(that._rollerConfigs[name], roller.option("selectedIndex"));                            that._setRollerState(that._rollerConfigs[name], roller.option("selectedIndex"));                            roller._toggleActive(false)                        }                    })                })            },            _setActiveRoller: function(currentRoller) {                var activeRoller = currentRoller && this._rollers[currentRoller.type];                $.each(this._rollers, function() {                    this._$element.toggleClass(DATEVIEW_ROLLER_CURRENT_CLASS, this === activeRoller)                })            },            _updateRollersPosition: function() {                var that = this;                $.each(this._rollers, function(type) {                    var correctIndex = that._rollerConfigs[type].getIndex(that._getCurrentDate());                    this.update();                    this._renderSelectedValue(correctIndex)                })            },            _setRollerState: function(roller, selectedIndex) {                if (selectedIndex !== roller.selectedIndex) {                    var rollerValue = roller.valueItems[selectedIndex],                        setValue = roller.setValue,                        currentValue = new Date(this._getCurrentDate()),                        currentDate = currentValue.getDate();                    if (roller.type === "month")                        currentDate = Math.min(currentDate, dateUtils.getMaxMonthDay(currentValue.getFullYear(), rollerValue));                    else if (roller.type === "year")                        currentDate = Math.min(currentDate, dateUtils.getMaxMonthDay(rollerValue, currentValue.getMonth()));                    currentValue.setDate(currentDate);                    currentValue[setValue](rollerValue);                    this.option("value", currentValue);                    roller.selectedIndex = selectedIndex                }                if (roller.type === "year") {                    this._refreshMonthRoller();                    this._refreshDayRoller()                }                if (roller.type === "month")                    this._refreshDayRoller()            },            _refreshMonthRoller: function() {                var monthRoller = this._rollers["month"];                if (monthRoller) {                    this._createRollerConfig("month");                    var monthRollerConfig = this._rollerConfigs["month"];                    if (monthRollerConfig.displayItems.length !== monthRoller.option("items").length)                        monthRoller.option({                            items: monthRollerConfig.displayItems,                            selectedIndex: monthRollerConfig.selectedIndex                        })                }            },            _refreshDayRoller: function() {                var dayRoller = this._rollers["day"];                if (dayRoller) {                    this._createRollerConfig("day");                    var dayRollerConfig = this._rollerConfigs["day"];                    if (dayRollerConfig.displayItems.length !== dayRoller.option("items").length)                        dayRoller.option({                            items: dayRollerConfig.displayItems,                            selectedIndex: dayRollerConfig.selectedIndex                        })                }            },            _createRollerConfigs: function(format) {                var that = this;                format = format || that.option("format");                that._rollerConfigs = {};                $.each(that._getFormatPattern(format).split(/\W+/), function(_, formatPart) {                    $.each(dateUtils.DATE_COMPONENTS_INFO, function(componentName, componentInfo) {                        if ($.inArray(formatPart, componentInfo.possibleFormats) > -1)                            that._createRollerConfig(componentName)                    })                })            },            _getFormatPattern: function(format) {                var culture = Globalize.culture(this.option("culture")),                    result = "";                if (format === "date")                    result = culture.calendar.patterns.d;                else if (format === "time")                    result = culture.calendar.patterns.t;                else if (format === "datetime")                    result = [culture.calendar.patterns.d, culture.calendar.patterns.t].join(" ");                return result            },            _createRollerConfig: function(componentName) {                var componentInfo = dateUtils.DATE_COMPONENTS_INFO[componentName],                    valueRange = this._calculateRollerConfigValueRange(componentName),                    startValue = valueRange.startValue,                    endValue = valueRange.endValue,                    formatter = componentInfo.formatter,                    showNames = this.option("showNames"),                    curDate = this._getCurrentDate();                var config = {                        type: componentName,                        setValue: componentInfo.setter,                        valueItems: [],                        displayItems: [],                        getIndex: function(value) {                            return value[componentInfo.getter]() - startValue                        }                    };                for (var i = startValue; i <= endValue; i++) {                    config.valueItems.push(i);                    config.displayItems.push(formatter(i, showNames, curDate))                }                config.selectedIndex = config.getIndex(curDate);                this._rollerConfigs[componentName] = config            },            _getCurrentDate: function() {                var curDate = this.option("value"),                    minDate = this.option("minDate"),                    maxDate = this.option("maxDate");                if (minDate && curDate.getTime() <= minDate.getTime())                    curDate = minDate;                else if (maxDate && curDate.getTime() >= maxDate.getTime())                    curDate = maxDate;                return curDate            },            _calculateRollerConfigValueRange: function(componentName) {                var curDate = this._getCurrentDate(),                    minDate = this.option("minDate"),                    maxDate = this.option("maxDate"),                    minYear = curDate.getFullYear() === minDate.getFullYear(),                    minMonth = minYear && curDate.getMonth() === minDate.getMonth(),                    maxYear = curDate.getFullYear() === maxDate.getFullYear(),                    maxMonth = maxYear && curDate.getMonth() === maxDate.getMonth(),                    componentInfo = dateUtils.DATE_COMPONENTS_INFO[componentName],                    startValue = componentInfo.startValue,                    endValue = componentInfo.endValue;                if (componentName === "year") {                    startValue = minDate.getFullYear();                    endValue = maxDate.getFullYear()                }                if (componentName === "month") {                    if (minYear)                        startValue = minDate.getMonth();                    if (maxYear)                        endValue = maxDate.getMonth()                }                if (componentName === "day") {                    endValue = dateUtils.getMaxMonthDay(curDate.getFullYear(), curDate.getMonth());                    if (minYear && minMonth)                        startValue = minDate.getDate();                    if (maxYear && maxMonth)                        endValue = maxDate.getDate()                }                return {                        startValue: startValue,                        endValue: endValue                    }            },            _refreshRollers: function() {                this._refreshMonthRoller();                this._refreshDayRoller()            },            _optionChanged: function(args) {                switch (args.name) {                    case"showNames":                    case"minDate":                    case"maxDate":                    case"culture":                    case"format":                        this._renderRollers();                        this._toggleFormatClasses(args.value, args.previousValue);                        break;                    case"visible":                        this.callBase(args);                        if (args.value)                            this._renderRollers();                        break;                    case"value":                        this.option("value", this._valueOption());                        this._refreshRollers();                        this._updateRollersPosition();                        break;                    default:                        this.callBase(args)                }            },            _clean: function() {                this.callBase();                delete this._$rollersContainer            },            _dispose: function() {                clearTimeout(this._deferredRenderDayTimeout);                clearTimeout(this._deferredRenderMonthTimeout);                this.callBase()            }        }))    })(jQuery, DevExpress);    /*! Module widgets-base, file ui.dateBox.js */    (function($, DX, undefined) {        var ui = DX.ui,            support = DX.support,            devices = DX.devices,            dateUtils = ui.dateUtils,            utils = DX.utils,            DATEBOX_CLASS = "dx-datebox",            DATEBOX_NATIVE_CLASS = "dx-datebox-native",            DATEBOX_OVERLAY_CLASS = "dx-datebox-overlay",            IE_ROUNDING_ERROR = 10,            NATIVE_BUTTONS_WIDTH = 48;        var realWidthSetted = function($element) {                var explicitWidth = $element[0].style.width;                if (explicitWidth && explicitWidth !== "auto" && explicitWidth !== "inherit")                    return true;                return false            };        var calculateWidth = function(value, $input, $element) {                var $longestValueElement = $("<div>").text(value).css({                        "font-style": $input.css("font-style"),                        "font-variant": $input.css("font-variant"),                        "font-weight": $input.css("font-weight"),                        "font-size": $input.css("font-size"),                        "font-family": $input.css("font-family"),                        "letter-spacing": $input.css("letter-spacing"),                        "padding-left": $input.css("padding-left"),                        "padding-right": $input.css("padding-right"),                        border: $input.css("border"),                        visibility: "hidden",                        "white-space": "nowrap",                        position: "absolute",                        float: "left"                    });                $longestValueElement.appendTo($element);                var width = $longestValueElement.outerWidth() + IE_ROUNDING_ERROR + ($input.prop("type") !== "text" ? NATIVE_BUTTONS_WIDTH : 0);                $longestValueElement.remove();                return width            };        DX.registerComponent("dxDateBox", ui, ui.dxDropDownEditor.inherit({            ctor: function(element, options) {                this._userOptions = $.extend({}, options);                this.callBase(element, options)            },            _supportedKeys: function() {                return $.extend(this.callBase(), this._strategy.supportedKeys())            },            _setDeprecatedOptions: function() {                this.callBase();                $.extend(this._deprecatedOptions, {                    closeOnValueChange: {                        since: "14.2",                        message: "Use the 'applyValueMode' option instead"                    },                    useNative: {                        since: "15.1",                        message: "'useNative' option is deprecated in 15.1. Use the 'pickerType' option instead"                    },                    useCalendar: {                        since: "15.1",                        message: "'useCalendar' option is deprecated in 15.1. Use the 'pickerType' option instead"                    }                })            },            _setDefaultOptions: function() {                this.callBase();                this.option({                    format: "date",                    value: new Date,                    min: undefined,                    max: undefined,                    useCalendar: false,                    maxZoomLevel: "month",                    minZoomLevel: "century",                    useNative: true,                    pickerType: "native"                })            },            _defaultOptionsRules: function() {                return this.callBase().concat([{                            device: {platform: "ios"},                            options: {showPopupTitle: true}                        }, {                            device: function(device) {                                return device.platform === "android"                            },                            options: {buttonsLocation: "bottom after"}                        }, {                            device: {platform: "win8"},                            options: {buttonsLocation: "bottom after"}                        }, {                            device: function() {                                var realDevice = DX.devices.real(),                                    platform = realDevice.platform,                                    version = realDevice.version;                                return platform === "generic" || platform === "win8" || platform === "android" && DX.compareVersions(version, [4, 4]) < 0                            },                            options: {pickerType: "rollers"}                        }, {                            device: {platform: "generic"},                            options: {                                pickerType: "calendar",                                buttonsLocation: "bottom after"                            }                        }])            },            _initOptions: function(options) {                if (DX.utils.isDefined(options.closeOnValueChange) && !DX.utils.isDefined(options.applyValueMode)) {                    var applyValueMode = options.closeOnValueChange ? "instantly" : "useButtons";                    $.extend(options, {applyValueMode: applyValueMode})                }                this.callBase(options)            },            _updatePickerOptions: function() {                this.option(this._getPickerOptions())            },            _getPickerOptions: function() {                var result = {},                    pickerType;                if (this._hasPickerTypePriority) {                    pickerType = this.option("pickerType");                    this.option().useNative = pickerType === "native";                    this.option().useCalendar = pickerType === "calendar" || pickerType === "list"                }                else {                    var userOptions = this._userOptions;                    if (userOptions) {                        pickerType = this.option("pickerType");                        if (userOptions.useNative === undefined)                            this.option("useNative", pickerType === "native");                        if (userOptions.useCalendar === undefined)                            this.option("useCalendar", pickerType === "list" || pickerType === "calendar")                    }                    var useNative = this.option("useNative"),                        useCalendar = this.option("useCalendar");                    if (userOptions && userOptions.useCalendar === true && userOptions.format === "time")                        result.pickerType = "list";                    else if (useNative)                        result.pickerType = "native";                    else if (useCalendar) {                        var format = this.option("format");                        result.pickerType = format === "date" || format === "datetime" ? "calendar" : "list"                    }                    else                        result.pickerType = "rollers"                }                return result            },            _init: function() {                this._hasPickerTypePriority = this._userOptions.pickerType !== undefined || this._userOptions.useNative === undefined && this._userOptions.useCalendar === undefined;                this._updatePickerOptions();                this._initStrategy();                this.option($.extend({}, this._strategy.getDefaultOptions(), this._userOptions));                delete this._userOptions;                this.callBase();                this._strategy.initFormat()            },            _initStrategy: function() {                this._parseFormat(this.option("format"));                var strategyName = this._getStrategyName(this._formatType),                    strategy = ui.dxDateBox.renderingStrategies[strategyName];                if (!(this._strategy && this._strategy.NAME === strategyName))                    this._strategy = new strategy(this)            },            _getStrategyName: function(format) {                switch (this.option("pickerType")) {                    case"calendar":                    case"list":                        if (format === "date")                            return "Calendar";                        if (format === "datetime")                            return "CalendarWithTime";                        return "List";                    case"rollers":                    case"native":                        return this.option().useCalendar ? "Calendar" : "DateView"                }            },            _parseFormat: function(format) {                var isTime = /h|m|s/g.test(format),                    isDate = /d|M|Y/g.test(format),                    formatType = "";                if (isDate)                    formatType += "date";                if (isTime)                    formatType += "time";                switch (format) {                    case"date":                        format = Globalize.culture().calendar.patterns["d"];                        break;                    case"datetime":                        format = Globalize.culture().calendar.patterns["d"] + " " + Globalize.culture().calendar.patterns["t"];                        break;                    case"time":                        format = Globalize.culture().calendar.patterns["t"];                        break                }                if (format)                    this._setFormatString(format);                if (formatType)                    this._setFormatType(formatType)            },            _setFormatString: function(formatString) {                this._formatString = formatString            },            _setFormatType: function(formatType) {                this._formatType = formatType            },            _attachChildKeyboardEvents: function() {                this._strategy.attachKeyboardEvents(this._keyboardProcessor)            },            _render: function() {                this.element().addClass(DATEBOX_CLASS).addClass(DATEBOX_CLASS + "-" + this.option("format"));                this.callBase();                this._strategy.render();                if (this._isNativeView())                    this.element().addClass(DATEBOX_NATIVE_CLASS);                this._updateSize();                this._updateDropButtonVisibility()            },            _popupShowingHandler: function() {                this.callBase();                this._strategy.popupShowingHandler()            },            _popupConfig: function() {                var popupConfig = this.callBase();                return $.extend(this._strategy.popupConfig(popupConfig), {                        title: this._getPopupTitle(),                        dragEnabled: false                    })            },            _renderPopup: function() {                this.callBase();                this._popup._$wrapper.addClass(DATEBOX_OVERLAY_CLASS)            },            _renderPopupContent: function() {                this.callBase();                this._strategy.renderPopupContent()            },            _popupHiddenHandler: function() {                this.callBase();                this._strategy.popupHiddenHandler()            },            _visibilityChanged: function(visible) {                if (visible)                    this._updateSize()            },            _updateSize: function() {                var $element = this.element(),                    widthOption = this.option("width"),                    isWidthSet = utils.isDefined(widthOption) || realWidthSetted($element) && !this._isSizeUpdatable,                    isElementVisible = $element.is(":visible"),                    pickerType = this.option("pickerType"),                    shouldCalculateWidth = pickerType !== "rollers" && devices.current().platform === "generic";                if (isWidthSet || !(shouldCalculateWidth && isElementVisible))                    return;                var $input = this._input(),                    calendar = Globalize.culture().calendar,                    format = this.option("formatString"),                    longestValue = Globalize.format(dateUtils.getLongestDate(format, calendar.months.names, calendar.days.names), format);                $element.width(calculateWidth(longestValue, $input, this.element()));                this._isSizeUpdatable = true            },            _usingNativeDatePicker: function() {                return support.inputType(this.option("mode")) && this.option("pickerType") === "native"            },            _readOnlyPropValue: function() {                return this.callBase() || this.option("pickerType") === "rollers"            },            _checkIfClearButtonShouldBeRendered: function() {                return !this._isNativeView() && this.callBase()            },            _renderValue: function() {                var mode = this.option("mode"),                    value = this.option("value"),                    patternKey = dateUtils.FORMATS_MAP[mode],                    pattern = this._getPattern(patternKey);                this._validateValue(value);                if (mode !== "text")                    this.option("text", dateUtils.toStandardDateFormat(value, mode, pattern));                else                    this.option("text", Globalize.format(value, this.option("formatString")));                this._strategy.renderValue();                this.callBase();                this._textHasBeenChanged = false            },            _getPattern: function(patternKey) {                return !support.inputType(this.option("mode")) ? Globalize.culture().calendar.patterns[patternKey] : null            },            _valueChangeEventHandler: function(e) {                var text = this.option("text"),                    date = this._strategy.getParsedText(text, this.option("formatString")),                    value = this.option("value"),                    modelValue = new Date(value && value.valueOf()),                    mode = this.option("mode"),                    newValue = (mode !== "text" ? dateUtils.mergeDates(modelValue, date, mode) : date) || null;                this._text = text;                this._textHasBeenChanged = true;                if (this._validateValue(date))                    this.option("value", newValue);                else                    this.option().value = null;                this.validationRequest.fire({                    value: newValue,                    editor: this                })            },            _validateValue: function(value) {                var text = this.option("text"),                    hasText = !!text,                    isDate = !!value,                    isDateInRange = isDate && utils.dateInRange(value, this.option("min"), this.option("max")),                    isValid = this._textHasBeenChanged && !hasText || !hasText && !value || isDateInRange,                    validationMessage = "";                if (!isDate)                    validationMessage = Globalize.localize("dxDateBox-validation-datetime");                else if (!isDateInRange)                    validationMessage = Globalize.localize("validation-range");                this.option({                    isValid: isValid,                    validationError: isValid ? null : {                        editorSpecific: true,                        message: validationMessage                    }                });                return isValid            },            _updateDropButtonVisibility: function() {                this.option("showDropButton", DX.devices.real().platform !== "generic" || this.option("pickerType") !== "native")            },            _renderProps: function() {                this.callBase();                this._input().attr("autocomplete", "off")            },            _renderOpenedState: function() {                this._openedStateRendering = true;                if (!this._isNativeView())                    this.callBase();                this._strategy.renderOpenedState();                this._openedStateRendering = false            },            _isNativeView: function() {                return this.option("pickerType") === "native"            },            _popupShownHandler: function(e) {                this.callBase.apply(this, arguments);                this._text = this.option("text")            },            _getPopupTitle: function() {                var result = this.option("placeholder");                if (!result) {                    var format = this.option("format");                    switch (format) {                        case"time":                            result = Globalize.localize("dxDateBox-simulatedDataPickerTitleTime");                            break;                        case"date":                        case"datetime":                            result = Globalize.localize("dxDateBox-simulatedDataPickerTitleDate");                            break                    }                }                return result            },            _renderPlaceholder: function() {                var popupTitle = this._getPopupTitle();                this._popup && this._popup.option("title", popupTitle);                this.callBase()            },            _refreshStrategy: function() {                this._strategy.dispose();                this._initStrategy();                this._strategy.initFormat();                this.option(this._strategy.getDefaultOptions());                this._refresh()            },            _applyButtonHandler: function() {                this.option("value", this._strategy.getValue());                this.callBase()            },            _dispose: function() {                this._strategy && this._strategy.dispose();                this.callBase()            },            _optionChanged: function(args) {                switch (args.name) {                    case"useCalendar":                    case"useNative":                        this._hasPickerTypePriority = false;                        this._updatePickerOptions();                        break;                    case"showClearButton":                        this.callBase.apply(this, arguments);                        this._updateSize();                        break;                    case"pickerType":                        this._hasPickerTypePriority = true;                        this._updatePickerOptions();                        this._refreshStrategy();                        this._invalidate();                        break;                    case"format":                        this._updatePickerOptions();                        this._refreshStrategy();                        this._updateSize();                        break;                    case"placeholder":                        this._renderPlaceholder();                        break;                    case"readOnly":                    case"min":                    case"max":                    case"interval":                    case"minZoomLevel":                    case"maxZoomLevel":                        this._invalidate();                        break;                    case"type":                        throw DX.Error("E1020");                    case"formatString":                    case"formatWidthCalculator":                        break;                    case"closeOnValueChange":                        var applyValueMode = args.value ? "instantly" : "useButtons";                        this.option("applyValueMode", applyValueMode);                        break;                    case"applyValueMode":                        this._suppressDeprecatedWarnings();                        this.option("closeOnValueChange", args.value === "instantly");                        this._resumeDeprecatedWarnings();                        this.callBase.apply(this, arguments);                        break;                    case"text":                        this._strategy.textChangedHandler(args.value);                        this.callBase.apply(this, arguments);                        break;                    case"isValid":                        this.callBase.apply(this, arguments);                        this._updateSize();                        break;                    default:                        this.callBase.apply(this, arguments)                }            }        }));        ui.dxDateBox.renderingStrategies = {}    })(jQuery, DevExpress);    /*! Module widgets-base, file ui.dateBox.strategy.js */    (function($, DX, undefined) {        var ui = DX.ui;        ui.dxDateBox.strategy = DX.Class.inherit({            ctor: function(dateBox) {                this.dateBox = dateBox            },            widgetOption: function() {                return this._widget && this._widget.option.apply(this._widget, arguments)            },            _renderWidget: function(element) {                element = element || $("<div>");                this._widget = this._createWidget(element);                this._widget.element().appendTo(this._getWidgetContainer())            },            _createWidget: function(element) {                return this.dateBox._createComponent(element, this._getWidgetName(), this._getWidgetOptions())            },            _getWidgetOptions: DX.abstract,            _getWidgetName: DX.abstract,            initFormat: function() {                this.dateBox.option("mode", "text")            },            supportedKeys: $.noop,            attachKeyboardEvents: function(keyboardProcessor) {                this._widgetKeyboardProcessor = keyboardProcessor.attachChildProcessor()            },            getParsedText: function(text, format) {                return Globalize.parseDate(text, format)            },            getDefaultOptions: DX.abstract,            _getDateBoxClass: DX.abstract,            renderOpenedState: function() {                if (this.dateBox.option("opened"))                    this._updateValue()            },            popupConfig: DX.abstract,            renderPopupContent: function() {                var popup = this._getPopup();                popup._wrapper().addClass(this._getPopupWrapperClass());                this._renderWidget();                popup.content().parent().off("mousedown").on("mousedown", $.proxy(this._preventFocusOnPopup, this))            },            _preventFocusOnPopup: function(e) {                e.preventDefault()            },            _getWidgetContainer: function() {                return this._getPopup().content()            },            _getPopup: function() {                return this.dateBox._popup            },            _getPopupWrapperClass: DX.abstract,            popupShowingHandler: $.noop,            popupHiddenHandler: $.noop,            _getDateBoxValue: function() {                return this.dateBox.option("value")            },            _updateValue: function() {                this._widget && this._widget.option("value", this._getDateBoxValue())            },            _valueChangedHandler: function(args) {                if (this.dateBox.option("opened") && this.dateBox.option("applyValueMode") === "instantly")                    this.dateBox.option("value", args.value)            },            textChangedHandler: $.noop,            renderValue: function() {                if (this.dateBox.option("opened"))                    this._updateValue()            },            getValue: function() {                return this._widget.option("value")            },            render: function() {                this.dateBox.element().addClass(this._getDateBoxClass())            },            dispose: function() {                this.dateBox.element().removeClass(this._getDateBoxClass());                var popup = this._getPopup();                if (popup) {                    popup._wrapper().removeClass(this._getPopupWrapperClass());                    popup.content().empty()                }            }        })    })(jQuery, DevExpress);    /*! Module widgets-base, file ui.dateBox.strategy.calendar.js */    (function($, DX, undefined) {        var ui = DX.ui,            utils = DX.utils,            DATEBOX_WITH_CALENDAR_CLASS = "dx-datebox-with-calendar",            DATEBOX_CALENDAR_OVERLAY_CLASS = "dx-datebox-calendar-overlay";        ui.dxDateBox.renderingStrategies["Calendar"] = ui.dxDateBox.strategy.inherit({            NAME: "Calendar",            supportedKeys: function() {                return {                        tab: function() {                            this.close()                        },                        rightArrow: function() {                            if (this.option("opened"))                                return true                        },                        leftArrow: function() {                            if (this.option("opened"))                                return true                        },                        enter: $.proxy(function(e) {                            if (this.dateBox.option("opened")) {                                if (this.dateBox._text !== e.target.value) {                                    this.dateBox._valueChangeEventHandler(e);                                    return false                                }                                if (this._widget.option("zoomLevel") === this._widget.option("maxZoomLevel")) {                                    var contouredDate = this._widget._view.option("contouredDate");                                    contouredDate && this.dateBox.option("value", contouredDate);                                    this.dateBox.close();                                    this.dateBox._valueChangeEventHandler(e)                                }                                else                                    return true                            }                        }, this)                    }            },            getDefaultOptions: function() {                return {formatString: Globalize.culture().calendar.patterns["d"]}            },            _getDateBoxClass: function() {                return DATEBOX_WITH_CALENDAR_CLASS            },            _getPopupWrapperClass: function() {                return DATEBOX_CALENDAR_OVERLAY_CLASS            },            _getWidgetName: function() {                return "dxCalendar"            },            _getWidgetOptions: function() {                return $.extend(this.dateBox.option("calendarOptions"), {                        value: this._getDateBoxValue(),                        _keyboardProcessor: this._widgetKeyboardProcessor,                        min: this.dateBox.option("min"),                        max: this.dateBox.option("max"),                        onValueChanged: $.proxy(this._valueChangedHandler, this),                        onCellClick: $.proxy(this._cellClickHandler, this),                        tabIndex: null,                        maxZoomLevel: this.dateBox.option("maxZoomLevel"),                        minZoomLevel: this.dateBox.option("minZoomLevel"),                        onContouredChanged: $.proxy(this._refreshActiveDescendant, this)                    })            },            _refreshActiveDescendant: function(e) {                this.dateBox.setAria("activedescendant", e.actionValue)            },            popupConfig: function(popupConfig) {                var buttons = popupConfig.buttons,                    buttonsLocation = this.dateBox.option("buttonsLocation");                var position = [];                if (buttonsLocation !== "default")                    position = DX.utils.splitPair(buttonsLocation);                else                    position = ["bottom", "center"];                if (this.dateBox.option("applyValueMode") === "useButtons")                    buttons.unshift({                        widget: "button",                        toolbar: position[0],                        location: position[1] === "after" ? "before" : position[1],                        options: {                            onClick: $.proxy(function() {                                this._widget._toTodayView()                            }, this),                            text: Globalize.localize("dxCalendar-todayButtonText"),                            type: "today"                        }                    });                return $.extend(popupConfig, {buttons: buttons})            },            _valueChangedHandler: function(e) {                if (this.dateBox._openedStateRendering)                    return;                var dateBox = this.dateBox,                    value = e.value,                    prevValue = e.previousValue;                var isSameDate = utils.sameMonthAndYear(value, prevValue) && value.getDate() === prevValue.getDate();                if (isSameDate)                    return;                if (dateBox.option("applyValueMode") === "instantly")                    dateBox.option("value", this.getValue())            },            _getParsedValue: function() {                return this.getParsedText(this.dateBox.option("text"), this.dateBox.option("formatString"))            },            _updateValue: function(preventDefaultValue) {                var parsedValue = this._getParsedValue();                if (!parsedValue && !preventDefaultValue)                    parsedValue = new Date;                if (this._widget) {                    var value = this.dateBox.option("value");                    if (parsedValue) {                        if (value)                            parsedValue.setHours(value.getHours(), value.getMinutes(), value.getSeconds());                        this._widget.option("value", parsedValue)                    }                }            },            textChangedHandler: function() {                if (this.dateBox.option("opened") && this._widget)                    this._updateValue(true)            },            _cellClickHandler: function() {                var dateBox = this.dateBox;                if (dateBox.option("applyValueMode") === "instantly")                    dateBox.option({                        opened: dateBox._textHasBeenChanged,                        value: this.getValue()                    })            },            dispose: function() {                this.dateBox.off("optionChanged");                this.callBase()            }        })    })(jQuery, DevExpress);    /*! Module widgets-base, file ui.dateBox.strategy.calendarWithTime.js */    (function($, DX, undefined) {        var ui = DX.ui,            CALENDAR_WITH_TIME_PICKER_CLASS = "dx-calendar-with-time-picker",            CALENDAR_WITH_TIME_PICKER_CONTAINER_CLASS = "dx-calendar-with-time-picker-container";        ui.dxDateBox.renderingStrategies["CalendarWithTime"] = ui.dxDateBox.renderingStrategies["Calendar"].inherit({            NAME: "CalendarWithTime",            supportedKeys: function() {                return $.extend(this.callBase(), {tab: function(e) {                            if (this.option("opened") === true) {                                e.preventDefault();                                this._strategy._timeView._hourBox.focus()                            }                        }})            },            getDefaultOptions: function() {                return $.extend(this.callBase(), {                        formatString: Globalize.culture().calendar.patterns["d"] + " " + Globalize.culture().calendar.patterns["t"],                        applyValueMode: "useButtons",                        buttonsLocation: "bottom after",                        showPopupTitle: false                    })            },            _renderWidget: function() {                this.callBase();                this._timeView = this.dateBox._createComponent($("<div>"), "dxTimeView", {                    value: this.dateBox.option("value"),                    onValueChanged: $.proxy(this._valueChangedHandler, this)                })            },            _updateValue: function(preventDefaultValue) {                var date = this._getParsedValue();                if (!date && !preventDefaultValue)                    date = new Date;                this.callBase.apply(this, arguments);                if (this._timeView && date)                    this._timeView.option("value", date)            },            renderPopupContent: function() {                this.callBase();                var $popupContent = this._getPopup().content().addClass(CALENDAR_WITH_TIME_PICKER_CONTAINER_CLASS);                var box = this.dateBox._createComponent($("<div>").appendTo($popupContent), "dxBox", {                        direction: "row",                        crossAlign: "start",                        items: [{                                ratio: 0,                                shrink: 0,                                baseSize: "auto",                                name: "calendar"                            }, {                                ratio: 0,                                shrink: 0,                                baseSize: "auto",                                name: "time"                            }],                        itemTemplate: $.proxy(function(data) {                            switch (data.name) {                                case"calendar":                                    return $("<div>").append(this._widget.element());                                case"time":                                    return $("<div>").append(this._timeView.element())                            }                        }, this)                    });                this._removeMinWidthTimer = setTimeout(function() {                    if (box.option("_layoutStrategy") === "fallback")                        $popupContent.find(".dx-timeview-clock").css("minWidth", 0)                }, 0);                this._attachTabHandler()            },            _attachTabHandler: function() {                var dateBox = this.dateBox,                    handler = function(e) {                        if (e.shiftKey) {                            e.preventDefault();                            dateBox.focus()                        }                    };                this._timeView._hourBox.registerKeyHandler("tab", handler)            },            _preventFocusOnPopup: function(e) {                if (!$(e.target).hasClass("dx-texteditor-input")) {                    this.callBase.apply(this, arguments);                    if (!this.dateBox.element().hasClass("dx-state-focused"))                        this.dateBox.focus()                }            },            getValue: function() {                var date = this._widget.option("value"),                    time = this._timeView.option("value");                date = date ? new Date(date) : new Date(1970, 0, 1, 0, 0, 0);                date.setHours(time.getHours(), time.getMinutes(), time.getSeconds());                return date            },            render: function() {                this.dateBox.element().addClass(CALENDAR_WITH_TIME_PICKER_CLASS);                this.callBase()            },            dispose: function() {                clearTimeout(this._removeMinWidthTimer);                this.dateBox.element().removeClass(CALENDAR_WITH_TIME_PICKER_CLASS);                this.callBase();                var popup = this._getPopup();                popup && popup._wrapper().removeClass(this._getPopupWrapperClass())            }        })    })(jQuery, DevExpress);    /*! Module widgets-base, file ui.dateBox.strategy.dateView.js */    var DATEVIEW_PICKER_OVERLAY_CLASS = "dx-dateview-picker-overlay";    (function($, DX, undefined) {        var ui = DX.ui,            support = DX.support,            dateUtils = ui.dateUtils,            DATEBOX_DATEVIEW_CLASS = "dx-datebox-dateview";        ui.dxDateBox.renderingStrategies["DateView"] = ui.dxDateBox.strategy.inherit({            NAME: "DateView",            popupShowingHandler: function() {                this._widget.option("visible", true)            },            popupHiddenHandler: function() {                this._widget.option("visible", false)            },            getDefaultOptions: function() {                return {                        openOnFieldClick: true,                        applyButtonText: Globalize.localize("Done")                    }            },            _getDateBoxClass: function() {                return DATEBOX_DATEVIEW_CLASS            },            popupConfig: function() {                return {                        showTitle: true,                        buttons: this.dateBox._popupButtonsConfig(),                        defaultOptionsRules: [{                                device: {platform: "win8"},                                options: {showNames: true}                            }, {                                device: {                                    platform: "win8",                                    phone: true                                },                                options: {                                    fullScreen: true,                                    animation: null                                }                            }, {                                device: function(device) {                                    return device.platform !== "win8"                                },                                options: {                                    width: 333,                                    height: 331                                }                            }, {                                device: {platform: "generic"},                                options: {                                    width: "auto",                                    height: "auto"                                }                            }, {                                device: {platform: "ios"},                                options: {                                    width: "auto",                                    height: "auto"                                }                            }, {                                device: {                                    platform: "ios",                                    phone: true                                },                                options: {                                    width: "100%",                                    position: {                                        my: "bottom",                                        at: "bottom",                                        of: window                                    }                                }                            }]                    }            },            getParsedText: function(text) {                return dateUtils.fromStandardDateFormat(text)            },            _renderWidget: function() {                if (this.dateBox._usingNativeDatePicker() || this.dateBox.option("readOnly")) {                    if (this._widget) {                        this._widget.element().remove();                        this._widget = null                    }                    return                }                var popup = this._getPopup();                if (this._widget)                    this._widget.option(this._getWidgetOptions());                else {                    var element = $("<div>").appendTo(popup.content());                    this._widget = this._createWidget(element)                }                this._widget.element().appendTo(this._getWidgetContainer());                popup._$wrapper.addClass(DATEVIEW_PICKER_OVERLAY_CLASS)            },            _getWidgetName: function() {                return "dxDateView"            },            _getDateBoxValue: function() {                return this.callBase() || new Date            },            _getWidgetOptions: function() {                return {                        value: this._getDateBoxValue(),                        format: this.dateBox.option("format"),                        minDate: this.dateBox.option("min") || new Date(1),                        maxDate: this.dateBox.option("max") || new Date($.now() + dateUtils.TEN_YEARS),                        visible: false,                        onDisposing: $.proxy(function() {                            this._widget = null                        }, this)                    }            },            _getPopupWrapperClass: function() {                return ""            },            initFormat: function() {                var format = this.dateBox.option("format");                if ($.inArray(format, dateUtils.SUPPORTED_FORMATS) === -1)                    format = "date";                else if (format === "datetime" && !support.inputType(format))                    format = "datetime-local";                this.dateBox.option({                    mode: format,                    formatString: dateUtils.FORMATS_MAP[format]                })            }        })    })(jQuery, DevExpress);    /*! Module widgets-base, file ui.dateBox.strategy.list.js */    (function($, DX, undefined) {        var ui = DX.ui,            dateUtils = ui.dateUtils,            DATEBOX_LIST_CLASS = "dx-datebox-list",            DATEBOX_LIST_POPUP_WRAPPER = "dx-datebox-list-popup-wrapper";        ui.dxDateBox.renderingStrategies["List"] = ui.dxDateBox.strategy.inherit({            NAME: "List",            supportedKeys: function() {                return {                        tab: function(e) {                            if (this.option("opened"))                                this.close()                        },                        space: $.noop,                        home: $.noop,                        end: $.noop                    }            },            getDefaultOptions: function() {                return {                        formatString: Globalize.culture().calendar.patterns["t"],                        applyValueMode: "instantly",                        interval: 30                    }            },            _getDateBoxClass: function() {                return DATEBOX_LIST_CLASS            },            _getPopupWrapperClass: function() {                return DATEBOX_LIST_POPUP_WRAPPER            },            popupConfig: function(popupConfig) {                return $.extend(popupConfig, {width: this.dateBox.element().outerWidth()})            },            popupShowingHandler: function() {                this._dimensionChanged()            },            _renderWidget: function() {                this.callBase();                this._refreshItems()            },            _getWidgetName: function() {                return "dxList"            },            _getWidgetOptions: function() {                var keyboardProcessor = this.dateBox._keyboardProcessor;                return {                        _keyboardProcessor: keyboardProcessor ? keyboardProcessor.attachChildProcessor() : null,                        itemTemplate: $.proxy(this._timeListItemTemplate, this),                        onItemClick: $.proxy(this._listItemClickHandler, this),                        tabIndex: -1,                        onFocusedItemChanged: $.proxy(this._refreshActiveDescendant, this)                    }            },            _refreshActiveDescendant: function(e) {                this.dateBox.setAria("activedescendant", "");                this.dateBox.setAria("activedescendant", e.actionValue)            },            _refreshItems: function() {                var items = this._getTimeListItems();                this._widget.option("items", items)            },            _getTimeListItems: function() {                var min = this.dateBox.option("min") || new Date(0, 0, 0, 0, 0),                    max = this.dateBox.option("max") || new Date(0, 0, 0, 23, 59),                    interval = this.dateBox.option("interval"),                    result = [],                    current = new Date(min),                    delta = max - min;                if (delta < 0)                    return [];                if (delta > dateUtils.ONE_DAY)                    delta = dateUtils.ONE_DAY;                while (current - min < delta) {                    result.push(new Date(current));                    current.setMinutes(current.getMinutes() + interval)                }                return result            },            _timeListItemTemplate: function(itemData) {                return Globalize.format(itemData, this.dateBox.option("formatString"))            },            _listItemClickHandler: function(e) {                this.dateBox.option("opened", false);                this.dateBox.option("value", e.itemData)            },            attachKeyboardEvents: function(keyboardProcessor) {                var child = keyboardProcessor.attachChildProcessor();                if (this._widget)                    this._widget.option("_keyboardProcessor", child)            },            _dimensionChanged: function() {                this._getPopup() && this._updatePopupDimensions()            },            _updatePopupDimensions: function() {                this._updatePopupWidth();                this._updatePopupHeight()            },            _updatePopupWidth: function() {                this.dateBox._setPopupOption("width", this.dateBox.element().outerWidth())            },            _updatePopupHeight: function() {                this.dateBox._setPopupOption("height", "auto");                var popupHeight = this.dateBox._popup.overlayContent().outerHeight();                var maxHeight = $(window).height() * 0.45;                this.dateBox._setPopupOption("height", Math.min(popupHeight, maxHeight));                this.dateBox._timeList && this.dateBox._timeList.updateDimensions()            }        })    })(jQuery, DevExpress);    /*! Module widgets-base, file ui.loadIndicator.js */    (function($, DX, undefined) {        var ui = DX.ui;        var LOADINDICATOR_CLASS = "dx-loadindicator",            LOADINDICATOR_WRAPPER_CLASS = "dx-loadindicator-wrapper",            LOADINDICATOR_CONTENT_CLASS = "dx-loadindicator-content",            LOADINDICATOR_ICON_CLASS = "dx-loadindicator-icon",            LOADINDICATOR_SEGMENT_CLASS = "dx-loadindicator-segment",            LOADINDICATOR_SEGMENT_INNER_CLASS = "dx-loadindicator-segment-inner",            LOADINDICATOR_IMAGE_CLASS = "dx-loadindicator-image";        DX.registerComponent("dxLoadIndicator", ui, ui.Widget.inherit({            _setDefaultOptions: function() {                this.callBase();                this.option({                    indicatorSrc: "",                    activeStateEnabled: false,                    hoverStateEnabled: false,                    _animatingSegmentCount: 0                })            },            _defaultOptionsRules: function() {                return this.callBase().concat([{                            device: function() {                                var realDevice = DevExpress.devices.real(),                                    obsoleteAndroid = realDevice.platform === "android" && !/chrome/i.test(navigator.userAgent);                                return DevExpress.browser.msie && DevExpress.browser.version < 10 || obsoleteAndroid                            },                            options: {viaImage: true}                        }, {                            device: [{platform: "win8"}],                            options: {_animatingSegmentCount: 5}                        }, {                            device: function(device) {                                return device.platform === "ios"                            },                            options: {_animatingSegmentCount: 11}                        }, {                            device: [{platform: "android"}],                            options: {_animatingSegmentCount: 2}                        }, {                            device: [{platform: "generic"}],                            options: {_animatingSegmentCount: 7}                        }])            },            _init: function() {                this.callBase();                this.element().addClass(LOADINDICATOR_CLASS)            },            _render: function() {                this._renderWrapper();                this._renderContent();                this._renderMarkup();                this.callBase()            },            _renderWrapper: function() {                this._$wrapper = $("<div>").addClass(LOADINDICATOR_WRAPPER_CLASS);                this.element().append(this._$wrapper)            },            _renderContent: function() {                this._$content = $("<div>").addClass(LOADINDICATOR_CONTENT_CLASS);                this._$wrapper.append(this._$content)            },            _renderMarkup: function() {                if (DX.support.animation && !this.option("viaImage") && !this.option("indicatorSrc"))                    this._renderMarkupForAnimation();                else                    this._renderMarkupForImage()            },            _renderMarkupForAnimation: function() {                var currentDevice = DX.devices.current();                this._$indicator = $("<div>").addClass(LOADINDICATOR_ICON_CLASS);                this._$content.append(this._$indicator);                for (var i = this.option("_animatingSegmentCount"); i >= 0; --i) {                    var $segment = $("<div>").addClass(LOADINDICATOR_SEGMENT_CLASS).addClass(LOADINDICATOR_SEGMENT_CLASS + i);                    if (currentDevice.platform === "android")                        $segment.append($("<div>").addClass(LOADINDICATOR_SEGMENT_INNER_CLASS));                    this._$indicator.append($segment)                }            },            _renderMarkupForImage: function() {                var indicatorSrc = this.option("indicatorSrc");                this._$wrapper.addClass(LOADINDICATOR_IMAGE_CLASS);                if (indicatorSrc)                    this._$wrapper.css("background-image", "url(" + indicatorSrc + ")")            },            _renderDimensions: function() {                this.callBase();                this._updateContentSizeForAnimation()            },            _updateContentSizeForAnimation: function() {                if (!this._$indicator)                    return;                var width = this.option("width"),                    height = this.option("height");                if (width || height) {                    width = this.element().width();                    height = this.element().height();                    var minDimention = Math.min(height, width);                    this._$wrapper.css({                        height: minDimention,                        width: minDimention,                        "font-size": minDimention                    })                }            },            _clean: function() {                this.callBase();                this._removeMarkupForAnimation();                this._removeMarkupForImage()            },            _removeMarkupForAnimation: function() {                if (!this._$indicator)                    return;                this._$indicator.remove();                delete this._$indicator            },            _removeMarkupForImage: function() {                this._$wrapper.css("background-image", "none")            },            _optionChanged: function(args) {                switch (args.name) {                    case"_animatingSegmentCount":                    case"indicatorSrc":                        this._invalidate();                        break;                    default:                        this.callBase(args)                }            }        }))    })(jQuery, DevExpress);    /*! Module widgets-base, file ui.loadPanel.js */    (function($, DX, undefined) {        var ui = DX.ui;        var LOADPANEL_CLASS = "dx-loadpanel",            LOADPANEL_WRAPPER_CLASS = "dx-loadpanel-wrapper",            LOADPANEL_INDICATOR_CLASS = "dx-loadpanel-indicator",            LOADPANEL_MESSAGE_CLASS = "dx-loadpanel-message",            LOADPANEL_CONTENT_CLASS = "dx-loadpanel-content",            LOADPANEL_CONTENT_WRAPPER_CLASS = "dx-loadpanel-content-wrapper",            LOADPANEL_PANE_HIDDEN_CLASS = "dx-loadpanel-pane-hidden";        DX.registerComponent("dxLoadPanel", ui, ui.dxOverlay.inherit({            _setDefaultOptions: function() {                this.callBase();                this.option({                    message: Globalize.localize("Loading"),                    width: 222,                    height: 90,                    animation: null,                    showIndicator: true,                    indicatorSrc: "",                    showPane: true,                    delay: 0,                    closeOnBackButton: false,                    resizeEnabled: false                })            },            _init: function() {                this.callBase.apply(this, arguments);                this._$contentWrapper = $("<div>").addClass(LOADPANEL_CONTENT_WRAPPER_CLASS);                this._$contentWrapper.appendTo(this._$content)            },            _render: function() {                this.callBase();                this.element().addClass(LOADPANEL_CLASS);                this._wrapper().addClass(LOADPANEL_WRAPPER_CLASS)            },            _renderContentImpl: function() {                this.callBase();                this.content().addClass(LOADPANEL_CONTENT_CLASS);                this._togglePaneVisible();                this._cleanPreviousContent();                this._renderLoadIndicator();                this._renderMessage()            },            _show: function() {                var delay = this.option("delay");                if (!delay)                    return this.callBase();                var deferred = $.Deferred();                var callBase = $.proxy(this.callBase, this);                this._clearShowTimeout();                this._showTimeout = setTimeout(function() {                    callBase().done(function() {                        deferred.resolve()                    })                }, delay);                return deferred.promise()            },            _hide: function() {                this._clearShowTimeout();                return this.callBase()            },            _clearShowTimeout: function() {                clearTimeout(this._showTimeout)            },            _renderMessage: function() {                var message = this.option("message");                if (!message)                    return;                var $message = $("<div>").addClass(LOADPANEL_MESSAGE_CLASS).text(message);                this._$contentWrapper.append($message)            },            _renderLoadIndicator: function() {                if (!this.option("showIndicator"))                    return;                this._$indicator = $("<div>").addClass(LOADPANEL_INDICATOR_CLASS).appendTo(this._$contentWrapper);                this._createComponent(this._$indicator, "dxLoadIndicator", {indicatorSrc: this.option("indicatorSrc")})            },            _cleanPreviousContent: function() {                this.content().find("." + LOADPANEL_MESSAGE_CLASS).remove();                this.content().find("." + LOADPANEL_INDICATOR_CLASS).remove()            },            _togglePaneVisible: function() {                this.content().toggleClass(LOADPANEL_PANE_HIDDEN_CLASS, !this.option("showPane"))            },            _optionChanged: function(args) {                switch (args.name) {                    case"delay":                        break;                    case"message":                    case"showIndicator":                        this._cleanPreviousContent();                        this._renderLoadIndicator();                        this._renderMessage();                        break;                    case"showPane":                        this._togglePaneVisible();                        break;                    case"indicatorSrc":                        if (this._$indicator)                            this._createComponent(this._$indicator, "dxLoadIndicator", {indicatorSrc: this.option("indicatorSrc")});                        break;                    default:                        this.callBase(args)                }            },            _dispose: function() {                this._clearShowTimeout();                this.callBase()            }        }));        ui.dxLoadPanel.__internals = {            LOADPANEL_CLASS: LOADPANEL_CLASS,            LOADPANEL_WRAPPER_CLASS: LOADPANEL_WRAPPER_CLASS,            LOADPANEL_MESSAGE_CLASS: LOADPANEL_MESSAGE_CLASS,            LOADPANEL_CONTENT_CLASS: LOADPANEL_CONTENT_CLASS,            LOADPANEL_PANE_HIDDEN_CLASS: LOADPANEL_PANE_HIDDEN_CLASS        }    })(jQuery, DevExpress);    /*! Module widgets-base, file ui.lookup.js */    (function($, DX, undefined) {        var ui = DX.ui,            utils = DX.utils,            events = ui.events;        var LOOKUP_CLASS = "dx-lookup",            LOOKUP_SELECTED_CLASS = "dx-lookup-selected",            LOOKUP_SEARCH_CLASS = "dx-lookup-search",            LOOKUP_SEARCH_WRAPPER_CLASS = "dx-lookup-search-wrapper",            LOOKUP_FIELD_CLASS = "dx-lookup-field",            LOOKUP_ARROW_CLASS = "dx-lookup-arrow",            LOOKUP_FIELD_WRAPPER_CLASS = "dx-lookup-field-wrapper",            LOOKUP_POPUP_CLASS = "dx-lookup-popup",            LOOKUP_POPUP_WRAPPER_CLASS = "dx-lookup-popup-wrapper",            LOOKUP_POPUP_SEARCH_CLASS = "dx-lookup-popup-search",            LOOKUP_POPOVER_MODE = "dx-lookup-popover-mode",            LOOKUP_EMPTY_CLASS = "dx-lookup-empty",            LOOKUP_POPUP_VALIDATION_MESSAGE = "dx-lookup-validation-message",            LOOKUP_POPUP_INVALID_CLASS = "dx-lookup-invalid",            LIST_ITEM_SELECTOR = ".dx-list-item",            LIST_ITEM_DATA_KEY = "dxListItemData";        var POPUP_OPTION_MAP = {                popupWidth: "width",                popupHeight: "height"            };        DX.registerComponent("dxLookup", ui, ui.dxDropDownList.inherit({            _supportedKeys: function() {                return $.extend(this.callBase(), {                        space: function(e) {                            this._validatedOpening()                        },                        enter: function(e) {                            this._validatedOpening()                        }                    })            },            _setDeprecatedOptions: function() {                this.callBase();                $.extend(this._deprecatedOptions, {                    minFilterLength: {                        since: "14.2",                        alias: "minSearchLength"                    },                    scrollAction: {                        since: "14.2",                        alias: "onScroll"                    },                    autoPagingEnabled: {                        since: "14.2",                        alias: "pagingEnabled"                    },                    pullRefreshAction: {                        since: "14.2",                        alias: "onPullRefresh"                    },                    pageLoadingAction: {                        since: "14.2",                        alias: "onPageLoading"                    },                    contentReadyAction: {                        since: "14.2",                        alias: "onContentReady"                    },                    titleRender: {                        since: "14.2",                        alias: "titleTemplate"                    },                    groupRender: {                        since: "14.2",                        alias: "groupTemplate"                    },                    doneButtonText: {                        since: "14.2",                        alias: "applyButtonText"                    },                    showDoneButton: {                        since: "14.2",                        message: "use the 'applyValueMode' option instead"                    },                    showNextButton: {                        since: "15.1",                        message: "Use the 'pageLoadMode' option instead"                    },                    pagingEnabled: {                        since: "15.1",                        message: "Use the 'dataSource.paginate' option instead"                    }                })            },            _setDefaultOptions: function() {                this.callBase();                this.option({                    title: "",                    titleTemplate: "title",                    onTitleRendered: null,                    placeholder: Globalize.localize("Select"),                    searchPlaceholder: Globalize.localize("Search"),                    searchEnabled: true,                    cleanSearchOnOpening: true,                    fullScreen: false,                    showCancelButton: true,                    cancelButtonText: Globalize.localize("Cancel"),                    showClearButton: false,                    clearButtonText: Globalize.localize("Clear"),                    applyButtonText: Globalize.localize("Done"),                    popupWidth: function() {                        return $(window).width() * 0.8                    },                    popupHeight: function() {                        return $(window).height() * 0.8                    },                    shading: true,                    closeOnOutsideClick: false,                    position: undefined,                    animation: undefined,                    pullRefreshEnabled: false,                    useNativeScrolling: true,                    pullingDownText: Globalize.localize("dxList-pullingDownText"),                    pulledDownText: Globalize.localize("dxList-pulledDownText"),                    refreshingText: Globalize.localize("dxList-refreshingText"),                    pageLoadingText: Globalize.localize("dxList-pageLoadingText"),                    onScroll: null,                    onPullRefresh: null,                    onPageLoading: null,                    pageLoadMode: "scrollBottom",                    showNextButton: undefined,                    nextButtonText: Globalize.localize("dxList-nextButtonText"),                    grouped: false,                    groupTemplate: "group",                    usePopover: false,                    showDropButton: false,                    showPopupTitle: true                })            },            _defaultOptionsRules: function() {                return this.callBase().concat([{                            device: function(device) {                                return !DX.support.nativeScrolling                            },                            options: {useNativeScrolling: false}                        }, {                            device: function(device) {                                return !DX.support.nativeScrolling && !DX.devices.isSimulator() && DX.devices.real().platform === "generic" && device.platform === "generic"                            },                            options: {                                pageLoadMode: "nextButton",                                usePopover: true                            }                        }, {                            device: function(device) {                                var browser = DX.browser;                                return browser.msie && DX.compareVersions(browser.version, 9) < 0                            },                            options: {usePopover: false}                        }, {                            device: {                                platform: "win8",                                phone: true                            },                            options: {                                showCancelButton: false,                                fullScreen: true                            }                        }, {                            device: {                                platform: "win8",                                phone: false                            },                            options: {popupWidth: function() {                                    return $(window).width()                                }}                        }, {                            device: {                                platform: "ios",                                phone: true                            },                            options: {fullScreen: true}                        }, {                            device: {                                platform: "ios",                                tablet: true                            },                            options: {                                popupWidth: function() {                                    return Math.min($(window).width(), $(window).height()) * 0.4                                },                                popupHeight: function() {                                    return Math.min($(window).width(), $(window).height()) * 0.4                                },                                usePopover: true                            }                        }, {                            device: {platform: "generic"},                            options: {buttonsLocation: "bottom center"}                        }])            },            _initOptions: function(options) {                if (DX.utils.isDefined(options.showDoneButton) && !DX.utils.isDefined(options.applyValueMode)) {                    var applyValueMode = options.showDoneButton ? "useButtons" : "instantly";                    $.extend(options, {applyValueMode: applyValueMode})                }                this.callBase(options)            },            _getAriaTarget: function() {                return this._$field            },            _dataSourceOptions: function() {                this._suppressDeprecatedWarnings();                var pagingEnabled = utils.ensureDefined(this.option("pagingEnabled"), true);                pagingEnabled = utils.isDefined(this.option("showNextButton")) ? pagingEnabled || this.option("showNextButton") : pagingEnabled;                this._resumeDeprecatedWarnings();                return $.extend(this.callBase(), {paginate: pagingEnabled})            },            _inputWrapper: function() {                return this.element().find("." + LOOKUP_FIELD_WRAPPER_CLASS)            },            _render: function() {                this.callBase();                this.element().addClass(LOOKUP_CLASS).toggleClass(LOOKUP_POPOVER_MODE, this.option("usePopover"))            },            _fireContentReadyAction: $.noop,            _popupWrapperClass: function() {                return ""            },            _renderInput: function() {                var fieldClickAction = this._createAction($.proxy(function() {                        this._validatedOpening()                    }, this));                this._$field = $("<div>").addClass(LOOKUP_FIELD_CLASS).on(events.addNamespace("dxclick", this.NAME), function(e) {                    fieldClickAction({jQueryEvent: e})                });                var $arrow = $("<div>").addClass(LOOKUP_ARROW_CLASS);                this._$fieldWrapper = $("<div>").addClass(LOOKUP_FIELD_WRAPPER_CLASS).append(this._$field).append($arrow).appendTo(this.element())            },            _popupShowingHandler: function() {                var validationError;                if (this._$popupValidationMessage) {                    validationError = this.option("validationError");                    if (validationError && validationError.message) {                        this._$popupValidationMessage.text(validationError.message);                        this._popup.content().addClass(LOOKUP_POPUP_INVALID_CLASS)                    }                    else                        this._popup.content().removeClass(LOOKUP_POPUP_INVALID_CLASS)                }                this.callBase.apply(this, arguments);                if (this.option("cleanSearchOnOpening")) {                    if (this.option("searchEnabled") && this._searchBox.option("value")) {                        this._searchBox.option("value", "");                        this._searchCanceled();                        this._searchDataSource()                    }                    this._list && this._list.option("focusedElement", null)                }            },            _popupPositionedHandler: function() {                if (this.option("usePopover"))                    this._updatePopoverHeight()            },            _updatePopoverHeight: function() {                if (!this._isInitialOptionValue("popupHeight"))                    return;                var listHeight = 0,                    topSpace = this._popup.content().position().top,                    bottomSpace = this._popup.bottomToolbar() ? this._popup.bottomToolbar().outerHeight(true) : 0,                    contentPaddings = topSpace + bottomSpace;                if (this._list) {                    listHeight += this._list.element().position().top;                    listHeight += this._list.element().outerHeight() - this._list.clientHeight();                    listHeight += this._list.scrollHeight()                }                this._popup.overlayContent().css("maxHeight", "none");                var popupHeight = Math.min(listHeight + contentPaddings, this._popup.overlayContent().outerHeight());                this._popup.overlayContent().css("maxHeight", popupHeight);                this._list && this._list.updateDimensions()            },            _renderPopup: function() {                if (this.option("usePopover") && !this.option("fullScreen"))                    this._renderPopover();                else                    this.callBase();                this._$popup.addClass(LOOKUP_POPUP_CLASS);                this._popup._wrapper().addClass(LOOKUP_POPUP_WRAPPER_CLASS)            },            _popupOptionMap: function(optionName) {                return POPUP_OPTION_MAP[optionName] || optionName            },            _renderPopover: function() {                this._popup = this._createComponent(this._$popup, "dxPopover", $.extend(this._popupConfig(), {                    target: this.element(),                    fullScreen: false,                    shading: false,                    closeOnTargetScroll: true,                    closeOnOutsideClick: true,                    width: this._isInitialOptionValue("popupWidth") ? this.element().width() : this._popupConfig().width                }));                this._popup.on({                    showing: $.proxy(this._popupShowingHandler, this),                    shown: $.proxy(this._popupShownHandler, this),                    hiding: $.proxy(this._popupHidingHandler, this),                    hidden: $.proxy(this._popupHiddenHandler, this),                    positioned: $.proxy(this._popupPositionedHandler, this)                });                this._popup.option("onContentReady", $.proxy(this._contentReadyHandler, this));                this._contentReadyHandler()            },            _popupHidingHandler: function() {                this.callBase();                this.option("focusStateEnabled") && this.focus()            },            _preventFocusOnPopup: $.noop,            _popupConfig: function() {                var result = $.extend(this.callBase(), {                        onShowing: null,                        showTitle: this.option("showPopupTitle"),                        title: this.option("title"),                        titleTemplate: this._getTemplateByOption("titleTemplate"),                        onTitleRendered: this.option("onTitleRendered"),                        buttons: this._getPopupButtons(),                        fullScreen: this.option("fullScreen"),                        shading: this.option("shading"),                        closeOnTargetScroll: false,                        closeOnOutsideClick: this.option("closeOnOutsideClick")                    });                delete result.animation;                delete result.position;                $.each(["position", "animation", "popupWidth", "popupHeight"], $.proxy(function(_, optionName) {                    if (this.option(optionName) !== undefined)                        result[this._popupOptionMap(optionName)] = this.option(optionName)                }, this));                return result            },            _getPopupButtons: function() {                var buttonsConfig = this.option("applyValueMode") === "useButtons" ? this._popupButtonsConfig() : [];                var cancelButton = this._getCancelButtonConfig();                if (cancelButton)                    buttonsConfig.push(cancelButton);                var clearButton = this._getClearButtonConfig();                if (clearButton)                    buttonsConfig.push(clearButton);                return this._applyButtonsLocation(buttonsConfig)            },            _popupButtonsConfig: function() {                return [{                            shortcut: "done",                            options: {                                onClick: $.proxy(this._applyButtonHandler, this),                                text: this.option("applyButtonText")                            }                        }]            },            _getCancelButtonConfig: function() {                return this.option("showCancelButton") ? {                        shortcut: "cancel",                        onClick: $.proxy(this._cancelButtonHandler, this),                        options: {text: this.option("cancelButtonText")}                    } : null            },            _getClearButtonConfig: function() {                return this.option("showClearButton") ? {                        shortcut: "clear",                        onClick: $.proxy(this._resetValue, this),                        options: {text: this.option("clearButtonText")}                    } : null            },            _applyButtonHandler: function() {                this.option("value", this._valueGetter(this._currentSelectedItem()));                this.callBase()            },            _cancelButtonHandler: function() {                this._refreshSelected();                this.callBase()            },            _refreshPopupVisibility: $.noop,            _dimensionChanged: function() {                if (this.option("usePopover") && !this.option("popupWidth"))                    this.option("popupWidth", this.element().width())            },            _input: function() {                return this._$searchBox || this.callBase()            },            _renderPopupContent: function() {                if (this._popup.NAME === "dxPopup")                    this._$popupValidationMessage = $("<div>").addClass(LOOKUP_POPUP_VALIDATION_MESSAGE).appendTo(this._popup.content());                this._renderSearch();                this.callBase()            },            _renderSearch: function() {                var $searchWrapper = this._$searchWrapper = $("<div>").addClass(LOOKUP_SEARCH_WRAPPER_CLASS);                var $searchBox = this._$searchBox = $("<div>").addClass(LOOKUP_SEARCH_CLASS).appendTo($searchWrapper);                var currentDevice = DX.devices.current(),                    searchMode = currentDevice.android && currentDevice.version[0] >= 5 ? "text" : "search";                this._searchBox = this._createComponent($searchBox, "dxTextBox", {                    mode: searchMode,                    showClearButton: true,                    valueChangeEvent: this.option("valueChangeEvent"),                    onValueChanged: $.proxy(this._search, this)                });                this._searchBox.registerKeyHandler("escape", $.proxy(function(e) {                    this.close()                }, this));                $searchWrapper.appendTo(this._popup.content());                this._renderSearchVisibility();                this._setSearchPlaceholder()            },            _renderSearchVisibility: function() {                if (this._popup) {                    var searchEnabled = this.option("searchEnabled");                    this._popup._wrapper().toggleClass(LOOKUP_POPUP_SEARCH_CLASS, searchEnabled);                    this._$searchWrapper.toggle(searchEnabled)                }            },            _setSearchPlaceholder: function() {                if (!this._$searchBox)                    return;                var minSearchLength = this.option("minSearchLength");                var placeholder = this.option("searchPlaceholder");                if (minSearchLength && placeholder === Globalize.localize("Search"))                    placeholder = utils.stringFormat(Globalize.localize("dxLookup-searchPlaceholder"), minSearchLength);                this._searchBox.option("placeholder", placeholder)            },            _renderList: function() {                this.callBase();                this._list.registerKeyHandler("escape", $.proxy(function(e) {                    this.close()                }, this))            },            _listConfig: function() {                return $.extend(this.callBase(), {                        tabIndex: 0,                        grouped: this.option("grouped"),                        groupTemplate: this._getTemplateByOption("groupTemplate"),                        pullRefreshEnabled: this.option("pullRefreshEnabled"),                        useNativeScrolling: this.option("useNativeScrolling"),                        pullingDownText: this.option("pullingDownText"),                        pulledDownText: this.option("pulledDownText"),                        refreshingText: this.option("refreshingText"),                        pageLoadingText: this.option("pageLoadingText"),                        onScroll: this.option("onScroll"),                        onPullRefresh: this.option("onPullRefresh"),                        onPageLoading: this.option("onPageLoading"),                        pageLoadMode: this._getPageLoadMode(),                        nextButtonText: this.option("nextButtonText")                    })            },            _listContentReadyHandler: function() {                if (this.option("usePopover"))                    this._popup.repaint();                this.callBase.apply(this, arguments)            },            _getPageLoadMode: function() {                this._suppressDeprecatedWarnings();                var result = utils.isDefined(this.option("showNextButton")) ? "nextButton" : this.option("pageLoadMode");                this._resumeDeprecatedWarnings();                return result            },            _setFocusPolicy: function() {                if (!this.option("focusStateEnabled"))                    return;                if (this.option("searchEnabled"))                    this._searchBox.focus();                else                    this._$list.focus()            },            _attachChildKeyboardEvents: $.noop,            _focusTarget: function() {                return this._$field            },            _keyboardEventBindingTarget: function() {                return this._$field            },            _selectedItemClass: function() {                return LOOKUP_SELECTED_CLASS            },            _listItemClickHandler: function(e) {                if (this._currentSelectedItem() === e.itemData)                    this._applyButtonHandler();                this._setCurrentSelectedClass(e.jQueryEvent.target);                if (this.option("applyValueMode") === "instantly")                    this._applyButtonHandler()            },            _currentSelectedItem: function() {                return this._listSelectedItemElements().data(LIST_ITEM_DATA_KEY)            },            _setCurrentSelectedClass: function(target) {                this._listSelectedItemElements().removeClass(LOOKUP_SELECTED_CLASS);                $(target).closest(LIST_ITEM_SELECTOR).addClass(LOOKUP_SELECTED_CLASS)            },            _resetValue: function() {                this.option("value", null);                this.option("opened", false)            },            _searchValue: function() {                return this.option("searchEnabled") ? this._searchBox.option("value") : ""            },            _renderInputValue: function() {                return this.callBase().always($.proxy(function() {                        this._refreshField()                    }, this))            },            _refreshField: function() {                this._$field.text(this.option("displayValue") || this.option("placeholder"));                this.element().toggleClass(LOOKUP_EMPTY_CLASS, !this.option("selectedItem"))            },            _clean: function() {                this._$fieldWrapper.remove();                this._$searchBox = null;                this.callBase()            },            _optionChanged: function(args) {                var name = args.name;                var value = args.value;                switch (name) {                    case"searchEnabled":                        this._renderSearchVisibility();                        break;                    case"searchPlaceholder":                        this._setSearchPlaceholder();                        break;                    case"minSearchLength":                        this._setSearchPlaceholder();                        this.callBase.apply(this, arguments);                        break;                    case"title":                    case"titleTemplate":                    case"onTitleRendered":                    case"shading":                    case"animation":                    case"position":                    case"closeOnOutsideClick":                        this._setPopupOption(name);                        break;                    case"fullScreen":                    case"usePopover":                        this._invalidate();                        break;                    case"clearButtonText":                    case"showClearButton":                    case"showCancelButton":                        this._setPopupOption("buttons", this._getPopupButtons());                        break;                    case"showDoneButton":                        this.option("applyValueMode", value ? "useButtons" : "instantly");                        break;                    case"applyValueMode":                        this.option("showDoneButton", value === "useButtons");                        this.callBase.apply(this, arguments);                        break;                    case"popupWidth":                        this._setPopupOption("popupWidth", value === "auto" ? this.initialOption("popupWidth") : value);                        break;                    case"popupHeight":                        this._setPopupOption("popupHeight", value === "auto" ? this.initialOption("popupHeight") : value);                        break;                    case"pullRefreshEnabled":                    case"useNativeScrolling":                    case"pullingDownText":                    case"pulledDownText":                    case"refreshingText":                    case"pageLoadingText":                    case"onScroll":                    case"onPullRefresh":                    case"onPageLoading":                    case"nextButtonText":                    case"grouped":                    case"groupTemplate":                        this._setListOption(name);                        break;                    case"showNextButton":                    case"pageLoadMode":                        this._setListOption("pageLoadMode", this._getPageLoadMode());                        break;                    case"cleanSearchOnOpening":                        break;                    default:                        this.callBase.apply(this, arguments)                }            },            focus: function() {                this.option("opened") ? this._setFocusPolicy() : this._focusTarget().focus()            },            field: function() {                return this._$field            }        }))    })(jQuery, DevExpress);    /*! Module widgets-base, file ui.autocomplete.js */    (function($, DX, undefined) {        var ui = DX.ui;        var AUTOCOMPLETE_CLASS = "dx-autocomplete",            AUTOCOMPLETE_POPUP_WRAPPER_CLASS = "dx-autocomplete-popup-wrapper",            CONTROL_KEY = {                "9": "tab",                "13": "enter",                "16": "shift",                "17": "ctrl",                "18": "alt",                "27": "escape",                "33": "pageUp",                "34": "pageDown",                "35": "end",                "36": "home",                "37": "leftArrow",                "38": "upArrow",                "39": "rightArrow",                "40": "downArrow"            };        DX.registerComponent("dxAutocomplete", ui, ui.dxDropDownList.inherit({            _supportedKeys: function() {                var item = this._list ? this._list.option("focusedElement") : null;                return $.extend(this.callBase(), {                        upArrow: function(e) {                            e.preventDefault();                            e.stopPropagation();                            if (item && !item.prev().length) {                                this._clearFocusedItem();                                return false                            }                            return true                        },                        downArrow: function(e) {                            e.preventDefault();                            e.stopPropagation();                            if (item && !item.next().length) {                                this._clearFocusedItem();                                return false                            }                            return true                        },                        enter: function(e) {                            if (!item)                                this.close();                            return true                        }                    })            },            _setDeprecatedOptions: function() {                this.callBase();                $.extend(this._deprecatedOptions, {displayExpr: {                        since: "14.2",                        alias: "valueExpr"                    }})            },            _setDefaultOptions: function() {                this.callBase();                this.option({                    minSearchLength: 1,                    maxItemCount: 10,                    noDataText: "",                    showDropButton: false                })            },            _defaultOptionsRules: function() {                return this.callBase().concat([{                            device: function(device) {                                return device.platform === "android"                            },                            options: {dropPosition: {offset: {                                        h: -16,                                        v: -9                                    }}}                        }])            },            _render: function() {                this.callBase();                this.element().addClass(AUTOCOMPLETE_CLASS);                this.setAria("autocomplete", "inline")            },            _loadValue: function() {                return $.Deferred().resolve(this.option("value"))            },            _displayGetterExpr: function() {                return this.option("valueExpr")            },            _setSelectedItem: function(item) {                this.callBase(item);                this.option("displayValue", this.option("value"))            },            _popupConfig: function() {                return $.extend(this.callBase(), {closeOnOutsideClick: $.proxy(function(e) {                            return !$(e.target).closest(this.element()).length                        }, this)})            },            _renderDimensions: function() {                this.callBase();                this._setPopupOption("width")            },            _hasItemsToShow: function() {                var resultItems = this._dataSource && this._dataSource.items() || [];                var value = this.option("value");                var firstResultValue = this._displayGetter(resultItems[0]) || "";                var firstResultValueShorterThanValue = firstResultValue.length < (value || "").length;                return this.callBase() && !firstResultValueShorterThanValue            },            _popupWrapperClass: function() {                return this.callBase() + " " + AUTOCOMPLETE_POPUP_WRAPPER_CLASS            },            _listConfig: function() {                return $.extend(this.callBase(), {                        pageLoadMode: "none",                        indicateLoading: false                    })            },            _listItemClickHandler: function(e) {                var value = this._displayGetter(e.itemData);                this.option("value", value);                this.close()            },            _refreshSelected: $.noop,            _searchCanceled: function() {                this.callBase();                this.close()            },            _dataSourceOptions: function() {                return {paginate: true}            },            _searchDataSource: function() {                this._dataSource.pageSize(this.option("maxItemCount"));                this.callBase();                this._clearFocusedItem()            },            _clearFocusedItem: function() {                if (this._list) {                    this._list.option("focusedElement", null);                    this._list.option("selectedIndex", -1)                }            },            _renderValueEventName: function() {                return "input keyup"            },            _keyUpHandler: function(e) {                if (CONTROL_KEY[e.which || e.keyCode])                    return;                this.callBase.apply(this, arguments);                this._search()            },            _optionChanged: function(args) {                if (args.name === "maxItemCount")                    this._searchDataSource();                else                    this.callBase(args)            }        }))    })(jQuery, DevExpress);    /*! Module widgets-base, file ui.selectBox.js */    (function($, DX, undefined) {        var ui = DX.ui,            events = ui.events,            SELECTBOX = "dxSelectBox",            SELECTBOX_CLASS = "dx-selectbox",            SELECTBOX_POPUP_CLASS = "dx-selectbox-popup",            SELECTBOX_SELECTED_CLASS = "dx-selectbox-selected",            SELECTBOX_CONTAINER_CLASS = "dx-selectbox-container",            SELECTBOX_POPUP_WRAPPER_CLASS = "dx-selectbox-popup-wrapper",            BLUR_EVENT_NAME = events.addNamespace("blur", SELECTBOX),            CLICK_EVENT_NAME = events.addNamespace("dxclick", SELECTBOX),            CONTROL_KEY = {                "9": "tab",                "13": "enter",                "16": "shift",                "17": "ctrl",                "18": "alt",                "27": "escape",                "33": "pageUp",                "34": "pageDown",                "35": "end",                "36": "home",                "37": "leftArrow",                "38": "upArrow",                "39": "rightArrow",                "40": "downArrow"            };        DX.registerComponent(SELECTBOX, ui, ui.dxDropDownList.inherit({            _supportedKeys: function() {                var parent = this.callBase(),                    clearSelectBox = function(e) {                        if (this.option("showClearButton")) {                            e.preventDefault();                            this.reset()                        }                    };                return $.extend({}, parent, {                        upArrow: function(e) {                            if (parent.upArrow.apply(this, arguments)) {                                if (!this.option("opened"))                                    this._setNextValue(-1);                                return true                            }                        },                        downArrow: function(e) {                            if (parent.downArrow.apply(this, arguments)) {                                if (!this.option("opened"))                                    this._setNextValue(1);                                return true                            }                        },                        enter: function(e) {                            if (parent.enter.apply(this, arguments))                                return this.option("opened")                        },                        backspace: clearSelectBox,                        del: clearSelectBox                    })            },            _setDefaultOptions: function() {                this.callBase();                this.option({                    placeholder: Globalize.localize("Select"),                    fieldTemplate: null,                    valueChangeEvent: "keyup",                    fieldEditEnabled: false,                    showSelectionControls: false,                    tooltipEnabled: false,                    openOnFieldClick: true,                    showDropButton: true,                    displayCustomValue: false,                    _isAdaptableDropPosition: false                })            },            _defaultOptionsRules: function() {                return this.callBase().concat([{                            device: {platform: "win8"},                            options: {                                _isAdaptableDropPosition: true,                                dropPosition: {                                    at: "left top",                                    offset: {                                        h: 0,                                        v: 0                                    }                                }                            }                        }, {                            device: function(device) {                                return device.platform === "android"                            },                            options: {                                _isAdaptableDropPosition: true,                                dropPosition: {                                    my: "top left",                                    at: "top left",                                    offset: {                                        h: -16,                                        v: -8                                    }                                }                            }                        }])            },            _selectedItemClass: function() {                return SELECTBOX_SELECTED_CLASS            },            _render: function() {                this.callBase();                this.element().addClass(SELECTBOX_CLASS);                this._renderTooltip()            },            _createPopup: function() {                this.callBase();                this._updatePopupPosition();                this._popup.element().addClass(SELECTBOX_POPUP_CLASS)            },            _popupWrapperClass: function() {                return this.callBase() + " " + SELECTBOX_POPUP_WRAPPER_CLASS            },            _renderOpenedState: function() {                this.callBase();                if (this.option("opened")) {                    this._updatePopupHeight();                    this._scrollToSelectedItem()                }            },            _updatePopupPosition: function() {                if (!this.option("_isAdaptableDropPosition") || this.option("dropPosition") !== this.initialOption("dropPosition"))                    return;                if (this.option("fieldEditEnabled") || this.option("searchEnabled")) {                    var adaptablePopupPosition = $.extend(this._getDefaultDropPosition(), {offset: {                                h: this.option("dropPosition").offset.h,                                v: -4                            }});                    this._setPopupOption("position", adaptablePopupPosition)                }                else                    this._setPopupOption("position", this.initialOption("dropPosition"))            },            _scrollToSelectedItem: function() {                if (this._dataSource.paginate() && this._isEditable())                    this._list.scrollTo(0);                else                    this._list.scrollToItem(this._$list.find("." + this._selectedItemClass()))            },            _renderInputValue: function() {                return this.callBase().always($.proxy(function() {                        this._renderTooltip();                        this._renderInputAddons()                    }, this))            },            _fitIntoRange: function(value, start, end) {                if (value > end)                    return start;                if (value < start)                    return end;                return value            },            _setNextValue: function(step) {                if (!this._dataSource.isLoaded())                    this._loadDataSource();                var item = this.option("selectedItem"),                    items = this._dataSource.items(),                    itemIndex = $.inArray(item, items),                    nextIndex = this._fitIntoRange(itemIndex + step, 0, items.length - 1);                this._setValue(this._valueGetter(items[nextIndex]))            },            _setSelectedItem: function(item) {                var isUnknownItem = !this._isCustomValueAllowed() && item === undefined;                this.callBase(isUnknownItem ? null : item)            },            _isCustomValueAllowed: function() {                return this.option("fieldEditEnabled") || this.option("displayCustomValue")            },            _displayValue: function(item) {                item = !DX.utils.isDefined(item) && this._isCustomValueAllowed() ? this.option("value") : item;                return this.callBase(item)            },            _listConfig: function() {                var result = $.extend(this.callBase(), {                        pageLoadMode: "scrollBottom",                        noDataText: "",                        onSelectionChanged: this._getSelectionChangeHandler(),                        selectionMode: "single"                    });                if (this.option("showSelectionControls"))                    $.extend(result, {showSelectionControls: true});                return result            },            _getSelectionChangeHandler: function() {                return this.option("showSelectionControls") ? $.proxy(this._selectionChangeHandler, this) : $.noop            },            _selectionChangeHandler: function(e) {                $.each(e.addedItems || [], $.proxy(function(_, addedItem) {                    this._setValue(this._valueGetter(addedItem))                }, this))            },            _toggleOpenState: function() {                this.callBase.apply(this, arguments);                if (this.option("opened") && this._isEditable())                    this._filterDataSource("")            },            _renderTooltip: function() {                if (this.option("tooltipEnabled"))                    this.element().attr("title", this.option("displayValue"))            },            _renderDimensions: function() {                this.callBase();                this._setPopupOption("width")            },            _renderInput: function() {                this.callBase();                this._$container.addClass(SELECTBOX_CONTAINER_CLASS);                this._input().off(BLUR_EVENT_NAME).on(BLUR_EVENT_NAME, $.proxy(this._fieldBlurHandler, this))            },            _fieldBlurHandler: function() {                if (this.option("searchEnabled") && !this.option("fieldEditEnabled")) {                    var selectedItem = this.option("selectedItem");                    this._renderInputValue().always($.proxy(function(e) {                        this._setSelectedItem(selectedItem);                        this._renderDisplayText(this._displayGetter(this.option("selectedItem")))                    }, this))                }            },            _renderValueChangeEvent: function() {                if (this._isEditable())                    this.callBase()            },            _isEditable: function() {                return this.option("fieldEditEnabled") || this.option("searchEnabled")            },            _fieldRenderData: function() {                return this.option("selectedItem")            },            _readOnlyPropValue: function() {                return !this._isEditable() || this.option("readOnly")            },            _isSelectedValue: function(value) {                return this._isValueEquals(value, this.option("value"))            },            _listItemClickHandler: function(e) {                this._completeSelection(this._valueGetter(e.itemData))            },            _completeSelection: function(value) {                if (value === undefined)                    value = this.option("fieldEditEnabled") && this._searchValue() ? this._searchValue() : this.option("value");                this.option("opened", false);                this._clearFilter();                this._setValue(value)            },            _setValue: function(value) {                this.option("value", value)            },            _clearValueHandler: function() {                this.reset()            },            _valueChangeEventHandler: function(e) {                if (CONTROL_KEY[e.which || e.keyCode])                    return;                if (this.option("fieldEditEnabled")) {                    this._valueUpdateSuppressed = true;                    this.callBase.apply(this, arguments);                    this._valueUpdateSuppressed = false                }                if (this.option("searchEnabled"))                    this._search()            },            _createClearButton: function() {                return this.callBase().on(CLICK_EVENT_NAME, function() {                        return false                    })            },            _optionChanged: function(args) {                switch (args.name) {                    case"_isAdaptableDropPosition":                        break;                    case"tooltipEnabled":                        this._renderTooltip();                        break;                    case"displayCustomValue":                    case"fieldEditEnabled":                    case"showSelectionControls":                        this._invalidate();                        break;                    default:                        this.callBase(args)                }            }        }))    })(jQuery, DevExpress);    /*! Module widgets-base, file ui.tagBox.js */    (function($, DX, undefined) {        var ui = DX.ui,            events = ui.events,            TAGBOX = "dxTagBox",            TAGBOX_TAG_DATA_KEY = "dxTagData",            TAGBOX_CLASS = "dx-tagbox",            TAGBOX_TAG_CONTAINER_CLASS = "dx-tag-container",            TAGBOX_TAG_CLASS = "dx-tag",            TAGBOX_TAG_CONTENT_CLASS = "dx-tag-content",            TAGBOX_TAG_REMOVE_BUTTON_CLASS = "dx-tag-remove-button",            TAGBOX_ONLY_SELECT_CLASS = "dx-tagbox-only-select",            EMPTY_INPUT_CLASS = "dx-texteditor-empty",            TAGBOX_TAG_REMOVE_CLICK_EVENT_NAME = events.addNamespace("dxclick", TAGBOX + "TagRemove");        var dxTagRemoveButton = ui.Widget.inherit({                _setDefaultOptions: function() {                    this.callBase();                    this.option({activeStateEnabled: true})                },                _render: function() {                    this.callBase();                    this.element().addClass(TAGBOX_TAG_REMOVE_BUTTON_CLASS)                }            });        DX.registerComponent(TAGBOX, ui, ui.dxSelectBox.inherit({            _supportedKeys: function() {                var parent = this.callBase();                return $.extend(parent, {                        backspace: function(e) {                            if (this._searchValue().length)                                return;                            e.preventDefault();                            e.stopPropagation();                            var values = this.option("values");                            this._removeTagWithUpdate(values[values.length - 1])                        },                        enter: function(e) {                            if (this.option("fieldEditEnabled") && !this._$list.find(".dx-state-focused").length)                                this._completeSelection();                            else                                this._keyboardProcessor._childProcessors[0].process(e)                        }                    })            },            _setNextValue: $.noop,            _setDefaultOptions: function() {                this.callBase();                this.option({                    values: [],                    onValuesChanged: null,                    showDropButton: false,                    tagTemplate: "tag",                    selectAllText: Globalize.localize("dxList-selectAll")                })            },            _init: function() {                this.callBase();                this._initValuesChangedAction();                this._initDynamicTagTemplate()            },            _initValuesChangedAction: function() {                this._valuesChangedAction = this._createActionByOption("onValuesChanged");                this._removeTagAction = this._createAction($.proxy(this._removeTagHandler, this))            },            _initDynamicTagTemplate: function() {                if (this._displayGetterExpr())                    this._dynamicTemplates["tag"] = new ui.DefaultTemplate($.proxy(function(data) {                        return this._displayGetter(data)                    }, this));                else                    delete this._dynamicTemplates["tag"]            },            _render: function() {                this.callBase();                this._updateValues();                this.element().addClass(TAGBOX_CLASS);                this.element().toggleClass(TAGBOX_ONLY_SELECT_CLASS, !(this.option("searchEnabled") || this.option("fieldEditEnabled")));                this.element().find(".dx-texteditor-container").off(TAGBOX_TAG_REMOVE_CLICK_EVENT_NAME).on(TAGBOX_TAG_REMOVE_CLICK_EVENT_NAME, "." + TAGBOX_TAG_REMOVE_BUTTON_CLASS, $.proxy(function(e) {                    this._removeTagAction({jQueryEvent: e})                }, this))            },            _renderInputValue: function() {                return this.callBase().always($.proxy(function() {                        this._renderMultiSelect()                    }, this))            },            _listContentReadyHandler: function() {                this._suppressingSelectionChanged(function() {                    this._valuesChangedAction = $.noop;                    this._setListOption("selectedItems", this._selectedItems)                });                this.callBase();                this._initValuesChangedAction()            },            _suppressingSelectionChanged: function(callback) {                this._setListOption("onSelectionChanged", $.noop);                callback.call(this);                this._setListOption("onSelectionChanged", this._getSelectionChangeHandler())            },            _listConfig: function() {                var config = this.callBase();                if (this.option("showSelectionControls"))                    $.extend(config, {                        selectionMode: "all",                        selectAllText: this.option("selectAllText")                    });                return config            },            _renderMultiSelect: function() {                this._$tagsContainer = this.element().find(".dx-texteditor-container").addClass(TAGBOX_TAG_CONTAINER_CLASS);                this._renderInputSize();                this._clearFilter();                this._renderTags();                this._popup && this._popup.repaint()            },            _renderInputSize: function() {                var $input = this._input();                $input.prop("size", $input.val() ? $input.val().length + 2 : 1)            },            _renderTags: function() {                this._cleanTags();                var $tagsBag = $("<div>");                this._selectedItems = [];                var itemLoadDeferreds = $.map(this._values(), $.proxy(function(value) {                        return this._renderTag(value, $tagsBag)                    }, this));                $tagsBag.children().insertBefore(this._input());                $.when.apply($, itemLoadDeferreds).done($.proxy(this._renderInputAddons, this));                this._renderEmptyState()            },            _renderEmptyState: function() {                var hasNoValues = !this._values().length;                this.element().toggleClass(EMPTY_INPUT_CLASS, hasNoValues);                this._placeholder().toggle(hasNoValues);                this._renderDisplayText()            },            _renderDisplayText: function() {                this._input().val("");                this._renderInputSize()            },            _cleanTags: function() {                var $tags = this._tagElements();                var values = this.option("values");                $.each($tags, function(_, tag) {                    var $tag = $(tag);                    if ($.inArray($tag.data(TAGBOX_TAG_DATA_KEY), values) < 0)                        $tag.remove()                })            },            _tagElements: function() {                return this.element().find("." + TAGBOX_TAG_CLASS)            },            _renderTag: function(value, $container) {                if (this._isTagRendered(value))                    return $.Deferred().resolve();                var $tag = $("<div>").addClass(TAGBOX_TAG_CLASS).data(TAGBOX_TAG_DATA_KEY, value).appendTo($container),                    tagTemplate = this._getTemplateByOption("tagTemplate");                var $tagContent = $("<div>").addClass(TAGBOX_TAG_CONTENT_CLASS).appendTo($tag);                $("<div>").dxTagRemoveButton().appendTo($tag);                return this._loadItem(value).always($.proxy(function(item) {                        item = DX.utils.isDefined(item) ? item : value;                        tagTemplate.render(item, $tagContent);                        this._selectedItems.push(item)                    }, this))            },            _isTagRendered: function(value) {                var $tags = this._tagElements();                var result = false;                $.each($tags, function(_, tag) {                    var $tag = $(tag);                    if (value === $tag.data(TAGBOX_TAG_DATA_KEY)) {                        result = true;                        return false                    }                });                return result            },            _toggleEmptinessEventHandler: function() {                this._toggleEmptiness(!this.option("values").length && !this._searchValue().length)            },            _removeTagHandler: function(args) {                var e = args.jQueryEvent;                e.stopPropagation();                var $tag = $(e.target).closest("." + TAGBOX_TAG_CLASS);                var itemValue = $tag.data(TAGBOX_TAG_DATA_KEY);                this._removeTagWithUpdate(itemValue)            },            _removeTagWithUpdate: function(itemValue) {                this._removeTag(itemValue);                this._suppressingSelectionChanged(function() {                    this._updateValues()                });                this.option("values", this.option("values"))            },            _selectionChangeHandler: function(e) {                $.each(e.removedItems || [], $.proxy(function(_, removedItem) {                    this._removeTag(this._valueGetter(removedItem))                }, this));                $.each(e.addedItems || [], $.proxy(function(_, addedItem) {                    this._addTag(this._valueGetter(addedItem))                }, this));                this.callBase(e);                this._updateValues();                this._valuesChangedAction(e)            },            _removeTag: function(value) {                this.option().value = value;                var values = this.option("values"),                    index = this._valueIndex(value);                if (index >= 0)                    values.splice(index, 1)            },            _addTag: function(value) {                var values = this.option("values"),                    index = this._valueIndex(value);                if (index < 0)                    values.push(value)            },            _fieldRenderData: function() {                return this._selectedItems            },            _setValue: function(value) {                if (value === null || this._isSelectedValue(value))                    return;                var values = this.option("values");                values.push(value);                this.option("values", values)            },            _isSelectedValue: function(value) {                return this._valueIndex(value) > -1            },            _valueIndex: function(value) {                var result = -1;                $.each(this._values(), $.proxy(function(index, selectedValue) {                    if (this._isValueEquals(value, selectedValue)) {                        result = index;                        return false                    }                }, this));                return result            },            _values: function() {                return this.option("values") || []            },            _optionValuesEqual: function(name, value, prevValue) {                if (name === "value")                    return false;                this.callBase(name, value, prevValue)            },            reset: function() {                this.option("values", []);                this.callBase()            },            _updateValues: function() {                var lastValue = this._lastValue() === undefined ? null : this._lastValue();                this.option("value", lastValue)            },            _lastValue: function() {                return this._values().slice(-1).pop()            },            _valueChangeEventHandler: function(e) {                this._renderInputSize();                if (this.option("fieldEditEnabled"))                    return;                this.callBase(e)            },            _valueChangeArgs: function() {                var result = this.callBase.apply(this, arguments);                delete result.previousValue;                return $.extend(result, {values: this.option("values")})            },            _optionChanged: function(args) {                switch (args.name) {                    case"displayExpr":                        this.callBase(args);                        this._initDynamicTagTemplate();                        this._invalidate();                        break;                    case"tagTemplate":                        this._initDynamicTagTemplate();                        this._invalidate();                        break;                    case"values":                        this._updateValues();                        break;                    case"onValuesChanged":                        this._initValuesChangedAction();                        break;                    case"selectAllText":                        this._setListOption("selectAllText", this.option("selectAllText"));                        break;                    default:                        this.callBase(args)                }            }        }));        DX.registerComponent("dxTagRemoveButton", ui[TAGBOX], dxTagRemoveButton)    })(jQuery, DevExpress);    /*! Module widgets-base, file ui.multiView.js */    (function($, DX, undefined) {        var ui = DX.ui,            utils = DX.utils,            fx = DX.fx,            translator = DX.translator;        var MULTIVIEW_CLASS = "dx-multiview",            MULTIVIEW_WRAPPER_CLASS = "dx-multiview-wrapper",            MULTIVIEW_ITEM_CONTAINER_CLASS = "dx-multiview-item-container",            MULTIVIEW_ITEM_CLASS = "dx-multiview-item",            MULTIVIEW_ITEM_HIDDEN_CLASS = "dx-multiview-item-hidden",            MULTIVIEW_ITEM_DATA_KEY = "dxMultiViewItemData",            MULTIVIEW_ANIMATION_DURATION = 200;        var toNumber = function(value) {                return +value            };        var position = function($element) {                return translator.locate($element).left            };        var move = function($element, position) {                translator.move($element, {left: position})            };        var animation = {                moveTo: function($element, position, duration, completeAction) {                    fx.animate($element, {                        type: "slide",                        to: {left: position},                        duration: duration,                        complete: completeAction                    })                },                complete: function($element) {                    fx.stop($element, true)                }            };        DX.registerComponent("dxMultiView", ui, ui.CollectionWidget.inherit({            _activeStateUnit: "." + MULTIVIEW_ITEM_CLASS,            _supportedKeys: function() {                return $.extend(this.callBase(), {                        pageUp: $.noop,                        pageDown: $.noop                    })            },            _setDefaultOptions: function() {                this.callBase();                this.option({                    selectedIndex: 0,                    swipeEnabled: true,                    animationEnabled: true,                    loop: false,                    _itemAttributes: {role: "tabpanel"},                    deferRendering: true,                    loopItemFocus: false,                    selectOnFocus: true,                    selectionMode: "single",                    selectionRequired: true,                    selectionByClick: false                })            },            _defaultOptionsRules: function() {                return this.callBase().concat([{                            device: function(device) {                                return DX.devices.real().generic && !DX.devices.isSimulator()                            },                            options: {focusStateEnabled: true}                        }])            },            _itemClass: function() {                return MULTIVIEW_ITEM_CLASS            },            _itemDataKey: function() {                return MULTIVIEW_ITEM_DATA_KEY            },            _itemContainer: function() {                return this._$itemContainer            },            _itemWidth: function() {                if (!this._itemWidthValue)                    this._itemWidthValue = this._$wrapper.width();                return this._itemWidthValue            },            _clearItemWidthCache: function() {                delete this._itemWidthValue            },            _itemsCount: function() {                return this.option("items").length            },            _normalizeIndex: function(index) {                var count = this._itemsCount();                if (index < 0)                    index = index + count;                if (index >= count)                    index = index - count;                return index            },            _getRTLSignCorrection: function() {                return this.option("rtlEnabled") ? -1 : 1            },            _init: function() {                this.callBase.apply(this, arguments);                var $element = this.element();                $element.addClass(MULTIVIEW_CLASS);                this._$wrapper = $("<div>").addClass(MULTIVIEW_WRAPPER_CLASS);                this._$wrapper.appendTo($element);                this._$itemContainer = $("<div>").addClass(MULTIVIEW_ITEM_CONTAINER_CLASS);                this._$itemContainer.appendTo(this._$wrapper);                this.option("loopItemFocus", this.option("loop"));                this._initSwipeable()            },            _render: function() {                this._deferredItems = [];                this.callBase()            },            _renderItemContent: function(index, itemData, $container) {                this._deferredItems.push($.Deferred());                this._deferredItems[index].done($.proxy(function(itemContentRenderer, args) {                    itemContentRenderer.apply(this, args)                }, this, this.callBase, arguments));                if (!this.option("deferRendering"))                    this._deferredItems[index].resolve()            },            _renderSelection: function(addedSelection) {                this._updateItems(addedSelection[0])            },            _updateItems: function(selectedIndex, newIndex) {                this._updateItemsPosition(selectedIndex, newIndex);                this._updateItemsVisibility(selectedIndex, newIndex)            },            _renderSpecificItem: function(index) {                var hasItemContent = this._itemElements().eq(index).find(this._itemContentClass()).length > 0;                if (DX.utils.isDefined(index) && !hasItemContent)                    this._deferredItems[index].resolve()            },            _updateItemsPosition: function(selectedIndex, newIndex) {                var $itemElements = this._itemElements(),                    positionSign = -this._animationDirection(newIndex, selectedIndex),                    $selectedItem = $itemElements.eq(selectedIndex);                move($selectedItem, 0);                move($itemElements.eq(newIndex), positionSign * 100 + "%")            },            _updateItemsVisibility: function(selectedIndex, newIndex) {                var $itemElements = this._itemElements();                $itemElements.each($.proxy(function(itemIndex, item) {                    var $item = $(item),                        isHidden = itemIndex !== selectedIndex && itemIndex !== newIndex;                    if (!isHidden)                        this._renderSpecificItem(itemIndex);                    $item.toggleClass(MULTIVIEW_ITEM_HIDDEN_CLASS, isHidden);                    this.setAria("hidden", isHidden || undefined, $item)                }, this))            },            _setAriaSelected: $.noop,            _updateSelection: function(addedSelection, removedSelection) {                var newIndex = addedSelection[0],                    prevIndex = removedSelection[0];                animation.complete(this._$itemContainer);                this._updateItems(prevIndex, newIndex);                var animationDirection = this._animationDirection(newIndex, prevIndex);                this._animateItemContainer(animationDirection * this._itemWidth(), $.proxy(function() {                    move(this._$itemContainer, 0);                    this._updateItems(newIndex);                    this._$itemContainer.width()                }, this))            },            _animateItemContainer: function(position, completeCallback) {                var duration = this.option("animationEnabled") ? MULTIVIEW_ANIMATION_DURATION : 0;                animation.moveTo(this._$itemContainer, position, duration, completeCallback)            },            _animationDirection: function(newIndex, prevIndex) {                var containerPosition = position(this._$itemContainer),                    indexDifference = (prevIndex - newIndex) * this._getRTLSignCorrection() * this._getItemFocusLoopSignCorrection(),                    isSwipePresent = containerPosition !== 0,                    directionSignVariable = isSwipePresent ? containerPosition : indexDifference;                return utils.sign(directionSignVariable)            },            _initSwipeable: function() {                this._createComponent(this.element(), "dxSwipeable", {                    disabled: !this.option("swipeEnabled"),                    elastic: false,                    itemSizeFunc: $.proxy(this._itemWidth, this),                    onStart: $.proxy(function(args) {                        this._swipeStartHandler(args.jQueryEvent)                    }, this),                    onUpdated: $.proxy(function(args) {                        this._swipeUpdateHandler(args.jQueryEvent)                    }, this),                    onEnd: $.proxy(function(args) {                        this._swipeEndHandler(args.jQueryEvent)                    }, this)                })            },            _swipeStartHandler: function(e) {                animation.complete(this._$itemContainer);                var selectedIndex = this.option("selectedIndex"),                    loop = this.option("loop"),                    lastIndex = this._itemsCount() - 1,                    rtl = this.option("rtlEnabled");                e.maxLeftOffset = toNumber(loop || (rtl ? selectedIndex > 0 : selectedIndex < lastIndex));                e.maxRightOffset = toNumber(loop || (rtl ? selectedIndex < lastIndex : selectedIndex > 0));                this._swipeDirection = null            },            _swipeUpdateHandler: function(e) {                var offset = e.offset,                    swipeDirection = utils.sign(offset) * this._getRTLSignCorrection();                move(this._$itemContainer, offset * 100 + "%");                if (swipeDirection !== this._swipeDirection) {                    this._swipeDirection = swipeDirection;                    var selectedIndex = this.option("selectedIndex"),                        newIndex = this._normalizeIndex(selectedIndex - swipeDirection);                    this._updateItems(selectedIndex, newIndex)                }            },            _swipeEndHandler: function(e) {                var targetOffset = e.targetOffset * this._getRTLSignCorrection();                if (targetOffset) {                    this.option("selectedIndex", this._normalizeIndex(this.option("selectedIndex") - targetOffset));                    var $selectedElement = this.itemElements().filter(".dx-item-selected");                    this.option("focusedElement", $selectedElement)                }                else                    this._animateItemContainer(0, $.noop)            },            _getItemFocusLoopSignCorrection: function() {                return this._itemFocusLooped ? -1 : 1            },            _moveFocus: function() {                this.callBase.apply(this, arguments);                this._itemFocusLooped = false            },            _prevItem: function($items) {                var $result = this.callBase.apply(this, arguments);                this._itemFocusLooped = $result.is($items.last());                return $result            },            _nextItem: function($items) {                var $result = this.callBase.apply(this, arguments);                this._itemFocusLooped = $result.is($items.first());                return $result            },            _dimensionChanged: function() {                this._clearItemWidthCache()            },            _visibilityChanged: function(visible) {                if (visible)                    this._dimensionChanged()            },            _optionChanged: function(args) {                var value = args.value;                switch (args.name) {                    case"loop":                        this.option("loopItemFocus", value);                        break;                    case"animationEnabled":                        break;                    case"swipeEnabled":                        this.element().dxSwipeable("option", "disabled", !value);                        break;                    case"deferRendering":                        this._invalidate();                        break;                    default:                        this.callBase(args)                }            }        }));        ui.dxMultiView.__internals = {animation: animation}    })(jQuery, DevExpress);    /*! Module widgets-base, file ui.validator.js */    (function($, DX, undefined) {        var ui = DX.ui,            validationEngine = DX.validationEngine;        var VALIDATOR_CLASS = "dx-validator";        DevExpress.ui.validation.defaultAdapter = DX.Class.inherit({            ctor: function(editor, validator) {                var that = this;                that.editor = editor;                that.validator = validator;                that.validationRequestsCallbacks = $.Callbacks();                var handler = function(params) {                        that.validationRequestsCallbacks.fire()                    };                editor.validationRequest.add(handler);                editor.on("disposing", function() {                    editor.validationRequest.remove(handler)                })            },            getValue: function() {                return this.editor.option("value")            },            getCurrentValidationError: function() {                return this.editor.option("validationError")            },            applyValidationResults: function(params) {                this.editor.option({                    isValid: params.isValid,                    validationError: params.brokenRule                })            },            reset: function() {                this.editor.reset()            },            focus: function() {                this.editor.focus()            }        });        var dxValidator = DX.DOMComponent.inherit({                _setDefaultOptions: function() {                    this.callBase();                    this.option({validationRules: []})                },                _init: function() {                    this.callBase();                    this._initGroupRegistration();                    this.focused = $.Callbacks();                    this._initAdapter()                },                _initGroupRegistration: function _initGroupRegistration() {                    var group = this._findGroup();                    if (!this._groupWasInit)                        this.on("disposing", function(args) {                            validationEngine.removeRegistredValidator(args.component._validationGroup, args.component)                        });                    if (!this._groupWasInit || this._validationGroup !== group) {                        validationEngine.removeRegistredValidator(this._validationGroup, this);                        this._groupWasInit = true;                        this._validationGroup = group;                        validationEngine.registerValidatorInGroup(group, this)                    }                },                _setOptionsByReference: function() {                    this.callBase();                    $.extend(this._optionsByReference, {validationGroup: true})                },                _initAdapter: function() {                    var that = this,                        dxStandardEditor = that.element().data("dx-validation-target"),                        adapter = that.option("adapter");                    if (!adapter) {                        if (dxStandardEditor) {                            adapter = new DevExpress.ui.validation.defaultAdapter(dxStandardEditor, this);                            adapter.validationRequestsCallbacks.add(function() {                                that.validate()                            });                            this.option("adapter", adapter);                            return                        }                        throw DX.Error("E0120");                    }                    if (adapter.validationRequestsCallbacks)                        adapter.validationRequestsCallbacks.add(function() {                            that.validate()                        })                },                _findGroup: DX.ui.validation.findGroup,                _render: function() {                    this.element().addClass(VALIDATOR_CLASS);                    this.callBase()                },                _optionChanged: function(args) {                    switch (args.name) {                        case"validationGroup":                            this._initGroupRegistration();                            return;                        case"validationRules":                            return;                        case"adapter":                            this._initAdapter();                            break;                        default:                            this.callBase(args)                    }                },                validate: function() {                    var that = this,                        adapter = that.option("adapter"),                        name = that.option("name"),                        value = adapter.getValue(),                        currentError = adapter.getCurrentValidationError && adapter.getCurrentValidationError(),                        rules = $.map(that.option("validationRules"), function(rule) {                            rule.validator = that;                            return rule                        }),                        result;                    if (currentError && currentError.editorSpecific) {                        currentError.validator = this;                        result = {                            isValid: false,                            brokenRule: currentError                        }                    }                    else                        result = validationEngine.validate(value, rules, name);                    this._applyValidationResult(result, adapter);                    return result                },                reset: function() {                    var that = this,                        adapter = that.option("adapter"),                        result = {                            isValid: true,                            brokenRule: null                        };                    adapter.reset();                    this._applyValidationResult(result, adapter)                },                _applyValidationResult: function(result, adapter) {                    var validatedAction = this._createActionByOption("onValidated");                    result.validator = this;                    adapter.applyValidationResults && adapter.applyValidationResults(result);                    this.option({isValid: result.isValid});                    validatedAction(result)                },                focus: function() {                    var adapter = this.option("adapter");                    adapter.focus()                }            });        DX.registerComponent("dxValidator", ui, dxValidator)    })(jQuery, DevExpress);    /*! Module widgets-base, file ui.validationGroup.js */    (function($, DX, undefined) {        var ui = DX.ui;        var VALIDATION_ENGINE_CLASS = "dx-validationgroup";        DX.registerComponent("dxValidationGroup", ui, DX.DOMComponent.inherit({            _setDefaultOptions: function() {                this.callBase();                this.option({})            },            _init: function() {                this.callBase()            },            _render: function() {                var $element = this.element();                $element.addClass(VALIDATION_ENGINE_CLASS);                $element.find(".dx-validator").each(function(_, validatorContainer) {                    $(validatorContainer).dxValidator("instance")._initGroupRegistration()                });                $element.find(".dx-validationsummary").each(function(_, summaryContainer) {                    $(summaryContainer).dxValidationSummary("instance")._initGroupRegistration()                });                this.callBase()            },            validate: function() {                return DX.validationEngine.validateGroup(this)            },            reset: function() {                return DX.validationEngine.resetGroup(this)            },            _optionChanged: function(args) {                switch (args.name) {                    default:                        this.callBase(args)                }            },            _dispose: function() {                DX.validationEngine.removeGroup(this);                this.element().removeClass(VALIDATION_ENGINE_CLASS);                this.callBase()            }        }))    })(jQuery, DevExpress);    /*! Module widgets-base, file ui.validationSummary.js */    (function($, DX, undefined) {        var ui = DX.ui;        var VALIDATION_SUMMARY_CLASS = "dx-validationsummary",            ITEM_CLASS = VALIDATION_SUMMARY_CLASS + "-item",            ITEM_DATA_KEY = VALIDATION_SUMMARY_CLASS + "-item-data";        DX.registerComponent("dxValidationSummary", ui, ui.CollectionWidget.inherit({            _setDefaultOptions: function() {                this.callBase();                this.option({                    focusStateEnabled: false,                    noDataText: null                })            },            _setOptionsByReference: function() {                this.callBase();                $.extend(this._optionsByReference, {validationGroup: true})            },            _findGroup: DX.ui.validation.findGroup,            _init: function() {                this.callBase();                this._initGroupRegistration()            },            _initGroupRegistration: function() {                var group = this._findGroup(),                    groupConfig = DX.validationEngine.addGroup(group);                this._unsubscribeGroup();                this._groupWasInit = true;                this._validationGroup = group;                this.groupSubscription = $.proxy(this._groupValidationHandler, this);                groupConfig.on("validated", this.groupSubscription)            },            _unsubscribeGroup: function() {                var groupConfig = DX.validationEngine.getGroupConfig(this._validationGroup);                groupConfig && groupConfig.off("validated", this.groupSubscription)            },            _getOrderedItems: function(validators, items) {                var orderedItems = [];                $.each(validators, function(_, validator) {                    var firstItem = $.grep(items, function(item) {                            if (item.validator === validator)                                return true                        })[0];                    if (firstItem)                        orderedItems.push(firstItem)                });                return orderedItems            },            _groupValidationHandler: function(params) {                var that = this,                    items = that._getOrderedItems(params.validators, $.map(params.brokenRules, function(rule) {                        return {                                text: rule.message,                                validator: rule.validator                            }                    }));                that.validators = params.validators;                $.each(that.validators, function(_, validator) {                    var handler = $.proxy(that._itemValidationHandler, that),                        disposingHandler = function() {                            validator.off("validated", handler);                            handler = null                        };                    validator.on("validated", handler);                    validator.on("disposing", disposingHandler)                });                that.option("items", items)            },            _itemValidationHandler: function(itemValidationResult) {                var items = this.option("items"),                    isValid = itemValidationResult.isValid,                    elementIndex,                    replacementFound = false,                    newMessage = itemValidationResult.brokenRule && itemValidationResult.brokenRule.message,                    validator = itemValidationResult.validator;                if (isValid) {                    $.each(items, function(index, item) {                        if (item.validator === validator) {                            elementIndex = index;                            replacementFound = true;                            return false                        }                    });                    if (replacementFound)                        items.splice(elementIndex, 1)                }                else {                    $.each(items, function(index, item) {                        if (item.validator === validator) {                            item.text = newMessage;                            replacementFound = true;                            return false                        }                    });                    if (!replacementFound)                        items.push({                            text: newMessage,                            validator: validator                        })                }                items = this._getOrderedItems(this.validators, items);                this.option("items", items)            },            _render: function() {                this.element().addClass(VALIDATION_SUMMARY_CLASS);                this.callBase()            },            _optionChanged: function(args) {                switch (args.name) {                    case"validationGroup":                        this._initGroupRegistration();                        break;                    default:                        this.callBase(args)                }            },            _itemClass: function() {                return ITEM_CLASS            },            _itemDataKey: function() {                return ITEM_DATA_KEY            },            _postprocessRenderItem: function(params) {                params.itemElement.on("click", function() {                    params.itemData.validator.focus()                })            },            _dispose: function() {                this.callBase();                this._unsubscribeGroup()            }        }))    })(jQuery, DevExpress);    /*! Module widgets-base, file ui.fileUploader.js */    (function($, DX, undefined) {        var ui = DX.ui,            utils = DX.utils;        var FILEUPLOADER_CLASS = "dx-fileuploader",            FILEUPLOADER_EMPTY_CLASS = "dx-fileuploader-empty",            FILEUPLOADER_DRAGOVER = "dx-fileuploader-dragover",            FILEUPLOADER_FILEINPUT_TAG = "<input type='file'>",            FILEUPLOADER_WRAPPER_CLASS = "dx-fileuploader-wrapper",            FILEUPLOADER_CONTAINER_CLASS = "dx-fileuploader-container",            FILEUPLOADER_CONTENT_CLASS = "dx-fileuploader-content",            FILEUPLOADER_INPUT_WRAPPER_CLASS = "dx-fileuploader-input-wrapper",            FILEUPLOADER_INPUT_CONTAINER_CLASS = "dx-fileuploader-input-container",            FILEUPLOADER_INPUT_LABEL_CLASS = "dx-fileuploader-input-label",            FILEUPLOADER_INPUT_CLASS = "dx-fileuploader-input",            FILEUPLOADER_FILES_CONTAINER_CLASS = "dx-fileuploader-files-container",            FILEUPLOADER_FILE_CONTAINER_CLASS = "dx-fileuploader-file-container",            FILEUPLOADER_FILE_INFO_CLASS = "dx-fileuploader-file-info",            FILEUPLOADER_FILE_STATUS_CLASS = "dx-fileuploader-file-status",            FILEUPLOADER_FILE_STATUS_MESSAGE_CLASS = "dx-fileuploader-file-status-message",            FILEUPLOADER_FILE_CLASS = "dx-fileuploader-file",            FILEUPLOADER_FILE_NAME_CLASS = "dx-fileuploader-file-name",            FILEUPLOADER_FILE_SIZE_CLASS = "dx-fileuploader-file-size",            FILEUPLOADER_BUTTON_CLASS = "dx-fileuploader-button",            FILEUPLOADER_BUTTON_CONTAINER_CLASS = "dx-fileuploader-button-container",            FILEUPLOADER_CANCEL_BUTTON_CLASS = "dx-fileuploader-cancel-button",            FILEUPLOADER_UPLOAD_BUTTON_CLASS = "dx-fileuploader-upload-button",            FILEUPLOADER_AFTER_LOAD_DELAY = 400;        var isFormDataSupported = function() {                return !!window.FormData            },            getFormDataPrototype = function() {                return FormData            },            getRequestPrototype = function() {                return XMLHttpRequest            };        DX.registerComponent("dxFileUploader", ui, ui.Editor.inherit({            _supportedKeys: function() {                var click = function(e) {                        e.preventDefault();                        if (this._$button)                            this._$button.click()                    };                return $.extend(this.callBase(), {                        space: click,                        enter: click                    })            },            _setDeprecatedOptions: function() {                this.callBase();                $.extend(this._deprecatedOptions, {buttonText: {                        since: "15.1",                        alias: "selectButtonText"                    }})            },            _setDefaultOptions: function() {                this.callBase();                this.option({                    value: null,                    values: [],                    selectButtonText: Globalize.localize("dxFileUploader-selectFile"),                    uploadButtonText: Globalize.localize("dxFileUploader-upload"),                    labelText: Globalize.localize("dxFileUploader-dropFile"),                    name: "files[]",                    multiple: false,                    accept: "",                    uploadUrl: "/",                    allowCanceling: true,                    showFileList: true,                    progress: 0,                    readyToUploadMessage: Globalize.localize("dxFileUploader-readyToUpload"),                    uploadedMessage: Globalize.localize("dxFileUploader-uploaded"),                    uploadFailedMessage: Globalize.localize("dxFileUploader-uploadFailedMessage"),                    uploadMode: "instantly"                })            },            _defaultOptionsRules: function() {                return this.callBase().concat([{                            device: function(device) {                                return DX.devices.real().generic && !DX.devices.isSimulator()                            },                            options: {focusStateEnabled: true}                        }])            },            _init: function() {                this.option("value", null);                this.option("values", []);                this.callBase.apply(this, arguments);                this._initFileInput();                this._initLabel();                this._initDragEvents();                this._createFiles();                this.element().addClass(FILEUPLOADER_CLASS)            },            _initFileInput: function() {                if (!this._$fileInput) {                    this._$fileInput = $(FILEUPLOADER_FILEINPUT_TAG);                    this._$fileInput.on("change", $.proxy(this._inputChangeHandler, this));                    this._$fileInput.on("click", $.proxy(function() {                        var isCustomEvent = this._isCustomEvent || false;                        this._isCustomEvent = false;                        return isCustomEvent                    }, this))                }                this._$fileInput.prop({                    multiple: this.option("multiple"),                    name: this.option("name"),                    accept: this.option("accept")                })            },            _inputChangeHandler: function(e) {                if (this._doPreventInputChange)                    return;                var fileName = this._$fileInput.val().replace(/^.*\\/, ''),                    files = this._$fileInput.prop("files"),                    values = [];                if (files && !files.length)                    return;                if (files)                    $.each(files, function(_, value) {                        values.push(value)                    });                else                    values = [{name: fileName}];                this._shouldChangeValue = true;                this.option("values", values);                delete this._shouldChangeValue;                if (this.option("uploadMode") === "instantly")                    this._uploadFiles()            },            _initLabel: function() {                if (!this._$inputLabel)                    this._$inputLabel = $("<div>");                this._$inputLabel.text(this.option("labelText"))            },            _initDragEvents: function() {                if (DX.devices.real().platform !== "generic" || DX.browser.msie)                    return;                this._dragEventsCount = 0;                this.element().on("dragenter", $.proxy(this._dragEnterHandler, this)).on("dragleave", $.proxy(this._dragLeaveHandler, this)).on("drop", $.proxy(this._dropHandler, this))            },            _dragEnterHandler: function() {                if (this.option("disabled"))                    return false;                this._dragEventsCount++;                this.element().addClass(FILEUPLOADER_DRAGOVER)            },            _dragLeaveHandler: function() {                this._dragEventsCount--;                if (this._dragEventsCount <= 0)                    this.element().removeClass(FILEUPLOADER_DRAGOVER)            },            _dropHandler: function() {                this._dragEventsCount = 0;                this.element().removeClass(FILEUPLOADER_DRAGOVER)            },            _focusTarget: function() {                return this.element().find("." + FILEUPLOADER_BUTTON_CLASS)            },            _render: function() {                this._renderWrapper();                this._renderInputWrapper();                this._renderSelectButton();                this._renderInputContainer();                this._renderFiles();                this._renderUploadButton();                this.callBase.apply(this, arguments)            },            _createFiles: function() {                this._files = [];                $.each(this.option("values"), $.proxy(function(_, value) {                    this._files.push(this._createFile(value))                }, this))            },            _createFile: function(value) {                return {                        value: value,                        loadedSize: 0,                        onProgress: $.Callbacks(),                        onLoad: $.Callbacks(),                        onError: $.Callbacks(),                        onLoadStart: $.Callbacks()                    }            },            _renderFiles: function() {                if (!this._$filesContainer)                    this._$filesContainer = $("<div>").addClass(FILEUPLOADER_FILES_CONTAINER_CLASS).appendTo(this._$content);                else                    this._$filesContainer.empty();                if (this.option("showFileList")) {                    var that = this;                    $.each(this._files, function(_, file) {                        that._renderFile(file)                    })                }                this.element().toggleClass(FILEUPLOADER_EMPTY_CLASS, !this._files.length);                this._updateFileNameMaxWidth()            },            _renderFile: function(file) {                var value = file.value;                var $fileContainer = $("<div>").addClass(FILEUPLOADER_FILE_CONTAINER_CLASS).appendTo(this._$filesContainer);                this._renderFileButtons(file, $fileContainer);                file.$file = $("<div>").addClass(FILEUPLOADER_FILE_CLASS).appendTo($fileContainer);                var $fileInfo = $("<div>").addClass(FILEUPLOADER_FILE_INFO_CLASS).appendTo(file.$file);                file.$statusMessage = $("<div>").addClass(FILEUPLOADER_FILE_STATUS_MESSAGE_CLASS).text(this.option("readyToUploadMessage")).appendTo(file.$file);                $("<div>").addClass(FILEUPLOADER_FILE_NAME_CLASS).text(value.name).appendTo($fileInfo);                if (utils.isDefined(value.size))                    $("<div>").addClass(FILEUPLOADER_FILE_SIZE_CLASS).text(this._getFileSize(value.size)).appendTo($fileInfo)            },            _updateFileNameMaxWidth: function() {                var cancelButtonsCount = this.option("allowCanceling") ? 1 : 0,                    uploadButtonsCount = this.option("uploadMode") === "useButtons" ? 1 : 0,                    filesContainerWidth = this._$filesContainer.width(),                    $buttonContainer = this._$filesContainer.find("." + FILEUPLOADER_BUTTON_CONTAINER_CLASS).eq(0),                    buttonsWidth = $buttonContainer.width() * (cancelButtonsCount + uploadButtonsCount),                    $fileSize = this._$filesContainer.find("." + FILEUPLOADER_FILE_SIZE_CLASS).eq(0);                var prevFileSize = $fileSize.text();                $fileSize.text("1000Mb");                var fileSizeWidth = $fileSize.width();                $fileSize.text(prevFileSize);                this._$filesContainer.find("." + FILEUPLOADER_FILE_NAME_CLASS).css("max-width", filesContainerWidth - buttonsWidth - fileSizeWidth)            },            _renderFileButtons: function(file, $container) {                file.cancelButton = this._createComponent($("<div>").addClass(FILEUPLOADER_BUTTON_CLASS + " " + FILEUPLOADER_CANCEL_BUTTON_CLASS), "dxButton", {                    onClick: $.proxy(function() {                        this._removeFile(file)                    }, this),                    icon: "close",                    visible: this.option("allowCanceling"),                    _templates: {}                });                $("<div>").addClass(FILEUPLOADER_BUTTON_CONTAINER_CLASS).append(file.cancelButton.element()).appendTo($container);                if (this.option("uploadMode") === "useButtons") {                    file.uploadButton = this._createComponent($("<div>").addClass(FILEUPLOADER_BUTTON_CLASS + " " + FILEUPLOADER_UPLOAD_BUTTON_CLASS), "dxButton", {                        onClick: $.proxy(function(e) {                            this._uploadFile(file)                        }, this),                        icon: "upload"                    });                    $("<div>").addClass(FILEUPLOADER_BUTTON_CONTAINER_CLASS).append(file.uploadButton.element()).appendTo($container);                    file.onLoadStart.add($.proxy(function() {                        file.uploadButton.element().remove()                    }, this))                }            },            _removeFile: function(file) {                file.$file.parent().remove();                var values = this.option("values");                values.splice($.inArray(file.value, values), 1);                this._files.splice($.inArray(file, this._files), 1);                this.element().toggleClass(FILEUPLOADER_EMPTY_CLASS, !this._files.length);                this._recalculateProgress();                this._doPreventInputChange = true;                this._$fileInput.val("");                this._doPreventInputChange = false            },            _getFileSize: function(size) {                var i = 0,                    labels = [Globalize.localize("dxFileUploader-bytes"), Globalize.localize("dxFileUploader-kb"), Globalize.localize("dxFileUploader-Mb"), Globalize.localize("dxFileUploader-Gb")],                    count = labels.length - 1;                while (i < count && size >= 1024) {                    size /= 1024;                    i++                }                return Math.round(size) + labels[i]            },            _renderSelectButton: function() {                var $button = $("<div>").addClass(FILEUPLOADER_BUTTON_CLASS).appendTo(this._$inputWrapper);                $button.off("click").on("click", $.proxy(this._selectButtonClickHandler, this));                this._selectButton = this._createComponent($button, "dxButton", {                    text: this.option("selectButtonText"),                    focusStateEnabled: false,                    _templates: {}                })            },            _selectButtonClickHandler: function() {                if (this.option("disabled"))                    return false;                this._isCustomEvent = true;                this._$fileInput.click()            },            _renderUploadButton: function() {                if (this.option("uploadMode") !== "useButtons")                    return;                var $uploadButton = $("<div>").addClass(FILEUPLOADER_BUTTON_CLASS).addClass(FILEUPLOADER_UPLOAD_BUTTON_CLASS).appendTo(this._$content);                this._uploadButton = this._createComponent($uploadButton, "dxButton", {                    text: this.option("uploadButtonText"),                    onClick: $.proxy(this._uploadButtonClickHandler, this),                    _templates: {}                })            },            _uploadButtonClickHandler: function() {                this._uploadFiles()            },            _renderInputContainer: function() {                this._$inputContainer = $("<div>").addClass(FILEUPLOADER_INPUT_CONTAINER_CLASS).appendTo(this._$inputWrapper);                if (DX.browser.msie)                    this._$inputContainer.css("display", "none");                this._$fileInput.addClass(FILEUPLOADER_INPUT_CLASS).appendTo(this._$inputContainer);                this._$inputLabel.addClass(FILEUPLOADER_INPUT_LABEL_CLASS).appendTo(this._$inputContainer)            },            _renderInputWrapper: function() {                this._$inputWrapper = $("<div>").addClass(FILEUPLOADER_INPUT_WRAPPER_CLASS).appendTo(this._$content)            },            _renderWrapper: function() {                var $wrapper = $("<div>").addClass(FILEUPLOADER_WRAPPER_CLASS).appendTo(this.element());                var $container = $("<div>").addClass(FILEUPLOADER_CONTAINER_CLASS).appendTo($wrapper);                this._$content = $("<div>").addClass(FILEUPLOADER_CONTENT_CLASS).appendTo($container)            },            _clean: function() {                this._$fileInput.detach();                delete this._$filesContainer;                this.callBase.apply(this, arguments)            },            _uploadFiles: function() {                if (!isFormDataSupported())                    return;                $.each(this._files, $.proxy(function(_, file) {                    this._uploadFile(file)                }, this))            },            _uploadFile: function(file) {                if (file.progressBar)                    return;                var $file = file.$file,                    value = file.value;                this._initUploadRequest(file);                if ($file) {                    file.progressBar = this._createProgressBar(value.size);                    file.progressBar.element().appendTo($file);                    this._initStatusMessage(file);                    this._initCancelButton(file);                    file.onError.add($.proxy(this._onErrorHandler, this, file))                }                file.onProgress.add($.proxy(this._onProgressHandler, this, file));                file.request.send(this._createFormData(this.option("name"), value))            },            _onErrorHandler: function(file) {                var that = this;                setTimeout(function() {                    file.$statusMessage.text(that.option("uploadFailedMessage"));                    file.$statusMessage.css("display", "");                    file.progressBar.element().remove()                }, FILEUPLOADER_AFTER_LOAD_DELAY)            },            _onLoadedHandler: function(file) {                var that = this;                setTimeout(function() {                    file.$statusMessage.text(that.option("uploadedMessage"));                    file.$statusMessage.css("display", "");                    file.progressBar.element().remove()                }, FILEUPLOADER_AFTER_LOAD_DELAY)            },            _onProgressHandler: function(file, e) {                var totalSize = this._getTotalSize(),                    currentLoadedSize = 0,                    loadedSize = this._getLoadedSize(),                    progress = 0;                if (file) {                    currentLoadedSize = Math.min(e.loaded, file.value.size);                    loadedSize += currentLoadedSize - file.loadedSize;                    file.progressBar && file.progressBar.option({                        value: currentLoadedSize,                        showStatus: true                    });                    file.loadedSize = currentLoadedSize                }                if (totalSize)                    progress = Math.round(loadedSize / totalSize * 100);                this.option("progress", progress);                this._setLoadedSize(loadedSize)            },            _initStatusMessage: function(file) {                file.$statusMessage.css("display", "none");                file.onLoad.add($.proxy(this._onLoadedHandler, this, file))            },            _initCancelButton: function(file) {                var cancelClickHandler = $.proxy(function() {                        file.request.abort();                        this._removeFile(file)                    }, this);                file.cancelButton.option("onClick", cancelClickHandler);                var hideCancelButton = function() {                        setTimeout(function() {                            file.cancelButton.option({visible: false})                        }, FILEUPLOADER_AFTER_LOAD_DELAY)                    };                file.onLoad.add(hideCancelButton);                file.onError.add(hideCancelButton)            },            _initUploadRequest: function(file) {                file.request = this._createRequest(this.option("uploadUrl"));                file.loadedSize = 0;                file.request.onreadystatechange = $.proxy(function(e) {                    if (e.currentTarget.readyState === 4)                        if (e.currentTarget.status === 200)                            this.onLoad.fire(e);                        else                            this.onError.fire(e)                }, file);                file.request.upload.onprogress = $.proxy(function(e) {                    this.onProgress.fire(e)                }, file);                file.request.upload.onloadstart = $.proxy(function(e) {                    this.onLoadStart.fire(e)                }, file)            },            _createRequest: function(url) {                var Request = getRequestPrototype(),                    request = new Request;                request.open("POST", url, true);                return request            },            _createFormData: function(fieldName, fieldValue) {                var FormData = getFormDataPrototype(),                    formData = new FormData;                formData.append(fieldName, fieldValue);                return formData            },            _createProgressBar: function(fileSize) {                return this._createComponent($("<div>"), "dxProgressBar", {                        value: undefined,                        min: 0,                        max: fileSize,                        statusFormat: function(ratio) {                            return Math.round(ratio * 100) + "%"                        },                        showStatus: false,                        statusPosition: "right"                    })            },            _getTotalSize: function() {                if (!this._totalSize) {                    var files = this.option("values"),                        totalSize = 0;                    $.each(files, function(_, file) {                        totalSize += file.size                    });                    this._totalSize = totalSize                }                return this._totalSize            },            _getLoadedSize: function() {                if (!this._loadedSize) {                    var loadedSize = 0;                    $.each(this._files, function(_, file) {                        loadedSize += file.loadedSize                    });                    this._loadedSize = loadedSize                }                return this._loadedSize            },            _setLoadedSize: function(value) {                this._loadedSize = value            },            _recalculateProgress: function() {                delete this._totalSize;                delete this._loadedSize;                this._onProgressHandler()            },            _optionChanged: function(args) {                var value = args.value;                switch (args.name) {                    case"height":                    case"width":                        this._updateFileNameMaxWidth();                        this.callBase(args);                        break;                    case"value":                        if (!this._shouldChangeValue) {                            this._$fileInput.val("");                            this.option("values", [])                        }                        this.callBase(args);                        break;                    case"values":                        if (value.length && !this._shouldChangeValue)                            this.option("values", []);                        else {                            this._createFiles();                            this._renderFiles();                            this.option("value", value[0] || null);                            this._recalculateProgress()                        }                        break;                    case"name":                    case"accept":                        this._initFileInput();                        break;                    case"multiple":                        this._initFileInput();                        if (!args.value)                            this.option("values", []);                        break;                    case"selectButtonText":                        this._selectButton.option("text", value);                        break;                    case"uploadButtonText":                        this._uploadButton && this._uploadButton.option("text", value);                        break;                    case"readyToUploadMessage":                    case"uploadedMessage":                    case"uploadFailedMessage":                        this._invalidate();                        break;                    case"labelText":                        this._$inputLabel.text(value);                        break;                    case"showFileList":                        this._renderFiles();                        break;                    case"uploadUrl":                    case"progress":                        break;                    case"allowCanceling":                    case"uploadMode":                        this.reset();                        this._invalidate();                        break;                    default:                        this.callBase(args)                }            },            _valueChangeArgs: function() {                return $.extend(this.callBase.apply(this, arguments), {values: this.option("values")})            }        }));        ui.dxFileUploader.__internals = {            FILEUPLOADER_CLASS: FILEUPLOADER_CLASS,            FILEUPLOADER_EMPTY_CLASS: FILEUPLOADER_EMPTY_CLASS,            FILEUPLOADER_DRAGOVER: FILEUPLOADER_DRAGOVER,            FILEUPLOADER_WRAPPER_CLASS: FILEUPLOADER_WRAPPER_CLASS,            FILEUPLOADER_CONTAINER_CLASS: FILEUPLOADER_CONTAINER_CLASS,            FILEUPLOADER_CONTENT_CLASS: FILEUPLOADER_CONTENT_CLASS,            FILEUPLOADER_INPUT_WRAPPER_CLASS: FILEUPLOADER_INPUT_WRAPPER_CLASS,            FILEUPLOADER_INPUT_CONTAINER_CLASS: FILEUPLOADER_INPUT_CONTAINER_CLASS,            FILEUPLOADER_INPUT_LABEL_CLASS: FILEUPLOADER_INPUT_LABEL_CLASS,            FILEUPLOADER_INPUT_CLASS: FILEUPLOADER_INPUT_CLASS,            FILEUPLOADER_FILES_CONTAINER_CLASS: FILEUPLOADER_FILES_CONTAINER_CLASS,            FILEUPLOADER_FILE_CONTAINER_CLASS: FILEUPLOADER_FILE_CONTAINER_CLASS,            FILEUPLOADER_FILE_CLASS: FILEUPLOADER_FILE_CLASS,            FILEUPLOADER_FILE_NAME_CLASS: FILEUPLOADER_FILE_NAME_CLASS,            FILEUPLOADER_FILE_SIZE_CLASS: FILEUPLOADER_FILE_SIZE_CLASS,            FILEUPLOADER_BUTTON_CLASS: FILEUPLOADER_BUTTON_CLASS,            FILEUPLOADER_CANCEL_BUTTON_CLASS: FILEUPLOADER_CANCEL_BUTTON_CLASS,            FILEUPLOADER_UPLOAD_BUTTON_CLASS: FILEUPLOADER_UPLOAD_BUTTON_CLASS,            FILEUPLOADER_FILE_INFO_CLASS: FILEUPLOADER_FILE_INFO_CLASS,            FILEUPLOADER_FILE_STATUS_CLASS: FILEUPLOADER_FILE_STATUS_CLASS,            FILEUPLOADER_FILE_STATUS_MESSAGE_CLASS: FILEUPLOADER_FILE_STATUS_MESSAGE_CLASS,            getFormDataPrototype: getFormDataPrototype,            getRequestPrototype: getRequestPrototype,            isFormDataSupported: isFormDataSupported,            changeFileInputTag: function(tag) {                FILEUPLOADER_FILEINPUT_TAG = tag            },            resetFileInputTag: function() {                FILEUPLOADER_FILEINPUT_TAG = "<input type='file'>"            },            changeRequestClass: function(requestClass) {                getRequestPrototype = function() {                    return requestClass                }            },            resetRequestClass: function() {                getRequestPrototype = this.getRequestPrototype            },            changeFormDataClass: function(customFormData) {                getFormDataPrototype = function() {                    return customFormData                }            },            resetFormDataClass: function() {                getFormDataPrototype = this.getFormDataPrototype            }        }    })(jQuery, DevExpress);    /*! Module widgets-base, file ui.tabPanel.js */    (function($, DX, undefined) {        var ui = DX.ui;        var TABPANEL_CLASS = "dx-tabpanel";        DX.registerComponent("dxTabPanel", ui, ui.dxMultiView.inherit({            _setDeprecatedOptions: function() {                this.callBase();                $.extend(this._deprecatedOptions, {titleTemplate: {                        since: "14.2",                        alias: "itemTitleTemplate"                    }})            },            _setDefaultOptions: function() {                this.callBase();                this.option({                    itemTitleTemplate: "title",                    onTitleClick: null,                    onTitleHold: null,                    onTitleRendered: null                })            },            _defaultOptionsRules: function() {                return this.callBase().concat([{                            device: function(device) {                                return DX.devices.real().generic && !DX.devices.isSimulator()                            },                            options: {focusStateEnabled: true}                        }, {                            device: function(device) {                                return !DX.support.touch                            },                            options: {swipeEnabled: false}                        }, {                            device: {platform: "generic"},                            options: {animationEnabled: false}                        }])            },            _init: function() {                this.callBase();                this.element().addClass(TABPANEL_CLASS);                this.setAria("role", "tabpanel");                this._renderBox()            },            _renderBox: function() {                var $box = $("<div>").appendTo(this.element());                this._box = this._createComponent($box, "dxBox", {                    direction: "col",                    align: "flex-start",                    crossAlign: "stretch",                    items: [{                            ratio: 0,                            shrink: 0,                            baseSize: "auto",                            template: $.proxy(function() {                                var $tabs = $("<div>");                                this._tabs = this._createComponent($tabs, "dxTabs", this._tabConfig());                                return $tabs                            }, this)                        }, {                            ratio: 1,                            shrink: 1,                            baseSize: "auto",                            template: $.proxy(function(_, __, $content) {                                this._$wrapper.addClass($content.attr("class"));                                $content.replaceWith(this._$wrapper)                            }, this)                        }],                    height: "100%"                })            },            _refreshActiveDescendant: function() {                var tabs = this._tabs,                    tabItems = tabs.itemElements(),                    $activeTab = $(tabItems[tabs.option("selectedIndex")]),                    id = this.getFocusedItemId();                this.setAria("controls", undefined, $(tabItems));                this.setAria("controls", id, $activeTab)            },            _tabConfig: function() {                return {                        selectOnFocus: true,                        focusStateEnabled: this.option("focusStateEnabled"),                        tabIndex: this.option("tabIndex"),                        selectedIndex: this.option("selectedIndex"),                        onItemClick: this.option("onTitleClick"),                        onItemHold: this.option("onTitleHold"),                        itemHoldTimeout: this.option("itemHoldTimeout"),                        onSelectionChanged: $.proxy(function(e) {                            this.option("selectedIndex", e.component.option("selectedIndex"));                            this._refreshActiveDescendant()                        }, this),                        onItemRendered: this.option("onTitleRendered"),                        itemTemplate: this._getTemplateByOption("itemTitleTemplate"),                        items: this.option("items"),                        scrollingEnabled: false,                        itemTemplateProperty: "tabTemplate",                        selectionRequired: true,                        onOptionChanged: $.proxy(function(args) {                            var name = args.name,                                value = args.value;                            if (name === "focusedElement") {                                var id = value ? value.index() : value;                                var newItem = value ? this._itemElements().eq(id) : value;                                this.option("focusedElement", newItem)                            }                        }, this),                        onFocusIn: $.proxy(this._focusInHandler, this),                        onFocusOut: $.proxy(this._focusOutHandler, this)                    }            },            _renderFocusTarget: function() {                this._focusTarget().attr("tabindex", -1);                this._refreshActiveDescendant()            },            _setTabsOption: function(name, value) {                if (this._tabs)                    this._tabs.option(name, value)            },            _updateSelection: function() {                this.callBase.apply(this, arguments);                this._box.repaint()            },            _optionChanged: function(args) {                var name = args.name,                    value = args.value;                switch (name) {                    case"dataSource":                        this.callBase(args);                        break;                    case"items":                    case"selectedIndex":                    case"selectedItem":                    case"itemHoldTimeout":                    case"focusStateEnabled":                        this._setTabsOption(name, value);                        this.callBase(args);                        break;                    case"focusedElement":                        var id = value ? value.index() : value;                        var newItem = value ? this._tabs._itemElements().eq(id) : value;                        this._setTabsOption("focusedElement", newItem);                        this.callBase(args);                        this._tabs.focus();                        break;                    case"itemTitleTemplate":                        this._setTabsOption("itemTemplate", this._getTemplateByOption("itemTitleTemplate"));                        break;                    case"onTitleClick":                        this._setTabsOption("onItemClick", value);                        break;                    case"onTitleHold":                        this._setTabsOption("onItemHold", value);                        break;                    case"onTitleRendered":                        this._setTabsOption("onItemRendered", value);                        break;                    default:                        this.callBase(args)                }            }        }))    })(jQuery, DevExpress);    DevExpress.MOD_WIDGETS_BASE = true}if (!DevExpress.MOD_WIDGETS_MOBILE) {    if (!DevExpress.MOD_WIDGETS_BASE)        throw Error('Required module is not referenced: widgets-base');    /*! Module widgets-mobile, file ui.pivotTabs.js */    (function($, DX, undefined) {        var ui = DX.ui,            fx = DX.fx,            translator = DX.translator,            events = ui.events;        var PIVOT_TABS_CLASS = "dx-pivottabs",            PIVOT_TAB_CLASS = "dx-pivottabs-tab",            PIVOT_TAB_SELECTED_CLASS = "dx-pivottabs-tab-selected",            PIVOT_GHOST_TAB_CLASS = "dx-pivottabs-ghosttab",            PIVOT_TAB_DATA_KEY = "dxPivotTabData",            PIVOT_TAB_MOVE_DURATION = 200,            PIVOT_TAB_MOVE_EASING = "cubic-bezier(.40, .80, .60, 1)";        var animation = {                moveTo: function($tab, position, completeAction) {                    return fx.animate($tab, {                            type: "slide",                            to: {left: position},                            duration: PIVOT_TAB_MOVE_DURATION,                            easing: PIVOT_TAB_MOVE_EASING,                            complete: completeAction                        })                },                slideAppear: function($tab, position) {                    return fx.animate($tab, {                            type: "slide",                            to: {                                left: position,                                opacity: 1                            },                            duration: PIVOT_TAB_MOVE_DURATION,                            easing: PIVOT_TAB_MOVE_EASING                        })                },                slideDisappear: function($tab, position) {                    return fx.animate($tab, {                            type: "slide",                            to: {                                left: position,                                opacity: 0                            },                            duration: PIVOT_TAB_MOVE_DURATION,                            easing: PIVOT_TAB_MOVE_EASING                        })                },                complete: function(elements) {                    if (!elements)                        return;                    $.each(elements, function(_, $element) {                        fx.stop($element, true)                    })                },                stop: function(elements) {                    if (!elements)                        return;                    $.each(elements, function(_, $element) {                        fx.stop($element)                    })                }            };        DX.registerComponent("dxPivotTabs", ui, ui.CollectionWidget.inherit({            _setDefaultOptions: function() {                this.callBase();                this.option({                    selectedIndex: 0,                    onPrepare: null,                    onUpdatePosition: null,                    onRollback: null,                    focusStateEnabled: false,                    selectionMode: "single",                    selectionRequired: true,                    swipeEnabled: true                })            },            _itemClass: function() {                return PIVOT_TAB_CLASS            },            _itemDataKey: function() {                return PIVOT_TAB_DATA_KEY            },            _itemContainer: function() {                return this.element()            },            _elementWidth: function() {                if (!this._elementWidthCache)                    this._elementWidthCache = this.element().width();                return this._elementWidthCache            },            _clearElementWidthCache: function() {                delete this._elementWidthCache            },            _itemWidths: function() {                if (!this._itemWidthsCache) {                    var $tabs = this._itemElements(),                        widths = [];                    $tabs.each(function() {                        widths.push($(this).outerWidth())                    });                    this._itemWidthsCache = widths                }                return this._itemWidthsCache            },            _init: function() {                this.callBase();                this._initGhostTab();                this._initSwipeHandlers();                this._initActions()            },            _dimensionChanged: function() {                this._clearElementWidthCache();                this._cleanPositionCache();                this._updateTabsPositions()            },            _initGhostTab: function() {                this._$ghostTab = $("<div>").addClass(PIVOT_GHOST_TAB_CLASS)            },            _initActions: function() {                this._updatePositionAction = this._createActionByOption("onUpdatePosition");                this._rollbackAction = this._createActionByOption("onRollback");                this._prepareAction = this._createActionByOption("onPrepare")            },            _render: function() {                this.element().addClass(PIVOT_TABS_CLASS);                this.callBase();                this._renderGhostTab()            },            _renderGhostTab: function() {                this._itemContainer().append(this._$ghostTab);                this._toggleGhostTab(false)            },            _toggleGhostTab: function(visible) {                var $ghostTab = this._$ghostTab;                if (visible) {                    this._updateGhostTabContent();                    $ghostTab.css("opacity", 1)                }                else                    $ghostTab.css("opacity", 0)            },            _isGhostTabVisible: function() {                return this._$ghostTab.css("opacity") === "1"            },            _updateGhostTabContent: function(prevIndex) {                prevIndex = prevIndex === undefined ? this._previousIndex() : prevIndex;                var $ghostTab = this._$ghostTab,                    $items = this._itemElements();                $ghostTab.html($items.eq(prevIndex).html())            },            _updateTabsPositions: function(offset) {                offset = this._applyOffsetBoundaries(offset);                var isPrevSwipeHandled = this.option("rtlEnabled") ^ offset > 0 && offset !== 0,                    tabPositions = this._calculateTabPositions(isPrevSwipeHandled ? "replace" : "append");                this._moveTabs(tabPositions, offset);                this._toggleGhostTab(isPrevSwipeHandled)            },            _moveTabs: function(positions, offset) {                offset = offset || 0;                var $tabs = this._allTabElements();                $tabs.each(function(index) {                    translator.move($(this), {left: positions[index] + offset})                })            },            _applyOffsetBoundaries: function(offset) {                offset = offset || 0;                var maxOffset = offset > 0 ? this._maxRightOffset : this._maxLeftOffset;                return offset * maxOffset            },            _animateRollback: function() {                var that = this,                    $tabs = this._itemElements(),                    positions = this._calculateTabPositions("prepend");                if (this._isGhostTabVisible()) {                    this._swapGhostWithTab($tabs.eq(this._previousIndex()));                    animation.moveTo(this._$ghostTab, positions[this._indexBoundary()], function() {                        that._toggleGhostTab(false)                    })                }                $tabs.each(function(index) {                    animation.moveTo($(this), positions[index])                })            },            _animateComplete: function(newIndex, currentIndex) {                var $tabs = this._itemElements(),                    isPrevSwipeHandled = this._isGhostTabVisible();                $tabs.eq(currentIndex).removeClass(PIVOT_TAB_SELECTED_CLASS);                if (isPrevSwipeHandled)                    this._animateIndexDecreasing(newIndex);                else                    this._animateIndexIncreasing(newIndex);                $tabs.eq(newIndex).addClass(PIVOT_TAB_SELECTED_CLASS)            },            _animateIndexDecreasing: function(newIndex) {                var $tabs = this._itemElements(),                    positions = this._calculateTabPositions("append", newIndex),                    animations = [];                $tabs.each(function(index) {                    animations.push(animation.moveTo($(this), positions[index]))                });                animations.push(animation.slideDisappear(this._$ghostTab, positions[this._indexBoundary()]));                return $.when.apply($, animations)            },            _animateIndexIncreasing: function(newIndex) {                var that = this,                    $tabs = this._itemElements(),                    positions = this._calculateTabPositions("prepend", newIndex),                    previousIndex = this._previousIndex(newIndex),                    $prevTab = $tabs.eq(previousIndex),                    prevTabPosition = translator.locate($prevTab).left,                    rtl = this.option("rtlEnabled"),                    bound = rtl ? this._elementWidth() - this._itemWidths()[previousIndex] : 0,                    isNextSwipeHandled = (prevTabPosition - bound) * this._getRTLSignCorrection() < 0,                    animations = [];                if (!isNextSwipeHandled)                    this._moveTabs(this._calculateTabPositions("append", previousIndex));                this._updateGhostTabContent(previousIndex);                this._swapGhostWithTab($tabs.eq(previousIndex));                $tabs.each(function(index) {                    var $tab = $(this),                        newPosition = positions[index];                    animations.push(index === previousIndex ? animation.slideAppear($tab, newPosition) : animation.moveTo($tab, newPosition))                });                animations.push(animation.moveTo(this._$ghostTab, positions[this._indexBoundary()], function() {                    that._toggleGhostTab(false)                }));                return $.when.apply($, animations)            },            _swapGhostWithTab: function($tab) {                var $ghostTab = this._$ghostTab,                    lastTabPosition = translator.locate($tab).left,                    lastTabOpacity = $tab.css("opacity");                translator.move($tab, {left: translator.locate($ghostTab).left});                $tab.css("opacity", $ghostTab.css("opacity"));                translator.move($ghostTab, {left: lastTabPosition});                $ghostTab.css("opacity", lastTabOpacity)            },            _calculateTabPositions: function(ghostPosition, index) {                index = index === undefined ? this.option("selectedIndex") : index;                var mark = index + ghostPosition;                if (this._calculetedPositionsMark !== mark) {                    this._calculetedPositions = this._calculateTabPositionsImpl(index, ghostPosition);                    this._calculetedPositionsMark = mark                }                return this._calculetedPositions            },            _calculateTabPositionsImpl: function(currentIndex, ghostPosition) {                var prevIndex = this._normalizeIndex(currentIndex - 1),                    widths = this._itemWidths();                var rtl = this.option("rtlEnabled"),                    signCorrection = this._getRTLSignCorrection(),                    tabsContainerWidth = this._elementWidth(),                    nextPosition = rtl ? tabsContainerWidth : 0,                    positions = [];                var calculateTabPosition = function(currentIndex, width) {                        var rtlOffset = rtl * width;                        positions.splice(currentIndex, 0, nextPosition - rtlOffset);                        nextPosition += width * signCorrection                    };                $.each(widths.slice(currentIndex), calculateTabPosition);                $.each(widths.slice(0, currentIndex), calculateTabPosition);                switch (ghostPosition) {                    case"replace":                        var lastTabPosition = positions[prevIndex];                        positions.splice(prevIndex, 1, rtl ? tabsContainerWidth : -widths[prevIndex]);                        positions.push(lastTabPosition);                        break;                    case"prepend":                        positions.push(rtl ? tabsContainerWidth : -widths[prevIndex]);                        break;                    case"append":                        positions.push(nextPosition - widths[currentIndex] * rtl);                        break                }                return positions            },            _allTabElements: function() {                return this._itemContainer().find("." + PIVOT_TAB_CLASS + ", ." + PIVOT_GHOST_TAB_CLASS)            },            _initSwipeHandlers: function() {                this.element().on(events.addNamespace("dxswipestart", this.NAME), {itemSizeFunc: $.proxy(this._elementWidth, this)}, $.proxy(this._swipeStartHandler, this)).on(events.addNamespace("dxswipe", this.NAME), $.proxy(this._swipeUpdateHandler, this)).on(events.addNamespace("dxswipeend", this.NAME), $.proxy(this._swipeEndHandler, this))            },            _swipeStartHandler: function(e) {                this._prepareAnimation();                this._prepareAction();                e.maxLeftOffset = 1;                e.maxRightOffset = 1;                if (DX.designMode || this.option("disabled") || !this.option("swipeEnabled") || this._indexBoundary() <= 1)                    e.cancel = true;                else                    this._swipeGestureRunning = true            },            _prepareAnimation: function() {                this._stopAnimation()            },            _stopAnimation: function() {                animation.complete(this._allTabElements())            },            _swipeUpdateHandler: function(e) {                var offset = e.offset;                this._updateTabsPositions(offset);                this._updatePositionAction({offset: offset})            },            _swipeEndHandler: function(e) {                var targetOffset = e.targetOffset * this._getRTLSignCorrection();                if (targetOffset === 0) {                    this._animateRollback();                    this._rollbackAction()                }                else {                    var newIndex = this._normalizeIndex(this.option("selectedIndex") - targetOffset);                    this.option("selectedIndex", newIndex)                }                this._swipeGestureRunning = false            },            _previousIndex: function(atIndex) {                atIndex = atIndex === undefined ? this.option("selectedIndex") : atIndex;                return this._normalizeIndex(atIndex - 1)            },            _normalizeIndex: function(index) {                var boundary = this._indexBoundary();                if (index < 0)                    index = boundary + index;                if (index >= boundary)                    index = index - boundary;                return index            },            _indexBoundary: function() {                return this.option("items").length            },            _renderSelection: function(current) {                this._calculateMaxOffsets(current);                this._updateTabsPositions();                this._itemElements().eq(current).addClass(PIVOT_TAB_SELECTED_CLASS)            },            _updateSelection: function(addedItems, removedItems) {                var newIndex = addedItems[0],                    oldIndex = removedItems[0];                this._calculateMaxOffsets(newIndex);                if (!this._swipeGestureRunning)                    this._prepareAnimation();                if (this._itemElements().length)                    this._animateComplete(newIndex, oldIndex)            },            _calculateMaxOffsets: function(index) {                var currentTabWidth = this._itemWidths()[index],                    prevTabWidth = this._itemWidths()[this._previousIndex(index)],                    rtl = this.option("rtlEnabled");                this._maxLeftOffset = rtl ? prevTabWidth : currentTabWidth;                this._maxRightOffset = rtl ? currentTabWidth : prevTabWidth            },            _getRTLSignCorrection: function() {                return this.option("rtlEnabled") ? -1 : 1            },            _visibilityChanged: function(visible) {                if (visible)                    this._dimensionChanged()            },            _clean: function() {                animation.stop(this._allTabElements());                this._clearElementWidthCache();                this._cleanPositionCache();                this.callBase()            },            _cleanPositionCache: function() {                delete this._itemWidthsCache;                delete this._calculetedPositionsMark            },            _optionChanged: function(args) {                switch (args.name) {                    case"items":                    case"rtlEnabled":                        this._cleanPositionCache();                        this.callBase(args);                        break;                    case"onPrepare":                    case"swipeEnabled":                        break;                    case"onUpdatePosition":                    case"onRollback":                        this._initActions();                        break;                    default:                        this.callBase(args)                }            },            prepare: function() {                this._prepareAnimation()            },            updatePosition: function(offset) {                this._updateTabsPositions(offset)            },            rollback: function() {                this._animateRollback()            }        }));        ui.dxPivotTabs.__internals = {animation: animation}    })(jQuery, DevExpress);    /*! Module widgets-mobile, file ui.pivot.js */    (function($, DX, undefined) {        var ui = DX.ui,            utils = DX.utils,            events = ui.events,            fx = DX.fx,            translator = DX.translator;        var PIVOT_CLASS = "dx-pivot",            PIVOT_AUTOHEIGHT_CLASS = "dx-pivot-autoheight",            PIVOT_WRAPPER_CLASS = "dx-pivot-wrapper",            PIVOT_TABS_CONTAINER_CLASS = "dx-pivottabs-container",            PIVOT_ITEM_CONTAINER_CLASS = "dx-pivot-itemcontainer",            PIVOT_ITEM_WRAPPER_CLASS = "dx-pivot-itemwrapper",            PIVOT_ITEM_CLASS = "dx-pivot-item",            PIVOT_ITEM_HIDDEN_CLASS = "dx-pivot-item-hidden",            PIVOT_ITEM_DATA_KEY = "dxPivotItemData",            PIVOT_RETURN_BACK_DURATION = 200,            PIVOT_SLIDE_AWAY_DURATION = 50,            PIVOT_SLIDE_BACK_DURATION = 250,            PIVOT_SLIDE_BACK_EASING = "cubic-bezier(.10, 1, 0, 1)";        var animation = {                returnBack: function($element) {                    fx.animate($element, {                        type: "slide",                        to: {left: 0},                        duration: PIVOT_RETURN_BACK_DURATION                    })                },                slideAway: function($element, position, complete) {                    fx.animate($element, {                        type: "slide",                        to: {left: position},                        duration: PIVOT_SLIDE_AWAY_DURATION,                        complete: complete                    })                },                slideBack: function($element) {                    fx.animate($element, {                        type: "slide",                        to: {left: 0},                        easing: PIVOT_SLIDE_BACK_EASING,                        duration: PIVOT_SLIDE_BACK_DURATION                    })                },                complete: function($element) {                    fx.stop($element, true)                }            };        DX.registerComponent("dxPivot", ui, ui.CollectionWidget.inherit({            _setDefaultOptions: function() {                this.callBase();                this.option({                    selectedIndex: 0,                    swipeEnabled: true,                    titleTemplate: "title",                    contentTemplate: "content",                    focusStateEnabled: false,                    selectionMode: "single",                    selectionRequired: true,                    selectionByClick: false                })            },            _itemClass: function() {                return PIVOT_ITEM_CLASS            },            _itemDataKey: function() {                return PIVOT_ITEM_DATA_KEY            },            _itemContainer: function() {                return this._$itemWrapper            },            _elementWidth: function() {                if (!this._elementWidthCache)                    this._elementWidthCache = this.element().width();                return this._elementWidthCache            },            _clearElementWidthCache: function() {                delete this._elementWidthCache            },            _init: function() {                this.callBase();                this.element().addClass(PIVOT_CLASS);                this._initWrapper();                this._initTabs();                this._initItemContainer();                this._clearItemsCache();                this._initSwipeHandlers()            },            _dimensionChanged: function() {                this._clearElementWidthCache()            },            _initWrapper: function() {                this._$wrapper = $("<div>").addClass(PIVOT_WRAPPER_CLASS).appendTo(this.element())            },            _initItemContainer: function() {                var $itemContainer = $("<div>").addClass(PIVOT_ITEM_CONTAINER_CLASS);                this._$wrapper.append($itemContainer);                this._$itemWrapper = $("<div>").addClass(PIVOT_ITEM_WRAPPER_CLASS);                $itemContainer.append(this._$itemWrapper)            },            _clearItemsCache: function() {                this._itemsCache = []            },            _initTabs: function() {                var that = this,                    $tabsContainer = $("<div>").addClass(PIVOT_TABS_CONTAINER_CLASS);                this._$wrapper.append($tabsContainer);                this._tabs = this._createComponent($tabsContainer, "dxPivotTabs", {                    itemTemplateProperty: "titleTemplate",                    itemTemplate: this._getTemplateByOption("titleTemplate"),                    items: this.option("items"),                    selectedIndex: this.option("selectedIndex"),                    onPrepare: function() {                        that._prepareAnimation()                    },                    onUpdatePosition: function(args) {                        that._updateContentPosition(args.offset)                    },                    onRollback: function() {                        that._animateRollback()                    },                    onSelectionChanged: function(args) {                        that.option("selectedItem", args.addedItems[0])                    },                    swipeEnabled: this.option("swipeEnabled")                })            },            _render: function() {                this._renderContentTemplate();                this.callBase();                var selectedIndex = this.option("selectedIndex");                this._renderCurrentContent(selectedIndex, selectedIndex)            },            _renderContentTemplate: function() {                if (utils.isDefined(this._singleContent))                    return;                this._getTemplateByOption("contentTemplate").render(this._$itemWrapper);                this._singleContent = !this._$itemWrapper.is(":empty")            },            _renderDimensions: function() {                this.callBase();                this.element().toggleClass(PIVOT_AUTOHEIGHT_CLASS, this.option("height") === "auto")            },            _renderCurrentContent: function(currentIndex, previousIndex) {                var itemsCache = this._itemsCache;                itemsCache[previousIndex] = this._selectedItemElement();                var $hidingItem = itemsCache[previousIndex],                    $showingItem = itemsCache[currentIndex];                utils.triggerHidingEvent($hidingItem);                $hidingItem.addClass(PIVOT_ITEM_HIDDEN_CLASS);                if ($showingItem) {                    $showingItem.removeClass(PIVOT_ITEM_HIDDEN_CLASS);                    utils.triggerShownEvent($showingItem)                }                else                    this._renderContent();                this._selectionChangePromise && this._selectionChangePromise.resolve();                this._selectionChangePromise = $.Deferred()            },            _updateContentPosition: function(offset) {                translator.move(this._$itemWrapper, {left: this._calculatePixelOffset(offset)})            },            _animateRollback: function() {                animation.returnBack(this._$itemWrapper)            },            _animateComplete: function(newIndex, currentIndex) {                var $itemWrapper = this._$itemWrapper,                    rtlSignCorrection = this._getRTLSignCorrection(),                    intermediatePosition = this._elementWidth() * (this._isPrevSwipeHandled() ? 1 : -1) * rtlSignCorrection;                animation.slideAway($itemWrapper, intermediatePosition, $.proxy(function() {                    translator.move($itemWrapper, {left: -intermediatePosition});                    this._renderCurrentContent(newIndex, currentIndex)                }, this));                animation.slideBack($itemWrapper)            },            _calculatePixelOffset: function(offset) {                offset = offset || 0;                return offset * this._elementWidth()            },            _isPrevSwipeHandled: function() {                var wrapperOffset = translator.locate(this._$itemWrapper).left,                    rtl = this.option("rtlEnabled");                return rtl ^ wrapperOffset > 0 && wrapperOffset !== 0            },            _initSwipeHandlers: function() {                this.element().on(events.addNamespace("dxswipestart", this.NAME), {itemSizeFunc: $.proxy(this._elementWidth, this)}, $.proxy(this._swipeStartHandler, this)).on(events.addNamespace("dxswipe", this.NAME), $.proxy(this._swipeUpdateHandler, this)).on(events.addNamespace("dxswipeend", this.NAME), $.proxy(this._swipeEndHandler, this))            },            _swipeStartHandler: function(e) {                this._prepareAnimation();                this._tabs.prepare();                if (DX.designMode || this.option("disabled") || !this.option("swipeEnabled") || this._indexBoundary() <= 1)                    e.cancel = true;                else                    this._swipeGestureRunning = true;                e.maxLeftOffset = 1;                e.maxRightOffset = 1            },            _prepareAnimation: function() {                this._stopAnimation()            },            _stopAnimation: function() {                animation.complete(this._$itemWrapper)            },            _swipeUpdateHandler: function(e) {                var offset = e.offset;                this._updateContentPosition(offset);                this._tabs.updatePosition(offset)            },            _swipeEndHandler: function(e) {                var targetOffset = e.targetOffset * this._getRTLSignCorrection();                if (targetOffset === 0) {                    this._animateRollback();                    this._tabs.rollback()                }                else {                    var newIndex = this._normalizeIndex(this.option("selectedIndex") - targetOffset);                    this.option("selectedIndex", newIndex)                }                this._swipeGestureRunning = false            },            _normalizeIndex: function(index) {                var boundary = this._indexBoundary();                if (index < 0)                    index = boundary + index;                if (index >= boundary)                    index = index - boundary;                return index            },            _indexBoundary: function() {                return this.option("items").length            },            _renderContentImpl: function() {                if (this._singleContent)                    return;                var items = this.option("items"),                    selectedIndex = this.option("selectedIndex");                if (items.length)                    this._renderItems([items[selectedIndex]])            },            _selectedItemElement: function() {                return this._$itemWrapper.children("." + PIVOT_ITEM_CLASS + ":not(." + PIVOT_ITEM_HIDDEN_CLASS + ")")            },            _getRTLSignCorrection: function() {                return this.option("rtlEnabled") ? -1 : 1            },            _clean: function() {                animation.complete(this._$itemWrapper);                this.callBase()            },            _cleanItemContainer: function() {                if (this._singleContent)                    return;                this.callBase()            },            _refresh: function() {                this._tabs._refresh();                this.callBase()            },            _updateSelection: function(addedItems, removedItems) {                var newIndex = addedItems[0],                    oldIndex = removedItems[0];                if (!this._swipeGestureRunning)                    this._prepareAnimation();                this._animateComplete(newIndex, oldIndex);                this._tabs.option("selectedIndex", newIndex)            },            _optionChanged: function(args) {                var value = args.value;                switch (args.name) {                    case"disabled":                        this._tabs.option("disabled", value);                        this.callBase(args);                        break;                    case"items":                        this._tabs.option("items", value);                        this._clearItemsCache();                        this.callBase(args);                        break;                    case"rtlEnabled":                        this._tabs.option("rtlEnabled", value);                        this._clearItemsCache();                        this.callBase(args);                        break;                    case"titleTemplate":                        this._tabs.option("itemTemplate", this._getTemplate(value));                        break;                    case"swipeEnabled":                        this._tabs.option("swipeEnabled", value);                        break;                    case"contentTemplate":                        this._singleContent = null;                        this._invalidate();                        break;                    default:                        this.callBase(args)                }            }        }));        ui.dxPivot.__internals = {animation: animation}    })(jQuery, DevExpress);    /*! Module widgets-mobile, file ui.actionSheet.js */    (function($, DX, undefined) {        var ui = DX.ui;        var ACTION_SHEET_CLASS = "dx-actionsheet",            ACTION_SHEET_CONTAINER_CLASS = "dx-actionsheet-container",            ACTION_SHEET_POPUP_WRAPPER_CLASS = "dx-actionsheet-popup-wrapper",            ACTION_SHEET_POPOVER_WRAPPER_CLASS = "dx-actionsheet-popover-wrapper",            ACTION_SHEET_CANCEL_BUTTON_CLASS = "dx-actionsheet-cancel",            ACTION_SHEET_ITEM_CLASS = "dx-actionsheet-item",            ACTION_SHEET_ITEM_DATA_KEY = "dxActionSheetItemData",            ACTION_SHEET_WITHOUT_TITLE_CLASS = "dx-actionsheet-without-title";        DX.registerComponent("dxActionSheet", ui, ui.CollectionWidget.inherit({            _setDeprecatedOptions: function() {                this.callBase();                $.extend(this._deprecatedOptions, {cancelClickAction: {                        since: "14.2",                        alias: "onCancelClick"                    }})            },            _setDefaultOptions: function() {                this.callBase();                this.option({                    usePopover: false,                    target: null,                    title: "",                    showTitle: true,                    showCancelButton: true,                    cancelText: Globalize.localize("Cancel"),                    onCancelClick: null,                    visible: false,                    noDataText: "",                    focusStateEnabled: false,                    selectionByClick: false                })            },            _defaultOptionsRules: function() {                return this.callBase().concat([{                            device: {                                platform: "ios",                                tablet: true                            },                            options: {usePopover: true}                        }])            },            _itemContainer: function() {                return this._$itemContainer            },            _itemClass: function() {                return ACTION_SHEET_ITEM_CLASS            },            _itemDataKey: function() {                return ACTION_SHEET_ITEM_DATA_KEY            },            _toggleVisibility: $.noop,            _renderDimensions: $.noop,            _render: function() {                this.element().addClass(ACTION_SHEET_CLASS);                this._createItemContainer();                this._renderPopup()            },            _createItemContainer: function() {                this._$itemContainer = $("<div>").addClass(ACTION_SHEET_CONTAINER_CLASS);                this._renderDisabled()            },            _renderDisabled: function() {                this._$itemContainer.toggleClass("dx-state-disabled", this.option("disabled"))            },            _renderPopup: function() {                this._$popup = $("<div>").appendTo(this.element());                this._popup = this._isPopoverMode() ? this._createPopover() : this._createPopup();                this._renderPopupTitle();                this._mapPopupOption("visible")            },            _mapPopupOption: function(optionName) {                this._popup.option(optionName, this.option(optionName))            },            _isPopoverMode: function() {                return this.option("usePopover") && this.option("target")            },            _renderPopupTitle: function() {                this._mapPopupOption("showTitle");                this._popup._wrapper().toggleClass(ACTION_SHEET_WITHOUT_TITLE_CLASS, !this.option("showTitle"))            },            _clean: function() {                if (this._$popup)                    this._$popup.remove();                this.callBase()            },            _createPopover: function() {                var popover = this._createComponent(this._$popup, "dxPopover", {                        showTitle: true,                        title: this.option("title"),                        width: this.option("width") || 200,                        height: this.option("height") || "auto",                        target: this.option("target"),                        onHidden: $.proxy(this.hide, this),                        onContentReady: $.proxy(this._popupContentReadyAction, this)                    });                popover._wrapper().addClass(ACTION_SHEET_POPOVER_WRAPPER_CLASS);                return popover            },            _createPopup: function() {                var popup = this._createComponent(this._$popup, "dxPopup", {                        dragEnabled: false,                        title: this.option("title"),                        width: this.option("width") || "100%",                        height: this.option("height") || "auto",                        onContentReady: $.proxy(this._popupContentReadyAction, this),                        showCloseButton: false,                        position: {                            my: "bottom",                            at: "bottom",                            of: window                        },                        animation: {                            show: {                                type: "slide",                                duration: 400,                                from: {position: {                                        my: "top",                                        at: "bottom",                                        of: window                                    }},                                to: {position: {                                        my: "bottom",                                        at: "bottom",                                        of: window                                    }}                            },                            hide: {                                type: "slide",                                duration: 400,                                from: {position: {                                        my: "bottom",                                        at: "bottom",                                        of: window                                    }},                                to: {position: {                                        my: "top",                                        at: "bottom",                                        of: window                                    }}                            }                        }                    });                popup.on("optionChanged", $.proxy(function(args) {                    if (args.name !== "visible")                        return;                    this.option("visible", args.value)                }, this));                popup._wrapper().addClass(ACTION_SHEET_POPUP_WRAPPER_CLASS);                return popup            },            _popupContentReadyAction: function() {                this._popup.content().append(this._$itemContainer);                this._attachClickEvent();                this._attachHoldEvent();                this._renderContent();                this._renderCancelButton()            },            _renderCancelButton: function() {                if (this._isPopoverMode())                    return;                if (this._$cancelButton)                    this._$cancelButton.remove();                if (this.option("showCancelButton")) {                    var cancelClickAction = this._createActionByOption("onCancelClick") || $.noop,                        that = this;                    this._$cancelButton = $("<div>").addClass(ACTION_SHEET_CANCEL_BUTTON_CLASS).appendTo(this._popup.content());                    this._createComponent(this._$cancelButton, "dxButton", {                        text: this.option("cancelText"),                        onClick: function(e) {                            var hidingArgs = {                                    jQueryEvent: e,                                    cancel: false                                };                            cancelClickAction(hidingArgs);                            if (!hidingArgs.cancel)                                that.hide()                        },                        _templates: {}                    })                }            },            _attachItemClickEvent: $.noop,            _itemClickHandler: function(e) {                this.callBase(e);                if (!$(e.target).is(".dx-state-disabled, .dx-state-disabled *"))                    this.hide()            },            _itemHoldHandler: function(e) {                this.callBase(e);                if (!$(e.target).is(".dx-state-disabled, .dx-state-disabled *"))                    this.hide()            },            _optionChanged: function(args) {                switch (args.name) {                    case"width":                    case"height":                    case"visible":                    case"title":                        this._mapPopupOption(args.name);                        break;                    case"disabled":                        this._renderDisabled();                        break;                    case"showTitle":                        this._renderPopupTitle();                        break;                    case"showCancelButton":                    case"onCancelClick":                    case"cancelText":                        this._renderCancelButton();                        break;                    case"target":                    case"usePopover":                    case"items":                        this._invalidate();                        break;                    default:                        this.callBase(args)                }            },            toggle: function(showing) {                var that = this,                    d = $.Deferred();                that._popup.toggle(showing).done(function() {                    that.option("visible", showing);                    d.resolveWith(that)                });                return d.promise()            },            show: function() {                return this.toggle(true)            },            hide: function() {                return this.toggle(false)            }        }))    })(jQuery, DevExpress);    /*! Module widgets-mobile, file ui.panorama.js */    (function($, DX, undefined) {        var ui = DX.ui,            events = ui.events,            fx = DX.fx,            translator = DX.translator;        var PANORAMA_CLASS = "dx-panorama",            PANORAMA_WRAPPER_CLASS = "dx-panorama-wrapper",            PANORAMA_TITLE_CLASS = "dx-panorama-title",            PANORAMA_GHOST_TITLE_CLASS = "dx-panorama-ghosttitle",            PANORAMA_ITEMS_CONTAINER_CLASS = "dx-panorama-itemscontainer",            PANORAMA_ITEM_CLASS = "dx-panorama-item",            PANORAMA_GHOST_ITEM_CLASS = "dx-panorama-ghostitem",            PANORAMA_ITEM_DATA_KEY = "dxPanoramaItemData",            PANORAMA_ITEM_MARGIN_SCALE = 0.02,            PANORAMA_TITLE_MARGIN_SCALE = 0.02,            PANORAMA_BACKGROUND_MOVE_DURATION = 300,            PANORAMA_BACKGROUND_MOVE_EASING = "cubic-bezier(.40, .80, .60, 1)",            PANORAMA_TITLE_MOVE_DURATION = 300,            PANORAMA_TITLE_MOVE_EASING = "cubic-bezier(.40, .80, .60, 1)",            PANORAMA_ITEM_MOVE_DURATION = 300,            PANORAMA_ITEM_MOVE_EASING = "cubic-bezier(.40, .80, .60, 1)";        var moveBackground = function($element, position) {                $element.css("background-position", position + "px 0%")            };        var position = function($element) {                return translator.locate($element).left            };        var move = function($element, position) {                translator.move($element, {left: position})            };        var animation = {                backgroundMove: function($element, position, completeAction) {                    return fx.animate($element, {                            to: {"background-position": position + "px 0%"},                            duration: PANORAMA_BACKGROUND_MOVE_DURATION,                            easing: PANORAMA_BACKGROUND_MOVE_EASING,                            complete: completeAction                        })                },                titleMove: function($title, position, completeAction) {                    return fx.animate($title, {                            type: "slide",                            to: {left: position},                            duration: PANORAMA_TITLE_MOVE_DURATION,                            easing: PANORAMA_TITLE_MOVE_EASING,                            complete: completeAction                        })                },                itemMove: function($item, position, completeAction) {                    return fx.animate($item, {                            type: "slide",                            to: {left: position},                            duration: PANORAMA_ITEM_MOVE_DURATION,                            easing: PANORAMA_ITEM_MOVE_EASING,                            complete: completeAction                        })                }            };        var endAnimation = function(elements) {                if (!elements)                    return;                $.each(elements, function(_, element) {                    fx.stop(element, true)                })            };        var PanoramaItemsRenderStrategy = DX.Class.inherit({                ctor: function(panorama) {                    this._panorama = panorama                },                init: $.noop,                render: $.noop,                allItemElements: function() {                    return this._panorama._itemElements()                },                updatePositions: DX.abstract,                animateRollback: DX.abstract,                detectBoundsTransition: DX.abstract,                animateComplete: DX.abstract,                _getRTLSignCorrection: function() {                    return this._panorama._getRTLSignCorrection()                },                _isRTLEnabled: function() {                    return this._panorama.option("rtlEnabled")                },                _itemMargin: function() {                    return this._containerWidth() * PANORAMA_ITEM_MARGIN_SCALE                },                _containerWidth: function() {                    return this._panorama._elementWidth()                },                _itemWidth: function() {                    return this._panorama._itemWidth()                },                _indexBoundary: function() {                    return this._panorama._indexBoundary()                },                _normalizeIndex: function(index) {                    return this._panorama._normalizeIndex(index)                },                _startNextPosition: function() {                    if (this._isRTLEnabled())                        return this._containerWidth() - (this._itemMargin() + this._itemWidth());                    else                        return this._itemMargin()                },                _startPrevPosition: function() {                    if (this._isRTLEnabled())                        return this._containerWidth();                    else                        return -this._itemWidth()                }            });        var PanoramaOneAndLessItemsRenderStrategy = PanoramaItemsRenderStrategy.inherit({                updatePositions: function() {                    var $items = this._panorama._itemElements(),                        startPosition = this._startNextPosition();                    $items.each(function() {                        move($(this), startPosition)                    })                },                animateRollback: $.noop,                detectBoundsTransition: $.noop,                animateComplete: $.noop            });        var PanoramaTwoItemsRenderStrategy = PanoramaItemsRenderStrategy.inherit({                init: function() {                    this._initGhostItem()                },                render: function() {                    this._renderGhostItem()                },                _initGhostItem: function() {                    this._$ghostItem = $("<div>").addClass(PANORAMA_GHOST_ITEM_CLASS)                },                _renderGhostItem: function() {                    this._panorama._itemContainer().append(this._$ghostItem);                    this._toggleGhostItem(false)                },                _toggleGhostItem: function(visible) {                    var $ghostItem = this._$ghostItem;                    if (visible)                        $ghostItem.css("opacity", 1);                    else                        $ghostItem.css("opacity", 0)                },                _updateGhostItemContent: function(index) {                    if (index !== false && index !== this._prevGhostIndex) {                        this._$ghostItem.html(this._panorama._itemElements().eq(index).html());                        this._prevGhostIndex = index                    }                },                _isGhostItemVisible: function() {                    return this._$ghostItem.css("opacity") === "1"                },                _swapGhostWithItem: function($item) {                    var $ghostItem = this._$ghostItem,                        lastItemPosition = position($item);                    move($item, position($ghostItem));                    move($ghostItem, lastItemPosition)                },                allItemElements: function() {                    return this._panorama._itemContainer().find("." + PANORAMA_ITEM_CLASS + ", ." + PANORAMA_GHOST_ITEM_CLASS)                },                updatePositions: function(offset) {                    var $items = this.allItemElements(),                        selectedIndex = this._panorama.option("selectedIndex"),                        adjustedOffset = offset * this._getRTLSignCorrection(),                        isGhostReplaceLast = adjustedOffset > 0 && selectedIndex === 0 || adjustedOffset < 0 && selectedIndex === 1,                        isGhostReplaceFirst = adjustedOffset < 0 && selectedIndex === 0 || adjustedOffset > 0 && selectedIndex === 1,                        ghostPosition = isGhostReplaceLast && "replaceLast" || isGhostReplaceFirst && "replaceFirst",                        ghostContentIndex = isGhostReplaceLast && 1 || isGhostReplaceFirst && 0,                        positions = this._calculateItemPositions(selectedIndex, ghostPosition);                    this._updateGhostItemContent(ghostContentIndex);                    this._toggleGhostItem(isGhostReplaceLast || isGhostReplaceFirst);                    $items.each(function(index) {                        move($(this), positions[index] + offset)                    })                },                animateRollback: function(currentIndex) {                    var that = this,                        $items = this._panorama._itemElements(),                        startPosition = this._startNextPosition(),                        signCorrection = this._getRTLSignCorrection(),                        offset = (position($items.eq(currentIndex)) - startPosition) * signCorrection,                        ghostOffset = (position(this._$ghostItem) - startPosition) * signCorrection,                        positions = this._calculateItemPositions(currentIndex, ghostOffset > 0 ? "prepend" : "append"),                        isLastReplasedByGhost = currentIndex === 0 && offset > 0 && ghostOffset > 0 || currentIndex === 1 && ghostOffset < 0;                    if (isLastReplasedByGhost)                        this._swapGhostWithItem($items.eq(1));                    else                        this._swapGhostWithItem($items.eq(0));                    $items.each(function(index) {                        animation.itemMove($(this), positions[index])                    });                    animation.itemMove(this._$ghostItem, positions[2], function() {                        that._toggleGhostItem(false)                    })                },                detectBoundsTransition: function(newIndex, currentIndex) {                    var ghostLocation = position(this._$ghostItem),                        startPosition = this._startNextPosition(),                        rtl = this._isRTLEnabled();                    if (newIndex === 0 && rtl ^ ghostLocation < startPosition)                        return "left";                    if (currentIndex === 0 && rtl ^ ghostLocation > startPosition)                        return "right"                },                animateComplete: function(boundCross, newIndex, currentIndex) {                    var that = this,                        ghostPosition = !boundCross ^ currentIndex !== 0 ? "prepend" : "append",                        $items = this._panorama._itemElements(),                        positions = this._calculateItemPositions(newIndex, ghostPosition),                        animations = [];                    $items.each(function(index) {                        animations.push(animation.itemMove($(this), positions[index]))                    });                    animations.push(animation.itemMove(this._$ghostItem, positions[2], function() {                        that._toggleGhostItem(false)                    }));                    return $.when.apply($, animations)                },                _calculateItemPositions: function(atIndex, ghostPosition) {                    var positions = [],                        itemMargin = this._itemMargin(),                        itemWidth = this._itemWidth(),                        itemPositionOffset = (itemWidth + itemMargin) * this._getRTLSignCorrection(),                        normalFlow = atIndex === 0,                        prevPosition = this._startPrevPosition(),                        nextPosition = this._startNextPosition();                    positions.push(nextPosition);                    nextPosition += itemPositionOffset;                    if (normalFlow)                        positions.push(nextPosition);                    else                        positions.splice(0, 0, nextPosition);                    nextPosition += itemPositionOffset;                    switch (ghostPosition) {                        case"replaceFirst":                            positions.push(positions[0]);                            if (normalFlow)                                positions[0] = nextPosition;                            else                                positions[0] = prevPosition;                            break;                        case"replaceLast":                            if (normalFlow)                                positions.splice(1, 0, prevPosition);                            else                                positions.splice(1, 0, nextPosition);                            break;                        case"prepend":                            positions.push(prevPosition);                            break;                        case"append":                            positions.push(nextPosition);                            break                    }                    return positions                }            });        var PanoramaThreeAndMoreItemsRenderStrategy = PanoramaItemsRenderStrategy.inherit({                updatePositions: function(offset) {                    var $items = this._panorama._itemElements(),                        movingBack = offset * this._getRTLSignCorrection() < 0,                        positions = this._calculateItemPositions(this._panorama.option("selectedIndex"), movingBack);                    $items.each(function(index) {                        move($(this), positions[index] + offset)                    })                },                animateRollback: function(selectedIndex) {                    var $items = this._panorama._itemElements(),                        positions = this._calculateItemPositions(selectedIndex),                        animatingItems = [selectedIndex, this._normalizeIndex(selectedIndex + 1)];                    if (this._isRTLEnabled() ^ position($items.eq(selectedIndex)) > this._startNextPosition())                        animatingItems.push(this._normalizeIndex(selectedIndex - 1));                    $items.each(function(index) {                        var $item = $(this);                        if ($.inArray(index, animatingItems) !== -1)                            animation.itemMove($item, positions[index]);                        else                            move($item, positions[index])                    })                },                detectBoundsTransition: function(newIndex, currentIndex) {                    var lastIndex = this._indexBoundary() - 1;                    if (currentIndex === lastIndex && newIndex === 0)                        return "left";                    if (currentIndex === 0 && newIndex === lastIndex)                        return "right"                },                animateComplete: function(boundCross, newIndex, currentIndex) {                    var animations = [],                        $items = this._panorama._itemElements(),                        positions = this._calculateItemPositions(newIndex);                    var transitionBack = this._normalizeIndex(currentIndex - 1) === newIndex,                        cyclingItemIndex = $items.length === 3 && transitionBack ? this._normalizeIndex(currentIndex + 1) : null,                        cyclingItemPosition = positions[this._indexBoundary()];                    var animatingItems = [newIndex, currentIndex],                        backAnimatedItemIndex = transitionBack ? currentIndex : newIndex;                    if (!transitionBack)                        animatingItems.push(this._normalizeIndex(backAnimatedItemIndex + 1));                    $items.each(function(index) {                        var $item = $(this);                        if ($.inArray(index, animatingItems) === -1) {                            move($item, positions[index]);                            return                        }                        animations.push(index !== cyclingItemIndex ? animation.itemMove($item, positions[index]) : animation.itemMove($item, cyclingItemPosition, function() {                            move($item, positions[index])                        }))                    });                    return $.when.apply($, animations)                },                _calculateItemPositions: function(atIndex, movingBack) {                    var previousIndex = this._normalizeIndex(atIndex - 1),                        itemMargin = this._itemMargin(),                        itemWidth = this._itemWidth(),                        itemPositionOffset = (itemWidth + itemMargin) * this._getRTLSignCorrection(),                        positions = [],                        prevPosition = this._startPrevPosition(),                        nextPosition = this._startNextPosition();                    for (var i = atIndex; i !== previousIndex; i = this._normalizeIndex(i + 1)) {                        positions[i] = nextPosition;                        nextPosition += itemPositionOffset                    }                    if (movingBack) {                        positions[previousIndex] = nextPosition;                        nextPosition += itemPositionOffset                    }                    else                        positions[previousIndex] = prevPosition;                    positions.push(nextPosition);                    return positions                }            });        DX.registerComponent("dxPanorama", ui, ui.CollectionWidget.inherit({            _setDefaultOptions: function() {                this.callBase();                this.option({                    selectedIndex: 0,                    title: "panorama",                    backgroundImage: {                        url: null,                        width: 0,                        height: 0                    },                    focusStateEnabled: false,                    selectionMode: "single",                    selectionRequired: true,                    selectionByClick: false                })            },            _itemClass: function() {                return PANORAMA_ITEM_CLASS            },            _itemDataKey: function() {                return PANORAMA_ITEM_DATA_KEY            },            _itemContainer: function() {                return this._$itemsContainer            },            _itemWidth: function() {                if (!this._itemWidthCache)                    this._itemWidthCache = this._itemElements().eq(0).outerWidth();                return this._itemWidthCache            },            _clearItemWidthCache: function() {                delete this._itemWidthCache            },            _elementWidth: function() {                if (!this._elementWidthCache)                    this._elementWidthCache = this.element().width();                return this._elementWidthCache            },            _clearElementWidthCache: function() {                delete this._elementWidthCache            },            _titleWidth: function() {                if (!this._titleWidthCache)                    this._titleWidthCache = this._$title.outerWidth();                return this._titleWidthCache            },            _clearTitleWidthCache: function() {                delete this._titleWidthCache            },            _init: function() {                this.callBase();                this._initItemsRenderStrategy();                this._initWrapper();                this._initTitle();                this._initItemsContainer();                this._initSwipeHandlers()            },            _dimensionChanged: function() {                this._clearItemWidthCache();                this._clearElementWidthCache();                this._clearTitleWidthCache();                this._updatePositions()            },            _initWrapper: function() {                this._$wrapper = $("<div>").addClass(PANORAMA_WRAPPER_CLASS).appendTo(this.element())            },            _initItemsRenderStrategy: function() {                var itemsRenderStrategy;                switch (this.option("items").length) {                    case 0:                    case 1:                        itemsRenderStrategy = PanoramaOneAndLessItemsRenderStrategy;                        break;                    case 2:                        itemsRenderStrategy = PanoramaTwoItemsRenderStrategy;                        break;                    default:                        itemsRenderStrategy = PanoramaThreeAndMoreItemsRenderStrategy                }                this._itemsRenderStrategy = new itemsRenderStrategy(this);                this._itemsRenderStrategy.init()            },            _initBackgroundImage: function() {                var bgUrl = this.option("backgroundImage.url");                if (bgUrl)                    this.element().css("background-image", "url(" + bgUrl + ")")            },            _initTitle: function() {                this._$title = $("<div>").addClass(PANORAMA_TITLE_CLASS);                this._$ghostTitle = $("<div>").addClass(PANORAMA_GHOST_TITLE_CLASS);                this._$wrapper.append(this._$title);                this._$wrapper.append(this._$ghostTitle);                this._updateTitle()            },            _updateTitle: function() {                var title = this.option("title");                this._$title.text(title);                this._$ghostTitle.text(title);                this._toggleGhostTitle(false)            },            _toggleGhostTitle: function(visible) {                var $ghostTitle = this._$ghostTitle;                if (visible)                    $ghostTitle.css("opacity", 1);                else                    $ghostTitle.css("opacity", 0)            },            _getRTLSignCorrection: function() {                return this.option("rtlEnabled") ? -1 : 1            },            _initItemsContainer: function() {                this._$itemsContainer = $("<div>").addClass(PANORAMA_ITEMS_CONTAINER_CLASS);                this._$wrapper.append(this._$itemsContainer)            },            _render: function() {                this.element().addClass(PANORAMA_CLASS);                this.callBase();                this._initBackgroundImage();                this._itemsRenderStrategy.render()            },            _updatePositions: function(offset) {                offset = offset || 0;                this._updateBackgroundPosition(offset * this._calculateBackgroundStep());                this._updateTitlePosition(offset * this._calculateTitleStep());                this._itemsRenderStrategy.updatePositions(offset * this._elementWidth())            },            _updateBackgroundPosition: function(offset) {                moveBackground(this.element(), this._calculateBackgroundPosition(this.option("selectedIndex")) + offset)            },            _updateTitlePosition: function(offset) {                move(this._$title, this._calculateTitlePosition(this.option("selectedIndex")) + offset)            },            _animateRollback: function(currentIndex) {                this._animateBackgroundMove(currentIndex);                this._animateTitleMove(currentIndex);                this._itemsRenderStrategy.animateRollback(currentIndex)            },            _animateBackgroundMove: function(toIndex) {                return animation.backgroundMove(this.element(), this._calculateBackgroundPosition(toIndex))            },            _animateTitleMove: function(toIndex) {                return animation.titleMove(this._$title, this._calculateTitlePosition(toIndex))            },            _animateComplete: function(newIndex, currentIndex) {                var that = this,                    boundCross = this._itemsRenderStrategy.detectBoundsTransition(newIndex, currentIndex);                var backgroundAnimation = this._performBackgroundAnimation(boundCross, newIndex);                var titleAnimation = this._performTitleAnimation(boundCross, newIndex);                var itemsAnimation = this._itemsRenderStrategy.animateComplete(boundCross, newIndex, currentIndex);                $.when(backgroundAnimation, titleAnimation, itemsAnimation).done(function() {                    that._indexChangeOnAnimation = true;                    that.option("selectedIndex", newIndex);                    that._indexChangeOnAnimation = false                })            },            _performBackgroundAnimation: function(boundCross, newIndex) {                if (boundCross)                    return this._animateBackgroundBoundsTransition(boundCross, newIndex);                return this._animateBackgroundMove(newIndex)            },            _animateBackgroundBoundsTransition: function(bound, newIndex) {                var that = this,                    isLeft = bound === "left",                    afterAnimationPosition = this._calculateBackgroundPosition(newIndex),                    animationEndPositionShift = isLeft ^ this.option("rtlEnabled") ? -this._calculateBackgroundScaledWidth() : this._calculateBackgroundScaledWidth(),                    animationEndPosition = afterAnimationPosition + animationEndPositionShift;                return animation.backgroundMove(this.element(), animationEndPosition, function() {                        moveBackground(that.element(), afterAnimationPosition)                    })            },            _performTitleAnimation: function(boundCross, newIndex) {                if (boundCross)                    return this._animateTitleBoundsTransition(boundCross, newIndex);                return this._animateTitleMove(newIndex)            },            _animateTitleBoundsTransition: function(bound, newIndex) {                var that = this,                    $ghostTitle = this._$ghostTitle,                    ghostWidth = this._titleWidth(),                    panoramaWidth = this._elementWidth(),                    isLeft = bound === "left",                    rtl = this.option("rtlEnabled"),                    ghostTitleStartPosition = isLeft ^ rtl ? panoramaWidth : -ghostWidth,                    ghostTitleEndPosition = isLeft ^ rtl ? -(panoramaWidth + ghostWidth) : panoramaWidth;                move($ghostTitle, ghostTitleStartPosition);                this._toggleGhostTitle(true);                this._swapGhostWithTitle();                var ghostAnimation = animation.titleMove($ghostTitle, ghostTitleEndPosition, function() {                        that._toggleGhostTitle(false)                    });                var titleAnimation = animation.titleMove(this._$title, this._calculateTitlePosition(newIndex));                return $.when(ghostAnimation, titleAnimation)            },            _swapGhostWithTitle: function() {                var $ghostTitle = this._$ghostTitle,                    $title = this._$title,                    lastTitlePosition = position($title);                move($title, position($ghostTitle));                move($ghostTitle, lastTitlePosition)            },            _calculateTitlePosition: function(atIndex) {                var panoramaWidth = this._elementWidth(),                    titleWidth = this._titleWidth(),                    titleMargin = panoramaWidth * PANORAMA_TITLE_MARGIN_SCALE,                    titleStartPosition = this.option("rtlEnabled") ? panoramaWidth - titleMargin - titleWidth : titleMargin,                    titleStep = atIndex * this._calculateTitleStep() * this._getRTLSignCorrection();                return titleStartPosition - titleStep            },            _calculateTitleStep: function() {                var panoramaWidth = this._elementWidth(),                    titleWidth = this._titleWidth(),                    indexBoundary = this._indexBoundary() || 1;                return Math.max((titleWidth - panoramaWidth) / indexBoundary, titleWidth / indexBoundary)            },            _calculateBackgroundPosition: function(atIndex) {                var panoramaWidth = this._elementWidth(),                    backgroundScaledWidth = this._calculateBackgroundScaledWidth(),                    backgroundStartPosition = this.option("rtlEnabled") ? panoramaWidth - backgroundScaledWidth : 0,                    backgroundOffset = atIndex * this._calculateBackgroundStep() * this._getRTLSignCorrection();                return backgroundStartPosition - backgroundOffset            },            _calculateBackgroundStep: function() {                var itemWidth = this._itemWidth(),                    backgroundScaledWidth = this._calculateBackgroundScaledWidth();                return Math.max((backgroundScaledWidth - itemWidth) / (this._indexBoundary() || 1), 0)            },            _calculateBackgroundScaledWidth: function() {                return this.element().height() * this.option("backgroundImage.width") / (this.option("backgroundImage.height") || 1)            },            _initSwipeHandlers: function() {                this.element().on(events.addNamespace("dxswipestart", this.NAME), {itemSizeFunc: $.proxy(this._elementWidth, this)}, $.proxy(this._swipeStartHandler, this)).on(events.addNamespace("dxswipe", this.NAME), $.proxy(this._swipeUpdateHandler, this)).on(events.addNamespace("dxswipeend", this.NAME), $.proxy(this._swipeEndHandler, this))            },            _swipeStartHandler: function(e) {                this._stopAnimations();                e.maxLeftOffset = 1;                e.maxRightOffset = 1;                if (DX.designMode || this.option("disabled") || this._indexBoundary() <= 1)                    e.cancel = true            },            _stopAnimations: function() {                endAnimation([this.element(), this._$ghostTitle, this._$title]);                endAnimation(this._itemsRenderStrategy.allItemElements())            },            _swipeUpdateHandler: function(e) {                this._updatePositions(e.offset)            },            _swipeEndHandler: function(e) {                var currentIndex = this.option("selectedIndex"),                    targetOffset = e.targetOffset * this._getRTLSignCorrection();                if (targetOffset === 0)                    this._animateRollback(currentIndex);                else                    this._animateComplete(this._normalizeIndex(currentIndex - targetOffset), currentIndex)            },            _renderSelection: function(current, previous) {                if (!this._indexChangeOnAnimation)                    this._updatePositions()            },            _normalizeIndex: function(index) {                var boundary = this._indexBoundary();                if (index < 0)                    index = boundary + index;                if (index >= boundary)                    index = index - boundary;                return index            },            _indexBoundary: function() {                return this.option("items").length            },            _visibilityChanged: function(visible) {                if (visible)                    this._dimensionChanged()            },            _optionChanged: function(args) {                switch (args.name) {                    case"width":                        this.callBase(args);                        this._dimensionChanged();                        break;                    case"backgroundImage":                        this._invalidate();                        break;                    case"title":                        this._updateTitle();                        break;                    case"items":                        this._initItemsRenderStrategy();                        this.callBase(args);                        break;                    default:                        this.callBase(args)                }            }        }));        ui.dxPanorama.__internals = {animation: animation}    })(jQuery, DevExpress);    /*! Module widgets-mobile, file ui.slideOutView.js */    (function($, DX, undefined) {        var ui = DX.ui,            fx = DX.fx,            translator = DX.translator;        var SLIDEOUTVIEW_CLASS = "dx-slideoutview",            SLIDEOUTVIEW_WRAPPER_CLASS = "dx-slideoutview-wrapper",            SLIDEOUTVIEW_MENU_CONTENT_CLASS = "dx-slideoutview-menu-content",            SLIDEOUTVIEW_CONTENT_CLASS = "dx-slideoutview-content",            SLIDEOUTVIEW_SHIELD_CLASS = "dx-slideoutview-shield",            INVISIBLE_STATE_CLASS = "dx-state-invisible",            ANONYMOUS_TEMPLATE_NAME = "content",            ANIMATION_DURATION = 400;        var animation = {                moveTo: function($element, position, completeAction) {                    fx.animate($element, {                        type: "slide",                        to: {left: position},                        duration: ANIMATION_DURATION,                        complete: completeAction                    })                },                complete: function($element) {                    fx.stop($element, true)                }            };        DX.registerComponent("dxSlideOutView", ui, ui.Widget.inherit({            _setDefaultOptions: function() {                this.callBase();                this.option({                    menuVisible: false,                    swipeEnabled: true,                    menuTemplate: "menu",                    contentTemplate: "content",                    contentOffset: 45                })            },            _defaultOptionsRules: function() {                return this.callBase().concat([{                            device: {android: true},                            options: {contentOffset: 54}                        }, {                            device: function(device) {                                return device.platform === "generic" && device.deviceType !== "desktop"                            },                            options: {contentOffset: 56}                        }, {                            device: {                                win8: true,                                phone: false                            },                            options: {contentOffset: 76}                        }])            },            _getAnonimousTemplateName: function() {                return ANONYMOUS_TEMPLATE_NAME            },            _init: function() {                this.callBase();                this.element().addClass(SLIDEOUTVIEW_CLASS);                this._deferredAnimate = undefined;                this._initHideTopOverlayHandler()            },            _initHideTopOverlayHandler: function() {                this._hideMenuHandler = $.proxy(this.hideMenu, this)            },            _render: function() {                this.callBase();                this._renderShield();                this._initSwipeHandlers();                this._dimensionChanged()            },            _renderContentImpl: function() {                this._renderMarkup();                var menuTemplate = this._getTemplate(this.option("menuTemplate")),                    contentTemplate = this._getTemplate(this.option("contentTemplate"));                menuTemplate && menuTemplate.render(this.menuContent());                contentTemplate && contentTemplate.render(this.content())            },            _renderMarkup: function() {                var $wrapper = $("<div>").addClass(SLIDEOUTVIEW_WRAPPER_CLASS);                this._$menu = $("<div>").addClass(SLIDEOUTVIEW_MENU_CONTENT_CLASS);                this._$container = $("<div>").addClass(SLIDEOUTVIEW_CONTENT_CLASS);                $wrapper.append(this._$menu);                $wrapper.append(this._$container);                this.element().append($wrapper);                this._$container.on("MSPointerDown", $.noop)            },            _renderShield: function() {                this._$shield = this._$shield || $("<div>").addClass(SLIDEOUTVIEW_SHIELD_CLASS);                this._$shield.appendTo(this.content());                this._$shield.off("dxclick").on("dxclick", $.proxy(this.hideMenu, this));                this._toggleShieldVisibility(this.option("menuVisible"))            },            _initSwipeHandlers: function() {                this._createComponent(this.content(), "dxSwipeable", {                    disabled: !this.option("swipeEnabled"),                    elastic: false,                    itemSizeFunc: $.proxy(this._getMenuWidth, this),                    onStart: $.proxy(this._swipeStartHandler, this),                    onUpdated: $.proxy(this._swipeUpdateHandler, this),                    onEnd: $.proxy(this._swipeEndHandler, this)                })            },            _swipeStartHandler: function(e) {                var event = e.jQueryEvent,                    menuVisible = this.option("menuVisible"),                    rtl = this.option("rtlEnabled");                event.maxLeftOffset = +(rtl ? !menuVisible : menuVisible);                event.maxRightOffset = +(rtl ? menuVisible : !menuVisible);                this._toggleShieldVisibility(true)            },            _swipeUpdateHandler: function(e) {                var event = e.jQueryEvent,                    offset = this.option("menuVisible") ? event.offset + 1 * this._getRTLSignCorrection() : event.offset;                offset *= this._getRTLSignCorrection();                this._renderPosition(offset, false)            },            _swipeEndHandler: function(e) {                var targetOffset = e.jQueryEvent.targetOffset * this._getRTLSignCorrection() + this.option("menuVisible"),                    menuVisible = targetOffset !== 0;                if (this.option("menuVisible") === menuVisible)                    this._renderPosition(this.option("menuVisible"), true);                else                    this.option("menuVisible", menuVisible)            },            _renderPosition: function(offset, animate) {                var pos = this._calculatePixelOffset(offset) * this._getRTLSignCorrection();                this._toggleHideMenuCallback(offset);                if (animate) {                    this._toggleShieldVisibility(true);                    animation.moveTo(this.content(), pos, $.proxy(this._animationCompleteHandler, this))                }                else                    translator.move(this.content(), {left: pos})            },            _calculatePixelOffset: function(offset) {                offset = offset || 0;                return offset * this._getMenuWidth()            },            _getMenuWidth: function() {                if (!this._menuWidth) {                    var maxMenuWidth = this.element().width() - this.option("contentOffset");                    this.menuContent().css("max-width", maxMenuWidth);                    var currentMenuWidth = this.menuContent().width();                    this._menuWidth = Math.min(currentMenuWidth, maxMenuWidth)                }                return this._menuWidth            },            _animationCompleteHandler: function() {                this._toggleShieldVisibility(this.option("menuVisible"));                if (this._deferredAnimate)                    this._deferredAnimate.resolveWith(this)            },            _toggleHideMenuCallback: function(subscribe) {                if (subscribe)                    DX.hideTopOverlayCallback.add(this._hideMenuHandler);                else                    DX.hideTopOverlayCallback.remove(this._hideMenuHandler)            },            _getRTLSignCorrection: function() {                return this.option("rtlEnabled") ? -1 : 1            },            _dispose: function() {                fx.stop(this.content());                this._toggleHideMenuCallback(false);                this.callBase()            },            _visibilityChanged: function(visible) {                if (visible)                    this._dimensionChanged()            },            _dimensionChanged: function() {                delete this._menuWidth;                this._renderPosition(this.option("menuVisible"), false)            },            _toggleShieldVisibility: function(visible) {                this._$shield.toggleClass(INVISIBLE_STATE_CLASS, !visible)            },            _optionChanged: function(args) {                switch (args.name) {                    case"width":                        this.callBase(args);                        this._dimensionChanged();                        break;                    case"contentOffset":                        this._dimensionChanged();                        break;                    case"menuVisible":                        this._renderPosition(args.value, true);                        break;                    case"swipeEnabled":                        this._initSwipeHandlers();                        break;                    case"contentTemplate":                    case"menuTemplate":                        this._invalidate();                        break;                    default:                        this.callBase(args)                }            },            menuContent: function() {                return this._$menu            },            content: function() {                return this._$container            },            showMenu: function() {                return this.toggleMenuVisibility(true)            },            hideMenu: function() {                return this.toggleMenuVisibility(false)            },            toggleMenuVisibility: function(showing) {                showing = showing === undefined ? !this.option("menuVisible") : showing;                this._deferredAnimate = $.Deferred();                this.option("menuVisible", showing);                return this._deferredAnimate.promise()            }        }));        ui.dxSlideOutView.__internals = {animation: animation}    })(jQuery, DevExpress);    /*! Module widgets-mobile, file ui.slideOut.js */    (function($, DX, undefined) {        var ui = DX.ui,            utils = DX.utils;        var SLIDEOUT_CLASS = "dx-slideout",            SLIDEOUT_ITEM_CONTAINER_CLASS = "dx-slideout-item-container",            SLIDEOUT_MENU = "dx-slideout-menu",            SLIDEOUT_ITEM_CLASS = "dx-slideout-item",            SLIDEOUT_ITEM_DATA_KEY = "dxSlideoutItemData";        DX.registerComponent("dxSlideOut", ui, ui.CollectionWidget.inherit({            _setDeprecatedOptions: function() {                this.callBase();                $.extend(this._deprecatedOptions, {                    menuItemRender: {                        since: "14.2",                        alias: "menuItemTemplate"                    },                    menuGroupRender: {                        since: "14.2",                        alias: "menuGroupTemplate"                    }                })            },            _setDefaultOptions: function() {                this.callBase();                this.option({                    activeStateEnabled: false,                    menuItemTemplate: "menuItem",                    swipeEnabled: true,                    menuVisible: false,                    menuGrouped: false,                    menuGroupTemplate: "menuGroup",                    onMenuItemRendered: null,                    onMenuGroupRendered: null,                    contentTemplate: "content",                    selectionMode: "single",                    selectionRequired: true                })            },            _itemClass: function() {                return SLIDEOUT_ITEM_CLASS            },            _itemDataKey: function() {                return SLIDEOUT_ITEM_DATA_KEY            },            _itemContainer: function() {                return this._slideOutView.content()            },            _init: function() {                this.callBase();                this.element().addClass(SLIDEOUT_CLASS);                this._initSlideOutView()            },            _initEditStrategy: function() {                if (this.option("menuGrouped")) {                    var strategy = ui.CollectionWidget.PlainEditStrategy.inherit({_getPlainItems: function() {                                return $.map(this.callBase(), function(group) {                                        return group.items                                    })                            }});                    this._editStrategy = new strategy(this)                }                else                    this.callBase()            },            _initSlideOutView: function() {                this._slideOutView = this._createComponent(this.element(), "dxSlideOutView", {                    _templates: [],                    menuVisible: this.option("menuVisible"),                    swipeEnabled: this.option("swipeEnabled"),                    onOptionChanged: $.proxy(this._slideOutViewOptionChanged, this)                });                this._itemContainer().addClass(SLIDEOUT_ITEM_CONTAINER_CLASS)            },            _slideOutViewOptionChanged: function(args) {                if (args.name === "menuVisible")                    this.option(args.name, args.value)            },            _render: function() {                this._slideOutView._renderShield();                this._renderList();                this._renderContentTemplate();                this.callBase()            },            _renderList: function() {                this._$list = this._$list || $("<div>").addClass(SLIDEOUT_MENU).appendTo(this._slideOutView.menuContent());                this._renderItemClickAction();                this._createComponent(this._$list, "dxList", {                    itemTemplateProperty: "menuTemplate",                    indicateLoading: false,                    onItemClick: $.proxy(this._listItemClickHandler, this),                    items: this.option("items"),                    dataSource: this.option("dataSource"),                    itemTemplate: this._getTemplateByOption("menuItemTemplate"),                    grouped: this.option("menuGrouped"),                    groupTemplate: this.option("menuGroupTemplate"),                    onItemRendered: this.option("onMenuItemRendered"),                    onGroupRendered: this.option("onMenuGroupRendered"),                    onContentReady: $.proxy(this._updateSlideOutView, this)                })            },            _updateSlideOutView: function() {                this._slideOutView._dimensionChanged()            },            _renderItemClickAction: function() {                this._itemClickAction = this._createActionByOption("onItemClick")            },            _listItemClickHandler: function(e) {                var selectedIndex = this._$list.find(".dx-list-item").index(e.itemElement);                this.option("selectedIndex", selectedIndex);                this._itemClickAction(e)            },            _renderContentTemplate: function() {                if (utils.isDefined(this._singleContent))                    return;                var $result = this._getTemplateByOption("contentTemplate").render(this._itemContainer());                this._singleContent = !!$result.length || $result.is(":empty")            },            _itemClickHandler: $.noop,            _renderContentImpl: function(template) {                if (this._singleContent)                    return;                var items = this.option("items"),                    selectedIndex = this.option("selectedIndex");                if (items.length && selectedIndex > -1) {                    var selectedItem = this._$list.dxList("instance").getItemByIndex(selectedIndex);                    this._renderItems([selectedItem])                }            },            _renderItem: function(index, item, container) {                this._itemContainer().find("." + SLIDEOUT_ITEM_CLASS).remove();                this.callBase(index, item)            },            _selectedItemElement: function(index) {                return this._itemElements().eq(0)            },            _renderSelection: function() {                this._renderContent()            },            _getListWidth: function() {                return this._slideOutView._getMenuWidth()            },            _changeMenuOption: function(name, value) {                this._$list.dxList("instance").option(name, value);                this._updateSlideOutView()            },            _cleanItemContainer: function() {                if (this._singleContent)                    return;                this.callBase()            },            _optionChanged: function(args) {                var name = args.name;                var value = args.value;                switch (name) {                    case"menuVisible":                    case"swipeEnabled":                    case"rtlEnabled":                        this._slideOutView.option(name, value);                        break;                    case"width":                        this.callBase(args);                        this._updateSlideOutView();                        break;                    case"menuItemTemplate":                        this._changeMenuOption("itemTemplate", this._getTemplate(value));                        break;                    case"items":                        this._changeMenuOption(name, value);                        break;                    case"dataSource":                        this._changeMenuOption(name, value);                        this.callBase(args);                        break;                    case"menuGrouped":                        this._initEditStrategy();                        this._changeMenuOption("grouped", value);                        break;                    case"menuGroupTemplate":                        this._changeMenuOption("groupTemplate", this._getTemplate(value));                        break;                    case"onMenuItemRendered":                        this._changeMenuOption("onItemRendered", value);                        break;                    case"onMenuGroupRendered":                        this._changeMenuOption("onGroupRendered", value);                        break;                    case"onItemClick":                        this._renderItemClickAction();                        break;                    case"contentTemplate":                        this._singleContent = null;                        this._invalidate();                        break;                    default:                        this.callBase(args)                }            },            showMenu: function() {                return this._slideOutView.toggleMenuVisibility(true)            },            hideMenu: function() {                return this._slideOutView.toggleMenuVisibility(false)            },            toggleMenuVisibility: function(showing) {                return this._slideOutView.toggleMenuVisibility(showing)            }        }))    })(jQuery, DevExpress);    DevExpress.MOD_WIDGETS_MOBILE = true}if (!DevExpress.MOD_WIDGETS_WEB) {    if (!DevExpress.MOD_WIDGETS_BASE)        throw Error('Required module is not referenced: widgets-base');    /*! Module widgets-web, file ui.accordion.js */    (function($, DX, undefined) {        var ui = DX.ui,            events = ui.events,            fx = DX.fx;        var ACCORDION_CLASS = "dx-accordion",            ACCORDION_WRAPPER_CLASS = "dx-accordion-wrapper",            ACCORDION_ITEM_CLASS = "dx-accordion-item",            ACCORDION_ITEM_OPENED_CLASS = "dx-accordion-item-opened",            ACCORDION_ITEM_CLOSED_CLASS = "dx-accordion-item-closed",            ACCORDION_ITEM_TITLE_CLASS = "dx-accordion-item-title",            ACCORDION_ITEM_BODY_CLASS = "dx-accordion-item-body",            ACCORDION_ITEM_DATA_KEY = "dxAccordionItemData",            ACCORDION_ITEM_TITLE_DATA_KEY = "dxAccordionItemTitleData",            ACCORDION_ITEM_CONTENT_DATA_KEY = "dxAccordionItemContentData";        DX.registerComponent("dxAccordion", ui, ui.CollectionWidget.inherit({            _activeStateUnit: "." + ACCORDION_ITEM_CLASS,            _setDefaultOptions: function() {                this.callBase();                this.option({                    height: undefined,                    itemTitleTemplate: "title",                    onItemTitleClick: null,                    onItemTitleHold: null,                    selectedIndex: 0,                    collapsible: false,                    multiple: false,                    animationDuration: 300,                    deferRendering: true,                    selectionByClick: true,                    activeStateEnabled: true,                    _itemAttributes: {role: "tab"}                })            },            _defaultOptionsRules: function() {                return this.callBase().concat([{                            device: function(device) {                                return DX.devices.real().generic && !DX.devices.isSimulator()                            },                            options: {                                hoverStateEnabled: true,                                focusStateEnabled: true                            }                        }])            },            _init: function() {                this.callBase();                this.option("selectionRequired", !this.option("collapsible"));                this.option("selectionMode", this.option("multiple") ? "multi" : "single");                var $element = this.element();                $element.addClass(ACCORDION_CLASS);                this._$container = $("<div>").addClass(ACCORDION_WRAPPER_CLASS);                $element.append(this._$container)            },            _render: function() {                this._deferredItems = [];                this.callBase();                this.setAria({                    role: "tablist",                    multiselectable: this.option("multiple")                });                this._attachItemTitleClickAction()            },            _itemDataKey: function() {                return ACCORDION_ITEM_DATA_KEY            },            _itemClass: function() {                return ACCORDION_ITEM_CLASS            },            _itemContainer: function() {                return this._$container            },            _itemTitles: function() {                return this._itemElements().find("." + ACCORDION_ITEM_TITLE_CLASS)            },            _itemContents: function() {                return this._itemElements().find("." + ACCORDION_ITEM_BODY_CLASS)            },            _getItemData: function(target) {                return $(target).parent().data(this._itemDataKey()) || this.callBase.apply(this, arguments)            },            _executeItemRenderAction: function(itemData, itemElement) {                if (itemData.type)                    return;                this.callBase.apply(this, arguments)            },            _itemSelectHandler: function(e) {                if ($(e.target).closest("." + ACCORDION_ITEM_BODY_CLASS).length)                    return;                this.callBase.apply(this, arguments)            },            _renderItemContent: function(index, itemData, $container) {                $container = $container || this._itemContainer();                var $itemTitle = this.callBase.apply(this, [index, $.extend({                            type: "title",                            titleTemplate: this._getTemplateByOption("itemTitleTemplate")                        }, itemData), $container]);                var $item = $itemTitle.parent();                this._deferredItems.push($.Deferred());                this._deferredItems[index].done($.proxy(this._renderItemBody, this, this.callBase, index, itemData, $item));                if (!this.option("deferRendering"))                    this._deferredItems[index].resolve()            },            _renderItemBody: function(baseRenderer, index, itemData, $item) {                var $itemBody = $("<div>").appendTo($item);                baseRenderer.apply(this, [index, $.extend({                        type: "content",                        template: this._getTemplateByOption("itemTemplate")                    }, itemData), $itemBody])            },            _getItemTemplateName: function(itemData) {                var templateProperty = this.option("itemTemplateProperty");                if (itemData.type === "title")                    templateProperty = "titleTemplate";                return itemData && itemData[templateProperty] || this.option("itemTemplate")            },            _addItemContentClasses: function($container, itemData) {                switch (itemData.type) {                    case"title":                        $container.addClass(ACCORDION_ITEM_TITLE_CLASS).data(ACCORDION_ITEM_TITLE_DATA_KEY, itemData);                        break;                    case"content":                        $container.addClass(ACCORDION_ITEM_BODY_CLASS).data(ACCORDION_ITEM_CONTENT_DATA_KEY, itemData);                        break;                    default:                        this.callBase.apply(this, arguments)                }            },            _attachItemTitleClickAction: function() {                var itemSelector = "." + ACCORDION_ITEM_TITLE_CLASS,                    eventName = events.addNamespace("dxclick", this.NAME);                this._itemContainer().off(eventName, itemSelector).on(eventName, itemSelector, $.proxy(this._itemTitleClickHandler, this))            },            _itemTitleClickHandler: function(e) {                this._itemJQueryEventHandler(e, "onItemTitleClick")            },            _renderSelection: function(addedSelection, removedSelection) {                this._itemElements().addClass(ACCORDION_ITEM_CLOSED_CLASS);                this._updateItems(addedSelection, removedSelection, true)            },            _updateSelection: function(addedSelection, removedSelection) {                this._updateItems(addedSelection, removedSelection, false)            },            _updateItems: function(addedSelection, removedSelection, skipAnimation) {                var $items = this._itemElements(),                    that = this;                $.each(addedSelection, function(_, index) {                    var $item = $items.eq(index);                    if ($item.find("." + ACCORDION_ITEM_BODY_CLASS).length === 0)                        that._deferredItems[index].resolve();                    $item.addClass(ACCORDION_ITEM_OPENED_CLASS);                    $item.removeClass(ACCORDION_ITEM_CLOSED_CLASS)                });                $.each(removedSelection, function(_, index) {                    $items.eq(index).removeClass(ACCORDION_ITEM_OPENED_CLASS)                });                this._updateItemHeights(skipAnimation)            },            _updateItemHeights: function(skipAnimation) {                var $items = this._itemElements();                var itemHeight = this._splitFreeSpace(this._calculateFreeSpace());                $.each($items, $.proxy(function(_, item) {                    var $item = $(item),                        $title = $item.children("." + ACCORDION_ITEM_TITLE_CLASS);                    var startItemHeight = $item.outerHeight();                    var finalItemHeight = $item.hasClass(ACCORDION_ITEM_OPENED_CLASS) ? itemHeight + $title.outerHeight() || $item.height("auto").outerHeight() : $title.outerHeight();                    if (fx.isAnimating($item))                        fx.stop($item);                    if (!skipAnimation)                        this._animateItem($item, startItemHeight, finalItemHeight);                    else                        $item.css("height", finalItemHeight)                }, this))            },            _animateItem: function(element, startHeight, endHeight) {                fx.animate(element, {                    type: "slide",                    from: {height: startHeight},                    to: {height: endHeight},                    duration: this.option("animationDuration"),                    complete: $.proxy(function() {                        if (this._deferredAnimate)                            this._deferredAnimate.resolveWith(this);                        this._itemElements().not("." + ACCORDION_ITEM_OPENED_CLASS).addClass(ACCORDION_ITEM_CLOSED_CLASS)                    }, this)                })            },            _splitFreeSpace: function(freeSpace) {                if (!freeSpace)                    return freeSpace;                return freeSpace / this.option("selectedItems").length            },            _calculateFreeSpace: function() {                var height = this.option("height");                if (height === undefined || height === "auto")                    return;                var $titles = this._itemTitles(),                    itemsHeight = 0;                $.each($titles, function(_, title) {                    itemsHeight += $(title).outerHeight()                });                return this.element().height() - itemsHeight            },            _visibilityChanged: function(visible) {                if (visible)                    this._dimensionChanged()            },            _dimensionChanged: function() {                this._updateItemHeights(true)            },            _optionChanged: function(args) {                switch (args.name) {                    case"animationDuration":                    case"onItemTitleClick":                        break;                    case"collapsible":                        this.option("selectionRequired", !this.option("collapsible"));                        break;                    case"itemTitleTemplate":                    case"itemContentTemplate":                    case"onItemTitleHold":                    case"height":                    case"deferRendering":                        this._invalidate();                        break;                    case"multiple":                        this.option("selectionMode", args.value ? "multi" : "single");                        break;                    default:                        this.callBase(args)                }            },            expandItem: function(index) {                this._deferredAnimate = $.Deferred();                this.selectItem(index);                return this._deferredAnimate.promise()            },            collapseItem: function(index) {                this._deferredAnimate = $.Deferred();                this.unselectItem(index);                return this._deferredAnimate.promise()            }        }))    })(jQuery, DevExpress);    /*! Module widgets-web, file ui.pager.js */    (function($, DX, undefined) {        var ui = DX.ui,            utils = DX.utils,            events = ui.events,            Class = DX.Class;        var PAGES_LIMITER = 4,            PAGER_CLASS = 'dx-pager',            PAGER_PAGE_CLASS = 'dx-page',            PAGER_PAGES_CLASS = 'dx-pages',            PAGER_SELECTION_CLASS = 'dx-selection',            PAGER_PAGE_SEPARATOR_CLASS = 'dx-separator',            PAGER_PAGE_SIZES_CLASS = 'dx-page-sizes',            PAGER_PAGE_SIZE_CLASS = 'dx-page-size',            PAGER_NAVIGATE_BUTTON = 'dx-navigate-button',            PAGER_PREV_BUTTON_CLASS = "dx-prev-button",            PAGER_NEXT_BUTTON_CLASS = "dx-next-button",            PAGER_INFO_CLASS = "dx-info",            PAGER_BUTTON_DISABLE_CLASS = "dx-button-disable";        var Page = Class.inherit({                ctor: function(value, index) {                    var that = this;                    that.index = index;                    that._$page = $('<div />').text(value).addClass(PAGER_PAGE_CLASS)                },                value: function(value) {                    var that = this;                    if (utils.isDefined(value))                        that._$page.text(value);                    else {                        var text = that._$page.text();                        if (utils.isNumber(text))                            return parseInt(text);                        else                            return text                    }                },                element: function() {                    return this._$page                },                select: function(value) {                    this._$page.toggleClass(PAGER_SELECTION_CLASS, value)                },                render: function(rootElement, rtlEnabled) {                    rtlEnabled ? this._$page.prependTo(rootElement) : this._$page.appendTo(rootElement)                }            });        DX.registerComponent("dxPager", ui, ui.Widget.inherit({            _setDefaultOptions: function() {                this.callBase();                this.option({                    visible: true,                    pageIndex: 1,                    maxPagesCount: 10,                    pageCount: 10,                    pageSize: 5,                    showPageSizes: true,                    pageSizes: [5, 10],                    hasKnownLastPage: true,                    showNavigationButtons: false,                    showInfo: false,                    infoText: Globalize.localize("dxPager-infoText"),                    rtlEnabled: false,                    pageIndexChanged: $.noop,                    pageSizeChanged: $.noop                })            },            _toggleVisibility: function(value) {                var $element = this.element();                if ($element)                    $element.css("display", value ? "" : "none")            },            _getPages: function(currentPage, count) {                var pages = [],                    showMoreButton = !this.option("hasKnownLastPage"),                    firstValue,                    i;                this._testPagesCount = count;                this._testShowMoreButton = showMoreButton;                if (count > 0 || showMoreButton)                    if (count <= this.option("maxPagesCount")) {                        for (i = 1; i <= count; i++)                            pages.push(new Page(i, i - 1));                        if (showMoreButton)                            pages.push(new Page('>', i - 1))                    }                    else {                        pages.push(new Page(1, 0));                        firstValue = currentPage ? currentPage.value() - currentPage.index : 1;                        for (i = 1; i <= PAGES_LIMITER; i++)                            pages.push(new Page(firstValue + i, i));                        pages.push(new Page(count, PAGES_LIMITER + 1));                        if (showMoreButton)                            pages.push(new Page('>', PAGES_LIMITER + 1))                    }                return pages            },            _getPageByValue: function(value) {                var that = this,                    page,                    i;                for (i = 0; i < that._pages.length; i++) {                    page = that._pages[i];                    if (page.value() === value)                        return page                }            },            _processSelectedPage: function(maxPagesCount, pageIndex, pageCount) {                var that = this,                    isPageIndexValid = false,                    selectedPageIndex;                if (that._pages) {                    $.each(that._pages, function(key, page) {                        if (pageIndex === page.value())                            isPageIndexValid = true                    });                    if (!isPageIndexValid)                        that.selectedPage = null                }                if (utils.isDefined(that.selectedPage)) {                    if (pageIndex === pageCount && pageCount > maxPagesCount && that.selectedPage.index !== PAGES_LIMITER + 1)                        that.selectedPage.index = PAGES_LIMITER + 1                }                else if (pageIndex > PAGES_LIMITER && pageIndex < pageCount) {                    selectedPageIndex = pageCount - PAGES_LIMITER < pageIndex ? PAGES_LIMITER - (pageCount - pageIndex) + 1 : 2;                    that.selectedPage = new Page(pageIndex, selectedPageIndex)                }            },            _selectPageByValue: function(value) {                var that = this,                    i,                    page = that._getPageByValue(value),                    pages = that._pages,                    pagesLength = pages.length,                    prevPage,                    nextPage,                    morePage;                if (!utils.isDefined(page))                    return;                prevPage = that._pages[page.index - 1];                nextPage = that._pages[page.index + 1];                if (nextPage && nextPage.value() === '>') {                    morePage = nextPage;                    nextPage = undefined;                    pagesLength--;                    pages.pop()                }                if (that.selectedPage)                    that.selectedPage.select(false);                page.select(true);                that.selectedPage = page;                if (nextPage && nextPage.value() - value > 1)                    if (page.index !== 0) {                        prevPage.value(value + 1);                        that._pages.splice(page.index, 1);                        that._pages.splice(page.index - 1, 0, page);                        that._pages[page.index].index = page.index;                        page.index = page.index - 1;                        for (i = page.index - 1; i > 0; i--)                            that._pages[i].value(that._pages[i + 1].value() - 1)                    }                    else                        for (i = 0; i < pagesLength - 1; i++)                            that._pages[i].value(i + 1);                if (prevPage && value - prevPage.value() > 1)                    if (page.index !== pagesLength - 1) {                        nextPage.value(value - 1);                        that._pages.splice(page.index, 1);                        that._pages.splice(page.index + 1, 0, page);                        that._pages[page.index].index = page.index;                        page.index = page.index + 1;                        for (i = page.index + 1; i < pagesLength - 1; i++)                            that._pages[i].value(that._pages[i - 1].value() + 1)                    }                    else                        for (i = 1; i <= pagesLength - 2; i++)                            that._pages[pagesLength - 1 - i].value(that._pages[pagesLength - 1].value() - i);                if (morePage)                    pages.push(morePage)            },            _nextPage: function(direction) {                var pageIndex = this.selectedPage && this.selectedPage.value(),                    pageCount = this.option("pageCount");                if (utils.isDefined(pageIndex)) {                    pageIndex = direction === "next" ? ++pageIndex : --pageIndex;                    if (pageIndex > 0 && pageIndex <= pageCount)                        this.option("pageIndex", pageIndex)                }            },            _renderPages: function(pages) {                var that = this,                    $separator,                    pageslength = pages.length,                    clickPagesIndexAction = that._createAction(function(args) {                        var e = args.jQueryEvent,                            pageNumber = $(e.target).text(),                            pageIndex = pageNumber === '>' ? that.option("pageCount") + 1 : Number(pageNumber);                        that._testPageIndex = pageIndex;                        that.option("pageIndex", pageIndex)                    }),                    page;                if (pageslength > 1) {                    that._pageClickHandler = function(e) {                        clickPagesIndexAction({jQueryEvent: e})                    };                    that.$pagesChooser.on(events.addNamespace("dxclick", that.Name + "Pages"), '.' + PAGER_PAGE_CLASS, that._pageClickHandler)                }                for (var i = 0; i < pageslength; i++) {                    page = pages[i];                    page.render(that.$pagesChooser, that.option('rtlEnabled'));                    that.setAria({                        role: "button",                        label: "Page " + page.value()                    }, page.element());                    if (pages[i + 1] && pages[i + 1].value() - page.value() > 1) {                        $separator = $("<div>. . .</div>").addClass(PAGER_PAGE_SEPARATOR_CLASS);                        that.option('rtlEnabled') ? $separator.prependTo(that.$pagesChooser) : $separator.appendTo(that.$pagesChooser)                    }                }            },            _renderPagesChooser: function() {                var that = this,                    $element = that.element();                if (!$element)                    return;                if (that._pages.length === 0) {                    that.selectedPage = null;                    return                }                if (utils.isDefined(that.$pagesChooser))                    that.$pagesChooser.empty();                else                    that.$pagesChooser = $('<div />').addClass(PAGER_PAGES_CLASS);                that._renderInfo();                that._renderNavigateButton("prev");                that._renderPages(that._pages);                that._renderNavigateButton("next");                if (!utils.isDefined(that.$pagesChooser[0].parentElement))                    that.$pagesChooser.appendTo($element)            },            _renderPagesSizeChooser: function() {                var that = this,                    i,                    $pageSize,                    currentPageSize = that.option("pageSize"),                    pageSizes = that.option("pageSizes"),                    showPageSizes = that.option("showPageSizes"),                    pageSizeValue,                    pagesSizesLength = pageSizes && pageSizes.length,                    $element = that.element();                if (!$element)                    return;                that._clickPagesSizeAction = that._createAction(function(args) {                    var e = args.jQueryEvent;                    pageSizeValue = parseInt($(e.target).text());                    that._testPageSizeIndex = pageSizeValue;                    that.option("pageSize", pageSizeValue)                });                if (utils.isDefined(that.pagesSizeChooserElement))                    that.pagesSizeChooserElement.empty();                else                    that.pagesSizeChooserElement = $('<div />').addClass(PAGER_PAGE_SIZES_CLASS).on(events.addNamespace("dxclick", that.Name + "PageSize"), '.' + PAGER_PAGE_SIZE_CLASS, function(e) {                        that._clickPagesSizeAction({jQueryEvent: e})                    });                if (!showPageSizes || !pagesSizesLength)                    return;                that._testCurrentPageSize = currentPageSize;                for (i = 0; i < pagesSizesLength; i++) {                    $pageSize = $('<div />').text(pageSizes[i]).addClass(PAGER_PAGE_SIZE_CLASS);                    that.setAria({                        role: "button",                        label: "Display " + pageSizes[i] + " items on page"                    }, $pageSize);                    if (currentPageSize === pageSizes[i])                        $pageSize.addClass(PAGER_SELECTION_CLASS);                    that.option('rtlEnabled') ? that.pagesSizeChooserElement.prepend($pageSize) : that.pagesSizeChooserElement.append($pageSize)                }                if (!utils.isDefined(that.pagesSizeChooserElement[0].parentElement))                    that.pagesSizeChooserElement.appendTo($element)            },            _renderInfo: function() {                var infoText = this.option("infoText");                if (this.option("showInfo") && utils.isDefined(infoText))                    $("<div>").addClass(PAGER_INFO_CLASS).text(utils.stringFormat(infoText, this.selectedPage && this.selectedPage.value(), this.option("pageCount"))).appendTo(this.$pagesChooser)            },            _renderNavigateButton: function(direction) {                var that = this,                    currentPageIndex,                    clickAction = that._createAction(function(e) {                        that._nextPage(direction)                    }),                    $button,                    enabled;                if (that.option("showNavigationButtons")) {                    currentPageIndex = that.option("pageIndex");                    enabled = currentPageIndex > 1 && direction === "prev" || currentPageIndex < that.option("pageCount") && direction === "next";                    $button = $("<div>").addClass(PAGER_NAVIGATE_BUTTON).addClass(!enabled ? PAGER_BUTTON_DISABLE_CLASS : "").on(events.addNamespace("dxclick", that.Name + "Pages"), function(e) {                        clickAction({jQueryEvent: e})                    });                    that.setAria({                        role: "button",                        label: direction === "prev" ? "Previous page" : " Next page"                    }, $button);                    if (that.option("rtlEnabled")) {                        $button.addClass(direction === "prev" ? PAGER_NEXT_BUTTON_CLASS : PAGER_PREV_BUTTON_CLASS);                        $button.prependTo(this.$pagesChooser)                    }                    else {                        $button.addClass(direction === "prev" ? PAGER_PREV_BUTTON_CLASS : PAGER_NEXT_BUTTON_CLASS);                        $button.appendTo(this.$pagesChooser)                    }                }            },            _render: function() {                this.callBase();                this._update();                this.element().addClass(PAGER_CLASS);                this._toggleVisibility(this.option("visible"));                this._renderPagesSizeChooser();                this._renderPagesChooser()            },            _update: function() {                var pageCount = this.option("pageCount"),                    pageIndex = this.option("pageIndex");                this._processSelectedPage(this.option("maxPagesCount"), pageIndex, pageCount);                this._pages = this._getPages(this.selectedPage, pageCount);                this._selectPageByValue(pageIndex)            },            _optionChanged: function(args) {                switch (args.name) {                    case"visible":                        this._toggleVisibility(args.value);                        break;                    case"pageIndex":                        var pageIndexChanged = this.option("pageIndexChanged");                        if (pageIndexChanged)                            pageIndexChanged(args.value);                        this._update();                        this._renderPagesChooser();                        break;                    case"maxPagesCount":                    case"pageCount":                    case"hasKnownLastPage":                    case"showNavigationButtons":                        this._update();                        this._renderPagesChooser();                        break;                    case"pageSize":                        var pageSizeChanged = this.option("pageSizeChanged");                        if (pageSizeChanged)                            pageSizeChanged(args.value);                        this._renderPagesSizeChooser();                        break;                    case"pageSizes":                        this._renderPagesSizeChooser();                        break;                    default:                        this._invalidate()                }            },            _clean: function() {                this.$pagesChooser && this.$pagesChooser.off(events.addNamespace("dxclick", this.Name + "Pages"), '.' + PAGER_PAGE_CLASS, this._pageClickHandler)            },            getHeight: function() {                return this.option("visible") ? this.element().outerHeight() : 0            }        }));        ui.dxPager.__internals = {            PAGER_CLASS: PAGER_CLASS,            PAGER_PAGE_CLASS: PAGER_PAGE_CLASS,            PAGER_PAGES_CLASS: PAGER_PAGES_CLASS,            PAGER_SELECTION_CLASS: PAGER_SELECTION_CLASS,            PAGER_PAGE_SEPARATOR_CLASS: PAGER_PAGE_SEPARATOR_CLASS,            PAGER_PAGE_SIZES_CLASS: PAGER_PAGE_SIZES_CLASS,            PAGER_PAGE_SIZE_CLASS: PAGER_PAGE_SIZE_CLASS,            PAGER_NAVIGATE_BUTTON: PAGER_NAVIGATE_BUTTON,            PAGER_PREV_BUTTON_CLASS: PAGER_PREV_BUTTON_CLASS,            PAGER_NEXT_BUTTON_CLASS: PAGER_NEXT_BUTTON_CLASS,            PAGER_INFO_CLASS: PAGER_INFO_CLASS,            PAGER_BUTTON_DISABLE_CLASS: PAGER_BUTTON_DISABLE_CLASS        }    })(jQuery, DevExpress);    /*! Module widgets-web, file ui.colorView.js */    (function($, DX, undefined) {        var ui = DX.ui,            translator = DX.translator;        var COLOR_VIEW_CLASS = "dx-colorview",            COLOR_VIEW_CONTAINER_CLASS = "dx-colorview-container",            COLOR_VIEW_ROW_CLASS = "dx-colorview-container-row",            COLOR_VIEW_CELL_CLASS = "dx-colorview-container-cell",            COLOR_VIEW_PALETTE_CLASS = "dx-colorview-palette",            COLOR_VIEW_PALETTE_CELL_CLASS = "dx-colorview-palette-cell",            COLOR_VIEW_PALETTE_HANDLE_CLASS = "dx-colorview-palette-handle",            COLOR_VIEW_PALETTE_GRADIENT_CLASS = "dx-colorview-palette-gradient",            COLOR_VIEW_PALETTE_GRADIENT_WHITE_CLASS = "dx-colorview-palette-gradient-white",            COLOR_VIEW_PALETTE_GRADIENT_BLACK_CLASS = "dx-colorview-palette-gradient-black",            COLOR_VIEW_HUE_SCALE_CLASS = "dx-colorview-hue-scale",            COLOR_VIEW_HUE_SCALE_CELL_CLASS = "dx-colorview-hue-scale-cell",            COLOR_VIEW_HUE_SCALE_HANDLE_CLASS = "dx-colorview-hue-scale-handle",            COLOR_VIEW_HUE_SCALE_WRAPPER_CLASS = "dx-colorview-hue-scale-wrapper",            COLOR_VIEW_CONTROLS_CONTAINER_CLASS = "dx-colorview-controls-container",            COLOR_VIEW_RED_LABEL_CLASS = "dx-colorview-label-red",            COLOR_VIEW_GREEN_LABEL_CLASS = "dx-colorview-label-green",            COLOR_VIEW_BLUE_LABEL_CLASS = "dx-colorview-label-blue",            COLOR_VIEW_HEX_LABEL_CLASS = "dx-colorview-label-hex",            COLOR_VIEW_ALPHA_CHANNEL_SCALE_CLASS = "dx-colorview-alpha-channel-scale",            COLOR_VIEW_APLHA_CHANNEL_ROW_CLASS = "dx-colorview-alpha-channel-row",            COLOR_VIEW_ALPHA_CHANNEL_SCALE_WRAPPER_CLASS = "dx-colorview-alpha-channel-wrapper",            COLOR_VIEW_ALPHA_CHANNEL_LABEL_CLASS = "dx-colorview-alpha-channel-label",            COLOR_VIEW_ALPHA_CHANNEL_HANDLE_CLASS = "dx-colorview-alpha-channel-handle",            COLOR_VIEW_ALPHA_CHANNEL_CELL_CLASS = "dx-colorview-alpha-channel-cell",            COLOR_VIEW_ALPHA_CHANNEL_BORDER_CLASS = "dx-colorview-alpha-channel-border",            COLOR_VIEW_COLOR_PREVIEW = "dx-colorview-color-preview",            COLOR_VIEW_COLOR_PREVIEW_CONTAINER_CLASS = "dx-colorview-color-preview-container",            COLOR_VIEW_COLOR_PREVIEW_CONTAINER_INNER_CLASS = "dx-colorview-color-preview-container-inner",            COLOR_VIEW_COLOR_PREVIEW_COLOR_CURRENT = "dx-colorview-color-preview-color-current",            COLOR_VIEW_COLOR_PREVIEW_COLOR_NEW = "dx-colorview-color-preview-color-new";        DX.registerComponent("dxColorView", ui, ui.Editor.inherit({            _supportedKeys: function() {                var isRTL = this.option("rtlEnabled");                var that = this,                    getHorizontalPaletteStep = function(e) {                        var step = 100 / that._paletteWidth;                        if (e.shiftKey)                            step = step * that.option("keyStep");                        step = step > 1 ? step : 1;                        return Math.round(step)                    },                    updateHorizontalPaletteValue = function(step) {                        var value = that._currentColor.hsv.s + step;                        if (value > 100)                            value = 100;                        else if (value < 0)                            value = 0;                        that._currentColor.hsv.s = value;                        updatePaletteValue()                    },                    getVerticalPaletteStep = function(e) {                        var step = 100 / that._paletteHeight;                        if (e.shiftKey)                            step = step * that.option("keyStep");                        step = step > 1 ? step : 1;                        return Math.round(step)                    },                    updateVerticalPaletteValue = function(step) {                        var value = that._currentColor.hsv.v + step;                        if (value > 100)                            value = 100;                        else if (value < 0)                            value = 0;                        that._currentColor.hsv.v = value;                        updatePaletteValue()                    },                    updatePaletteValue = function() {                        that._placePaletteHandle();                        that._updateColorFromHsv(that._currentColor.hsv.h, that._currentColor.hsv.s, that._currentColor.hsv.v)                    },                    getHueScaleStep = function(e) {                        var step = 360 / (that._hueScaleWrapperHeight - that._hueScaleHandleHeight);                        if (e.shiftKey)                            step = step * that.option("keyStep");                        step = step > 1 ? step : 1;                        return step                    },                    updateHueScaleValue = function(step) {                        that._currentColor.hsv.h += step;                        that._placeHueScaleHandle();                        var handleLocation = translator.locate(that._$hueScaleHandle);                        that._updateColorHue(handleLocation.top + that._hueScaleHandleHeight / 2)                    },                    getAlphaScaleStep = function(e) {                        var step = 1 / that._alphaChannelScaleWorkWidth;                        if (e.shiftKey)                            step = step * that.option("keyStep");                        step = step > 0.01 ? step : 0.01;                        step = isRTL ? -step : step;                        return step                    },                    updateAlphaScaleValue = function(step) {                        that._currentColor.a += step;                        that._placeAlphaChannelHandle();                        var handleLocation = translator.locate(that._$alphaChannelHandle);                        that._calculateColorTransparenceByScaleWidth(handleLocation.left + that._alphaChannelHandleWidth / 2)                    };                return $.extend(this.callBase(), {                        upArrow: function(e) {                            e.preventDefault();                            e.stopPropagation();                            if (e.ctrlKey) {                                if (this._currentColor.hsv.h <= 360 && !this._isTopColorHue)                                    updateHueScaleValue(getHueScaleStep(e))                            }                            else if (this._currentColor.hsv.v < 100)                                updateVerticalPaletteValue(getVerticalPaletteStep(e))                        },                        downArrow: function(e) {                            e.preventDefault();                            e.stopPropagation();                            if (e.ctrlKey) {                                if (this._currentColor.hsv.h >= 0) {                                    if (this._isTopColorHue)                                        this._currentColor.hsv.h = 360;                                    updateHueScaleValue(-getHueScaleStep(e))                                }                            }                            else if (this._currentColor.hsv.v > 0)                                updateVerticalPaletteValue(-getVerticalPaletteStep(e))                        },                        rightArrow: function(e) {                            e.preventDefault();                            e.stopPropagation();                            if (e.ctrlKey) {                                if (isRTL ? this._currentColor.a < 1 : this._currentColor.a > 0 && this.option("editAlphaChannel"))                                    updateAlphaScaleValue(-getAlphaScaleStep(e))                            }                            else if (this._currentColor.hsv.s < 100)                                updateHorizontalPaletteValue(getHorizontalPaletteStep(e))                        },                        leftArrow: function(e) {                            e.preventDefault();                            e.stopPropagation();                            if (e.ctrlKey) {                                if (isRTL ? this._currentColor.a > 0 : this._currentColor.a < 1 && this.option("editAlphaChannel"))                                    updateAlphaScaleValue(getAlphaScaleStep(e))                            }                            else if (this._currentColor.hsv.s > 0)                                updateHorizontalPaletteValue(-getHorizontalPaletteStep(e))                        },                        enter: function(e) {                            if (this.option("applyValueMode") === "useButtons")                                this.applyColor()                        }                    })            },            _setDefaultOptions: function() {                this.callBase();                this.option({                    value: null,                    editAlphaChannel: false,                    applyValueMode: "useButtons",                    keyStep: 1                })            },            _defaultOptionsRules: function() {                return this.callBase().concat([{                            device: function(device) {                                return DX.devices.real().generic && !DX.devices.isSimulator()                            },                            options: {focusStateEnabled: true}                        }])            },            _init: function() {                this.callBase();                this._initColorAndOpacity()            },            _initColorAndOpacity: function() {                this._setCurrentColor(this.option("value"))            },            _setCurrentColor: function(value) {                value = value || "#000000";                var newColor = new DX.Color(value);                if (!newColor.colorIsInvalid) {                    if (!this._currentColor || this._makeRgba(this._currentColor) !== this._makeRgba(newColor)) {                        this._currentColor = newColor;                        if (this._$currentColor)                            this._makeTransparentBackground(this._$currentColor, newColor)                    }                }                else                    this.option("value", this._currentColor.baseColor)            },            _render: function() {                this.callBase();                this.element().addClass(COLOR_VIEW_CLASS);                this._renderColorPickerContainer()            },            _enterKeyHandler: function() {                if (this.option("applyValueMode") === "useButtons")                    this.applyColor()            },            _makeTransparentBackground: function($el, color) {                if (!(color instanceof DX.Color))                    color = new DX.Color(color);                if (DX.browser.msie && DX.browser.version === "8.0")                    $el.css({                        background: color.toHex(),                        filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=" + color.a * 100 + ")"                    });                else                    $el.css("backgroundColor", this._makeRgba(color))            },            _makeRgba: function(color) {                if (!(color instanceof DX.Color))                    color = new DX.Color(color);                return "rgba(" + [color.r, color.g, color.b, color.a].join(", ") + ")"            },            _renderValue: function() {                this.callBase(this.option("editAlphaChannel") ? this._makeRgba(this._currentColor) : this.option("value"))            },            _renderColorPickerContainer: function() {                var $parent = this.element();                this._$colorPickerContainer = $("<div>", {                    "class": COLOR_VIEW_CONTAINER_CLASS,                    appendTo: $parent                });                this._renderHtmlRows();                this._renderPalette();                this._renderHueScale();                this._renderControlsContainer();                this._renderControls();                this._renderAlphaChannelElements()            },            _renderHtmlRows: function(updatedOption) {                var $renderedRows = this._$colorPickerContainer.find("." + COLOR_VIEW_ROW_CLASS),                    renderedRowsCount = $renderedRows.length,                    rowCount = this._calculateRowsCount(),                    delta = renderedRowsCount - rowCount;                if (delta > 0) {                    var index = this._calculateRemovedHtmlRowIndex(renderedRowsCount, updatedOption);                    $renderedRows.eq(index).remove()                }                if (delta < 0) {                    delta = Math.abs(delta);                    var rows = [];                    for (var i = 0; i < delta; i++)                        rows.push($("<div>", {"class": COLOR_VIEW_ROW_CLASS}));                    if (renderedRowsCount) {                        var previousRowIndex = this._calculateHtmlRowIndex(renderedRowsCount, updatedOption);                        $renderedRows.eq(previousRowIndex).after(rows)                    }                    else                        this._$colorPickerContainer.append(rows)                }            },            _renderHtmlCellInsideRow: function(rowSelector, $rowParent, additionalClass) {                return $("<div>", {                        "class": COLOR_VIEW_CELL_CLASS,                        addClass: additionalClass,                        appendTo: $rowParent.find("." + COLOR_VIEW_ROW_CLASS + rowSelector)                    })            },            _calculateRowsCount: function() {                if (this.option("editAlphaChannel"))                    return this.option("applyValueMode") === "instantly" ? 2 : 3;                return this.option("applyValueMode") === "instantly" ? 1 : 2            },            _calculateRemovedHtmlRowIndex: function(renderedRowsCount, updatedOption) {                var index = -1;                if (renderedRowsCount === 3) {                    if (updatedOption === "editAlphaChannel")                        index = -2;                    if (updatedOption === "applyValueMode")                        index = -1                }                return index            },            _calculateHtmlRowIndex: function(renderedRowsCount, updatedOption) {                var index = 0;                if (renderedRowsCount === 2)                    if (updatedOption === "applyValueMode")                        index = 1;                return index            },            _renderPalette: function() {                var $paletteCell = this._renderHtmlCellInsideRow(":first", this._$colorPickerContainer, COLOR_VIEW_PALETTE_CELL_CLASS),                    $paletteGradientWhite = $("<div>", {"class": [COLOR_VIEW_PALETTE_GRADIENT_CLASS, COLOR_VIEW_PALETTE_GRADIENT_WHITE_CLASS].join(" ")}),                    $paletteGradientBlack = $("<div>", {"class": [COLOR_VIEW_PALETTE_GRADIENT_CLASS, COLOR_VIEW_PALETTE_GRADIENT_BLACK_CLASS].join(" ")});                this._$palette = $("<div>", {                    "class": COLOR_VIEW_PALETTE_CLASS,                    css: {backgroundColor: this._currentColor.getPureColor().toHex()},                    appendTo: $paletteCell                });                this._paletteHeight = this._$palette.height();                this._paletteWidth = this._$palette.width();                this._renderPaletteHandle();                this._$palette.append([$paletteGradientWhite, $paletteGradientBlack])            },            _renderPaletteHandle: function() {                this._createComponent(this._$paletteHandle = $("<div>", {                    "class": COLOR_VIEW_PALETTE_HANDLE_CLASS,                    appendTo: this._$palette                }), "dxDraggable", {                    area: this._$palette,                    allowMoveByClick: true,                    boundOffset: $.proxy(function() {                        return -this._paletteHandleHeight / 2                    }, this),                    onDrag: $.proxy(function(e) {                        var paletteHandlePosition = translator.locate(this._$paletteHandle);                        this._updateByDrag = true;                        this._updateColorFromHsv(this._currentColor.hsv.h, this._calculateColorSaturation(paletteHandlePosition), this._calculateColorValue(paletteHandlePosition))                    }, this)                });                this._paletteHandleWidth = this._$paletteHandle.width();                this._paletteHandleHeight = this._$paletteHandle.height();                this._placePaletteHandle()            },            _placePaletteHandle: function() {                translator.move(this._$paletteHandle, {                    left: Math.round(this._paletteWidth * this._currentColor.hsv.s / 100 - this._paletteHandleWidth / 2),                    top: Math.round(this._paletteHeight - this._paletteHeight * this._currentColor.hsv.v / 100 - this._paletteHandleHeight / 2)                })            },            _calculateColorValue: function(paletteHandlePosition) {                var value = Math.floor(paletteHandlePosition.top + this._paletteHandleHeight / 2);                return 100 - Math.round(value * 100 / this._paletteHeight)            },            _calculateColorSaturation: function(paletteHandlePosition) {                var saturation = Math.floor(paletteHandlePosition.left + this._paletteHandleWidth / 2);                return Math.round(saturation * 100 / this._paletteWidth)            },            _updateColorFromHsv: function(hue, saturation, value) {                var a = this._currentColor.a;                this._currentColor = new DX.Color("hsv(" + [hue, saturation, value].join(",") + ")");                this._currentColor.a = a;                this._updateColorParamsAndColorPreview();                if (this.option("applyValueMode") === "instantly")                    this.applyColor()            },            _renderHueScale: function() {                var $hueScaleCell = this._renderHtmlCellInsideRow(":first", this._$colorPickerContainer, COLOR_VIEW_HUE_SCALE_CELL_CLASS);                this._$hueScaleWrapper = $("<div>", {                    "class": COLOR_VIEW_HUE_SCALE_WRAPPER_CLASS,                    appendTo: $hueScaleCell                });                this._$hueScale = $("<div>", {                    "class": COLOR_VIEW_HUE_SCALE_CLASS,                    appendTo: this._$hueScaleWrapper                });                this._hueScaleHeight = this._$hueScale.height();                this._hueScaleWrapperHeight = this._$hueScaleWrapper.outerHeight();                this._renderHueScaleHandle()            },            _renderHueScaleHandle: function() {                this._createComponent(this._$hueScaleHandle = $("<div>", {                    "class": COLOR_VIEW_HUE_SCALE_HANDLE_CLASS,                    appendTo: this._$hueScaleWrapper                }), "dxDraggable", {                    area: this._$hueScaleWrapper,                    allowMoveByClick: true,                    direction: "vertical",                    onDrag: $.proxy(function(e) {                        this._updateByDrag = true;                        this._updateColorHue(translator.locate(this._$hueScaleHandle).top + this._hueScaleHandleHeight / 2)                    }, this)                });                this._hueScaleHandleHeight = this._$hueScaleHandle.height();                this._placeHueScaleHandle()            },            _placeHueScaleHandle: function() {                var hueScaleHeight = this._hueScaleWrapperHeight,                    handleHeight = this._hueScaleHandleHeight,                    top = (hueScaleHeight - handleHeight) * (360 - this._currentColor.hsv.h) / 360;                if (hueScaleHeight < top + handleHeight)                    top = hueScaleHeight - handleHeight;                if (top < 0)                    top = 0;                translator.move(this._$hueScaleHandle, {top: Math.round(top)})            },            _updateColorHue: function(handlePosition) {                var hue = 360 - Math.round((handlePosition - this._hueScaleHandleHeight / 2) * 360 / (this._hueScaleWrapperHeight - this._hueScaleHandleHeight)),                    saturation = this._currentColor.hsv.s,                    value = this._currentColor.hsv.v;                this._isTopColorHue = false;                hue = hue < 0 ? 0 : hue;                if (hue >= 360) {                    this._isTopColorHue = true;                    hue = 0                }                this._updateColorFromHsv(hue, saturation, value);                this._$palette.css("backgroundColor", this._currentColor.getPureColor().toHex())            },            _renderControlsContainer: function() {                var $controlsContainerCell = this._renderHtmlCellInsideRow(":first", this._$colorPickerContainer);                this._$controlsContainer = $("<div>", {                    "class": COLOR_VIEW_CONTROLS_CONTAINER_CLASS,                    appendTo: $controlsContainerCell                })            },            _renderControls: function() {                this._renderColorsPreview();                this._renderRgbInputs();                this._renderHexInput()            },            _renderColorsPreview: function() {                var $colorsPreviewContainer = $("<div>", {                        "class": COLOR_VIEW_COLOR_PREVIEW_CONTAINER_CLASS,                        appendTo: this._$controlsContainer                    }),                    $colorsPreviewContainerInner = $("<div>", {                        "class": COLOR_VIEW_COLOR_PREVIEW_CONTAINER_INNER_CLASS,                        appendTo: $colorsPreviewContainer                    });                this._$currentColor = $("<div>", {"class": [COLOR_VIEW_COLOR_PREVIEW, COLOR_VIEW_COLOR_PREVIEW_COLOR_CURRENT].join(" ")});                this._$newColor = $("<div>", {"class": [COLOR_VIEW_COLOR_PREVIEW, COLOR_VIEW_COLOR_PREVIEW_COLOR_NEW].join(" ")});                this._makeTransparentBackground(this._$currentColor, this._currentColor);                this._makeTransparentBackground(this._$newColor, this._currentColor);                $colorsPreviewContainerInner.append([this._$currentColor, this._$newColor])            },            _renderAlphaChannelElements: function() {                if (this.option("editAlphaChannel")) {                    this._$colorPickerContainer.find("." + COLOR_VIEW_ROW_CLASS).eq(1).addClass(COLOR_VIEW_APLHA_CHANNEL_ROW_CLASS);                    this._renderAlphaChannelScale();                    this._renderAlphaChannelInput()                }            },            _renderRgbInputs: function() {                this._rgbInputsWithLabels = [this._renderEditorWithLabel({                        editorType: "dxNumberBox",                        value: this._currentColor.r,                        onValueChanged: $.proxy(this._updateColor, this, false),                        labelText: "R",                        labelAriaText: Globalize.localize("dxColorView-ariaRed"),                        labelClass: COLOR_VIEW_RED_LABEL_CLASS                    }), this._renderEditorWithLabel({                        editorType: "dxNumberBox",                        value: this._currentColor.g,                        onValueChanged: $.proxy(this._updateColor, this, false),                        labelText: "G",                        labelAriaText: Globalize.localize("dxColorView-ariaGreen"),                        labelClass: COLOR_VIEW_GREEN_LABEL_CLASS                    }), this._renderEditorWithLabel({                        editorType: "dxNumberBox",                        value: this._currentColor.b,                        onValueChanged: $.proxy(this._updateColor, this, false),                        labelText: "B",                        labelAriaText: Globalize.localize("dxColorView-ariaBlue"),                        labelClass: COLOR_VIEW_BLUE_LABEL_CLASS                    })];                this._$controlsContainer.append(this._rgbInputsWithLabels);                this._rgbInputs = [this._rgbInputsWithLabels[0].find(".dx-numberbox").dxNumberBox("instance"), this._rgbInputsWithLabels[1].find(".dx-numberbox").dxNumberBox("instance"), this._rgbInputsWithLabels[2].find(".dx-numberbox").dxNumberBox("instance")];                $.each(this._rgbInputs, $.proxy(function(_, instance) {                    this._attachEnterKeyHandler(instance)                }, this))            },            _renderEditorWithLabel: function(options) {                var $editor = $("<div>"),                    $label = $("<label>", {                        "class": options.labelClass,                        text: options.labelText + ":",                        append: $editor                    }).off("dxclick").on("dxclick", function(e) {                        e.preventDefault()                    }),                    editorType = options.editorType,                    editorOptions = {                        value: options.value,                        onValueChanged: options.onValueChanged                    };                if (editorType === "dxNumberBox") {                    editorOptions.min = options.min || 0;                    editorOptions.max = options.max || 255;                    editorOptions.step = options.step || 1                }                $editor[editorType](editorOptions);                this.setAria("label", options.labelAriaText, $editor);                return $label            },            _renderHexInput: function() {                this._hexInput = this._renderEditorWithLabel({                    editorType: "dxTextBox",                    value: this._currentColor.toHex().replace("#", ""),                    onValueChanged: $.proxy(this._updateColor, this, true),                    labelClass: COLOR_VIEW_HEX_LABEL_CLASS,                    labelText: "#",                    labelAriaText: Globalize.localize("dxColorView-ariaHex")                }).appendTo(this._$controlsContainer).find(".dx-textbox").dxTextBox("instance");                this._attachEnterKeyHandler(this._hexInput)            },            _attachEnterKeyHandler: function(instance) {                instance.registerKeyHandler("enter", $.proxy(function(e) {                    this._enterKeyHandler(e)                }, this))            },            _renderAlphaChannelScale: function() {                var $alphaChannelScaleCell = this._renderHtmlCellInsideRow(":eq(1)", this._$colorPickerContainer, COLOR_VIEW_ALPHA_CHANNEL_CELL_CLASS),                    $alphaChannelBorder = $("<div>", {                        "class": COLOR_VIEW_ALPHA_CHANNEL_BORDER_CLASS,                        appendTo: $alphaChannelScaleCell                    }),                    $alphaChannelScaleWrapper = $("<div>", {                        "class": COLOR_VIEW_ALPHA_CHANNEL_SCALE_WRAPPER_CLASS,                        appendTo: $alphaChannelBorder                    });                this._$alphaChannelScale = $("<div>", {                    "class": COLOR_VIEW_ALPHA_CHANNEL_SCALE_CLASS,                    appendTo: $alphaChannelScaleWrapper                });                this._makeCSSLinearGradient(this._$alphaChannelScale);                this._renderAlphaChannelHandle($alphaChannelScaleCell)            },            _makeCSSLinearGradient: function($el) {                var color = this._currentColor,                    colorAsRgb = [color.r, color.g, color.b].join(","),                    colorAsHex = color.toHex().replace("#", "");                var combineGradientString = function(colorAsRgb, colorAsHex) {                        var rtlEnabled = this.option("rtlEnabled"),                            startColor = "rgba(" + colorAsRgb + ", " + (rtlEnabled ? "1" : "0") + ")",                            finishColor = "rgba(" + colorAsRgb + ", " + (rtlEnabled ? "0" : "1") + ")",                            startColorIE = "'#" + (rtlEnabled ? "00" : "") + colorAsHex + "'",                            finishColorIE = "'#" + (rtlEnabled ? "" : "00") + colorAsHex + "'";                        return ["background-image: -webkit-linear-gradient(180deg, " + startColor + ", " + finishColor + ")", "background-image: -moz-linear-gradient(-90deg, " + startColor + ", " + finishColor + ")", "background-image: -ms-linear-gradient(-90deg, " + startColor + ", " + finishColor + ")", "background-image: -o-linear-gradient(-90deg, " + startColor + ", " + finishColor + ")", "background-image: linear-gradient(-90deg, " + startColor + ", " + finishColor + ")", "filter: progid:DXImageTransform.Microsoft.gradient(GradientType=1,startColorstr=" + startColorIE + ", endColorstr=" + finishColorIE + ")", "-ms-filter: progid:DXImageTransform.Microsoft.gradient(GradientType=1,startColorstr=" + startColorIE + ", endColorstr=" + finishColorIE + ")"].join(";")                    };                $el.attr("style", combineGradientString.call(this, colorAsRgb, colorAsHex))            },            _renderAlphaChannelInput: function() {                var that = this,                    $alphaChannelInputCell = this._renderHtmlCellInsideRow(":eq(1)", this._$colorPickerContainer);                that._alphaChannelInput = this._renderEditorWithLabel({                    editorType: "dxNumberBox",                    value: this._currentColor.a,                    max: 1,                    step: 0.1,                    onValueChanged: function(e) {                        var value = e.value;                        value = that._currentColor.isValidAlpha(value) ? value : that._currentColor.a;                        that._updateColorTransparence(value);                        that._placeAlphaChannelHandle()                    },                    labelClass: COLOR_VIEW_ALPHA_CHANNEL_LABEL_CLASS,                    labelText: "Alpha",                    labelAriaText: Globalize.localize("dxColorView-ariaAlpha")                }).appendTo($alphaChannelInputCell).find(".dx-numberbox").dxNumberBox("instance");                this._attachEnterKeyHandler(that._alphaChannelInput)            },            _updateColorTransparence: function(transparence) {                this._currentColor.a = transparence;                this._makeTransparentBackground(this._$newColor, this._currentColor);                if (this.option("applyValueMode") === "instantly")                    this.applyColor()            },            _renderAlphaChannelHandle: function($parent) {                this._createComponent(this._$alphaChannelHandle = $("<div>", {                    "class": COLOR_VIEW_ALPHA_CHANNEL_HANDLE_CLASS,                    appendTo: $parent                }), "dxDraggable", {                    area: $parent,                    allowMoveByClick: true,                    direction: "horizontal",                    onDrag: $.proxy(function(e) {                        this._updateByDrag = true;                        var $alphaChannelHandle = this._$alphaChannelHandle,                            alphaChannelHandlePosition = translator.locate($alphaChannelHandle).left + this._alphaChannelHandleWidth / 2;                        this._calculateColorTransparenceByScaleWidth(alphaChannelHandlePosition)                    }, this)                });                this._alphaChannelHandleWidth = this._$alphaChannelHandle.width();                this._alphaChannelScaleWorkWidth = $parent.width() - this._alphaChannelHandleWidth;                this._placeAlphaChannelHandle()            },            _calculateColorTransparenceByScaleWidth: function(handlePosition) {                var transparence = (handlePosition - this._alphaChannelHandleWidth / 2) / this._alphaChannelScaleWorkWidth,                    rtlEnabled = this.option("rtlEnabled");                transparence = rtlEnabled ? transparence : 1 - transparence;                if (handlePosition >= this._alphaChannelScaleWorkWidth + this._alphaChannelHandleWidth / 2)                    transparence = rtlEnabled ? 1 : 0;                else if (transparence < 1)                    transparence = transparence.toFixed(2);                this._alphaChannelInput.option("value", transparence)            },            _placeAlphaChannelHandle: function() {                var left = this._alphaChannelScaleWorkWidth * (1 - this._currentColor.a);                if (left < 0)                    left = 0;                if (this._alphaChannelScaleWorkWidth < left)                    left = this._alphaChannelScaleWorkWidth;                translator.move(this._$alphaChannelHandle, {left: this.option("rtlEnabled") ? this._alphaChannelScaleWorkWidth - left : left})            },            applyColor: function() {                var colorValue = this.option("editAlphaChannel") ? this._makeRgba(this._currentColor) : this._currentColor.toHex();                this._makeTransparentBackground(this._$currentColor, this._currentColor);                this.option("value", colorValue)            },            cancelColor: function() {                this._initColorAndOpacity();                this._refreshMarkup()            },            _updateColor: function(isHex) {                var rgba,                    newColor;                if (isHex)                    newColor = this._validateHex("#" + this._hexInput.option("value"));                else {                    rgba = this._validateRgb();                    if (this._alphaChannelInput) {                        rgba.push(this._alphaChannelInput.option("value"));                        newColor = "rgba(" + rgba.join(", ") + ")"                    }                    else                        newColor = "rgb(" + rgba.join(", ") + ")"                }                if (!this._suppressEditorsValueUpdating) {                    this._currentColor = new DX.Color(newColor);                    this._refreshMarkup();                    if (this.option("applyValueMode") === "instantly")                        this.applyColor()                }            },            _validateHex: function(hex) {                return this._currentColor.isValidHex(hex) ? hex : this._currentColor.toHex()            },            _validateRgb: function() {                var r = this._rgbInputs[0].option("value"),                    g = this._rgbInputs[1].option("value"),                    b = this._rgbInputs[2].option("value");                if (!this._currentColor.isValidRGB(r, g, b)) {                    r = this._currentColor.r;                    g = this._currentColor.g;                    b = this._currentColor.b                }                return [r, g, b]            },            _refreshMarkup: function() {                this._placeHueScaleHandle();                this._placePaletteHandle();                this._updateColorParamsAndColorPreview();                this._$palette.css("backgroundColor", this._currentColor.getPureColor().toHex());                if (this._$alphaChannelHandle) {                    this._updateColorTransparence(this._currentColor.a);                    this._placeAlphaChannelHandle()                }            },            _updateColorParamsAndColorPreview: function() {                this._suppressEditorsValueUpdating = true;                this._hexInput.option("value", this._currentColor.toHex().replace("#", ""));                this._rgbInputs[0].option("value", this._currentColor.r);                this._rgbInputs[1].option("value", this._currentColor.g);                this._rgbInputs[2].option("value", this._currentColor.b);                this._suppressEditorsValueUpdating = false;                this._makeTransparentBackground(this._$newColor, this._currentColor);                if (this.option("editAlphaChannel")) {                    this._makeCSSLinearGradient.call(this, this._$alphaChannelScale);                    this._alphaChannelInput.option("value", this._currentColor.a)                }            },            _optionChanged: function(args) {                var value = args.value;                switch (args.name) {                    case"value":                        this._setCurrentColor(value);                        if (!this._updateByDrag)                            this._refreshMarkup();                        this._updateByDrag = false;                        this.callBase(args);                        break;                    case"editAlphaChannel":                        if (this._$colorPickerContainer) {                            this._renderHtmlRows("editAlphaChannel");                            this._renderAlphaChannelElements()                        }                        break;                    case"applyValueMode":                        if (this._$colorPickerContainer)                            this._renderHtmlRows("applyValueMode");                        break;                    case"keyStep":                        break;                    default:                        this.callBase(args)                }            }        }))    })(jQuery, DevExpress);    /*! Module widgets-web, file ui.colorBox.js */    (function($, DX, undefined) {        var ui = DX.ui;        var COLOR_BOX_CLASS = "dx-colorbox",            COLOR_BOX_INPUT_CLASS = COLOR_BOX_CLASS + "-input",            COLOR_BOX_INPUT_CONTAINER_CLASS = COLOR_BOX_INPUT_CLASS + "-container",            COLOR_BOX_COLOR_RESULT_PREVIEW_CLASS = COLOR_BOX_CLASS + "-color-result-preview",            COLOR_BOX_COLOR_IS_NOT_DEFINED = COLOR_BOX_CLASS + "-color-is-not-defined",            COLOR_BOX_OVERLAY_CLASS = COLOR_BOX_CLASS + "-overlay",            COLOR_BOX_CONTAINER_CELL_CLASS = "dx-colorview-container-cell",            COLOR_BOX_BUTTON_CELL_CLASS = "dx-colorview-button-cell",            COLOR_BOX_BUTTONS_CONTAINER_CLASS = "dx-colorview-buttons-container",            COLOR_BOX_APPLY_BUTTON_CLASS = "dx-colorview-apply-button",            COLOR_BOX_CANCEL_BUTTON_CLASS = "dx-colorview-cancel-button";        var colorEditorPrototype = ui.dxColorView.prototype,            colorUtils = {                makeTransparentBackground: $.proxy(colorEditorPrototype._makeTransparentBackground, colorEditorPrototype),                makeRgba: $.proxy(colorEditorPrototype._makeRgba, colorEditorPrototype)            };        DX.registerComponent("dxColorBox", ui, ui.dxDropDownEditor.inherit({            _supportedKeys: function() {                var arrowHandler = function(e) {                        e.stopPropagation();                        if (this.option("opened")) {                            e.preventDefault();                            return true                        }                    };                var upArrowHandler = function(e) {                        if (!this.option("opened")) {                            e.preventDefault();                            return false                        }                        if (e.altKey) {                            this.close();                            return false                        }                        return true                    };                var downArrowHandler = function(e) {                        if (!this.option("opened") && !e.altKey) {                            e.preventDefault();                            return false                        }                        if (!this.option("opened") && e.altKey) {                            this._validatedOpening();                            return false                        }                        return true                    };                return $.extend(this.callBase(), {                        tab: function(e) {                            if (this.option("opened")) {                                e.preventDefault();                                this._colorView._rgbInputs[0].focus()                            }                        },                        enter: this._enterKeyHandler,                        leftArrow: arrowHandler,                        rightArrow: arrowHandler,                        upArrow: upArrowHandler,                        downArrow: downArrowHandler                    })            },            _setDefaultOptions: function() {                this.callBase();                this.option({                    editAlphaChannel: false,                    applyButtonText: Globalize.localize("OK"),                    cancelButtonText: Globalize.localize("Cancel"),                    applyValueMode: "useButtons",                    keyStep: 1,                    onApplyButtonClick: null,                    onCancelButtonClick: null,                    buttonsLocation: "bottom after"                })            },            _popupConfig: function() {                return $.extend(this.callBase(), {                        height: "auto",                        width: ""                    })            },            _contentReadyHandler: function() {                this._createColorView();                this._addPopupBottomClasses()            },            _addPopupBottomClasses: function() {                var $popupBottom = this._popup.bottomToolbar();                if ($popupBottom) {                    $popupBottom.addClass(COLOR_BOX_CONTAINER_CELL_CLASS).addClass(COLOR_BOX_BUTTON_CELL_CLASS).find(".dx-toolbar-items-container").addClass(COLOR_BOX_BUTTONS_CONTAINER_CLASS);                    $popupBottom.find(".dx-popup-done").addClass(COLOR_BOX_APPLY_BUTTON_CLASS);                    $popupBottom.find(".dx-popup-cancel").addClass(COLOR_BOX_CANCEL_BUTTON_CLASS)                }            },            _createColorView: function() {                this._popup.overlayContent().addClass(COLOR_BOX_OVERLAY_CLASS);                var $colorView = $("<div>").appendTo(this._popup.content());                this._colorView = this._createComponent($colorView, "dxColorView", this._colorViewConfig());                this._colorView._enterKeyHandler = $.proxy(this._enterKeyHandler, this);                $colorView.on("focus", $.proxy(function() {                    this.focus()                }, this))            },            _colorViewConfig: function() {                var that = this,                    isAttachKeyboardEvent = that.option("focusStateEnabled") && !that.option("disabled");                return {                        value: that.option("value"),                        editAlphaChannel: that.option("editAlphaChannel"),                        applyValueMode: that.option("applyValueMode"),                        focusStateEnabled: that.option("focusStateEnabled"),                        onValueChanged: function(args) {                            var value = args.value;                            that.option("value", value);                            if (value)                                colorUtils.makeTransparentBackground(that._$colorResultPreview, value)                        },                        _keyboardProcessor: isAttachKeyboardEvent ? that._keyboardProcessor.attachChildProcessor() : null                    }            },            _enterKeyHandler: function(e) {                var newValue = this._input().val(),                    oldValue = this.option("editAlphaChannel") ? colorUtils.makeRgba(this.option("value")) : this.option("value");                if (newValue && newValue !== oldValue) {                    this._applyColorFromInput(newValue);                    this.option("value", this.option("editAlphaChannel") ? colorUtils.makeRgba(newValue) : newValue);                    return false                }                if (this.option("applyValueMode") === "useButtons")                    this._colorView.applyColor();                if (this.option("opened")) {                    e.preventDefault();                    this.close()                }                return false            },            _applyButtonHandler: function() {                this._colorView.applyColor();                if ($.isFunction(this.option("onApplyButtonClick")))                    this.option("onApplyButtonClick")();                this.callBase()            },            _cancelButtonHandler: function() {                this._colorView.cancelColor();                if ($.isFunction(this.option("onCancelButtonClick")))                    this.option("onCancelButtonClick")();                this.callBase()            },            _attachChildKeyboardEvents: function() {                var child = this._keyboardProcessor.attachChildProcessor();                if (this._colorView) {                    this._colorView.option("_keyboardProcessor", child);                    return                }            },            _init: function() {                this.callBase()            },            _render: function() {                this.callBase();                this.element().addClass(COLOR_BOX_CLASS)            },            _renderInput: function() {                this.callBase();                this.element().wrapInner($("<div/>").addClass(COLOR_BOX_INPUT_CONTAINER_CLASS));                this._$colorBoxInputContainer = this.element().children().eq(0);                this._$colorResultPreview = $("<div>", {                    "class": COLOR_BOX_COLOR_RESULT_PREVIEW_CLASS,                    appendTo: this._$colorBoxInputContainer                });                if (!this.option("value"))                    this._$colorBoxInputContainer.addClass(COLOR_BOX_COLOR_IS_NOT_DEFINED);                else                    colorUtils.makeTransparentBackground(this._$colorResultPreview, this.option("value"));                this._input().addClass(COLOR_BOX_INPUT_CLASS)            },            _renderValue: function() {                var value = this.option("value");                this.option("text", this.option("editAlphaChannel") ? colorUtils.makeRgba(value) : value);                this.callBase()            },            _valueChangeEventHandler: function(e) {                var value = this._input().val();                if (value) {                    value = this._applyColorFromInput(value);                    if (this._colorView) {                        this._colorView._setCurrentColor(value);                        this._colorView._refreshMarkup()                    }                }                this.callBase(e, value)            },            _applyColorFromInput: function(value) {                var newColor = new DX.Color(value);                if (newColor.colorIsInvalid) {                    value = this.option("value");                    this._input().val(value)                }                return value            },            _optionChanged: function(args) {                var value = args.value,                    name = args.name;                switch (name) {                    case"value":                        this._$colorBoxInputContainer.toggleClass(COLOR_BOX_COLOR_IS_NOT_DEFINED, !value);                        if (value)                            colorUtils.makeTransparentBackground(this._$colorResultPreview, value);                        else                            this._$colorResultPreview.removeAttr("style");                        if (this._colorView)                            this._colorView.option("value", value);                        this.callBase(args);                        break;                    case"applyButtonText":                    case"cancelButtonText":                        this.callBase(args);                        this._popup && this._addPopupBottomClasses();                        break;                    case"editAlphaChannel":                    case"onCancelButtonClick":                    case"onApplyButtonClick":                    case"keyStep":                        if (this._colorView)                            this._colorView.option(name, value);                        break;                    case"applyValueMode":                        if (this._colorView)                            this._colorView.option(name, value);                        this.callBase(args);                        break;                    case"rtlEnabled":                        if (this._colorView)                            this._colorView.option(name, value);                        this.callBase(args);                        break;                    default:                        this.callBase(args)                }            }        }));        DX.registerComponent("dxColorPicker", ui, ui.dxColorBox.inherit({ctor: function() {                DX.log("W0000", this.NAME, "14.2", "Use 'dxColorBox' instead");                this.callBase.apply(this, arguments)            }}));        ui.dxColorBox.__internals = {            COLOR_BOX_CLASS: COLOR_BOX_CLASS,            COLOR_BOX_INPUT_CLASS: COLOR_BOX_INPUT_CLASS,            COLOR_BOX_INPUT_CONTAINER_CLASS: COLOR_BOX_INPUT_CONTAINER_CLASS,            COLOR_BOX_COLOR_RESULT_PREVIEW_CLASS: COLOR_BOX_COLOR_RESULT_PREVIEW_CLASS,            COLOR_BOX_COLOR_IS_NOT_DEFINED: COLOR_BOX_COLOR_IS_NOT_DEFINED,            COLOR_BOX_OVERLAY_CLASS: COLOR_BOX_OVERLAY_CLASS        }    })(jQuery, DevExpress);    /*! Module widgets-web, file ui.menuBase.js */    (function($, DX, undefined) {        var ui = DX.ui,            utils = DX.utils;        var DX_MENU_CLASS = "dx-menu",            DX_MENU_BASE_CLASS = "dx-menu-base",            DX_MENU_ITEM_CLASS = DX_MENU_CLASS + "-item",            DX_MENU_SELECTED_ITEM_CLASS = DX_MENU_ITEM_CLASS + "-selected",            DX_MENU_ITEM_WRAPPER_CLASS = DX_MENU_ITEM_CLASS + "-wrapper",            DX_MENU_ITEMS_CONTAINER_CLASS = DX_MENU_CLASS + "-items-container",            DX_MENU_ITEM_EXPANDED_CLASS = DX_MENU_ITEM_CLASS + "-expanded",            DX_MENU_SEPARATOR_CLASS = DX_MENU_CLASS + "-separator",            DX_MENU_ITEM_LAST_GROUP_ITEM = DX_MENU_CLASS + "-last-group-item",            DX_ITEM_HAS_TEXT = DX_MENU_ITEM_CLASS + "-has-text",            DX_ITEM_HAS_ICON = DX_MENU_ITEM_CLASS + "-has-icon",            DX_ITEM_HAS_SUBMENU = DX_MENU_ITEM_CLASS + "-has-submenu",            DX_STATE_FOCUSED_CLASS = "dx-state-focused",            DX_MENU_ITEM_CLASS_SELECTOR = "." + DX_MENU_ITEM_CLASS,            DX_ITEM_SELECTED_SELECTOR = "." + DX_MENU_SELECTED_ITEM_CLASS,            SINGLE_SELECTION_MODE = "single",            NONE_SELECTION_MODE = "none",            FIRST_SUBMENU_LEVEL = 1,            DEFAULT_SHOW_DELAY = 50,            DEFAULT_HIDE_DELAY = 300;        var dxMenuBase = ui.CollectionWidget.inherit({                NAME: "dxMenuBase",                _setDefaultOptions: function() {                    this.callBase();                    this.option({                        items: [],                        cssClass: "",                        activeStateEnabled: true,                        showSubmenuMode: {                            name: "onHover",                            delay: {                                show: 50,                                hide: 300                            }                        },                        animation: {                            show: {                                type: "fade",                                from: 0,                                to: 1,                                duration: 100                            },                            hide: {                                type: "fade",                                from: 1,                                to: 0,                                duration: 100                            }                        },                        selectionByClick: false,                        selectionMode: "none",                        focusOnSelectedItem: false,                        _remoteSelectionSync: false,                        hoverStateEnabled: true,                        _itemAttributes: {role: "menuitem"}                    })                },                _defaultOptionsRules: function() {                    return this.callBase().concat([{                                device: function(device) {                                    return DX.devices.real().generic && !DX.devices.isSimulator()                                },                                options: {focusStateEnabled: true}                            }])                },                _activeStateUnit: DX_MENU_ITEM_CLASS_SELECTOR,                _itemDataKey: function() {                    return "dxMenuItemDataKey"                },                _itemClass: function() {                    return DX_MENU_ITEM_CLASS                },                _setAriaSelected: $.noop,                _selectedItemClass: function() {                    return DX_MENU_SELECTED_ITEM_CLASS                },                _focusTarget: function() {                    return this._itemContainer()                },                _eventBindingTarget: function() {                    return this._itemContainer()                },                _supportedKeys: function() {                    var selectItem = function(e) {                            var $item = this.option("focusedElement");                            if (!$item || !this._isSelectionEnabled())                                return;                            this.selectItem($item)                        };                    return $.extend(this.callBase(), {                            space: selectItem,                            pageUp: $.noop,                            pageDown: $.noop                        })                },                _isSelectionEnabled: function() {                    return this._getSelectionMode() === SINGLE_SELECTION_MODE                },                _getSelectionMode: function() {                    return this.option("selectionMode") === SINGLE_SELECTION_MODE ? SINGLE_SELECTION_MODE : NONE_SELECTION_MODE                },                _init: function() {                    this.callBase();                    this._initActions()                },                _initActions: $.noop,                _render: function() {                    var $element = this.element();                    this.callBase(arguments);                    this._addCustomCssClass($element);                    this._itemContainer().addClass(DX_MENU_BASE_CLASS)                },                _getShowSubmenuMode: function() {                    var modeName;                    if (utils.isObject(this.option("showSubmenuMode")))                        modeName = this._isDesktopDevice() ? this.option("showSubmenuMode").name : "onClick";                    else                        modeName = this._isDesktopDevice() ? this.option("showSubmenuMode") : "onClick";                    return modeName                },                _isDesktopDevice: function() {                    return DX.devices.real().deviceType === "desktop"                },                _initEditStrategy: function() {                    var strategy = ui.CollectionWidget.MenuBaseEditStrategy;                    this._editStrategy = new strategy(this)                },                _addCustomCssClass: function($element) {                    $element.addClass(this.option("cssClass"))                },                _itemWrapperSelector: function() {                    return "." + DX_MENU_ITEM_WRAPPER_CLASS                },                _hoverStartHandler: function(e) {                    var that = this,                        $itemElement = that._getItemElementByEventArgs(e);                    if ($itemElement) {                        if (that._isItemDisabled($itemElement))                            return;                        e.stopPropagation();                        that.option("focusedElement", $itemElement);                        if (that._getShowSubmenuMode() === "onHover")                            setTimeout($.proxy(that._showSubmenu, that, $itemElement), that._getSubmenuShowDelay())                    }                },                _isItemDisabled: function($item) {                    return $item.data(this._itemDataKey()).disabled                },                _showSubmenu: function($itemElement) {                    if ($itemElement.hasClass(DX_STATE_FOCUSED_CLASS))                        this._addExpandedClass($itemElement)                },                _addExpandedClass: function($itemElement) {                    $itemElement.addClass(DX_MENU_ITEM_EXPANDED_CLASS)                },                _getSubmenuHideDelay: function() {                    var delay = this.option("showSubmenuMode").delay;                    if (delay)                        return utils.isObject(delay) ? delay.hide : delay;                    else                        return DEFAULT_HIDE_DELAY                },                _getSubmenuShowDelay: function() {                    var delay = this.option("showSubmenuMode").delay,                        resultDelay;                    if (delay)                        resultDelay = utils.isObject(delay) ? delay.show : delay;                    else                        resultDelay = DEFAULT_SHOW_DELAY;                    return resultDelay                },                _getItemElementByEventArgs: function(eventArgs) {                    var $target = $(eventArgs.target);                    if ($target.hasClass(this._itemClass()) || $target.get(0) === eventArgs.currentTarget)                        return $target;                    while (!$target.hasClass(this._itemClass())) {                        $target = $target.parent();                        if ($target.hasClass("dx-submenu"))                            return null                    }                    return $target                },                _hoverEndHandler: $.noop,                _hasSubmenu: function(item) {                    return item.items && item.items.length > 0                },                _renderItems: function(items, submenuLevel, submenuContainer) {                    submenuLevel = submenuLevel || FIRST_SUBMENU_LEVEL;                    var that = this,                        $itemsContainer;                    if (items.length) {                        $itemsContainer = this._renderContainer(submenuLevel, submenuContainer);                        $.each(items, function(index, item) {                            that._renderItem(index, item, $itemsContainer, submenuLevel)                        })                    }                    this._setSelectionFromItems()                },                _renderContainer: function(submenuLevel) {                    return this._createItemsContainer().addClass(DX_MENU_ITEMS_CONTAINER_CLASS)                },                _createItemsContainer: function() {                    var $rootGroup = $("<div>").appendTo(this.element());                    return $("<ul>").appendTo($rootGroup)                },                _renderItem: function(index, item, $itemsContainer, submenuLevel) {                    var items = this.option("items"),                        $itemWrapper = $("<li>"),                        $item;                    this._renderSeparator(item, index, $itemsContainer);                    $itemWrapper.appendTo($itemsContainer).addClass(DX_MENU_ITEM_WRAPPER_CLASS);                    if (items[index + 1] && items[index + 1].beginGroup)                        $itemWrapper.addClass(DX_MENU_ITEM_LAST_GROUP_ITEM);                    if (!utils.isObject(item))                        item = {text: item};                    if (!utils.isDefined(item.selected))                        item.selected = false;                    $item = this.callBase(index, item, $itemWrapper);                    this._addContentClasses(item, $item);                    if (this._hasSubmenu(item))                        this._renderSubmenuItems(item, $item, submenuLevel)                },                _addContentClasses: function(item, $item) {                    if (item.text)                        $item.addClass(DX_ITEM_HAS_TEXT);                    if (item.icon || item.iconSrc)                        $item.addClass(DX_ITEM_HAS_ICON);                    if (item.items && item.items.length > 0)                        $item.addClass(DX_ITEM_HAS_SUBMENU)                },                _setSelectionFromItems: function() {                    var selectedIndex = this.option("selectedIndex"),                        searchSelectedFromItems = !selectedIndex || selectedIndex === -1;                    if (this.option("_remoteSelectionSync") || !searchSelectedFromItems)                        return;                    $.each(this._editStrategy._getPlainItems(), function(index, item) {                        if (item.selected && item.selectable !== false)                            selectedIndex = index                    });                    if (selectedIndex >= 0)                        this.option("selectedIndex", selectedIndex)                },                _renderSeparator: function(item, index, $itemsContainer) {                    if (item.beginGroup && index > 0)                        $("<li>").appendTo($itemsContainer).addClass(DX_MENU_SEPARATOR_CLASS)                },                _renderSubmenuItems: function(item, $item) {                    this.setAria("haspopup", "true", $item)                },                _itemClickHandler: function(e) {                    var itemClickActionHandler = this._createAction($.proxy(this._updateSubmenuVisibilityOnClick, this));                    this._itemJQueryEventHandler(e, "onItemClick", {}, {afterExecute: $.proxy(itemClickActionHandler, this)})                },                _updateSubmenuVisibilityOnClick: function(actionArgs) {                    this._updateSelectedItemOnClick(actionArgs);                    if (this._getShowSubmenuMode() === "onClick")                        this._addExpandedClass(actionArgs.args[0].itemElement)                },                _updateSelectedItemOnClick: function(actionArgs) {                    var args = actionArgs.args ? actionArgs.args[0] : actionArgs,                        isSelectionByClickEnabled = this._isSelectionEnabled() && this.option("selectionByClick"),                        $selectedItem,                        selectedItemData;                    if (isSelectionByClickEnabled && args.itemData.selectable !== false && !this._hasSubmenu(args.itemData)) {                        $selectedItem = this._itemContainer().find(DX_ITEM_SELECTED_SELECTOR);                        if ($selectedItem.length) {                            selectedItemData = this._getItemData($selectedItem);                            $selectedItem.removeClass(this._selectedItemClass());                            if (selectedItemData) {                                selectedItemData.selected = false;                                this._clearSelectedItems()                            }                            if (!$selectedItem.is(args.itemElement))                                this._setSelectedItems(args)                        }                        else                            this._setSelectedItems(args)                    }                },                _setSelectedItems: function(args) {                    args.itemData.selected = true;                    this.option("selectedItems", [args.itemData])                },                _syncSelectionOptions: function(byOption) {                    var items = this._editStrategy._getPlainItems() || [],                        selectedItems = this.option("selectedItems") || [],                        selectedItem = this.option("selectedItem"),                        selectedIndex = this.option("selectedIndex");                    byOption = byOption || this._chooseSelectOption();                    switch (byOption) {                        case"selectedItems":                            this._setOptionSilent("selectedItem", selectedItems[0]);                            this._setOptionSilent("selectedIndex", $.inArray(selectedItems[0], items));                            break;                        case"selectedItem":                            if (utils.isDefined(selectedItem)) {                                this._setOptionSilent("selectedItems", [selectedItem]);                                this._setOptionSilent("selectedIndex", $.inArray(selectedItem, items))                            }                            else {                                this._setOptionSilent("selectedItems", []);                                this._setOptionSilent("selectedIndex", -1)                            }                            break;                        case"selectedIndex":                            if (utils.isDefined(items[selectedIndex])) {                                this._setOptionSilent("selectedItems", [items[selectedIndex]]);                                this._setOptionSilent("selectedItem", items[selectedIndex])                            }                            else {                                this._setOptionSilent("selectedItems", []);                                this._setOptionSilent("selectedItem", null)                            }                            break                    }                },                _getStringifiedArray: function(array) {                    return $.map(array, function(item) {                            return JSON.stringify(item)                        })                },                _isOwnItem: function(item) {                    var plainItems = this._editStrategy._getPlainItems();                    return $.inArray(JSON.stringify(item), this._getStringifiedArray(plainItems)) >= 0                },                _optionChanged: function(args) {                    switch (args.name) {                        case"showSubmenuMode":                            break;                        case"_remoteSelectionSync":                        case"cssClass":                        case"position":                        case"selectionByClick":                        case"animation":                            this._invalidate();                            break;                        default:                            this.callBase(args)                    }                },                selectItem: function(itemElement) {                    var itemIndex = this._editStrategy.getNormalizedIndex(itemElement),                        itemData = this._getItemData(itemElement);                    if (itemIndex === -1)                        return;                    var itemSelectionIndex = $.inArray(itemIndex, this._selectedItemIndices);                    if (itemSelectionIndex !== -1)                        return;                    if (this.option("selectionMode") === "single" && itemData.selectable !== false) {                        var items = this._editStrategy.fetchSelectedItems([itemIndex]);                        items[0].selected = true;                        this.option("selectedItems", items)                    }                },                unselectItem: function(itemElement) {                    var itemIndex = this._editStrategy.getNormalizedIndex(itemElement);                    if (itemIndex === -1)                        return;                    var itemSelectionIndex = $.inArray(itemIndex, this._selectedItemIndices);                    if (itemSelectionIndex === -1)                        return;                    var items = this._editStrategy.fetchSelectedItems([itemSelectionIndex]);                    items[0].selected = false;                    this.option("selectedItems", [])                }            });        ui.dxMenuBase = dxMenuBase    })(jQuery, DevExpress);    /*! Module widgets-web, file ui.menuBase.edit.strategy.js */    (function($, DX, undefined) {        var ui = DX.ui;        ui.CollectionWidget.MenuBaseEditStrategy = ui.CollectionWidget.PlainEditStrategy.inherit({            _getPlainItems: function() {                return $.map(this._collectionWidget.option("items"), function getMenuItems(item) {                        return item.items ? [item].concat($.map(item.items, getMenuItems)) : item                    })            },            _getStringifiedArray: function(array) {                var that = this;                return $.map(array, function(item) {                        return that._stringifyItem(item)                    })            },            _stringifyItem: function(item) {                var that = this;                return JSON.stringify(item, function(key, value) {                        if (key === "template")                            return that._getTemplateString(value);                        return value                    })            },            _getTemplateString: function(template) {                var result;                if (typeof template === "object")                    result = $(template).text();                else                    result = template.toString();                return result            },            selectedItemIndices: function() {                var selectedIndices = [],                    items = this._getStringifiedArray(this._getPlainItems()),                    selectedItems = this._collectionWidget.option("selectedItems");                $.each(selectedItems, function(_, selectedItem) {                    var index = $.inArray(JSON.stringify(selectedItem), items);                    if (index !== -1)                        selectedIndices.push(index);                    else                        DX.log("W1002", selectedItem)                });                return selectedIndices            },            fetchSelectedItems: function(indices) {                indices = indices || this._collectionWidget._selectedItemIndices;                var items = this._getPlainItems(),                    selectedItems = [];                $.each(indices, function(_, index) {                    selectedItems.push(items[index])                });                return selectedItems            }        })    })(jQuery, DevExpress);    /*! Module widgets-web, file ui.contextMenu.js */    (function($, DX, undefined) {        var ui = DX.ui,            utils = DX.utils,            events = ui.events,            fx = DX.fx;        var DX_MENU_CLASS = "dx-menu",            DX_MENU_ITEM_CLASS = DX_MENU_CLASS + "-item",            DX_MENU_ITEM_EXPANDED_CLASS = DX_MENU_ITEM_CLASS + "-expanded",            DX_MENU_PHONE_CLASS = "dx-menu-phone-overlay",            DX_MENU_ITEMS_CONTAINER_CLASS = DX_MENU_CLASS + "-items-container",            DX_MENU_ITEM_WRAPPER_CLASS = DX_MENU_ITEM_CLASS + "-wrapper",            DX_SUBMENU_CLASS = "dx-submenu",            DX_CONTEXT_MENU_CLASS = "dx-context-menu",            DX_HAS_CONTEXT_MENU_CLASS = "dx-has-context-menu",            DX_STATE_DISABLED_CLASS = "dx-state-disabled",            DX_SUBMENU_LEVEL_ID = "dxSubmenuLevel",            FOCUS_UP = "up",            FOCUS_DOWN = "down",            FOCUS_LEFT = "left",            FOCUS_RIGHT = "right",            FOCUS_FIRST = "first",            FOCUS_LAST = "last",            ACTIONS = ["onShowing", "onShown", "onHiding", "onHidden", "onPositioning", "onLeftFirstItem", "onLeftLastItem", "onCloseRootSubmenu", "onExpandLastSubmenu"],            LOCAL_SUBMENU_DIRECTIONS = [FOCUS_UP, FOCUS_DOWN, FOCUS_FIRST, FOCUS_LAST];        DX.registerComponent("dxContextMenu", ui, ui.dxMenuBase.inherit({            _setDefaultOptions: function() {                this.callBase();                this.option({                    alternativeInvocationMode: {                        enabled: false,                        invokingElement: null                    },                    position: {                        at: "top left",                        my: "top left"                    },                    onShowing: null,                    onShown: null,                    onHiding: null,                    onHidden: null,                    onPositioning: null,                    submenuDirection: "auto",                    visible: false,                    target: window,                    onLeftFirstItem: null,                    onLeftLastItem: null,                    onCloseRootSubmenu: null,                    onExpandLastSubmenu: null                })            },            _initActions: function() {                this._actions = {};                $.each(ACTIONS, $.proxy(function(index, action) {                    this._actions[action] = this._createActionByOption(action) || $.noop                }, this))            },            _setOptionsByReference: function() {                this.callBase();                $.extend(this._optionsByReference, {                    animation: true,                    position: true,                    selectedItem: true                })            },            _itemContainer: function() {                return this._overlay.content()            },            _supportedKeys: function() {                return $.extend(this.callBase(), {esc: this.hide})            },            _moveFocus: function(location) {                var $items = this._getItemsByLocation(location),                    $oldTarget = this._getActiveItem(true),                    $newTarget,                    $focusedItem = this.option("focusedElement");                switch (location) {                    case FOCUS_UP:                        $newTarget = $focusedItem ? this._prevItem($items) : $items.last();                        if ($oldTarget.is($items.first()))                            this._actions.onLeftFirstItem($oldTarget);                        break;                    case FOCUS_DOWN:                        $newTarget = $focusedItem ? this._nextItem($items) : $items.first();                        if ($oldTarget.is($items.last()))                            this._actions.onLeftLastItem($oldTarget);                        break;                    case FOCUS_RIGHT:                        $newTarget = this.option("rtlEnabled") ? this._hideSubmenuHandler($items) : this._expandSubmenuHandler($items);                        break;                    case FOCUS_LEFT:                        $newTarget = this.option("rtlEnabled") ? this._expandSubmenuHandler($items) : this._hideSubmenuHandler($items);                        break;                    case FOCUS_FIRST:                        $newTarget = $items.first();                        break;                    case FOCUS_LAST:                        $newTarget = $items.last();                        break;                    default:                        return this.callBase(location)                }                if ($newTarget.length !== 0)                    this.option("focusedElement", $newTarget)            },            _getItemsByLocation: function(location) {                var $items,                    $activeItem = this._getActiveItem(true),                    expandedLocation = this.option("rtlEnabled") ? FOCUS_LEFT : FOCUS_RIGHT;                if ($.inArray(location, LOCAL_SUBMENU_DIRECTIONS) >= 0)                    $items = $activeItem.closest("." + DX_MENU_ITEMS_CONTAINER_CLASS).children().children();                else {                    $items = this._itemElements();                    if (location !== expandedLocation)                        $items = $items.filter(":visible")                }                return $items            },            _refreshActiveDescendant: function() {                var $target = this._overlay.content(),                    id = this.getFocusedItemId();                if (!$target)                    return this.callBase();                this.setAria("activedescendant", "", $target);                this.setAria("activedescendant", id, $target)            },            _hideSubmenuHandler: function($items) {                var $curItem = this._getActiveItem(true),                    $parentItem = $curItem.parents("." + DX_MENU_ITEM_EXPANDED_CLASS).first();                if ($parentItem.length) {                    this._hideSubmenusOnSameLevel($parentItem);                    return $parentItem                }                this._actions.onCloseRootSubmenu($curItem);                return $curItem            },            _expandSubmenuHandler: function($items) {                var $curItem = this._getActiveItem(true),                    $submenu = $curItem.children("." + DX_SUBMENU_CLASS);                if ($submenu.length && !$curItem.hasClass(DX_STATE_DISABLED_CLASS)) {                    if ($submenu.css("visibility") === "hidden")                        this._showSubmenu($curItem);                    return this._nextItem($items)                }                this._actions.onExpandLastSubmenu($curItem);                return $curItem            },            _render: function() {                this.element().addClass(DX_HAS_CONTEXT_MENU_CLASS);                this.callBase();                this.setAria("role", "menu")            },            _renderContentImpl: function() {                this._renderContextMenuOverlay();                this._detachShowContextMenuEvents();                this._attachShowContextMenuEvents();                this._attachInvokeContextMenuEvents();                this.callBase()            },            _renderContextMenuOverlay: function() {                var overlayOptions = this._getOverlayOptions(),                    $overlayElement = $("<div>"),                    $overlayContent;                this._overlay = this._createComponent($overlayElement.appendTo(this._$element), "dxOverlay", overlayOptions);                $overlayContent = this._overlay.content();                $overlayContent.addClass(DX_CONTEXT_MENU_CLASS);                this._addCustomCssClass($overlayContent);                this._addPlatformDependentClass($overlayContent);                if (this.option("visible"))                    this._show()            },            _addPlatformDependentClass: function($element) {                if (DX.devices.current().phone)                    $element.addClass(DX_MENU_PHONE_CLASS)            },            _detachShowContextMenuEvents: function() {                var eventName = events.addNamespace("dxcontextmenu", this.NAME);                $(this.option("target")).off(eventName);                this._overlay && this._overlay.content().off(eventName)            },            _attachShowContextMenuEvents: function() {                var that = this,                    eventName = events.addNamespace("dxcontextmenu", this.NAME),                    contextMenuAction = this._createAction($.proxy(function(e) {                        if (!that.option("alternativeInvocationMode").enabled)                            that._show(e.jQueryEvent)                    }, this));                this._overlay && this._overlay.content().on(eventName, $.noop);                $(this.option("target")).on(eventName, $.proxy(function(e) {                    contextMenuAction({jQueryEvent: e})                }, this))            },            _attachInvokeContextMenuEvents: function() {                var that = this,                    eventName = events.addNamespace("dxclick", this.NAME),                    contextMenuAction = this._createAction($.proxy(function() {                        that.toggle()                    }, this));                if (this.option("alternativeInvocationMode").enabled && this._getInvokeTarget())                    $(this._getInvokeTarget()).off(eventName).on(eventName, $.proxy(function(e) {                        contextMenuAction({jQueryEvent: e})                    }, this))            },            _getInvokeTarget: function() {                return this.option("alternativeInvocationMode").invokingElement            },            _hoverEndHandler: function(e) {                e.stopPropagation()            },            _renderDimensions: $.noop,            _renderContainer: function(submenuLevel, submenuContainer) {                var $submenu = $("<div>"),                    $itemsContainer = $("<ul>"),                    $holder = submenuLevel === 1 ? this._itemContainer() : submenuContainer;                $submenu.appendTo($holder).addClass(DX_SUBMENU_CLASS).data(DX_SUBMENU_LEVEL_ID, submenuLevel).css("visibility", submenuLevel === 1 ? "visible" : "hidden");                $itemsContainer.appendTo($submenu).addClass(DX_MENU_ITEMS_CONTAINER_CLASS);                if (submenuLevel === 1) {                    if (this.option("width"))                        $itemsContainer.css("min-width", this.option("width"));                    if (this.option("height"))                        $itemsContainer.css("min-height", this.option("height"))                }                return $itemsContainer            },            _renderSubmenuItems: function(item, $item, submenuLevel) {                this._renderItems(item.items, ++submenuLevel, $item);                this.callBase(item, $item)            },            _getOverlayOptions: function() {                var position = this.option("position"),                    overlayAnimation = this.option("animation"),                    overlayOptions = {                        focusStateEnabled: this.option("focusStateEnabled"),                        animation: overlayAnimation,                        closeOnOutsideClick: $.proxy(this._closeOnOutsideClickHandler, this),                        closeOnTargetScroll: true,                        deferRendering: false,                        disabled: this.option("disabled"),                        position: {                            at: position.at,                            my: position.my,                            of: this.option("target")                        },                        shading: false,                        showTitle: false,                        height: "auto",                        width: "auto",                        onShowing: $.proxy(this._overlayShowingActionHandler, this),                        onShown: $.proxy(this._overlayShownActionHandler, this),                        onHiding: $.proxy(this._overlayHidingActionHandler, this),                        onHidden: $.proxy(this._overlayHiddenActionHandler, this),                        onPositioned: $.proxy(this._overlayPositionedActionHandler, this),                        onPositioning: $.proxy(this._overlayPositioningActionHandler, this)                    };                return overlayOptions            },            _overlayShowingActionHandler: function(arg) {                this._actions.onShowing(arg);                this._clearFocusedItem()            },            _overlayShownActionHandler: function(arg) {                this._actions.onShown(arg);                this._clearFocusedItem()            },            _clearFocusedItem: function() {                this._removeFocusedItem();                this.option("focusedElement", null)            },            _overlayHidingActionHandler: function(arg) {                this._actions.onHiding(arg);                if (!arg.cancel)                    this._hideAllShownSubmenus()            },            _overlayHiddenActionHandler: function(arg) {                this._actions.onHidden(arg);                this._setOptionSilent("visible", false)            },            _overlayPositionedActionHandler: $.noop,            _overlayPositioningActionHandler: function(arg) {                var targetPosition = arg.position,                    newPosition = targetPosition;                if ((targetPosition.h.oversize !== 0 || targetPosition.v.oversize !== 0) && !this.option("_notChangePosition")) {                    newPosition.h.location = Math.round(targetPosition.h.location - targetPosition.h.oversize);                    newPosition.v.location = Math.round(targetPosition.v.location - targetPosition.v.oversize);                    DX.position(this.element(), newPosition)                }            },            _closeOnOutsideClickHandler: function(e) {                var $clickedItem,                    $activeItemContainer,                    $itemContainers,                    $rootItem,                    isRootItemClicked,                    isInnerOverlayClicked,                    isInvokeTarget = $(e.target).closest(this._getInvokeTarget());                if (e.target === document)                    return true;                if (isInvokeTarget && isInvokeTarget.length)                    return false;                $activeItemContainer = this._getActiveItemsContainer(e.target);                $itemContainers = this._getItemsContainers();                $clickedItem = this._searchActiveItem(e.target);                $rootItem = this.element().parents("." + DX_MENU_ITEM_CLASS);                isRootItemClicked = $clickedItem[0] === $rootItem[0] && $clickedItem.length && $rootItem.length;                isInnerOverlayClicked = this._isIncludeOverlay($activeItemContainer, $itemContainers) && $clickedItem.length;                if (isInnerOverlayClicked || isRootItemClicked) {                    if (this._getShowSubmenuMode() === "onClick")                        this._hideAllShownChildSubmenus($clickedItem);                    return false                }                return true            },            _getActiveItemsContainer: function(target) {                return $(target).closest("." + DX_MENU_ITEMS_CONTAINER_CLASS)            },            _getItemsContainers: function() {                return this._overlay._$content.find("." + DX_MENU_ITEMS_CONTAINER_CLASS)            },            _searchActiveItem: function(target) {                return $(target).closest("." + DX_MENU_ITEM_CLASS).eq(0)            },            _isIncludeOverlay: function($activeOverlay, $allOverlays) {                var isSame = false;                $.each($allOverlays, function(index, $overlay) {                    if ($activeOverlay.is($overlay) && !isSame)                        isSame = true                });                return isSame            },            _hideAllShownChildSubmenus: function($clickedItem) {                var that = this,                    $submenuElements = $clickedItem.find("." + DX_SUBMENU_CLASS),                    shownSubmenus = $.extend([], this._shownSubmenus),                    $context;                if ($submenuElements.length > 0)                    $.each(shownSubmenus, function(index, $submenu) {                        $context = that._searchActiveItem($submenu.context).parent();                        if ($context.parent().is($clickedItem.parent().parent()) && !$context.is($clickedItem.parent()))                            that._hideSubmenu($submenu)                    })            },            _showSubmenu: function($item) {                var isItemHasSubmenu = $item.children("." + DX_SUBMENU_CLASS).length,                    isSubmenuVisible;                this._hideSubmenusOnSameLevel($item);                if (isItemHasSubmenu) {                    this.callBase($item);                    $item.closest("." + DX_MENU_ITEMS_CONTAINER_CLASS).find("." + DX_MENU_ITEM_EXPANDED_CLASS).removeClass(DX_MENU_ITEM_EXPANDED_CLASS);                    isSubmenuVisible = this._isSubmenuVisible($item.children("." + DX_SUBMENU_CLASS));                    if (!isSubmenuVisible) {                        $item.addClass(DX_MENU_ITEM_EXPANDED_CLASS);                        this._drawSubmenu($item)                    }                }            },            _hideSubmenusOnSameLevel: function($item) {                var $expandedItems = $item.closest("." + DX_MENU_ITEMS_CONTAINER_CLASS).find("." + DX_MENU_ITEM_EXPANDED_CLASS);                if ($expandedItems.length) {                    $expandedItems.removeClass(DX_MENU_ITEM_EXPANDED_CLASS);                    this._hideSubmenu($expandedItems.find("." + DX_SUBMENU_CLASS))                }            },            _hideSubmenuGroup: function($submenu) {                if (this._isSubmenuVisible($submenu))                    this._hideSubmenuCore($submenu)            },            _isSubmenuVisible: function($submenu) {                return $submenu.css("visibility") === "visible"            },            _drawSubmenu: function($itemElement) {                var animation = this.option("animation") ? this.option("animation").show : {},                    $submenu = $itemElement.children("." + DX_SUBMENU_CLASS);                if (this._overlay && this._overlay.option("visible")) {                    if (!utils.isDefined(this._shownSubmenus))                        this._shownSubmenus = [];                    if ($.inArray($submenu, this._shownSubmenus))                        this._shownSubmenus.push($submenu);                    DX.position($submenu, this._getSubmenuPosition($itemElement));                    animation && this._animate($submenu, animation);                    $submenu.css("visibility", "visible");                    this._stopAnimate($submenu)                }            },            _animate: function($container, options) {                fx.animate($container, options)            },            _getSubmenuPosition: function($rootItem) {                var submenuDirection = this.option("submenuDirection").toLowerCase(),                    $rootItemWrapper = $rootItem.parent("." + DX_MENU_ITEM_WRAPPER_CLASS),                    position = {                        collision: "flip",                        of: $rootItemWrapper,                        offset: {                            h: 0,                            v: -1                        }                    };                switch (submenuDirection) {                    case"left":                        position.at = "left top";                        position.my = "right top";                        break;                    case"right":                        position.at = "right top";                        position.my = "left top";                        break;                    default:                        if (this.option("rtlEnabled")) {                            position.at = "left top";                            position.my = "right top"                        }                        else {                            position.at = "right top";                            position.my = "left top"                        }                        break                }                return position            },            _updateSubmenuVisibilityOnClick: function(actionArgs) {                var $itemElement,                    itemData,                    $submenuElement,                    notCloseMenuOnItemClick;                if (actionArgs.args.length && actionArgs.args[0]) {                    actionArgs.args[0].jQueryEvent.stopPropagation();                    $itemElement = actionArgs.args[0].itemElement;                    itemData = this._getItemData($itemElement);                    notCloseMenuOnItemClick = itemData && itemData.closeMenuOnClick === false;                    $submenuElement = $itemElement.children("." + DX_SUBMENU_CLASS);                    if ($itemElement.context === $submenuElement.context && $submenuElement.css("visibility") === "visible")                        return;                    if (!itemData || itemData.disabled || notCloseMenuOnItemClick)                        return;                    this._updateSelectedItemOnClick(actionArgs);                    if ($submenuElement.length === 0) {                        var $prevSubmenu = $($itemElement.parents("." + DX_SUBMENU_CLASS)[0]);                        this._hideSubmenu($prevSubmenu);                        if (!actionArgs.canceled && this._overlay && this._overlay.option("visible"))                            this.option("visible", false)                    }                    else {                        if (this._shownSubmenus && this._shownSubmenus.length > 0)                            if (this._shownSubmenus[0].is($submenuElement) || this._shownSubmenus[0].has($submenuElement).length === 1)                                this._hideSubmenu($submenuElement);                            else                                this._hideAllShownSubmenus();                        this._showSubmenu($itemElement)                    }                }            },            _hideSubmenu: function($curSubmenu) {                var that = this,                    shownSubmenus = $.extend([], that._shownSubmenus);                $.each(shownSubmenus, function(index, $submenu) {                    if ($curSubmenu.is($submenu) || $curSubmenu.has($submenu).length) {                        $submenu.parent().removeClass(DX_MENU_ITEM_EXPANDED_CLASS);                        that._hideSubmenuCore($submenu)                    }                })            },            _hideSubmenuCore: function($submenu) {                var index = $.inArray($submenu, this._shownSubmenus),                    animation = this.option("animation") ? this.option("animation").hide : null;                if (index >= 0)                    this._shownSubmenus.splice(index, 1);                this._stopAnimate($submenu);                animation && this._animate($submenu, animation);                $submenu.css("visibility", "hidden")            },            _stopAnimate: function($container) {                fx.stop($container, true)            },            _hideAllShownSubmenus: function() {                var that = this,                    shownSubmenus = $.extend([], that._shownSubmenus),                    $expandedItems = this._overlay.content().find("." + DX_MENU_ITEM_EXPANDED_CLASS);                $expandedItems.removeClass(DX_MENU_ITEM_EXPANDED_CLASS);                $.each(shownSubmenus, function(_, $submenu) {                    that._hideSubmenuCore($submenu)                })            },            _optionChanged: function(args) {                if (this._cancelOptionChange)                    return;                if ($.inArray(args.name, ACTIONS) > -1) {                    this._initActions();                    return                }                switch (args.name) {                    case"visible":                        this._toggleVisibility(args.value);                        break;                    case"alternativeInvocationMode":                        this._invalidate();                        break;                    case"items":                        if (this._overlay.option("visible"))                            this._overlay.hide();                        this.callBase(args);                        break;                    case"position":                    case"submenuDirection":                        this._invalidate();                        break;                    case"target":                        args.previousValue && this._detachShowContextMenuEvents($(args.previousValue));                        this._invalidate();                        break;                    case"focusedElement":                        this.callBase(args);                        break;                    default:                        if (this._overlay)                            if (this._overlay.option("visible"))                                this._overlay.hide();                        this.callBase(args)                }            },            _toggleVisibility: function(showing) {                showing ? this._show() : this._hide()            },            _show: function(jQEvent) {                var canShowMenu = !(this._overlay && this._positionContextMenu(jQEvent)),                    id = new DevExpress.data.Guid,                    promise;                if (canShowMenu && this._overlay) {                    this.option("focusedElement", this._itemElements().first());                    promise = this._overlay.show();                    this._overlay.content().attr({                        id: id,                        role: "menu"                    });                    this.setAria("owns", id);                    this._setOptionSilent("visible", true)                }                return promise || $.Deferred().reject().promise()            },            _positionContextMenu: function(jQEvent) {                var position = this.option("position"),                    positioningAction = this._createActionByOption("onPositioning", actionArgs),                    actionArgs;                if (jQEvent && jQEvent.preventDefault)                    position = {                        at: "top left",                        my: "top left",                        of: jQEvent                    };                if (!position.of)                    position.of = this.option("target");                actionArgs = {                    position: position,                    jQueryEvent: jQEvent                };                positioningAction(actionArgs);                if (!actionArgs.canceled && this._overlay)                    position && this._overlay.option("position", position);                else                    actionArgs.jQueryEvent.cancel = true;                return actionArgs.canceled            },            _hide: function() {                var promise;                if (this._overlay) {                    this._overlay.content().removeAttr("id");                    promise = this._overlay.hide();                    this._setOptionSilent("visible", false)                }                this.setAria("owns", undefined);                return promise || $.Deferred().reject().promise()            },            _clean: function() {                if (this._overlay) {                    this._overlay.element().remove();                    this._overlay = null                }                this._detachShowContextMenuEvents($(this.option("target")))            },            toggle: function(showing) {                var visible = this.option("visible");                showing = showing === undefined ? !visible : showing;                return showing ? this._show() : this._hide()            },            show: function() {                return this.toggle(true)            },            hide: function() {                return this.toggle(false)            }        }))    })(jQuery, DevExpress);    /*! Module widgets-web, file ui.menu.js */    (function($, DX, undefined) {        var ui = DX.ui,            utils = DX.utils,            events = ui.events;        var DX_MENU_CLASS = "dx-menu",            DX_MENU_VERTICAL_CLASS = DX_MENU_CLASS + "-vertical",            DX_MENU_HORIZONTAL_CLASS = DX_MENU_CLASS + "-horizontal",            DX_MENU_ITEM_CLASS = DX_MENU_CLASS + "-item",            DX_MENU_ITEMS_CONTAINER_CLASS = DX_MENU_CLASS + "-items-container",            DX_MENU_ITEM_EXPANDED_CLASS = DX_MENU_ITEM_CLASS + "-expanded",            DX_CONTEXT_MENU_CLASS = "dx-context-menu",            DX_CONTEXT_MENU_CONTAINER_BORDER_CLASS = DX_CONTEXT_MENU_CLASS + "-container-border",            DX_CONTEXT_MENU_CONTENT_DELIMITER_CLASS = "dx-context-menu-content-delimiter",            DX_SUBMENU_CLASS = "dx-submenu",            DX_STATE_DISABLED_CLASS = "dx-state-disabled",            DX_STATE_FOCUSED_CLASS = "dx-state-focused",            DX_STATE_HOVER_CLASS = "dx-state-hover",            FOCUS_UP = "up",            FOCUS_DOWN = "down",            FOCUS_LEFT = "left",            FOCUS_RIGHT = "right",            SHOW_SUBMENU_OPERATION = "showSubmenu",            NEXTITEM_OPERATION = "nextItem",            PREVITEM_OPERATION = "prevItem",            DEFAULT_SHOW_DELAY = 50,            DEFAULT_HIDE_DELAY = 300,            ACTIONS = ["onSubmenuShowing", "onSubmenuShown", "onSubmenuHiding", "onSubmenuHidden"],            dxSubmenu = ui.dxContextMenu.inherit({                _setDefaultOptions: function() {                    this.callBase();                    this.option({orientation: "horizontal"})                },                _renderContentImpl: function() {                    this.callBase();                    this._renderDelimiter()                },                _renderDelimiter: function() {                    this.$contentDelimiter = $("<div>").appendTo(this._itemContainer()).addClass(DX_CONTEXT_MENU_CONTENT_DELIMITER_CLASS)                },                _overlayPositionedActionHandler: function(arg) {                    this._showDelimiter(arg)                },                _hoverEndHandler: function(e) {                    var $itemElement = $(e.currentTarget);                    $itemElement.removeClass(DX_STATE_FOCUSED_CLASS)                },                _hoverStartHandler: function(e) {                    this.callBase(e);                    var $itemElement = $(e.currentTarget);                    $itemElement.addClass(DX_STATE_FOCUSED_CLASS)                },                _showDelimiter: function(arg) {                    var $submenu = this._itemContainer().children("." + DX_SUBMENU_CLASS).eq(0),                        $rootItem = this.option("position").of,                        position = {of: $submenu},                        containerOffset,                        rootOffset;                    if (this.$contentDelimiter) {                        containerOffset = arg.position;                        rootOffset = $rootItem.offset();                        this.$contentDelimiter.css("display", "block");                        if (this.option("orientation") === "horizontal") {                            this.$contentDelimiter.width($rootItem.width() < $submenu.width() ? $rootItem.width() - 2 : $submenu.width() - 2);                            this.$contentDelimiter.height(2);                            if (containerOffset.v.location > rootOffset.top)                                if (Math.round(containerOffset.h.location) === Math.round(rootOffset.left)) {                                    position.offset = "1 -1";                                    position.at = "left top";                                    position.my = "left top"                                }                                else {                                    position.offset = "-1 -1";                                    position.at = "right top";                                    position.my = "right top"                                }                            else {                                this.$contentDelimiter.height(4);                                if (Math.round(containerOffset.h.location) === Math.round(rootOffset.left)) {                                    position.offset = "1 2";                                    position.at = "left bottom";                                    position.my = "left bottom"                                }                                else {                                    position.offset = "-1 2";                                    position.at = "right bottom";                                    position.my = "right bottom"                                }                            }                        }                        else if (this.option("orientation") === "vertical") {                            this.$contentDelimiter.width(2);                            this.$contentDelimiter.height($rootItem.height() < $submenu.height() ? $rootItem.height() - 2 : $submenu.height() - 2);                            if (containerOffset.h.location > rootOffset.left)                                if (Math.round(containerOffset.v.location) === Math.round(rootOffset.top)) {                                    position.offset = "-1 1";                                    position.at = "left top";                                    position.my = "left top"                                }                                else {                                    position.offset = "-1 -1";                                    position.at = "left bottom";                                    position.my = "left bottom"                                }                            else if (Math.round(containerOffset.v.location) === Math.round(rootOffset.top)) {                                position.offset = "1 1";                                position.at = "right top";                                position.my = "right top"                            }                            else {                                position.offset = "1 -1";                                position.at = "right bottom";                                position.my = "right bottom"                            }                        }                        DX.position(this.$contentDelimiter, position)                    }                }            });        DX.registerComponent("dxMenu", ui, ui.dxMenuBase.inherit({            _setDeprecatedOptions: function() {                this.callBase();                $.extend(this._deprecatedOptions, {                    allowSelection: {                        since: "14.2",                        message: 'Use the "selectionMode" option instead'                    },                    submenuHiddenAction: {                        since: "14.2",                        alias: "onSubmenuHidden"                    },                    submenuHidingAction: {                        since: "14.2",                        alias: "onSubmenuHiding"                    },                    submenuShowingAction: {                        since: "14.2",                        alias: "onSubmenuShowing"                    },                    submenuShownAction: {                        since: "14.2",                        alias: "onSubmenuShown"                    }                })            },            _setDefaultOptions: function() {                this.callBase();                this.option({                    orientation: "horizontal",                    submenuDirection: "auto",                    showFirstSubmenuMode: {                        name: "onClick",                        delay: {                            show: 50,                            hide: 300                        }                    },                    hideSubmenuOnMouseLeave: false,                    onSubmenuShowing: null,                    onSubmenuShown: null,                    onSubmenuHiding: null,                    onSubmenuHidden: null                })            },            _setOptionsByReference: function() {                this.callBase();                $.extend(this._optionsByReference, {                    animation: true,                    selectedItem: true                })            },            _focusTarget: function() {                return this.element()            },            _eventBindingTarget: function() {                return this.element()            },            _getOrientation: function() {                return this.option("orientation") === "vertical" ? "vertical" : "horizontal"            },            _isMenuHorizontal: function() {                return this._getOrientation() === "horizontal"            },            _moveFocus: function(location) {                var $items = this._itemElements().filter(":visible"),                    isMenuHorizontal = this._isMenuHorizontal(),                    argument,                    $activeItem = this._getActiveItem(true),                    operation,                    navigationAction,                    $newTarget;                switch (location) {                    case FOCUS_UP:                        operation = isMenuHorizontal ? SHOW_SUBMENU_OPERATION : this._getItemsNavigationOperation(PREVITEM_OPERATION);                        argument = isMenuHorizontal ? $activeItem : $items;                        navigationAction = this._getKeyboardNavigationAction(operation, argument);                        $newTarget = navigationAction();                        break;                    case FOCUS_DOWN:                        operation = isMenuHorizontal ? SHOW_SUBMENU_OPERATION : this._getItemsNavigationOperation(NEXTITEM_OPERATION);                        argument = isMenuHorizontal ? $activeItem : $items;                        navigationAction = this._getKeyboardNavigationAction(operation, argument);                        $newTarget = navigationAction();                        break;                    case FOCUS_RIGHT:                        operation = isMenuHorizontal ? this._getItemsNavigationOperation(NEXTITEM_OPERATION) : SHOW_SUBMENU_OPERATION;                        argument = isMenuHorizontal ? $items : $activeItem;                        navigationAction = this._getKeyboardNavigationAction(operation, argument);                        $newTarget = navigationAction();                        break;                    case FOCUS_LEFT:                        operation = isMenuHorizontal ? this._getItemsNavigationOperation(PREVITEM_OPERATION) : SHOW_SUBMENU_OPERATION;                        argument = isMenuHorizontal ? $items : $activeItem;                        navigationAction = this._getKeyboardNavigationAction(operation, argument);                        $newTarget = navigationAction();                        break;                    default:                        return this.callBase(location)                }                if ($newTarget && $newTarget.length !== 0)                    this.option("focusedElement", $newTarget)            },            _getItemsNavigationOperation: function(operation) {                var navOperation = operation;                if (this.option("rtlEnabled"))                    navOperation = operation === PREVITEM_OPERATION ? NEXTITEM_OPERATION : PREVITEM_OPERATION;                return navOperation            },            _getKeyboardNavigationAction: function(operation, argument) {                var action = $.noop;                switch (operation) {                    case SHOW_SUBMENU_OPERATION:                        if (!argument.hasClass(DX_STATE_DISABLED_CLASS))                            action = $.proxy(this._showSubmenu, this, argument);                        break;                    case NEXTITEM_OPERATION:                        action = $.proxy(this._nextItem, this, argument);                        break;                    case PREVITEM_OPERATION:                        action = $.proxy(this._prevItem, this, argument);                        break                }                return action            },            _init: function() {                this.callBase();                this._submenus = []            },            _initActions: function() {                this._actions = {};                $.each(ACTIONS, $.proxy(function(index, action) {                    this._actions[action] = this._createActionByOption(action) || $.noop                }, this))            },            _render: function() {                this._visibleSubmenu = [];                this.callBase();                this.element().addClass(DX_MENU_CLASS);                this.setAria("role", "menubar")            },            _getHideDelay: function() {                var delay = this.option("showFirstSubmenuMode").delay;                if (delay)                    return utils.isObject(delay) ? delay.hide : delay;                else                    return DEFAULT_HIDE_DELAY            },            _getShowDelay: function() {                var delay = this.option("showFirstSubmenuMode").delay,                    resultDelay;                if (delay)                    resultDelay = utils.isObject(delay) ? delay.show : delay;                else                    resultDelay = DEFAULT_SHOW_DELAY;                return resultDelay            },            _renderContainer: function() {                var isVerticalMenu = this.option("orientation") === "vertical",                    $rootGroup = $("<div>"),                    $itemsContainer = $("<ul>");                $rootGroup.appendTo(this.element()).addClass(isVerticalMenu ? DX_MENU_VERTICAL_CLASS : DX_MENU_HORIZONTAL_CLASS);                $itemsContainer.appendTo($rootGroup).addClass(DX_MENU_ITEMS_CONTAINER_CLASS).css("min-height", this._getValueHeight($rootGroup));                return $itemsContainer            },            _getValueHeight: function($root) {                var $div = $("<div>").html("Jj").css({                        width: "auto",                        position: "fixed",                        top: "-3000px",                        left: "-3000px"                    }).appendTo($root),                    height = $div.height();                $div.remove();                return height            },            _renderSubmenuItems: function(item, $item) {                var submenu = this._createSubmenu(item.items, $item);                this._submenus.push(submenu);                this._renderBorderElement($item);                this.callBase(item, $item)            },            _createSubmenu: function(items, $rootItem) {                var $submenuContainer = $("<div>").addClass(DX_CONTEXT_MENU_CLASS).appendTo($rootItem);                var result = this._createComponent($submenuContainer, "dxSubmenu", $.extend(this._getSubmenuOptions(), {                        items: items,                        position: this.getSubmenuPosition($rootItem)                    }));                this._attachSubmenuHandlers($rootItem, result);                return result            },            _getSubmenuOptions: function() {                var $submenuTarget = $("<div>"),                    isMenuHorizontal = this._isMenuHorizontal();                return {                        itemTemplate: this.option("itemTemplate"),                        templateProvider: this.option("templateProvider"),                        target: $submenuTarget,                        orientation: this.option("orientation"),                        selectionMode: this.option("selectionMode"),                        selectionByClick: this.option("selectionByClick"),                        cssClass: this.option("cssClass"),                        hoverStateEnabled: this.option("hoverStateEnabled"),                        activeStateEnabled: this.option("activeStateEnabled"),                        focusStateEnabled: this.option("focusStateEnabled"),                        animation: this.option("animation"),                        disabled: this.option("disabled"),                        showSubmenuMode: this._getShowSubmenuMode(),                        onSelectionChanged: $.proxy(this._nestedItemOnSelectionChangedHandler, this),                        onItemClick: $.proxy(this._nestedItemOnItemClickHandler, this),                        onLeftFirstItem: isMenuHorizontal ? null : $.proxy(this._moveMainMenuFocus, this, PREVITEM_OPERATION),                        onLeftLastItem: isMenuHorizontal ? null : $.proxy(this._moveMainMenuFocus, this, NEXTITEM_OPERATION),                        onCloseRootSubmenu: isMenuHorizontal ? $.proxy(this._moveMainMenuFocus, this, PREVITEM_OPERATION) : null,                        onExpandLastSubmenu: isMenuHorizontal ? $.proxy(this._moveMainMenuFocus, this, NEXTITEM_OPERATION) : null,                        _remoteSelectionSync: true,                        _notChangePosition: true                    }            },            _getShowFirstSubmenuMode: function() {                var modeName;                if (utils.isObject(this.option("showFirstSubmenuMode")))                    modeName = this._isDesktopDevice() ? this.option("showFirstSubmenuMode").name : "onClick";                else                    modeName = this._isDesktopDevice() ? this.option("showFirstSubmenuMode") : "onClick";                return modeName            },            _moveMainMenuFocus: function(direction) {                var $expandedItem = this.element().find("." + DX_MENU_ITEM_EXPANDED_CLASS).first(),                    $newItem;                switch (direction) {                    case PREVITEM_OPERATION:                        $newItem = $expandedItem.parent().prev();                        if (!$newItem.length)                            $newItem = $expandedItem.parent().siblings().last();                        $newItem = $newItem.children();                        break;                    case NEXTITEM_OPERATION:                        $newItem = $expandedItem.parent().next();                        if (!$newItem.length)                            $newItem = $expandedItem.parent().siblings().first();                        $newItem = $newItem.children();                        break                }                this._visibleSubmenu.length && this._hideSubmenu(this._visibleSubmenu);                this.focus();                this.option("focusedElement", $newItem)            },            _nestedItemOnSelectionChangedHandler: function(args) {                var selectedItems = args.addedItems,                    submenu = args.element.dxSubmenu("instance");                this._clearSelectionInSubmenus(selectedItems[0], submenu);                this._clearRootSelection();                this.option("selectedItems", selectedItems)            },            _clearSelectionInSubmenus: function(item, targetSubmenu) {                var that = this,                    cleanAllSubmenus = !arguments.length;                $.each(this._submenus, function(index, submenu) {                    var $submenu = submenu._itemContainer(),                        isOtherItem = !$submenu.is(targetSubmenu && targetSubmenu._itemContainer()),                        $selectedItem = $submenu.find("." + that._selectedItemClass());                    if (isOtherItem && $selectedItem.length || cleanAllSubmenus) {                        var selectedItemData;                        $selectedItem.removeClass(that._selectedItemClass());                        selectedItemData = that._getItemData($selectedItem);                        if (selectedItemData)                            selectedItemData.selected = false;                        submenu._clearSelectedItems()                    }                })            },            _clearRootSelection: function() {                var $prevSelectedItem = this.element().find("." + DX_MENU_ITEMS_CONTAINER_CLASS).first().children().children().filter("." + this._selectedItemClass());                if ($prevSelectedItem.length) {                    var prevSelectedItemData;                    prevSelectedItemData = this._getItemData($prevSelectedItem);                    prevSelectedItemData.selected = false;                    $prevSelectedItem.removeClass(this._selectedItemClass())                }                this._clearSelectedItems()            },            _nestedItemOnItemClickHandler: function(arg) {                var onItemClick = this._createActionByOption("onItemClick", {});                onItemClick(arg)            },            _updateSelectedItemOnClick: function(actionArgs) {                var selectedIndex = this.option("selectedIndex");                this.callBase(actionArgs);                if (selectedIndex !== this.option("selectedIndex"))                    this._clearSelectionInSubmenus()            },            _attachSubmenuHandlers: function($rootItem, submenu) {                var that = this,                    $submenuOverlayContent = submenu._overlay.content(),                    submenus = $submenuOverlayContent.find("." + DX_SUBMENU_CLASS),                    submenuMouseLeaveName = events.addNamespace("dxhoverend", this.NAME + "_submenu");                submenu.option({                    onShowing: $.proxy(this._submenuOnShowingHandler, this, $rootItem, submenu),                    onShown: $.proxy(this._submenuOnShownHandler, this, $rootItem, submenu),                    onHiding: $.proxy(this._submenuOnHidingHandler, this, $rootItem, submenu),                    onHidden: $.proxy(this._submenuOnHiddenHandler, this, $rootItem, submenu)                });                $.each(submenus, function(index, submenu) {                    $(submenu).off(submenuMouseLeaveName).on(submenuMouseLeaveName, null, $.proxy(that._submenuMouseLeaveHandler, that, $rootItem))                })            },            _submenuOnShowingHandler: function($rootItem, submenu) {                var $border = $rootItem.children("." + DX_CONTEXT_MENU_CONTAINER_BORDER_CLASS);                this._actions.onSubmenuShowing({                    rootItem: $rootItem,                    submenu: submenu                });                if (this._options.width !== undefined)                    if (this._options.rtlEnabled)                        $border.css("width", this._$element.width() - $rootItem.position().right);                    else                        $border.css("width", this._$element.width() - $rootItem.position().left);                $border.show();                $rootItem.addClass(DX_MENU_ITEM_EXPANDED_CLASS)            },            _submenuOnShownHandler: function($rootItem, submenu) {                this._actions.onSubmenuShown({                    rootItem: $rootItem,                    submenu: submenu                })            },            _submenuOnHidingHandler: function($rootItem, submenu, eventArgs) {                var $border = $rootItem.children("." + DX_CONTEXT_MENU_CONTAINER_BORDER_CLASS),                    args = eventArgs;                args.rootItem = $rootItem;                args.submenu = submenu;                this._actions.onSubmenuHiding(args);                eventArgs = args;                if (!eventArgs.cancel) {                    $border.hide();                    $rootItem.removeClass(DX_MENU_ITEM_EXPANDED_CLASS)                }            },            _submenuOnHiddenHandler: function($rootItem, submenu) {                this._actions.onSubmenuHidden({                    rootItem: $rootItem,                    submenu: submenu                })            },            _submenuMouseLeaveHandler: function($rootItem, eventArgs) {                var that = this,                    target = $(eventArgs.relatedTarget).parents("." + DX_CONTEXT_MENU_CLASS)[0],                    contextmenu = this._getSubmenuElementByRootElement($rootItem).dxSubmenu("instance")._overlay.content()[0];                if (this.option("hideSubmenuOnMouseLeave") && target !== contextmenu) {                    clearTimeout(this._showSubmenuTimer);                    clearTimeout(this._hideSubmenuTimer);                    setTimeout($.proxy(this._hideSubmenuAfterTimeout, this), that._getHideDelay(), $rootItem)                }            },            _hideSubmenuAfterTimeout: function($rootItem) {                var $submenu = this._getSubmenuElementByRootElement($rootItem),                    hasVisibleSubmenu = this._visibleSubmenu.length,                    isRootItemHovered = $(this._visibleSubmenu.context).hasClass(DX_STATE_HOVER_CLASS);                if (hasVisibleSubmenu && !this._getFocusedSubmenuItem(this._getSubmenuInstance(this._visibleSubmenu)).length && !isRootItemHovered)                    $submenu.length && this._getSubmenuInstance($submenu).hide()            },            _getFocusedSubmenuItem: function($submenu) {                return $submenu._overlay.content().find("." + DX_STATE_FOCUSED_CLASS)            },            _getSubmenuInstance: function($submenu) {                return $submenu.dxSubmenu("instance")            },            _getSubmenuElementByRootElement: function($rootItem) {                return $rootItem && $rootItem.children("." + DX_CONTEXT_MENU_CLASS)            },            _getSubmenuInstanceByRootElement: function($rootItem) {                var $submenu = this._getSubmenuElementByRootElement($rootItem);                return $submenu.length && this._getSubmenuInstance($submenu)            },            getSubmenuPosition: function($rootItem) {                var isVerticalMenu = this.option("orientation").toLowerCase() === "vertical",                    submenuDirection = this.option("submenuDirection").toLowerCase(),                    rtlEnabled = this.option("rtlEnabled"),                    submenuPosition = {                        collision: "flip",                        of: $rootItem                    };                switch (submenuDirection) {                    case"leftortop":                        submenuPosition.at = isVerticalMenu ? "left top" : "left top";                        submenuPosition.my = isVerticalMenu ? "right top" : "left bottom";                        break;                    case"rightorbottom":                        submenuPosition.at = isVerticalMenu ? "right top" : "left bottom";                        submenuPosition.my = isVerticalMenu ? "left top" : "left top";                        break;                    default:                        if (isVerticalMenu) {                            submenuPosition.at = rtlEnabled ? "left top" : "right top";                            submenuPosition.my = rtlEnabled ? "right top" : "left top"                        }                        else {                            submenuPosition.at = rtlEnabled ? "right bottom" : "left bottom";                            submenuPosition.my = rtlEnabled ? "right top" : "left top"                        }                        break                }                return submenuPosition            },            _renderBorderElement: function($item) {                $("<div>").appendTo($item).addClass(DX_CONTEXT_MENU_CONTAINER_BORDER_CLASS).hide()            },            _hoverStartHandler: function(e) {                var mouseMoveEventName = events.addNamespace("dxpointermove", this.NAME),                    $item = this._getItemElementByEventArgs(e),                    submenu = this._getSubmenuInstanceByRootElement($item),                    isSelectionActive = utils.isDefined(e.buttons) && e.buttons === 1 || !utils.isDefined(e.buttons) && e.which === 1;                if (this._isItemDisabled($item))                    return;                $item.off(mouseMoveEventName);                if (this._getShowFirstSubmenuMode() === "onHover" && submenu && !isSelectionActive) {                    clearTimeout(this._hideSubmenuTimer);                    clearTimeout(this._showSubmenuTimer);                    if (!submenu._overlay.option("visible")) {                        $item.on(mouseMoveEventName, $.proxy(this._itemMouseMoveHandler, this));                        this._showSubmenuTimer = this._getHideDelay()                    }                    if (!submenu.element().is(this._visibleSubmenu))                        this._hideSubmenu(this._visibleSubmenu)                }            },            _hoverEndHandler: function(eventArg) {                var that = this,                    $item = this._getItemElementByEventArgs(eventArg);                if (this._isItemDisabled($item))                    return;                if ($(eventArg.relatedTarget).hasClass(DX_CONTEXT_MENU_CONTENT_DELIMITER_CLASS))                    return;                if (this.option("hideSubmenuOnMouseLeave") && !$(eventArg.relatedTarget).hasClass(DX_MENU_ITEMS_CONTAINER_CLASS)) {                    clearTimeout(this._showSubmenuTimer);                    clearTimeout(this._hideSubmenuTimer);                    this._hideSubmenuTimer = setTimeout(function() {                        that._hideSubmenuAfterTimeout($item)                    }, that._getHideDelay())                }            },            _showSubmenu: function($itemElement) {                var $submenu = this._getSubmenuElementByRootElement($itemElement);                if (this._visibleSubmenu.length && !this._visibleSubmenu.is($submenu))                    this._hideSubmenu(this._visibleSubmenu);                $submenu.length && this._getSubmenuInstance($submenu).show();                this._visibleSubmenu = $submenu;                this._hoveredRootItem = $itemElement            },            _hideSubmenu: function($submenu) {                $submenu.length && this._getSubmenuInstance($submenu).hide();                if (this._visibleSubmenu.length && this._visibleSubmenu.is($submenu))                    this._visibleSubmenu = [];                this._hoveredRootItem = null            },            _itemMouseMoveHandler: function(e) {                var that = this,                    $item = $(e.currentTarget);                if (this._showSubmenuTimer) {                    clearTimeout(this._hideSubmenuTimer);                    clearTimeout(this._showSubmenuTimer);                    this._showSubmenuTimer = setTimeout(function() {                        if (!that._getSubmenuInstanceByRootElement($item)._overlay.option("visible"))                            that._showSubmenu($item)                    }, that._getShowDelay())                }            },            _updateSubmenuVisibilityOnClick: function(actionArgs) {                var $item,                    item,                    submenu,                    args = actionArgs.args.length && actionArgs.args[0];                if (args) {                    args.jQueryEvent.stopPropagation();                    item = args.itemData;                    $item = args.itemElement;                    if (item.disabled)                        return;                    submenu = this._getSubmenuInstanceByRootElement($item);                    this._updateSelectedItemOnClick(actionArgs);                    if (submenu)                        if (submenu._overlay.option("visible")) {                            if (this._getShowFirstSubmenuMode() === "onClick")                                this._hideSubmenu(submenu.element())                        }                        else                            this._showSubmenu($item);                    else if (this._visibleSubmenu.length)                        this._hideSubmenu(this._visibleSubmenu)                }            },            _optionChanged: function(args) {                if (this._cancelOptionChange)                    return;                this._hideShownSubmenuOnOptionChange(args.name);                switch (args.name) {                    case"selectedItems":                        var item = args.value[0];                        if (this._isItemInSubmenu(item)) {                            this._syncSelectionOptions(args.name);                            this._normalizeSelectedItems()                        }                        else                            this.callBase(args);                        break;                    case"orientation":                    case"submenuDirection":                    case"hideSubmenuOnMouseLeave":                    case"showFirstSubmenuMode":                        this._invalidate();                        break;                    case"showSubmenuMode":                        this._changeSubmenusOption(args.name, args.value);                        break;                    case"onSubmenuShowing":                    case"onSubmenuShown":                    case"onSubmenuHiding":                    case"onSubmenuHidden":                        this._initActions();                        break;                    default:                        this.callBase(args)                }            },            _hideShownSubmenuOnOptionChange: function(optionName) {                if (optionName !== "focusedElement" && this._visibleSubmenu.length)                    this._hideSubmenu(this._visibleSubmenu)            },            _changeSubmenusOption: function(name, value) {                $.each(this._submenus, function(index, submenu) {                    submenu.option(name, value)                })            },            _isItemInSubmenu: function(item) {                return $.inArray(JSON.stringify(item), this._getStringifiedArray(this.option("items"))) < 0            },            selectItem: function(itemElement) {                var itemData = this._getItemData(itemElement);                if (this._isItemInSubmenu(itemData))                    $.each(this._submenus, function(index, submenu) {                        if (submenu._isOwnItem(itemData))                            submenu.selectItem(itemElement)                    });                else                    this.callBase(itemElement)            }        }));        DX.registerComponent("dxSubmenu", ui.dxMenu, dxSubmenu);        ui.dxMenu.__internals = {}    })(jQuery, DevExpress);    /*! Module widgets-web, file ui.treeView.js */    (function($, DX, undefined) {        var ui = DX.ui,            events = ui.events,            dataUtils = DX.data.utils,            utils = DX.utils;        var WIDGET_CLASS = "dx-treeview",            NODE_CONTAINER_CLASS = "dx-treeview-node-container",            OPENED_NODE_CONTAINER_CLASS = "dx-treeview-node-container-opened",            NODE_CLASS = "dx-treeview-node",            ITEM_CLASS = "dx-treeview-item",            ITEM_WITH_CHECKBOX_CLASS = "dx-treeview-item-with-checkbox",            ITEM_DATA_KEY = "dx-treeview-item-data",            IS_LEAF = "dx-treeview-node-is-leaf",            TOGGLE_ITEM_VISIBILITY_CLASS = "dx-treeview-toggle-item-visibility",            TOGGLE_ITEM_VISIBILITY_OPENED_CLASS = "dx-treeview-toggle-item-visibility-opened",            SELECT_ALL_ITEM_CLASS = "dx-treeview-select-all-item",            FOCUSED_STATE_CLASS = "dx-state-focused",            DISABLED_STATE_CLASS = "dx-state-disabled",            DATA_ITEM_ID = "data-item-id",            DBLCLICK_EVENT_NAME = "dxdblclick";        var scrollableContainerUpdatedOnInit = $.noop;        DX.registerComponent("dxTreeView", ui, ui.CollectionWidget.inherit({            _supportedKeys: function(e) {                var click = function(e) {                        var $itemElement = this.option("focusedElement");                        if (!$itemElement)                            return;                        e.target = $itemElement;                        e.currentTarget = $itemElement;                        this._itemClickHandler(e, $itemElement.find(">." + ITEM_CLASS))                    };                var select = function(e) {                        e.preventDefault();                        this._changeCheckBoxState(this.option("focusedElement"))                    };                var toggleExpandedNestedItems = function(state, e) {                        if (!this.option("expandAllEnabled"))                            return;                        e.preventDefault();                        var $rootElement = this.option("focusedElement");                        if (!$rootElement)                            return;                        var rootItem = this._getItemData($rootElement.find("." + ITEM_CLASS));                        this._toggleExpandedNestedItems([rootItem], state)                    };                return $.extend(this.callBase(), {                        enter: this.option("showCheckBoxes") ? select : click,                        space: this.option("showCheckBoxes") ? select : click,                        asterisk: $.proxy(toggleExpandedNestedItems, this, true),                        minus: $.proxy(toggleExpandedNestedItems, this, false)                    })            },            _changeCheckBoxState: function($element) {                var $checkbox = $element.find("> .dx-checkbox");                var checkboxInstance = $checkbox.dxCheckBox("instance"),                    currentState = checkboxInstance.option("value");                if (!checkboxInstance.option("disabled"))                    this._updateItemSelection(!currentState, $element.find("." + ITEM_CLASS).get(0), true, $element)            },            _toggleExpandedNestedItems: function(items, state) {                if (!items)                    return;                for (var i = 0, len = items.length; i < len; i++) {                    var item = items[i];                    this._toggleExpandedState(item, state);                    this._toggleExpandedNestedItems(item.items, state)                }            },            _getNodeElementById: function(id) {                return this.element().find("[" + DATA_ITEM_ID + "='" + id + "']")            },            _activeStateUnit: "." + ITEM_CLASS,            _setDefaultOptions: function() {                this.callBase();                this.option({                    animationEnabled: true,                    dataStructure: "tree",                    expandedItems: [],                    expandAllEnabled: false,                    keyExpr: "id",                    displayExpr: "text",                    selectedExpr: "selected",                    expandedExpr: "expanded",                    disabledExpr: "disabled",                    itemsExpr: "items",                    parentIdExpr: "parentId",                    hasItemsExpr: "hasItems",                    showCheckBoxes: false,                    selectNodesRecursive: true,                    selectAllEnabled: false,                    selectAllText: "(" + Globalize.localize("dxList-selectAll") + ")",                    onItemSelected: null,                    onItemExpanded: null,                    onItemCollapsed: null,                    scrollDirection: "vertical",                    virtualModeEnabled: false,                    rootValue: 0,                    focusStateEnabled: false,                    selectionMode: "multi"                })            },            _setDeprecatedOptions: function() {                this.callBase();                $.extend(this._deprecatedOptions, {                    selectedItems: {                        since: "14.2",                        message: "Use item.selected instead"                    },                    expandedItems: {                        since: "14.2",                        message: "Use item.expanded instead"                    }                })            },            _initSelectedItems: $.noop,            _syncSelectionOptions: $.noop,            _fireSelectionChanged: function() {                var selectionChangePromise = this._selectionChangePromise;                $.when(selectionChangePromise).done($.proxy(function() {                    this._createActionByOption("onSelectionChanged", {excludeValidators: ["disabled", "readOnly"]})()                }, this))            },            _initExpressions: function() {                this._compileKeyAccessors();                this._compileDisplayAccessors();                this._compileSelectedAccessors();                this._compileExpandedAccessors();                this._compileItemsAccessors();                this._compileParentIdAccessors();                this._compileDisabledAccessors();                this._compileHasItemsAccessors()            },            _initDynamicTemplates: function() {                var displayExpr = this.option("displayExpr");                if (displayExpr !== "text" && displayExpr !== "html")                    this._dynamicTemplates["item"] = new ui.DefaultTemplate($.proxy(function(itemData) {                        var $itemContent = $("<div>"),                            icon = itemData.icon || itemData.iconSrc;                        if (icon)                            utils.getImageContainer(icon).appendTo($itemContent);                        $("<span>").text(this._displayGetter(itemData)).appendTo($itemContent);                        return $itemContent                    }, this));                else                    delete this._dynamicTemplates["item"]            },            _compileKeyAccessors: function() {                this._keyGetter = dataUtils.compileGetter(this.option("keyExpr"));                this._keySetter = dataUtils.compileSetter(this.option("keyExpr"))            },            _compileDisplayAccessors: function() {                this._displayGetter = dataUtils.compileGetter(this.option("displayExpr"));                this._displaySetter = dataUtils.compileSetter(this.option("displayExpr"))            },            _compileSelectedAccessors: function() {                this._selectedGetter = dataUtils.compileGetter(this.option("selectedExpr"));                this._selectedSetter = dataUtils.compileSetter(this.option("selectedExpr"))            },            _compileExpandedAccessors: function() {                this._expandedGetter = dataUtils.compileGetter(this.option("expandedExpr"));                this._expandedSetter = dataUtils.compileSetter(this.option("expandedExpr"))            },            _compileItemsAccessors: function() {                this._itemsGetter = dataUtils.compileGetter(this.option("itemsExpr"));                this._itemsSetter = dataUtils.compileSetter(this.option("itemsExpr"))            },            _compileParentIdAccessors: function() {                this._parentIdGetter = dataUtils.compileGetter(this.option("parentIdExpr"));                this._parentIdSetter = dataUtils.compileSetter(this.option("parentIdExpr"))            },            _compileDisabledAccessors: function() {                this._disabledGetter = dataUtils.compileGetter(this.option("disabledExpr"));                this._disabledSetter = dataUtils.compileSetter(this.option("disabledExpr"))            },            _compileHasItemsAccessors: function() {                this._hasItemsGetter = dataUtils.compileGetter(this.option("hasItemsExpr"));                this._hasItemsSetter = dataUtils.compileSetter(this.option("hasItemsExpr"))            },            _defaultOptionsRules: function() {                return this.callBase().concat([{                            device: function(device) {                                return DX.devices.real().generic && !DX.devices.isSimulator()                            },                            options: {                                hoverStateEnabled: true,                                focusStateEnabled: true                            }                        }])            },            _optionChanged: function(args) {                var name = args.name,                    value = args.value;                switch (name) {                    case"selectAllEnabled":                        if (value) {                            if (!this._$selectAllItem || !this._$selectAllItem.length)                                this._renderSelectAllItem()                        }                        else if (this._$selectAllItem) {                            this._$selectAllItem.remove();                            delete this._$selectAllItem                        }                        break;                    case"selectAllText":                        if (this._$selectAllItem)                            this._$selectAllItem.dxCheckBox("instance").option("text", value);                        break;                    case"scrollDirection":                        this._scrollableContainer.option("direction", value);                        break;                    case"selectedItems":                        if (this._$selectAllItem) {                            var selectAllItem = this._$selectAllItem.dxCheckBox("instance"),                                selectAllItemValue = selectAllItem.option("value");                            if (selectAllItemValue && this._itemsCount === value.length)                                return;                            this._suppressUpdateSelectAllItemValue = true;                            selectAllItem.option("value", this._calculateSelectAllItemValue());                            this._suppressUpdateSelectAllItemValue = false                        }                        break;                    case"items":                        this._suppressDeprecatedWarnings();                        delete this._$selectAllItem;                        if (this.option("selectedItems").length)                            this.option("selectedItems", []);                        if (this.option("expandedItems").length)                            this.option("expandedItems", []);                        this.callBase(args);                        this._resumeDeprecatedWarnings();                        break;                    case"keyExpr":                    case"displayExpr":                        if (!this._dynamicTemplates["item"])                            this._initDynamicTemplates();                        this._initExpressions();                        this.repaint();                        break;                    case"itemsExpr":                    case"selectedExpr":                    case"expandedExpr":                    case"parentIdExpr":                    case"disabledExpr":                    case"hasItemsExpr":                        this._initExpressions();                        this.repaint();                        break;                    case"dataStructure":                    case"showCheckBoxes":                    case"rootValue":                        this.repaint();                        break;                    case"expandedItems":                        var isFocused = this.element().hasClass(FOCUSED_STATE_CLASS);                        this.repaint();                        if (isFocused) {                            this.element().focus();                            var key = this.option("focusedElement").attr(DATA_ITEM_ID);                            var $node = this._getNodeElementById(key);                            this.option("focusedElement", $node)                        }                        break;                    case"selectNodesRecursive":                    case"onItemSelected":                    case"onItemExpanded":                    case"onItemCollapsed":                    case"expandAllEnabled":                    case"animationEnabled":                    case"virtualModeEnabled":                        break;                    case"virtualModeEnabled":                    case"rootValue":                        this.callBase(args);                        break;                    default:                        this.callBase(args)                }            },            _nodes: [],            _initDataSource: function() {                this.callBase();                if (this._isVirtualMode())                    this._dataSource.filter(this.option("parentIdExpr"), this.option("rootValue"))            },            _dataSourceLoadErrorHandler: function() {                this._renderEmptyMessage()            },            _init: function() {                this._initExpressions();                this.callBase();                this._initDynamicTemplates()            },            _render: function() {                var that = this;                this.element().addClass(WIDGET_CLASS);                this._itemsCount = 0;                this.element().off("dxpointerdown").on("dxpointerdown", function(e) {                    var $target = $(e.target).closest(that._activeStateUnit);                    if (!$target.length)                        e.preventDefault()                });                this._makeNodes();                this._setKeyForItems(this._nodes, 1);                this.callBase();                this.setAria("role", "tree");                if (this._isVirtualMode() && this._dataSource && !this._dataSource.items().length)                    this._initialized = false            },            _makeNodes: function() {                this._nodes = this._getSmartItemsCopy(this.option("items"));                if (this.option("dataStructure") === "plain")                    this._nodes = this._createHierarchicalStructure(this._nodes)            },            _getSmartItemsCopy: function(items) {                var that = this,                    result = [];                $.each(items, function(_, item) {                    var itemCopy = $.extend(true, {}, item);                    if (that._itemHasChildren(itemCopy)) {                        var children = that._itemsGetter(itemCopy);                        var childrenCopy = that._getSmartItemsCopy(children);                        that._itemsSetter(itemCopy, childrenCopy)                    }                    result.push(itemCopy)                });                return result            },            _setKeyForItems: function(items, startKey) {                var that = this;                $.each(items, function(index, item) {                    if (that._isPrimitiveValue(item))                        item = that._makeObjectFromPrimitive(item);                    if (utils.isDefined(that._keyGetter(item)))                        return false;                    that._keySetter(item, startKey);                    startKey++;                    if (that._itemHasChildren(item))                        startKey = that._setKeyForItems(that._itemsGetter(item), startKey)                });                return startKey            },            _makePlainItems: function() {                return this._makePlainList(this.option("items"), null, true)            },            _makePlainNodes: function() {                return this._makePlainList(this._nodes, null, true)            },            _updateSelectionItemsOption: function() {                var that = this,                    selectedItems = [];                $.each(that._plainItems, function(_, item) {                    if (that._selectedGetter(item))                        selectedItems.push(item)                });                return selectedItems            },            _renderContentImpl: function() {                var items = this._nodes;                if (items.length) {                    this._makePlainStructures();                    this._applyExpandedItemsFromOption();                    this._applySelectedItemsFromOption(items);                    var plainList = this._makePlainList(items, null);                    if (this.option("selectNodesRecursive")) {                        items = this._calculateChildrenSelectedState(items);                        this._calculateParentSelectedState(plainList)                    }                    this._calculateParentExpandedState(plainList);                    this._createParentFieldForEachItem(items);                    this._suppressDeprecatedWarnings();                    var selectedItems = this._updateSelectionItemsOption();                    if (selectedItems.length)                        this.option("selectedItems", selectedItems);                    this._resumeDeprecatedWarnings();                    this._renderScrollableContainer();                    var $nodeContainer = this._renderNodeContainer();                    this._scrollableContainer.content().append($nodeContainer);                    this._renderItems($nodeContainer, items, true);                    if (this.option("selectAllEnabled"))                        this._renderSelectAllItem($nodeContainer)                }                this._renderEmptyMessage()            },            _makePlainStructures: function() {                this._startIndex = 1;                this._plainItems = this._makePlainItems();                this._startIndex = 1;                this._plainNodes = this._makePlainNodes()            },            _isVirtualMode: function() {                return this.option("virtualModeEnabled") && this.option("dataSource")            },            _fireContentReadyAction: function() {                this.callBase();                if (this._scrollableContainer && this._scrollableContainer.content().height() > this.element().height()) {                    this._scrollableContainer.update();                    scrollableContainerUpdatedOnInit()                }            },            _createHierarchicalStructure: function(items) {                var result = [],                    lookup = {},                    itemCount = items.length,                    i;                for (i = 0; i < itemCount; i++) {                    lookup[this._keyGetter(items[i])] = items[i];                    this._itemsSetter(items[i], [])                }                for (i = 0; i < itemCount; i++) {                    var parentId = this._parentIdGetter(items[i]),                        node = this._createNode(items[i]);                    if (parentId) {                        var children = this._itemsGetter(lookup[parentId]);                        children.push(node)                    }                    else                        result.push(node)                }                return result            },            _createNode: function(itemData) {                var node = {};                this._keySetter(node, this._keyGetter(itemData));                this._displaySetter(node, this._displayGetter(itemData));                this._itemsSetter(node, this._itemsGetter(itemData));                this._expandedSetter(node, this._expandedGetter(itemData));                this._disabledSetter(node, this._disabledGetter(itemData));                if (itemData.hasOwnProperty(this.option("selectedExpr")) && typeof this._selectedGetter(itemData) !== "undefined")                    this._selectedSetter(node, this._selectedGetter(itemData));                else                    this._selectedSetter(node, false);                return node            },            _createParentFieldForEachItem: function(items, parent) {                var that = this;                parent = parent ? $.extend(true, {}, parent) : null;                $.each(items, function(_, item) {                    that._itemsCount++;                    if (utils.isDefined(parent) && that._itemsGetter(parent))                        that._itemsSetter(parent, null);                    if (that._isPrimitiveValue(item))                        item = that._makeObjectFromPrimitive(item);                    item.parent = parent;                    that._plainNodes[that._keyGetter(item)].parent = parent;                    if (that._itemHasChildren(item))                        that._createParentFieldForEachItem(that._itemsGetter(item), item)                })            },            _makeObjectFromPrimitive: function(item) {                var key = item;                item = {};                this._keySetter(item, key);                return item            },            _isPrimitiveValue: function(value) {                return $.inArray($.type(value), ["object", "array", "function"]) === -1            },            _itemHasChildren: function(item) {                var items = this._itemsGetter(item);                return items && items.length            },            _renderScrollableContainer: function() {                this._scrollableContainer = this._createComponent($("<div />").appendTo(this.element()), "dxScrollable", {                    direction: this.option("scrollDirection"),                    useKeyboard: false                })            },            _renderNodeContainer: function($parent) {                var $container = $("<ul />").addClass(NODE_CONTAINER_CLASS);                this.setAria("role", "group", $container);                if ($parent) {                    var itemData = this._getItemData($parent.find("> ." + ITEM_CLASS));                    if (this._expandedGetter(itemData))                        $container.addClass(OPENED_NODE_CONTAINER_CLASS);                    $container.appendTo($parent)                }                return $container            },            _renderItems: function($nodeContainer, items) {                var that = this,                    showCheckBoxes = that.option("showCheckBoxes");                $.each(items, function(i, item) {                    if (that._isPrimitiveValue(item))                        item = that._makeObjectFromPrimitive(item);                    var key = that._keyGetter(item);                    var $node = $("<li />").addClass(NODE_CLASS).appendTo($nodeContainer).attr(DATA_ITEM_ID, key);                    var sourceItem = that._getSourceItemByKey(key);                    that.setAria({                        role: "treeitem",                        label: that._displayGetter(sourceItem) || "",                        expanded: sourceItem.items && (that._expandedGetter(sourceItem) || "false")                    }, $node);                    if (showCheckBoxes)                        that._renderCheckBox($node, item);                    var $item = that._renderItem.call(that, i, sourceItem, $node);                    that._attachDblclickToItem($item);                    if (that._hasItemsGetter(sourceItem) !== false) {                        if (that._isVirtualMode()) {                            that._renderToggleItemVisibilityIcon($node, item);                            that._renderNodeContainer($node);                            return                        }                        var nestedItems = that._itemsGetter(item);                        if (nestedItems && $.isArray(nestedItems) && nestedItems.length) {                            that._renderToggleItemVisibilityIcon($node, item);                            var $nestedNodeContainer = that._renderNodeContainer($node);                            if (that._expandedGetter(item)) {                                that._renderItems($nestedNodeContainer, nestedItems, false);                                $nestedNodeContainer.addClass(OPENED_NODE_CONTAINER_CLASS)                            }                        }                        else                            that._addLeafClass($node)                    }                    else                        that._addLeafClass($node)                });                this._renderFocusTarget()            },            _addLeafClass: function($node) {                $node.addClass(IS_LEAF)            },            _attachDblclickToItem: function($item) {                var that = this,                    eventName = events.addNamespace(DBLCLICK_EVENT_NAME, that.NAME);                $item.off(eventName).on(eventName, function() {                    var itemData = that._getItemData($item);                    that._toggleExpandedState(itemData)                })            },            _toggleExpandedState: function(itemData, state, e) {                if (this._isVirtualMode()) {                    var $node = this._getNodeElementById(this._getItemKey(itemData));                    this._createLoadIndicator($node)                }                var currentState = this._expandedGetter(itemData);                if (this._disabledGetter(itemData))                    return;                if (utils.isDefined(currentState) && currentState === state)                    return;                if (!utils.isDefined(state))                    state = !currentState;                this._updateExpandedState(itemData, state);                this._updateExpandedItemsUI(itemData, state);                this._fireExpandedStateUpdatedEvt(state, itemData, e)            },            _createLoadIndicator: function($node) {                var $icon = $node.find(">." + TOGGLE_ITEM_VISIBILITY_CLASS),                    $nodeContainer = $node.find(" > ." + NODE_CONTAINER_CLASS);                if (!$icon.hasClass(TOGGLE_ITEM_VISIBILITY_OPENED_CLASS) && $nodeContainer.is(":empty")) {                    this._createComponent("<div>", "dxLoadIndicator", {                        width: 15,                        height: 15                    }).element().appendTo($node);                    $icon.css("display", "none")                }            },            _getSourceItemByKey: function(key) {                return this._plainItems[key]            },            _getItemKey: function(itemData) {                var result = this._keyGetter(itemData);                if (!utils.isDefined(result))                    result = this._getKeyForSourceItem(itemData);                return result            },            _getKeyForSourceItem: function(itemData) {                var result = null;                $.each(this._plainItems, function(key, item) {                    if (itemData === item) {                        result = key;                        return false                    }                });                return result            },            _getNodeByKey: function(key) {                return this._plainNodes[key]            },            _renderSelectAllItem: function($container) {                $container = $container || this.element().find("." + NODE_CONTAINER_CLASS).first();                this._$selectAllItem = $("<div />").addClass(SELECT_ALL_ITEM_CLASS);                this._createComponent(this._$selectAllItem, "dxCheckBox", {                    value: this._calculateSelectAllItemValue(),                    text: this.option("selectAllText"),                    onValueChanged: $.proxy(this._toggleSelectAll, this)                });                $container.before(this._$selectAllItem)            },            _calculateSelectAllItemValue: function() {                this._suppressDeprecatedWarnings();                var result = false,                    selectedItemsCount = this.option("selectedItems").length;                if (selectedItemsCount)                    result = this._itemsCount === selectedItemsCount ? true : undefined;                this._resumeDeprecatedWarnings();                return result            },            _toggleSelectAll: function(args) {                if (!this._suppressUpdateSelectAllItemValue) {                    this._suppressDeprecatedWarnings();                    this._updateAllItems(this._nodes, args.value);                    if (!args.value)                        this.option("selectedItems", []);                    else {                        var selectedItems = this._updateSelectionItemsOption();                        this.option("selectedItems", selectedItems)                    }                    this._resumeDeprecatedWarnings();                    this._fireSelectionChanged()                }            },            _updateAllItems: function(nodes, value) {                var that = this;                $.each(nodes, function(_, node) {                    var $node = that._getNodeElementById(that._keyGetter(node));                    var itemData = that._getSourceItemByKey(that._keyGetter(node)),                        currentState = that._selectedGetter(node);                    if (currentState === value)                        return true;                    if ($node.length)                        $node.find("> .dx-checkbox").dxCheckBox("instance").option("value", value);                    that._commonSelectedSetter(itemData, node, value);                    $node = null;                    if (that._itemHasChildren(node))                        that._updateAllItems(that._itemsGetter(node), value)                })            },            _applySelectedItemsFromOption: function(items) {                var that = this;                this._suppressDeprecatedWarnings();                $.each(this.option("selectedItems"), function(_, item) {                    var currentItem = that._getItemFromArray(item, items);                    if (currentItem) {                        var currentNode = that._getNodeByKey(that._keyGetter(currentItem));                        that._commonSelectedSetter(currentItem, currentNode, true)                    }                    var node = that._getNodeByKey(that._getItemKey(item));                    that._commonSelectedSetter(item, node, true)                });                this._resumeDeprecatedWarnings()            },            _applyExpandedItemsFromOption: function() {                var that = this;                this._suppressDeprecatedWarnings();                $.each(this.option("expandedItems"), function(_, item) {                    var node = that._getNodeByKey(that._getItemKey(item));                    that._commonExpandedSetter(item, node, true)                });                this._resumeDeprecatedWarnings()            },            _commonExpandedSetter: function(item, node, value) {                this._expandedSetter(item, value);                this._expandedSetter(node, value)            },            _commonSelectedSetter: function(item, node, value) {                this._selectedSetter(item, value);                this._selectedSetter(node, value)            },            _calculateChildrenSelectedState: function(items) {                var that = this;                $.each(items, function(_, item) {                    if (that._selectedGetter(item))                        if (that._itemHasChildren(item))                            $.each(that._itemsGetter(item), function(_, child) {                                var sourceItem = that._getSourceItemByKey(that._keyGetter(child));                                that._commonSelectedSetter(sourceItem, child, true)                            });                    if (that._itemHasChildren(item))                        that._itemsSetter(item, that._calculateChildrenSelectedState(that._itemsGetter(item)))                });                return items            },            _makePlainList: function(items, plainList, makeHash) {                var that = this,                    dataStructure = makeHash ? {} : [];                plainList = plainList || dataStructure;                $.each(items, function(_, item) {                    if (makeHash) {                        if (that._isPrimitiveValue(item))                            item = that._makeObjectFromPrimitive(item);                        var index = that._keyGetter(item);                        if (!utils.isDefined(index))                            index = that._startIndex;                        plainList[index] = item;                        that._startIndex++                    }                    else                        plainList.push(item);                    if (that._itemHasChildren(item))                        that._makePlainList(that._itemsGetter(item), plainList, makeHash)                });                return plainList            },            _calculateParentSelectedState: function(list) {                var listSize = list.length - 1,                    that = this;                function isSelected(child) {                    return that._selectedGetter(child) === true                }                function isIntermediate(child) {                    return child.hasOwnProperty(that.option("selectedExpr")) && typeof that._selectedGetter(child) === "undefined"                }                for (var i = listSize; i >= 0; i--) {                    if (this._selectedGetter(list[i]))                        continue;                    var children = this._itemsGetter(list[i]);                    if (children && children.length) {                        var selectedChildren = $.grep(children, isSelected),                            indeterminateChildren = $.grep(children, isIntermediate),                            sourceItem = this._getSourceItemByKey(this._keyGetter(list[i])),                            selected = false;                        if (selectedChildren.length)                            selected = selectedChildren.length === children.length ? true : undefined;                        else if (indeterminateChildren.length)                            selected = undefined;                        that._commonSelectedSetter(list[i], sourceItem, selected)                    }                }                return list            },            _calculateParentExpandedState: function(list) {                var listSize = list.length - 1,                    that = this;                function isExpanded(child) {                    return that._expandedGetter(child) === true                }                for (var i = listSize; i >= 0; i--) {                    if (this._expandedGetter(list[i]))                        continue;                    var children = this._itemsGetter(list[i]);                    if (children && children.length) {                        var expandedChildren = $.grep(children, isExpanded);                        if (expandedChildren.length) {                            var sourceItem = this._getSourceItemByKey(this._keyGetter(list[i]));                            this._commonExpandedSetter(list[i], sourceItem, true)                        }                    }                }            },            _renderCheckBox: function($node, node) {                var checkBoxValue = this._calculateCheckBoxValue(node);                $node.addClass(ITEM_WITH_CHECKBOX_CLASS);                this.setAria("selected", checkBoxValue, $node);                var $checkbox = $("<div />").appendTo($node);                this._createComponent($checkbox, "dxCheckBox", {                    value: checkBoxValue,                    onValueChanged: $.proxy(this._changeCheckboxValue, this),                    focusStateEnabled: false,                    disabled: this._disabledGetter(node)                });                this._attachCheckboxClick($checkbox, node)            },            _attachCheckboxClick: function($checkbox, node) {                var eventName = events.addNamespace("dxclick", this.NAME),                    key = this._keyGetter(node);                var handleItemSelected = function(e) {                        this._itemJQueryEventHandler(e, "onItemSelected", {node: this._getNodeByKey(key)})                    };                $checkbox.off(eventName).on(eventName, $.proxy(handleItemSelected, this))            },            _renderToggleItemVisibilityIcon: function($node, itemData) {                var $icon = $("<div />").addClass(TOGGLE_ITEM_VISIBILITY_CLASS).appendTo($node);                if (this._expandedGetter(itemData) && !this._isVirtualMode()) {                    $icon.addClass(TOGGLE_ITEM_VISIBILITY_OPENED_CLASS);                    $node.parent().addClass(OPENED_NODE_CONTAINER_CLASS)                }                if (this._disabledGetter(itemData))                    $icon.addClass(DISABLED_STATE_CLASS);                this._renderToggleItemVisibilityIconClick($icon, itemData)            },            _renderToggleItemVisibilityIconClick: function($icon, itemData) {                var eventName = events.addNamespace("dxclick", this.NAME),                    that = this;                $icon.off(eventName).on(eventName, function(e) {                    var $item = $icon.parent().find(">." + ITEM_CLASS),                        itemData = that._getItemData($item);                    that._toggleExpandedState(itemData, undefined, e)                })            },            _updateExpandedState: function(itemData, isExpanded) {                this._suppressDeprecatedWarnings();                var expandedItems = this.option("expandedItems"),                    key = this._getItemKey(itemData),                    node = this._getNodeByKey(key),                    that = this;                that._commonExpandedSetter(itemData, node, isExpanded);                if (isExpanded) {                    if (!that._getItemFromArray(itemData, expandedItems))                        expandedItems.push(itemData)                }                else                    $.each(expandedItems, function(i, item) {                        if (that._keyGetter(item) === key) {                            expandedItems.splice(i, 1);                            return false                        }                    });                this._resumeDeprecatedWarnings()            },            _updateExpandedItemsUI: function(itemData, state) {                var $node = this._getNodeElementById(this._getItemKey(itemData)),                    $icon = $node.find(">." + TOGGLE_ITEM_VISIBILITY_CLASS),                    $nodeContainer = $node.find(" > ." + NODE_CONTAINER_CLASS);                $icon.toggleClass(TOGGLE_ITEM_VISIBILITY_OPENED_CLASS, state);                this.setAria("expanded", state, $node);                this._renderNestedItems($nodeContainer);                this._animateNodeContainer($nodeContainer, state)            },            _animateNodeContainer: function($nodeContainer, state) {                var nodeHeight = $nodeContainer.height();                DX.fx.stop($nodeContainer, true);                DX.fx.animate($nodeContainer, {                    type: "custom",                    duration: this.option("animationEnabled") ? 400 : 0,                    from: {"max-height": state ? 0 : nodeHeight},                    to: {"max-height": state ? nodeHeight : 0},                    start: function() {                        $nodeContainer.addClass(OPENED_NODE_CONTAINER_CLASS)                    },                    complete: $.proxy(function() {                        $nodeContainer.css("max-height", "none");                        $nodeContainer.toggleClass(OPENED_NODE_CONTAINER_CLASS, state);                        this._scrollableContainer.update()                    }, this)                })            },            _fireExpandedStateUpdatedEvt: function(isExpanded, itemData, e) {                var optionName = isExpanded ? "onItemExpanded" : "onItemCollapsed",                    itemKey = this._getItemKey(itemData),                    node = this._getNodeByKey(itemKey);                var handler = this.option(optionName);                if (handler)                    handler.call(this, {                        itemData: itemData,                        node: node,                        itemElement: this._getNodeElementById(this._keyGetter(itemData)).find(">." + ITEM_CLASS),                        jQueryEvent: e                    })            },            _getParentById: function(nodes, id) {                var parent;                $.each(nodes, function(_, node) {                    if (node.id === id)                        parent = node;                    return                });                return parent            },            _renderNestedItems: function($container) {                if (!$container.is(":empty"))                    return;                var itemElement = $container.parent().find(">." + ITEM_CLASS),                    itemData = this._getItemData(itemElement),                    itemKey = this._getItemKey(itemData),                    node = this._getNodeByKey(itemKey);                if (this._isVirtualMode())                    this._renderVirtualNodes($container);                else                    this._renderItems($container, this._itemsGetter(node), false)            },            _renderVirtualNodes: function($container) {                var itemElement = $container.parent().find(">." + ITEM_CLASS),                    itemData = this._getItemData(itemElement),                    itemKey = this._getItemKey(itemData),                    that = this;                this._dataSource.filter([this.option("parentIdExpr"), itemKey]);                this._dataSource.load().done(function(data) {                    var virtualItems = [];                    $.each(data, function(_, item) {                        virtualItems.push(that._createNode(item))                    });                    that._renderItems($container, virtualItems, false);                    if (virtualItems.length && !that._selectedGetter(itemData)) {                        var firstItemKey = that._keyGetter(virtualItems[0]),                            $firstChild = that._getNodeElementById(firstItemKey);                        that._updateParentsState(that._getNodeByKey(firstItemKey), $firstChild)                    }                    that._normalizeIconState(itemElement, virtualItems.length)                })            },            _normalizeIconState: function(itemElement, hasNewItems) {                var $loadIndicator = itemElement.siblings(".dx-loadindicator"),                    $icon = itemElement.siblings("." + TOGGLE_ITEM_VISIBILITY_CLASS);                $loadIndicator.dxLoadIndicator("instance").option("visible", false);                if (!hasNewItems) {                    itemElement.siblings("." + TOGGLE_ITEM_VISIBILITY_CLASS).removeClass(TOGGLE_ITEM_VISIBILITY_CLASS);                    itemElement.parent().addClass(IS_LEAF)                }                else                    $icon.css("display", "block")            },            _dataSourceChangedHandler: function(newItems) {                if (this._initialized && this._isVirtualMode()) {                    this.option().items = this.option("items").concat(newItems);                    this._updateNodesFields(newItems)                }                else                    this.option("items", newItems)            },            _updateNodes: function() {                this._makeNodes();                this._makePlainStructures()            },            _calculateCheckBoxValue: function(itemData) {                var result;                if (this._isVirtualMode())                    result = !!itemData.selected;                else                    result = itemData.hasOwnProperty(this.option("selectedExpr")) ? this._selectedGetter(itemData) : false;                return result            },            _changeCheckboxValue: function(e) {                if (this._isVirtualMode())                    this._updateNodesFields();                var $node = e.element.parent("." + NODE_CLASS),                    itemData = this._getItemData($node.find("> ." + ITEM_CLASS)),                    value = e.value,                    key = this._getItemKey(itemData),                    node = this._getNodeByKey(key);                this._commonSelectedSetter(itemData, node, value);                this.setAria("selected", value, $node);                if (e.jQueryEvent && !this.option("selectNodesRecursive"))                    this._fireSelectionChanged();                if (!e.jQueryEvent || !this.option("selectNodesRecursive"))                    return;                this._updateParentsAndChildren(node, value, false, $node)            },            _updateNodesFields: function(newItems) {                if (this._isVirtualMode()) {                    var parentId = this._dataSource.filter() && this._dataSource.filter()[1];                    if (parentId && parentId !== this.option("rootValue")) {                        var parentNode = this._getNodeByKey(parentId),                            selectNodesRecursive = this.option("selectNodesRecursive");                        if (newItems && newItems.length)                            this._itemsSetter(parentNode, newItems);                        this._updateNodes();                        if (newItems && this._selectedGetter(parentNode)) {                            if (selectNodesRecursive)                                $.each(newItems, $.proxy(function(_, item) {                                    this._selectedSetter(item, true)                                }, this))                        }                        else {                            if (selectNodesRecursive)                                this._calculateParentSelectedState(this._makePlainList(this._nodes, null));                            this._createParentFieldForEachItem(this._nodes)                        }                    }                }            },            _updateParentsAndChildren: function(node, childValue, suppressOnSelectionChanged, $node) {                if (node.parent && node.parent !== null)                    this._updateParentsState(node, $node);                if (node.items && node.items.length)                    this._updateChildrenState(this._itemsGetter(node), childValue, $node);                this._suppressDeprecatedWarnings();                var selectedItems = this._updateSelectionItemsOption();                this.option("selectedItems", selectedItems);                this._resumeDeprecatedWarnings();                if (!suppressOnSelectionChanged)                    this._fireSelectionChanged()            },            _getItemFromArray: function(itemData, data) {                var result = null,                    that = this,                    key = that._keyGetter(itemData);                $.each(data, function(_, item) {                    if (key === that._keyGetter(item)) {                        result = item;                        return false                    }                });                return result            },            _calculateSelectedItemsOption: function(value, itemData) {                var key = this._getItemKey(itemData),                    node = this._getNodeByKey(key);                this._commonSelectedSetter(itemData, node, value)            },            _reduceSelectedItemsOption: function(selectedItems, itemData) {                var that = this,                    itemDataKey = that._keyGetter(itemData);                $.each(selectedItems, function(index, item) {                    if (itemDataKey === that._keyGetter(item))                        return false                })            },            _updateParentsState: function(node, $node) {                var parentNode = this._getNodeByKey(this._keyGetter(node.parent)),                    $parentNode,                    that = this;                $.each(this._itemsGetter(parentNode), function(_, item) {                    if (that._keyGetter(node) === that._keyGetter(item))                        that._selectedSetter(item, that._selectedGetter(node))                });                var nodesCount = this._itemsGetter(parentNode).length,                    selectedNodesCount = this._getSelectedChildrenFromNode(parentNode),                    intermediateNodesCount = this._getIntermediateChildrenFromNode(parentNode),                    parentValue;                if (selectedNodesCount === nodesCount)                    parentValue = true;                else if (!selectedNodesCount && !intermediateNodesCount)                    parentValue = false;                if ($node && this.option("showCheckBoxes")) {                    $parentNode = $($node.parents("." + NODE_CLASS)[0]);                    $parentNode.find("> .dx-checkbox").dxCheckBox("instance").option("value", parentValue)                }                this._updateParentField(node, parentValue);                this._selectedSetter(parentNode, parentValue);                if (parentNode.parent)                    this._updateParentsState(parentNode, $parentNode);                this._calculateSelectedItemsOption(parentValue, this._getSourceItemByKey(this._keyGetter(node.parent)))            },            _getSelectedChildrenFromNode: function(node) {                var items = this._itemsGetter(node),                    that = this;                if (items && items.length)                    return $.grep(items, function(item) {                            return that._selectedGetter(item) === true                        }).length;                return 0            },            _getIntermediateChildrenFromNode: function(node) {                var items = this._itemsGetter(node),                    that = this;                if (items && items.length)                    return $.grep(items, function(item) {                            return item.hasOwnProperty(that.option("selectedExpr")) && that._selectedGetter(item) === undefined                        }).length;                return 0            },            _updateChildrenState: function(childNodes, value, $node) {                var that = this;                $.each(childNodes, function(_, childNode) {                    var itemData = that._getSourceItemByKey(that._keyGetter(childNode));                    that._updateParentField(childNode, value);                    that._calculateSelectedItemsOption(value, itemData);                    if (that._itemHasChildren(childNode))                        that._updateChildrenState(that._itemsGetter(childNode), value)                });                if ($node) {                    var $childrenContainer = $node.find("> ." + NODE_CONTAINER_CLASS);                    $childrenContainer.find(".dx-checkbox").each(function(_, checkbox) {                        $(checkbox).dxCheckBox("instance").option("value", value)                    })                }            },            _updateParentField: function(node, value) {                if (node.parent)                    this._selectedSetter(node.parent, value)            },            _itemEventHandlerImpl: function(initiator, action, actionArgs) {                var $itemElement = $(initiator).closest("." + NODE_CLASS).find("> ." + ITEM_CLASS);                actionArgs = $.extend({                    itemElement: $itemElement,                    itemData: this._getItemData($itemElement)                }, actionArgs);                return action(actionArgs)            },            _itemClass: function() {                return ITEM_CLASS            },            _itemDataKey: function() {                return ITEM_DATA_KEY            },            _selectionEnabled: function() {                return true            },            _attachClickEvent: function() {                var that = this,                    itemSelector = that._itemSelector(),                    eventName = events.addNamespace("dxclick", that.NAME),                    pointerDownEvent = events.addNamespace("dxpointerdown", this.NAME);                that._itemContainer().off(eventName, itemSelector).on(eventName, itemSelector, function(e) {                    that._itemClickHandler(e, $(this))                }).off(pointerDownEvent, itemSelector).on(pointerDownEvent, itemSelector, $.proxy(this._itemPointerDownHandler, this))            },            _itemClickHandler: function(e, $item) {                var itemData = this._getItemData($item),                    node = this._getNodeByKey(this._getItemKey(itemData));                this._itemJQueryEventHandler(e, "onItemClick", {node: node})            },            _updateItemSelection: function(value, itemElement, suppressOnSelectionChanged, $node) {                var itemData = itemElement.nodeType ? this._getItemData(itemElement) : itemElement,                    key = this._getItemKey(itemData),                    node = this._getNodeByKey(key);                if (this._disabledGetter(itemData))                    return;                var currentState = this._selectedGetter(node);                if (currentState === value)                    return;                if (!$node) {                    var $tmpNode = this._getNodeElementById(key);                    if ($tmpNode.length)                        $node = $tmpNode                }                if ($node)                    $node.find("> .dx-checkbox").dxCheckBox("instance").option("value", value);                this._commonSelectedSetter(itemData, node, value);                this._calculateSelectedItemsOption(value, node);                if (this.option("selectNodesRecursive"))                    this._updateParentsAndChildren(node, value, suppressOnSelectionChanged, $node);                else {                    this._suppressDeprecatedWarnings();                    var selectedItems = this._updateSelectionItemsOption();                    this.option("selectedItems", selectedItems);                    this._resumeDeprecatedWarnings()                }                var handler = this.option("onItemSelected");                if (handler)                    handler.call(this, {                        itemData: itemData,                        node: node                    })            },            _updateSelectionToFirstItem: function($items, startIndex) {                var itemIndex = startIndex;                while (itemIndex >= 0) {                    var $item = $($items[itemIndex]);                    this._updateItemSelection(true, $item.find("." + ITEM_CLASS).get(0), true, $item);                    itemIndex--                }            },            _updateSelectionToLastItem: function($items, startIndex) {                var itemIndex = startIndex,                    length = $items.length;                while (itemIndex < length) {                    var $item = $($items[itemIndex]);                    this._updateItemSelection(true, $item.find("." + ITEM_CLASS).get(0), true, $item);                    itemIndex++                }            },            _enlargeExpandedItemsOption: function(itemData, expandedItems) {                if (!this._getItemFromArray(itemData, expandedItems)) {                    expandedItems.push(itemData);                    this._expandedSetter(itemData, true)                }                if (itemData.parent)                    this._enlargeExpandedItemsOption(itemData.parent, expandedItems);                return expandedItems            },            _reduceExpandedItemsOption: function(node, expandedItems) {                var that = this,                    nodeKey = that._keyGetter(node);                var sourceItem = that._getSourceItemByKey(nodeKey);                that._commonExpandedSetter(sourceItem, node, false);                $.each(expandedItems, function(i, item) {                    if (that._keyGetter(item) === nodeKey) {                        expandedItems.splice(i, 1);                        if (that._itemHasChildren(node))                            $.each(that._itemsGetter(node), function(_, child) {                                var sourceItemChild = that._getSourceItemByKey(that._keyGetter(child));                                that._commonExpandedSetter(sourceItemChild, child, false);                                that._reduceExpandedItemsOption(child, expandedItems)                            })                    }                });                return expandedItems            },            _focusInHandler: function(e) {                var currentTarget = e.currentTarget,                    focusTargets = this._focusTarget();                if ($.inArray(currentTarget, focusTargets) !== -1)                    $(currentTarget).addClass(FOCUSED_STATE_CLASS);                if (!this.option("focusedElement")) {                    var $activeItem = this._getActiveItem();                    this.option("focusedElement", $activeItem.closest("." + NODE_CLASS))                }                else                    this._setFocusedItem(this.option("focusedElement"))            },            _setFocusedItem: function($target) {                if (!$target || !$target.length)                    return;                if (!$target.children().hasClass(DISABLED_STATE_CLASS))                    this.callBase($target)            },            _itemPointerDownHandler: function(e) {                if (!this.option("focusStateEnabled"))                    return;                var $target = $(e.target).closest("." + NODE_CLASS);                if ($target.hasClass(NODE_CLASS))                    if ($target.hasClass(DISABLED_STATE_CLASS))                        this.option("focusedElement", null);                    else                        this.option("focusedElement", $target)            },            _moveFocus: function(location, e) {                var FOCUS_UP = "up",                    FOCUS_DOWN = "down",                    FOCUS_FIRST = "first",                    FOCUS_LAST = "last",                    FOCUS_LEFT = this.option("rtlEnabled") ? "right" : "left",                    FOCUS_RIGHT = this.option("rtlEnabled") ? "left" : "right";                this.element().find("." + NODE_CONTAINER_CLASS).each(function() {                    DX.fx.stop(this, true)                });                var $items = this._nodeElements().not(function() {                        return $(this).find(">." + ITEM_CLASS).hasClass(DISABLED_STATE_CLASS)                    });                switch (location) {                    case FOCUS_UP:                        var $prevItem = this._prevItem($items);                        this.option("focusedElement", $prevItem);                        if (e.shiftKey && this.option("showCheckBoxes"))                            this._updateItemSelection(true, $prevItem.find("." + ITEM_CLASS).get(0), true, $prevItem);                        break;                    case FOCUS_DOWN:                        var $nextItem = this._nextItem($items);                        this.option("focusedElement", $nextItem);                        if (e.shiftKey && this.option("showCheckBoxes"))                            this._updateItemSelection(true, $nextItem.find("." + ITEM_CLASS).get(0), true, $nextItem);                        break;                    case FOCUS_FIRST:                        var $firstItem = $items.first();                        if (e.shiftKey && this.option("showCheckBoxes"))                            this._updateSelectionToFirstItem($items, $items.index(this._prevItem($items)));                        this.option("focusedElement", $firstItem);                        break;                    case FOCUS_LAST:                        var $lastItem = $items.last();                        if (e.shiftKey && this.option("showCheckBoxes"))                            this._updateSelectionToLastItem($items, $items.index(this._nextItem($items)));                        this.option("focusedElement", $lastItem);                        break;                    case FOCUS_RIGHT:                        this._expandFocusedContainer();                        break;                    case FOCUS_LEFT:                        this._collapseFocusedContainer();                        break;                    default:                        this.callBase.apply(this, arguments);                        return                }            },            _nodeElements: function() {                return this.element().find("." + NODE_CLASS).not(":hidden")            },            _expandFocusedContainer: function() {                var $focusedItem = this.option("focusedElement");                if (!$focusedItem || $focusedItem.hasClass(IS_LEAF))                    return;                var $node = $focusedItem.find("." + NODE_CONTAINER_CLASS).eq(0);                if ($node.hasClass(OPENED_NODE_CONTAINER_CLASS)) {                    this.option("focusedElement", this._nextItem(this._nodeElements()));                    return                }                var itemData = this._getItemData($focusedItem.find(">." + ITEM_CLASS));                this._toggleExpandedState(itemData, true)            },            _collapseFocusedContainer: function() {                var $focusedItem = this.option("focusedElement");                if (!$focusedItem)                    return;                var nodeElement = $focusedItem.find("." + NODE_CONTAINER_CLASS).eq(0);                if (!$focusedItem.hasClass(IS_LEAF) && nodeElement.hasClass(OPENED_NODE_CONTAINER_CLASS)) {                    var itemData = this._getItemData($focusedItem.find(">." + ITEM_CLASS));                    this._toggleExpandedState(itemData, false)                }                else {                    var parentElement = $focusedItem.parent("." + NODE_CONTAINER_CLASS);                    var collapsedNode = parentElement.parent("." + NODE_CLASS).eq(0);                    if (collapsedNode.length)                        this.option("focusedElement", collapsedNode)                }            },            updateDimensions: function() {                var that = this,                    deferred = $.Deferred();                if (that._scrollableContainer)                    that._scrollableContainer.update().done(function() {                        deferred.resolveWith(that)                    });                else                    deferred.resolveWith(that);                return deferred.promise()            },            selectItem: function(itemElement) {                this._updateItemSelection(true, itemElement)            },            unselectItem: function(itemElement) {                this._updateItemSelection(false, itemElement)            },            expandItem: function(itemElement) {                var itemData = this._getItemData($(itemElement));                this._toggleExpandedState(itemData, true)            },            collapseItem: function(itemElement) {                var itemData = this._getItemData($(itemElement));                this._toggleExpandedState(itemData, false)            },            getNodes: function() {                return this._nodes            },            selectAll: function() {                this._toggleSelectAll({value: true})            },            unselectAll: function() {                this._toggleSelectAll({value: false})            }        }));        ui.dxTreeView.__internals = {            WIDGET_CLASS: WIDGET_CLASS,            NODE_CONTAINER_CLASS: NODE_CONTAINER_CLASS,            OPENED_NODE_CONTAINER_CLASS: OPENED_NODE_CONTAINER_CLASS,            ITEM_CLASS: ITEM_CLASS,            NODE_CLASS: NODE_CLASS,            ITEM_WITH_CHECKBOX_CLASS: ITEM_WITH_CHECKBOX_CLASS,            ITEM_DATA_KEY: ITEM_DATA_KEY,            IS_LEAF: IS_LEAF,            TOGGLE_ITEM_VISIBILITY_CLASS: TOGGLE_ITEM_VISIBILITY_CLASS,            TOGGLE_ITEM_VISIBILITY_OPENED_CLASS: TOGGLE_ITEM_VISIBILITY_OPENED_CLASS,            SELECT_ALL_ITEM_CLASS: SELECT_ALL_ITEM_CLASS,            scrollableContainerUpdatedOnInitAccessor: function(value) {                if (value)                    scrollableContainerUpdatedOnInit = value;                return scrollableContainerUpdatedOnInit            }        }    })(jQuery, DevExpress);    /*! Module widgets-web, file ui.sortable.js */    (function($, DX) {        var ui = DX.ui,            addNamespace = ui.events.addNamespace;        var SORTABLE_NAMESPACE = "dxSortable",            SORTABLE_CLASS = "dx-sortable";        var elementHasPoint = function(element, x, y) {                var $item = $(element),                    offset = $item.offset();                if (x >= offset.left && x <= offset.left + $item.outerWidth(true))                    if (y >= offset.top && y <= offset.top + $item.outerHeight(true))                        return true            };        DX.registerComponent("dxSortable", ui, DX.DOMComponent.inherit({            _setDefaultOptions: function() {                this.callBase();                this.option({                    onChanged: null,                    onDragging: null,                    itemRender: null,                    groupSelector: null,                    itemSelector: ".dx-sort-item",                    itemContainerSelector: ".dx-sortable",                    sourceClass: "dx-drag-source",                    dragClass: "dx-drag",                    targetClass: "dx-drag-target"                })            },            _renderItem: function($sourceItem, target) {                var itemRender = this.option("itemRender"),                    $item;                if (itemRender)                    $item = itemRender($sourceItem, target);                else {                    $item = $sourceItem.clone();                    $item.css({                        width: $sourceItem.width(),                        height: $sourceItem.height()                    })                }                return $item            },            _attachEventHandlers: function() {                var that = this,                    itemSelector = that.option("itemSelector"),                    itemContainerSelector = that.option("itemContainerSelector"),                    groupSelector = that.option("groupSelector"),                    sourceClass = that.option("sourceClass"),                    dragClass = that.option("dragClass"),                    targetClass = that.option("targetClass"),                    $sourceItem,                    sourceIndex,                    $targetItem,                    $targetGroup,                    startPosition,                    $draggable,                    element = that.element();                element.off(addNamespace("dxdragstart dxdrag dxdragend dxdragenter dxdragleave dxdrop", SORTABLE_NAMESPACE));                element.on(addNamespace("dxdragstart", SORTABLE_NAMESPACE), itemSelector, function(e) {                    $sourceItem = $(e.currentTarget);                    startPosition = $sourceItem.offset();                    startPosition.top -= element.offset().top;                    startPosition.left -= element.offset().left;                    $draggable = that._renderItem($sourceItem, 'drag').appendTo(element);                    $targetItem = that._renderItem($sourceItem, 'target');                    $draggable.addClass(dragClass);                    $sourceItem.addClass(sourceClass);                    sourceIndex = $sourceItem.index();                    $targetItem.addClass(targetClass)                });                element.on(addNamespace("dxdrag", SORTABLE_NAMESPACE), function(e) {                    if (!$sourceItem)                        return;                    var onDragging = that.option("onDragging"),                        draggingArgs,                        $item,                        $itemContainer,                        $items,                        $groups = groupSelector ? element.find(groupSelector) : element;                    $targetGroup && $targetGroup.removeClass(targetClass);                    $targetGroup = undefined;                    $.each($groups, function() {                        if (elementHasPoint(this, e.pageX, e.pageY)) {                            $targetGroup = $(this);                            return false                        }                    });                    if ($targetGroup) {                        $itemContainer = $targetGroup.find(itemContainerSelector);                        $items = $itemContainer.find(itemSelector);                        $.each($items, function() {                            if (elementHasPoint(this, e.pageX, e.pageY)) {                                $item = $(this);                                return false                            }                        })                    }                    if ($targetGroup && $sourceItem) {                        draggingArgs = {                            sourceGroup: $sourceItem.closest(groupSelector).attr("group"),                            sourceIndex: sourceIndex,                            sourceElement: $sourceItem,                            targetGroup: $targetGroup.attr("group"),                            targetIndex: $targetItem.index()                        };                        onDragging && onDragging(draggingArgs)                    }                    if (draggingArgs && draggingArgs.cancel) {                        $targetGroup = undefined;                        $item = undefined                    }                    $targetGroup && $targetGroup.addClass(targetClass);                    if ($item) {                        if (!$item.hasClass(targetClass)) {                            $targetItem.detach();                            if (!$item.hasClass(sourceClass) && !$item.prev().hasClass(sourceClass))                                $targetItem.insertBefore($item)                        }                    }                    else {                        $targetItem.detach();                        if ($targetGroup && !$items.last().hasClass(sourceClass))                            $targetItem.appendTo($itemContainer)                    }                    $draggable.css({                        top: startPosition.top + e.offset.y,                        left: startPosition.left + e.offset.x                    })                });                element.on(addNamespace("dxdragend", SORTABLE_NAMESPACE), function() {                    var onChanged = that.option("onChanged"),                        changedArgs,                        sourceGroup;                    if ($sourceItem) {                        if ($targetGroup) {                            $targetGroup.removeClass(targetClass);                            sourceGroup = $sourceItem.closest(groupSelector).attr("group");                            changedArgs = {                                sourceGroup: sourceGroup,                                sourceIndex: sourceIndex,                                sourceElement: $sourceItem,                                targetGroup: $targetGroup.attr("group"),                                targetIndex: $targetItem.index(),                                removeSourceElement: true                            };                            if (sourceGroup !== changedArgs.targetGroup || $targetItem.parent().length) {                                onChanged && onChanged(changedArgs);                                if (changedArgs.removeSourceElement)                                    $sourceItem.remove()                            }                        }                        $sourceItem.removeClass(sourceClass);                        $draggable.remove();                        $sourceItem = null;                        $targetItem.removeClass(targetClass);                        $targetItem = null                    }                })            },            _init: function() {                this.callBase();                this._attachEventHandlers()            },            _render: function() {                this.callBase();                this.element().addClass(SORTABLE_CLASS)            },            _optionChanged: function(args) {                var that = this;                switch (args.name) {                    case"onDragging":                    case"onChanged":                    case"itemRender":                    case"groupSelector":                    case"itemSelector":                    case"itemContainerSelector":                    case"sourceClass":                    case"targetClass":                    case"dragClass":                        that._attachEventHandlers();                        break;                    default:                        that.callBase(args)                }            }        }))    })(jQuery, DevExpress);    /*! Module widgets-web, file ui.dataGrid.js */    (function($, DX) {        var ui = DX.ui,            utils = DX.utils;        var DATAGRID_ROW_SELECTOR = ".dx-row",            DATAGRID_DEPRECATED_TEMPLATE_WARNING = "Specifying grid templates with the name of a jQuery selector is now deprecated. Instead, use the jQuery object that references this selector.";        var ModuleItem = DX.Class.inherit({                ctor: function(component) {                    var that = this;                    that.component = component;                    that._actions = {};                    that._actionConfigs = {};                    $.each(this.callbackNames() || [], function(index, name) {                        var flags = that.callbackFlags(name);                        that[this] = $.Callbacks(flags)                    })                },                callbackNames: function(){},                callbackFlags: function(name){},                publicMethods: function(){},                init: function(){},                option: function() {                    return this.component.option.apply(this.component, arguments)                },                on: function() {                    return this.component.on.apply(this.component, arguments)                },                off: function() {                    return this.component.off.apply(this.component, arguments)                },                optionChanged: function(args) {                    if (args.name in this._actions) {                        this.createAction(args.name, this._actionConfigs[args.name]);                        args.handled = true                    }                },                getAction: function(actionName) {                    return this._actions[actionName]                },                setAria: function() {                    return this.component.setAria.apply(this.component, arguments)                },                _createComponent: function() {                    return this.component._createComponent.apply(this.component, arguments)                },                getController: function(name) {                    return this.component._controllers[name]                },                createAction: function(actionName, config) {                    var action;                    if (utils.isFunction(actionName)) {                        action = this.component._createAction($.proxy(actionName, this), config);                        return function(e) {                                action({jQueryEvent: e})                            }                    }                    else {                        this._actions[actionName] = this.component._createActionByOption(actionName, config);                        this._actionConfigs[actionName] = config                    }                },                executeAction: function(actionName, options) {                    var action = this._actions[actionName];                    return action && action(options)                },                dispose: function() {                    var that = this;                    $.each(that.callbackNames() || [], function() {                        that[this].empty()                    })                }            });        var Controller = ModuleItem;        var ViewController = Controller.inherit({                getView: function(name) {                    return this.component._views[name]                },                getViews: function() {                    return this.component._views                }            });        var View = ModuleItem.inherit({                element: function() {                    return this._$element                },                _renderCore: function(options){},                _resizeCore: function(){},                _afterRender: function($root){},                _parentElement: function() {                    return this._$parent                },                ctor: function(component) {                    this.callBase(component);                    this.renderCompleted = $.Callbacks();                    this.resizeCompleted = $.Callbacks()                },                isVisible: function() {                    return true                },                getTemplate: function(name) {                    return this.component._getTemplate(name)                },                render: function($parent, options) {                    var $element = this._$element,                        isVisible = this.isVisible();                    if (!$element) {                        $element = this._$element = $('<div />').appendTo($parent);                        this._$parent = $parent                    }                    $element.toggle(isVisible);                    if (isVisible) {                        this._renderCore(options);                        this._afterRender($parent);                        this.renderCompleted.fire()                    }                },                resize: function() {                    this.isResizing = true;                    this._resizeCore();                    this.resizeCompleted.fire();                    this.isResizing = false                },                focus: function() {                    this.element().focus()                }            });        var processModules = function(that, modules) {                var controllerTypes = {},                    viewTypes = {};                $.each(modules, function() {                    var controllers = this.controllers,                        moduleName = this.name,                        views = this.views;                    controllers && $.each(controllers, function(name, type) {                        if (controllerTypes[name])                            throw DX.Error("E1001", moduleName, name);                        else if (!(type && type.subclassOf && type.subclassOf(Controller))) {                            type.subclassOf(Controller);                            throw DX.Error("E1002", moduleName, name);                        }                        controllerTypes[name] = type                    });                    views && $.each(views, function(name, type) {                        if (viewTypes[name])                            throw DX.Error("E1003", moduleName, name);                        else if (!(type && type.subclassOf && type.subclassOf(View)))                            throw DX.Error("E1004", moduleName, name);                        viewTypes[name] = type                    })                });                $.each(modules, function() {                    var extenders = this.extenders;                    if (extenders) {                        extenders.controllers && $.each(extenders.controllers, function(name, extender) {                            if (controllerTypes[name])                                controllerTypes[name] = controllerTypes[name].inherit(extender)                        });                        extenders.views && $.each(extenders.views, function(name, extender) {                            if (viewTypes[name])                                viewTypes[name] = viewTypes[name].inherit(extender)                        })                    }                });                var registerPublicMethods = function(that, name, moduleItem) {                        var publicMethods = moduleItem.publicMethods();                        if (publicMethods)                            $.each(publicMethods, function(index, methodName) {                                if (moduleItem[methodName])                                    if (!that[methodName])                                        that[methodName] = function() {                                            return moduleItem[methodName].apply(moduleItem, arguments)                                        };                                    else                                        throw DX.Error("E1005", methodName);                                else                                    throw DX.Error("E1006", name, methodName);                            })                    };                var createModuleItems = function(moduleTypes) {                        var moduleItems = {};                        $.each(moduleTypes, function(name, moduleType) {                            var moduleItem = new moduleType(that);                            moduleItem.name = name;                            registerPublicMethods(that, name, moduleItem);                            moduleItems[name] = moduleItem                        });                        return moduleItems                    };                that._controllers = createModuleItems(controllerTypes);                that._views = createModuleItems(viewTypes)            };        var callModuleItemsMethod = function(that, methodName, args) {                args = args || [];                if (that._controllers)                    $.each(that._controllers, function() {                        this[methodName] && this[methodName].apply(this, args)                    });                if (that._views)                    $.each(that._views, function() {                        this[methodName] && this[methodName].apply(this, args)                    })            };        DX.registerComponent("dxDataGrid", ui, ui.Widget.inherit({            _activeStateUnit: DATAGRID_ROW_SELECTOR,            _setDeprecatedOptions: function() {                this.callBase();                $.extend(this._deprecatedOptions, {                    rowClick: {                        since: "14.2",                        alias: "onRowClick"                    },                    cellClick: {                        since: "14.2",                        alias: "onCellClick"                    },                    cellHoverChanged: {                        since: "14.2",                        alias: "onCellHoverChanged"                    },                    cellPrepared: {                        since: "14.2",                        message: "The cellPrepared option is deprecated. Use the onCellPrepared option instead. For further information, see http://js.devexpress.com/Documentation/ApiReference/UI_Widgets/dxDataGrid/Configuration/?version=14_2#onCellPrepared"                    },                    rowPrepared: {                        since: "14.2",                        message: "The rowPrepared option is deprecated. Use the onRowPrepared option instead. For further information, see http://js.devexpress.com/Documentation/ApiReference/UI_Widgets/dxDataGrid/Configuration/?version=14_2#onRowPrepared"                    },                    selectionChanged: {                        since: "14.2",                        alias: "onSelectionChanged"                    },                    dataErrorOccurred: {                        since: "14.2",                        alias: "onDataErrorOccurred"                    },                    initNewRow: {                        since: "14.2",                        alias: "onInitNewRow"                    },                    rowInserting: {                        since: "14.2",                        alias: "onRowInserting"                    },                    rowInserted: {                        since: "14.2",                        alias: "onRowInserted"                    },                    editingStart: {                        since: "14.2",                        alias: "onEditingStart"                    },                    rowUpdating: {                        since: "14.2",                        alias: "onRowUpdating"                    },                    rowUpdated: {                        since: "14.2",                        alias: "onRowUpdated"                    },                    rowRemoving: {                        since: "14.2",                        alias: "onRowRemoving"                    },                    rowRemoved: {                        since: "14.2",                        alias: "onRowRemoved"                    },                    editorPreparing: {                        since: "14.2",                        message: "The editorPreparing option is deprecated. Use the onEditorPreparing option instead. For further information, see http://js.devexpress.com/Documentation/ApiReference/UI_Widgets/dxDataGrid/Configuration/?version=14_2#onEditorPreparing"                    },                    editorPrepared: {                        since: "14.2",                        message: "The editorPrepared option is deprecated. Use the onEditorPrepared option instead. For further information, see http://js.devexpress.com/Documentation/ApiReference/UI_Widgets/dxDataGrid/Configuration/?version=14_2#onEditorPrepared"                    },                    contentReadyAction: {                        since: "14.2",                        alias: "onContentReady"                    }                })            },            _setDefaultOptions: function() {                var that = this;                that.callBase();                $.each(ui.dxDataGrid.modules, function() {                    if ($.isFunction(this.defaultOptions))                        that.option(this.defaultOptions())                })            },            _defaultOptionsRules: function() {                return this.callBase().concat([{                            device: {platform: "ios"},                            options: {showRowLines: true}                        }, {                            device: function() {                                return DevExpress.browser.webkit                            },                            options: {loadPanel: {animation: {show: {                                            easing: 'cubic-bezier(1, 0, 1, 0)',                                            duration: 500,                                            from: {opacity: 0},                                            to: {opacity: 1}                                        }}}}                        }])            },            _init: function() {                var that = this;                that.callBase();                processModules(that, ui.dxDataGrid.modules);                callModuleItemsMethod(that, 'init')            },            _clean: $.noop,            _optionChanged: function(args) {                var that = this;                callModuleItemsMethod(that, 'optionChanged', [args]);                if (!args.handled)                    that.callBase(args)            },            _dimensionChanged: function() {                this.updateDimensions()            },            _visibilityChanged: function(visible) {                if (visible)                    this.updateDimensions()            },            _renderContentImpl: function() {                var that = this;                that.getView('gridView').render(that.element())            },            _renderContent: function() {                this._renderContentImpl()            },            _getTemplate: function(templateName) {                var template = templateName;                if (DX.utils.isString(template) && template[0] === '#') {                    template = $(templateName);                    DX.utils.logger.warn(DATAGRID_DEPRECATED_TEMPLATE_WARNING)                }                return this.callBase(template)            },            _dispose: function() {                var that = this;                that.callBase();                callModuleItemsMethod(that, 'dispose')            },            isReady: function() {                return this.getController("data").isReady()            },            beginUpdate: function() {                var that = this;                that.callBase();                callModuleItemsMethod(that, 'beginUpdate')            },            endUpdate: function() {                var that = this;                callModuleItemsMethod(that, 'endUpdate');                that.callBase()            },            getController: function(name) {                return this._controllers[name]            },            getView: function(name) {                return this._views[name]            },            focus: function(element) {                this.callBase();                if (utils.isDefined(element))                    this.getController("keyboardNavigation").focus(element)            }        }));        var MAX_EQUAL_KEYS_LEVEL = 3;        $.extend(ui.dxDataGrid, {            __internals: {},            modules: [],            View: View,            ViewController: ViewController,            Controller: Controller,            registerModule: function(name, module) {                var modules = this.modules,                    i;                for (i = 0; i < modules.length; i++)                    if (modules[i].name === name)                        return;                module.name = name;                modules.push(module)            },            unregisterModule: function(name) {                this.modules = $.grep(this.modules, function(module) {                    return module.name !== name                })            },            processModules: processModules,            formatValue: function(value, options) {                var valueText = DX.formatHelper.format(value, options.format, options.precision) || value && value.toString() || '',                    formatObject = {                        value: value,                        valueText: options.getDisplayFormat ? options.getDisplayFormat(valueText) : valueText                    };                return options.customizeText ? options.customizeText.call(options, formatObject) : formatObject.valueText            },            getDisplayValue: function(column, value) {                return column.lookup ? column.lookup.calculateCellValue(value) : value            },            getGroupRowSummaryText: function(summaryItems, summaryTexts) {                var result = "(",                    i,                    summaryItem;                for (i = 0; i < summaryItems.length; i++) {                    summaryItem = summaryItems[i];                    result += (i > 0 ? ", " : "") + ui.dxDataGrid.getSummaryText(summaryItem, summaryTexts)                }                return result += ")"            },            getSummaryText: function(summaryItem, summaryTexts) {                var displayFormat = summaryItem.displayFormat || summaryItem.columnCaption && summaryTexts[summaryItem.summaryType + "OtherColumn"] || summaryTexts[summaryItem.summaryType];                return this.formatValue(summaryItem.value, {                        format: summaryItem.valueFormat,                        precision: summaryItem.precision,                        getDisplayFormat: function(valueText) {                            return displayFormat ? utils.stringFormat(displayFormat, valueText, summaryItem.columnCaption) : valueText                        },                        customizeText: summaryItem.customizeText                    })            },            equalKeys: function(key1, key2, level) {                var propertyName,                    i;                level = level || 0;                if (level < MAX_EQUAL_KEYS_LEVEL)                    if (utils.isObject(key1) && utils.isObject(key2)) {                        for (propertyName in key1)                            if (key1.hasOwnProperty(propertyName) && !ui.dxDataGrid.equalKeys(key1[propertyName], key2[propertyName], level + 1))                                return false;                        for (propertyName in key2)                            if (!(propertyName in key1))                                return false;                        return true                    }                    else if (utils.isArray(key1) && utils.isArray(key2)) {                        if (key1.length !== key2.length)                            return false;                        for (i = 0; i < key1.length; i++)                            if (!ui.dxDataGrid.equalKeys(key1[i], key2[i], level + 1))                                return false;                        return true                    }                    else if (utils.isDate(key1) && utils.isDate(key2))                        return key1.getTime() === key2.getTime();                    else                        return key1 === key2;                return true            },            getIndexByKey: function(key, items) {                var index = -1;                $.each(items, function(i, item) {                    if (ui.dxDataGrid.equalKeys(key, item.key)) {                        index = i;                        return false                    }                });                return index            },            normalizeSortingInfo: function(sort) {                sort = sort || [];                var result,                    i;                result = DX.data.utils.normalizeSortingInfo(sort);                for (i = 0; i < sort.length; i++)                    if (sort && sort[i] && sort[i].isExpanded !== undefined)                        result[i].isExpanded = sort[i].isExpanded;                return result            }        })    })(jQuery, DevExpress);    /*! Module widgets-web, file ui.dataGrid.stateStoring.js */    (function($, DX) {        var ui = DX.ui,            utils = DX.utils,            dataGrid = ui.dxDataGrid;        dataGrid.StateStoringController = dataGrid.ViewController.inherit(function() {            var getStorage = function(options) {                    var storage = options.type === 'sessionStorage' ? sessionStorage : localStorage;                    if (!storage)                        throw new Error("E1007");                    return storage                };            var getUniqueStorageKey = function(options) {                    return 'dx_datagrid_' + (utils.isDefined(options.storageKey) ? options.storageKey : 'storage')                };            var dateReviver = function(key, value) {                    var date;                    if (typeof value === 'string') {                        date = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);                        if (date)                            return new Date(Date.UTC(+date[1], +date[2] - 1, +date[3], +date[4], +date[5], +date[6]))                    }                    return value                };            var processLoadState = function(that) {                    var columnsController = that.getController('columns'),                        selectionController = that.getController('selection'),                        exportController = that.getController("export"),                        dataController = that.getController('data'),                        pagerView = that.getView('pagerView');                    if (columnsController)                        columnsController.columnsChanged.add(function() {                            $.extend(that._state, {columns: columnsController.getUserState()});                            that.isEnabled() && that.save()                        });                    if (selectionController)                        selectionController.selectionChanged.add(function(keys) {                            $.extend(that._state, {selectedRowKeys: keys});                            that.isEnabled() && that.save()                        });                    if (dataController) {                        that._initialPageSize = that.option("paging.pageSize");                        dataController.changed.add(function() {                            $.extend(that._state, {                                searchText: that.option("searchPanel.text"),                                pageIndex: dataController.pageIndex(),                                pageSize: dataController.pageSize(),                                allowedPageSizes: pagerView ? pagerView.getPageSizes() : undefined                            });                            that.isEnabled() && that.save()                        })                    }                    if (exportController)                        exportController.selectionOnlyChanged.add(function() {                            $.extend(that._state, {exportSelectionOnly: exportController.selectionOnly()});                            that.isEnabled() && that.save()                        })                };            var applyState = function(that, state) {                    var allowedPageSizes = state.allowedPageSizes,                        searchText = state.searchText,                        selectedRowKeys = state.selectedRowKeys,                        exportController = that.getController("export"),                        columnsController = that.getController('columns'),                        scrollingMode = that.option('scrolling.mode');                    that.component.beginUpdate();                    if (columnsController)                        columnsController.setUserState(state.columns);                    if (exportController)                        exportController.selectionOnly(state.exportSelectionOnly);                    that.option('selectedRowKeys', selectedRowKeys || []);                    if (allowedPageSizes && that.option('pager.allowedPageSizes') === 'auto')                        that.option('pager').allowedPageSizes = allowedPageSizes;                    that.option('searchPanel.text', searchText || '');                    that.option('paging.pageSize', scrollingMode !== "virtual" && scrollingMode !== "infinite" && state.pageSize ? state.pageSize : that._initialPageSize);                    that.option('paging.pageIndex', state.pageIndex || 0);                    that.component.endUpdate()                };            return {                    _loadState: function() {                        var options = this.option('stateStoring');                        if (options.type === 'custom')                            return options.customLoad && options.customLoad();                        try {                            return JSON.parse(getStorage(options).getItem(getUniqueStorageKey(options)), dateReviver)                        }                        catch(e) {                            DX.utils.logger.error(e.message)                        }                    },                    _saveState: function(state) {                        var options = this.option('stateStoring');                        if (options.type === 'custom') {                            options.customSave && options.customSave(state);                            return                        }                        try {                            getStorage(options).setItem(getUniqueStorageKey(options), JSON.stringify(state))                        }                        catch(e) {}                    },                    publicMethods: function() {                        return ['state']                    },                    isEnabled: function() {                        return this.option('stateStoring.enabled')                    },                    init: function() {                        var that = this;                        that._state = {};                        that._isLoaded = false;                        that._isLoading = false;                        that._windowUnloadHandler = function() {                            if (that._savingTimeoutID !== undefined)                                that._saveState(that.state())                        },                        $(window).on('unload', that._windowUnloadHandler);                        processLoadState(that)                    },                    isLoaded: function() {                        return this._isLoaded                    },                    isLoading: function() {                        return this._isLoading                    },                    load: function() {                        var that = this,                            loadResult;                        that._isLoading = true;                        loadResult = that._loadState();                        if (!loadResult || !$.isFunction(loadResult.done))                            loadResult = $.Deferred().resolve(loadResult);                        loadResult.done(function(state) {                            that._isLoaded = true;                            that._isLoading = false;                            that.state(state)                        });                        return loadResult                    },                    state: function(state) {                        var that = this;                        if (!arguments.length)                            return $.extend(true, {}, that._state);                        else {                            that._state = $.extend({}, state);                            applyState(that, $.extend({}, state))                        }                    },                    save: function() {                        var that = this;                        clearTimeout(that._savingTimeoutID);                        that._savingTimeoutID = setTimeout(function() {                            that._saveState(that.state());                            that._savingTimeoutID = undefined                        }, that.option('stateStoring.savingTimeout'))                    },                    optionChanged: function(args) {                        var that = this;                        switch (args.name) {                            case'stateStoring':                                if (that.isEnabled())                                    that.load();                                args.handled = true;                                break;                            default:                                that.callBase(args)                        }                    },                    dispose: function() {                        clearTimeout(this._savingTimeoutID);                        $(window).off('unload', this._windowUnloadHandler)                    }                }        }());        dataGrid.registerModule('stateStoring', {            defaultOptions: function() {                return {stateStoring: {                            enabled: false,                            storageKey: null,                            type: 'localStorage',                            customLoad: null,                            customSave: null,                            savingTimeout: 2000                        }}            },            controllers: {stateStoring: ui.dxDataGrid.StateStoringController},            extenders: {controllers: {                    columns: {getVisibleColumns: function() {                            var visibleColumns = this.callBase(),                                stateStoringController = this.getController('stateStoring');                            return stateStoringController.isEnabled() && !stateStoringController.isLoaded() ? [] : visibleColumns                        }},                    data: {                        _refreshDataSource: function() {                            var that = this,                                callBase = that.callBase,                                stateStoringController = that.getController('stateStoring');                            if (stateStoringController.isEnabled() && !stateStoringController.isLoaded()) {                                clearTimeout(that._restoreStateTimeoutID);                                that._restoreStateTimeoutID = setTimeout(function() {                                    stateStoringController.load().always(function() {                                        that._restoreStateTimeoutID = null;                                        callBase.call(that)                                    })                                })                            }                            else if (!that._restoreStateTimeoutID)                                callBase.call(that)                        },                        isLoading: function() {                            var that = this,                                stateStoringController = that.getController('stateStoring');                            return this.callBase() || stateStoringController.isLoading()                        },                        dispose: function() {                            clearTimeout(this._restoreStateTimeoutID);                            this.callBase()                        }                    }                }}        })    })(jQuery, DevExpress);    /*! Module widgets-web, file ui.dataGrid.columnsController.js */    (function($, DX, undefined) {        var ui = DX.ui,            dataGrid = ui.dxDataGrid,            normalizeSortingInfo = dataGrid.normalizeSortingInfo,            utils = DX.utils,            normalizeIndexes = utils.normalizeIndexes,            dataUtils = DX.data.utils,            isDefined = utils.isDefined;        var USER_STATE_FIELD_NAMES_15_1 = ['filterValues', 'filterType', 'fixed', 'fixedPosition'],            USER_STATE_FIELD_NAMES = ['visibleIndex', 'dataField', 'name', 'dataType', 'width', 'visibleWidth', 'visible', 'sortOrder', 'sortIndex', 'groupIndex', 'filterValue', 'selectedFilterOperation'].concat(USER_STATE_FIELD_NAMES_15_1),            DATAGRID_COMMAND_EXPAND_CLASS = 'dx-command-expand';        dataGrid.checkChanges = function(changes, changeNames) {            var changesWithChangeNamesCount = 0,                i;            for (i = 0; i < changeNames.length; i++)                if (changes[changeNames[i]])                    changesWithChangeNamesCount++;            return changes.length && changes.length === changesWithChangeNamesCount        };        var ColumnsController = dataGrid.Controller.inherit(function() {                var DEFAULT_COLUMN_OPTIONS = {                        visible: true,                        showInColumnChooser: true                    },                    DATATYPE_OPERATIONS = {                        number: ['=', '<>', '<', '>', '<=', '>='],                        string: ['contains', 'notcontains', 'startswith', 'endswith', '=', '<>'],                        date: ['=', '<>', '<', '>', '<=', '>=']                    },                    GROUP_LOCATION = 'group',                    COLUMN_CHOOSER_LOCATION = 'columnChooser';                var convertNameToCaption = function(name) {                        var captionList = [],                            i,                            char,                            isPrevCharNewWord = false,                            isNewWord = false;                        for (i = 0; i < name.length; i++) {                            char = name.charAt(i);                            isNewWord = char === char.toUpperCase() || char in ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];                            if (char === '_' || char === '.') {                                char = ' ';                                isNewWord = true                            }                            else if (i === 0) {                                char = char.toUpperCase();                                isNewWord = true                            }                            else if (!isPrevCharNewWord && isNewWord)                                if (captionList.length > 0)                                    captionList.push(' ');                            captionList.push(char);                            isPrevCharNewWord = isNewWord                        }                        return captionList.join('')                    };                var createColumn = function(that, columnOptions, userStateColumnOptions) {                        var commonColumnOptions,                            calculatedColumnOptions;                        if (columnOptions) {                            if (utils.isString(columnOptions))                                columnOptions = {dataField: columnOptions};                            if (columnOptions.command)                                return $.extend(true, {}, columnOptions);                            else {                                commonColumnOptions = that.getCommonSettings();                                if (userStateColumnOptions && userStateColumnOptions.name && userStateColumnOptions.dataField)                                    columnOptions = $.extend({}, columnOptions, {dataField: userStateColumnOptions.dataField});                                calculatedColumnOptions = that._createCalculatedColumnOptions(columnOptions);                                return $.extend(true, {}, DEFAULT_COLUMN_OPTIONS, commonColumnOptions, calculatedColumnOptions, columnOptions)                            }                        }                    };                var createColumnsFromOptions = function(that, columnsOptions) {                        var result = [];                        if (columnsOptions)                            $.each(columnsOptions, function(index, columnOptions) {                                var userStateColumnOptions = that._columnsUserState && checkUserStateColumn(columnOptions, that._columnsUserState[index]) && that._columnsUserState[index],                                    column = createColumn(that, columnOptions, userStateColumnOptions);                                if (column)                                    result.push(column)                            });                        return result                    };                var getValueDataType = function(value) {                        var dataType = $.type(value);                        if (dataType !== 'string' && dataType !== 'boolean' && dataType !== 'number' && dataType !== 'date')                            dataType = undefined;                        return dataType                    };                var getSerializationFormat = function(dataType, value) {                        switch (dataType) {                            case'date':                                if (utils.isNumber(value))                                    return 'number';                                else if (utils.isString(value))                                    return 'yyyy/MM/dd';                                break;                            case'number':                                if (utils.isString(value))                                    return 'string'                        }                    };                var updateSerializers = function(options, dataType) {                        if (!options.deserializeValue) {                            if (dataType === 'date') {                                options.deserializeValue = function(value) {                                    var serializationFormat = this.serializationFormat,                                        parsedValue;                                    if (!serializationFormat || serializationFormat === 'number' || serializationFormat === 'yyyy/MM/dd') {                                        parsedValue = serializationFormat === 'number' ? value : !utils.isDate(value) && Date.parse(value);                                        return parsedValue ? new Date(parsedValue) : value                                    }                                    else if (value !== undefined)                                        return Globalize.parseDate(value, serializationFormat)                                };                                options.serializeValue = function(value) {                                    var serializationFormat = this.serializationFormat;                                    if (serializationFormat === 'number')                                        return value && value.valueOf && value.valueOf();                                    else if (serializationFormat)                                        return Globalize.format(value, serializationFormat);                                    else                                        return value                                }                            }                            if (dataType === 'number') {                                options.deserializeValue = function(value) {                                    return value ? Number(value) : value                                };                                options.serializeValue = function(value) {                                    return value ? value.toString() : value                                }                            }                        }                    };                var getAlignmentByDataType = function(dataType, isRTL) {                        switch (dataType) {                            case'number':                                return 'right';                            case'boolean':                                return 'center';                            case'date':                                return 'left';                            default:                                return isRTL ? 'right' : 'left'                        }                    };                var getFormatByDataType = function(dataType) {                        switch (dataType) {                            case"date":                                return "shortDate"                        }                    };                var getCustomizeTextByDataType = function(dataType) {                        if (dataType === 'boolean')                            return function(e) {                                    if (e.value === true)                                        return this.trueText || 'true';                                    else if (e.value === false)                                        return this.falseText || 'false';                                    else                                        return e.valueText || ''                                }                    };                var createColumnsFromDataSource = function(that, dataSource) {                        var firstItems = getFirstItems(dataSource),                            fieldName,                            processedFields = {},                            i,                            result = [];                        for (i = 0; i < firstItems.length; i++)                            if (firstItems[i])                                for (fieldName in firstItems[i])                                    processedFields[fieldName] = true;                        for (fieldName in processedFields)                            if (fieldName.indexOf('__') !== 0) {                                var column = createColumn(that, fieldName);                                result.push(column)                            }                        return result                    };                var equalSortParameters = function(sortParameters1, sortParameters2) {                        var i;                        if ($.isArray(sortParameters1) && $.isArray(sortParameters2)) {                            if (sortParameters1.length !== sortParameters2.length)                                return false;                            else                                for (i = 0; i < sortParameters1.length; i++)                                    if (sortParameters1[i].selector !== sortParameters2[i].selector || sortParameters1[i].desc !== sortParameters2[i].desc || Boolean(sortParameters1[i].isExpanded) !== Boolean(sortParameters2[i].isExpanded))                                        return false;                            return true                        }                        else                            return (!sortParameters1 || !sortParameters1.length) === (!sortParameters2 || !sortParameters2.length)                    };                var getFirstItems = function(dataSource) {                        var groupsCount,                            items = [];                        var getFirstItemsCore = function(items, groupsCount) {                                var i,                                    childItems;                                if (!items || !groupsCount)                                    return items;                                for (i = 0; i < items.length; i++) {                                    childItems = getFirstItemsCore(items[i].items || items[i].collapsedItems, groupsCount - 1);                                    if (childItems && childItems.length)                                        return childItems                                }                            };                        if (dataSource && dataSource.items().length > 0) {                            groupsCount = normalizeSortingInfo(dataSource.group()).length;                            items = getFirstItemsCore(dataSource.items(), groupsCount) || []                        }                        return items                    };                var updateColumnIndexes = function(that) {                        $.each(that._columns, function(index, column) {                            column.index = index                        });                        $.each(that._commandColumns, function(index, column) {                            column.index = -(index + 1)                        })                    };                var updateColumnGroupIndexes = function(that, currentColumn) {                        normalizeIndexes(that._columns, 'groupIndex', currentColumn, function(column) {                            var grouped = column.grouped;                            delete column.grouped;                            return grouped                        })                    };                var updateColumnSortIndexes = function(that, currentColumn) {                        $.each(that._columns, function(index, column) {                            if (isDefined(column.sortIndex) && !isSortOrderValid(column.sortOrder))                                delete column.sortIndex                        });                        normalizeIndexes(that._columns, 'sortIndex', currentColumn, function(column) {                            return !isDefined(column.groupIndex) && isSortOrderValid(column.sortOrder)                        })                    };                var updateColumnVisibleIndexes = function(that, currentColumn) {                        normalizeIndexes(that._columns, 'visibleIndex', currentColumn)                    };                var getColumnIndexByVisibleIndex = function(that, visibleIndex, location) {                        var columns = location === GROUP_LOCATION ? that.getGroupColumns() : location === COLUMN_CHOOSER_LOCATION ? that.getChooserColumns() : that.getVisibleColumns(),                            column = columns[visibleIndex];                        return column && isDefined(column.index) ? column.index : -1                    };                var moveColumnToGroup = function(that, column, groupIndex) {                        var groupColumns = that.getGroupColumns(),                            i;                        if (groupIndex >= 0) {                            for (i = 0; i < groupColumns.length; i++)                                if (groupColumns[i].groupIndex >= groupIndex)                                    groupColumns[i].groupIndex++                        }                        else {                            groupIndex = 0;                            for (i = 0; i < groupColumns.length; i++)                                groupIndex = Math.max(groupIndex, groupColumns[i].groupIndex + 1)                        }                        column.groupIndex = groupIndex                    };                var checkUserStateColumn = function(column, userStateColumn) {                        return column && userStateColumn && userStateColumn.name === column.name && (userStateColumn.dataField === column.dataField || column.name)                    };                var applyUserState = function(that) {                        var columnsUserState = that._columnsUserState,                            columns = that._columns,                            resultColumns = [],                            column,                            i;                        function handleStateField(index, fieldName) {                            if (fieldName === 'dataType')                                column[fieldName] = column[fieldName] || columnsUserState[i][fieldName];                            else if ($.inArray(fieldName, USER_STATE_FIELD_NAMES_15_1) >= 0) {                                if (fieldName in columnsUserState[i])                                    column[fieldName] = columnsUserState[i][fieldName]                            }                            else                                column[fieldName] = columnsUserState[i][fieldName]                        }                        if (columnsUserState) {                            if (columns.length !== columnsUserState.length)                                return;                            for (i = 0; i < columnsUserState.length; i++) {                                column = isDefined(columnsUserState[i].initialIndex) ? columns[columnsUserState[i].initialIndex] : columns[i];                                if (column && checkUserStateColumn(column, columnsUserState[i])) {                                    column = $.extend({}, column);                                    $.each(USER_STATE_FIELD_NAMES, handleStateField);                                    resultColumns.push(column)                                }                                else                                    return                            }                            assignColumns(that, resultColumns)                        }                    };                var updateIndexes = function(that, column) {                        updateColumnIndexes(that);                        updateColumnGroupIndexes(that, column);                        updateColumnSortIndexes(that, column);                        updateColumnVisibleIndexes(that, column)                    };                var isLocalDataSource = function(dataSource) {                        return dataSource && dataSource.store && dataSource.store() instanceof DX.data.ArrayStore                    };                var assignColumns = function(that, columns) {                        that._columns = columns;                        that._visibleColumns = undefined;                        that.updateColumnDataTypes()                    };                var updateColumnChanges = function(that, changeType, optionName, columnIndex) {                        var columnChanges = that._columnChanges || {                                optionNames: {length: 0},                                changeTypes: {length: 0},                                columnIndex: columnIndex                            };                        optionName = optionName || 'all';                        var changeTypes = columnChanges.changeTypes;                        if (changeType && !changeTypes[changeType]) {                            changeTypes[changeType] = true;                            changeTypes.length++                        }                        var optionNames = columnChanges.optionNames;                        if (optionName && !optionNames[optionName]) {                            optionNames[optionName] = true;                            optionNames.length++                        }                        if (columnIndex === undefined || columnIndex !== columnChanges.columnIndex)                            delete columnChanges.columnIndex;                        that._columnChanges = columnChanges;                        that._visibleColumns = undefined                    };                var fireColumnsChanged = function(that) {                        var onColumnsChanging = that.option("onColumnsChanging"),                            columnChanges = that._columnChanges;                        if (that.isInitialized() && !that._updateLockCount && columnChanges) {                            if (onColumnsChanging) {                                that._updateLockCount++;                                onColumnsChanging($.extend({component: that.component}, columnChanges));                                that._updateLockCount--                            }                            that._columnChanges = undefined;                            if (columnChanges.optionNames && columnChanges.optionNames.dataField)                                that.reinit();                            that.columnsChanged.fire(columnChanges)                        }                    };                var columnOptionCore = function(that, column, optionName, value, notFireEvent) {                        var optionGetter = dataUtils.compileGetter(optionName),                            changeType;                        if (arguments.length === 3)                            return optionGetter(column, {functionsAsIs: true});                        if (optionGetter(column, {functionsAsIs: true}) !== value) {                            if (optionName === 'groupIndex')                                changeType = 'grouping';                            else if (optionName === 'sortIndex' || optionName === 'sortOrder')                                changeType = 'sorting';                            else                                changeType = 'columns';                            dataUtils.compileSetter(optionName)(column, value, {functionsAsIs: true});                            if (!notFireEvent)                                updateColumnChanges(that, changeType, optionName, column.index)                        }                    };                var isSortOrderValid = function(sortOrder) {                        return sortOrder === 'asc' || sortOrder === 'desc'                    };                var addExpandColumn = function(that) {                        that.addCommandColumn({                            command: 'expand',                            width: 'auto',                            cssClass: DATAGRID_COMMAND_EXPAND_CLASS,                            allowEditing: false,                            allowGrouping: false,                            allowSorting: false,                            allowResizing: false,                            allowReordering: false,                            allowHiding: false                        })                    };                return {                        init: function() {                            var that = this,                                columns = that.option('columns');                            that._updateLockCount = that._updateLockCount || 0;                            that._commandColumns = that._commandColumns || [];                            that._columns = that._columns || [];                            addExpandColumn(that);                            that._isColumnsFromOptions = !!columns;                            if (that._isColumnsFromOptions) {                                assignColumns(that, columns ? createColumnsFromOptions(that, columns) : []);                                applyUserState(that)                            }                            else                                assignColumns(that, that._columnsUserState ? createColumnsFromOptions(that, that._columnsUserState) : that._columns);                            if (that._dataSourceApplied)                                that.applyDataSource(that._dataSource, true);                            else                                updateIndexes(that)                        },                        callbackNames: function() {                            return ['columnsChanged']                        },                        optionChanged: function(args) {                            switch (args.name) {                                case'columns':                                    args.handled = true;                                    this._columnsUserState = null;                                    this.init();                                    break;                                case'commonColumnSettings':                                case'columnAutoWidth':                                case'allowColumnResizing':                                case'allowColumnReordering':                                case'columnFixing':                                case'grouping':                                case'groupPanel':                                case'regenerateColumnsByVisibleItems':                                case'customizeColumns':                                case'editing':                                    args.handled = true;                                    this.reinit();                                    break;                                case'rtlEnabled':                                    this.reinit();                                    break;                                default:                                    this.callBase(args)                            }                        },                        publicMethods: function() {                            return ['addColumn', 'columnOption', 'columnCount', 'clearSorting', 'clearGrouping']                        },                        applyDataSource: function(dataSource, forceApplying) {                            var that = this,                                isDataSourceLoaded = dataSource && dataSource.isLoaded();                            that._dataSource = dataSource;                            if (!that._dataSourceApplied || that._dataSourceColumnsCount === 0 || forceApplying || that.option('regenerateColumnsByVisibleItems'))                                if (isDataSourceLoaded) {                                    if (!that._isColumnsFromOptions) {                                        assignColumns(that, createColumnsFromDataSource(that, dataSource));                                        that._dataSourceColumnsCount = that._columns.length;                                        applyUserState(that)                                    }                                    return that.updateColumns(dataSource, forceApplying)                                }                        },                        reset: function() {                            this._dataSourceApplied = false;                            this._dataSourceColumnsCount = undefined;                            this.reinit()                        },                        reinit: function() {                            this._columnsUserState = this.getUserState();                            this.init()                        },                        isInitialized: function() {                            return !!this._columns.length                        },                        isDataSourceApplied: function() {                            return this._dataSourceApplied                        },                        beginUpdate: function() {                            this._updateLockCount++                        },                        endUpdate: function() {                            var that = this;                            that._updateLockCount--;                            if (!that._updateLockCount)                                fireColumnsChanged(that)                        },                        getCommonSettings: function() {                            var commonColumnSettings = this.option('commonColumnSettings') || {},                                groupingOptions = this.option('grouping') || {},                                groupPanelOptions = this.option('groupPanel') || {};                            return $.extend({                                    allowFixing: this.option('columnFixing.enabled'),                                    allowResizing: this.option('allowColumnResizing'),                                    allowReordering: this.option('allowColumnReordering'),                                    autoExpandGroup: groupingOptions.autoExpandAll,                                    allowCollapsing: groupingOptions.allowCollapsing,                                    allowGrouping: groupPanelOptions.allowColumnDragging && groupPanelOptions.visible                                }, commonColumnSettings)                        },                        isColumnOptionUsed: function(optionName) {                            for (var i = 0; i < this._columns.length; i++)                                if (this._columns[i][optionName])                                    return true                        },                        isAllDataTypesDefined: function() {                            var columns = this._columns,                                i;                            if (!columns.length)                                return false;                            for (i = 0; i < columns.length; i++)                                if (!columns[i].dataType)                                    return false;                            return true                        },                        getColumns: function() {                            return $.extend(true, [], this._columns)                        },                        getGroupColumns: function() {                            var result = [];                            $.each(this._columns, function() {                                var column = this;                                if (isDefined(column.groupIndex))                                    result[column.groupIndex] = column                            });                            return result                        },                        getVisibleColumns: function() {                            this._visibleColumns = this._visibleColumns || this._getVisibleColumnsCore();                            return this._visibleColumns                        },                        getFixedColumns: function() {                            var that = this,                                result = [],                                isColumnFixing = that._isColumnFixing(),                                notFixedColumnCount = 0,                                transparentColumnIndex,                                visibleColumns;                            if (isColumnFixing) {                                visibleColumns = that.getVisibleColumns();                                $.each(visibleColumns, function(index, column) {                                    if (!column.command && !column.fixed) {                                        notFixedColumnCount++;                                        if (!isDefined(transparentColumnIndex))                                            transparentColumnIndex = index                                    }                                });                                if (notFixedColumnCount < visibleColumns.length) {                                    result = visibleColumns.slice(0);                                    result.splice(transparentColumnIndex, notFixedColumnCount, {                                        command: "transparent",                                        colspan: notFixedColumnCount                                    })                                }                            }                            return result                        },                        _isColumnFixing: function() {                            var isColumnFixing = this.option("columnFixing.enabled");                            !isColumnFixing && $.each(this._columns, function(_, column) {                                if (column.fixed) {                                    isColumnFixing = true;                                    return false                                }                            });                            return isColumnFixing                        },                        _getExpandColumnsCore: function() {                            return this.getGroupColumns()                        },                        getExpandColumns: function() {                            var expandColumns = this._getExpandColumnsCore(),                                expandColumn;                            if (expandColumns.length)                                expandColumn = this.columnOption("command:expand");                            expandColumns = $.map(expandColumns, function(column) {                                return $.extend({}, column, {visibleWidth: "auto"}, expandColumn, {index: column.index})                            });                            return expandColumns                        },                        _getVisibleColumnsCore: function() {                            var result = this.getExpandColumns(),                                positiveIndexedColumns = [{}, {}, {}],                                negativeIndexedColumns = {},                                notGroupedColumnsCount = 0,                                isFixedToEnd,                                rtlEnabled = this.option("rtlEnabled"),                                columns = this._columns.length ? this._commandColumns.concat(this._columns) : [];                            $.each(columns, function() {                                var column = this,                                    visibleIndex = column.visibleIndex,                                    indexedColumns;                                if (column.visible && (!isDefined(column.groupIndex) || column.showWhenGrouped)) {                                    column = $.extend(true, {}, column);                                    if (visibleIndex < 0) {                                        visibleIndex = -visibleIndex;                                        indexedColumns = negativeIndexedColumns                                    }                                    else if (column.fixed || column.command) {                                        isFixedToEnd = column.fixedPosition === "right";                                        if (rtlEnabled)                                            isFixedToEnd = !isFixedToEnd;                                        if (isFixedToEnd || column.command)                                            indexedColumns = positiveIndexedColumns[2];                                        else                                            indexedColumns = positiveIndexedColumns[0]                                    }                                    else                                        indexedColumns = positiveIndexedColumns[1];                                    indexedColumns[visibleIndex] = indexedColumns[visibleIndex] || [];                                    indexedColumns[visibleIndex].push(column);                                    notGroupedColumnsCount++                                }                            });                            utils.orderEach(negativeIndexedColumns, function(_, columns) {                                result.unshift.apply(result, columns)                            });                            $.each(positiveIndexedColumns, function(index, positiveColumns) {                                utils.orderEach(positiveColumns, function(_, columns) {                                    result.push.apply(result, columns)                                })                            });                            if (!notGroupedColumnsCount && this._columns.length)                                result.push({command: 'empty'});                            return result                        },                        getHiddenColumns: function() {                            var result = [];                            $.each(this._columns, function(_, column) {                                if (!column.visible)                                    result.push(column)                            });                            return result                        },                        getChooserColumns: function() {                            return $.grep(this.getHiddenColumns(), function(column) {                                    return column.showInColumnChooser                                })                        },                        allowMoveColumn: function(fromVisibleIndex, toVisibleIndex, sourceLocation, targetLocation) {                            var that = this,                                columnIndex = getColumnIndexByVisibleIndex(that, fromVisibleIndex, sourceLocation),                                sourceColumn = that._columns[columnIndex];                            if (sourceColumn && (sourceColumn.allowReordering || sourceColumn.allowGrouping || sourceColumn.allowHiding)) {                                if (sourceLocation === targetLocation) {                                    if (sourceLocation === COLUMN_CHOOSER_LOCATION)                                        return false;                                    return fromVisibleIndex !== toVisibleIndex && fromVisibleIndex + 1 !== toVisibleIndex                                }                                else if (sourceLocation === GROUP_LOCATION && targetLocation !== COLUMN_CHOOSER_LOCATION || targetLocation === GROUP_LOCATION)                                    return sourceColumn && sourceColumn.allowGrouping;                                else if (sourceLocation === COLUMN_CHOOSER_LOCATION || targetLocation === COLUMN_CHOOSER_LOCATION)                                    return sourceColumn && sourceColumn.allowHiding;                                return true                            }                            return false                        },                        moveColumn: function(fromVisibleIndex, toVisibleIndex, sourceLocation, targetLocation) {                            var that = this,                                fromIndex,                                toIndex,                                targetGroupIndex,                                isGroupMoving = sourceLocation === GROUP_LOCATION || targetLocation === GROUP_LOCATION,                                column;                            fromIndex = getColumnIndexByVisibleIndex(that, fromVisibleIndex, sourceLocation);                            toIndex = getColumnIndexByVisibleIndex(that, toVisibleIndex, targetLocation);                            if (fromIndex >= 0) {                                column = that._columns[fromIndex];                                targetGroupIndex = toIndex >= 0 ? that._columns[toIndex].groupIndex : -1;                                if (isDefined(column.groupIndex) && sourceLocation === GROUP_LOCATION) {                                    if (targetGroupIndex > column.groupIndex)                                        targetGroupIndex--;                                    delete column.groupIndex;                                    delete column.sortOrder;                                    updateColumnGroupIndexes(that)                                }                                if (targetLocation === GROUP_LOCATION) {                                    moveColumnToGroup(that, column, targetGroupIndex);                                    updateColumnGroupIndexes(that)                                }                                else if (toVisibleIndex >= 0) {                                    if (toIndex < 0)                                        column.visibleIndex = undefined;                                    else {                                        var targetColumn = that._columns[toIndex];                                        if (column.fixed ^ targetColumn.fixed)                                            column.visibleIndex = undefined;                                        else                                            column.visibleIndex = targetColumn.visibleIndex                                    }                                    updateColumnVisibleIndexes(that, column)                                }                                column.visible = targetLocation !== COLUMN_CHOOSER_LOCATION;                                updateColumnChanges(that, isGroupMoving ? 'grouping' : 'columns');                                fireColumnsChanged(that)                            }                        },                        changeSortOrder: function(columnIndex, sortOrder) {                            var that = this,                                sortingOptions = that.option('sorting'),                                sortingMode = sortingOptions && sortingOptions.mode,                                needResetSorting = sortingMode === 'single' || !sortOrder,                                allowSorting = sortingMode === 'single' || sortingMode === 'multiple',                                column = that._columns[columnIndex],                                nextSortOrder = function(column) {                                    if (sortOrder === "ctrl") {                                        if (!("sortOrder" in column && "sortIndex" in column))                                            return false;                                        delete column.sortOrder;                                        delete column.sortIndex                                    }                                    else if (isDefined(column.groupIndex) || isDefined(column.sortIndex))                                        column.sortOrder = column.sortOrder === 'desc' ? 'asc' : 'desc';                                    else                                        column.sortOrder = 'asc';                                    return true                                },                                isSortingChanged = false;                            if (allowSorting && column && column.allowSorting) {                                if (needResetSorting && !isDefined(column.groupIndex))                                    $.each(that._columns, function(index) {                                        if (index !== columnIndex && this.sortOrder && !isDefined(this.groupIndex)) {                                            delete this.sortOrder;                                            delete this.sortIndex;                                            isSortingChanged = true                                        }                                    });                                if (isSortOrderValid(sortOrder)) {                                    if (column.sortOrder !== sortOrder) {                                        column.sortOrder = sortOrder;                                        isSortingChanged = true                                    }                                }                                else if (sortOrder === 'none') {                                    if (column.sortOrder) {                                        delete column.sortIndex;                                        delete column.sortOrder;                                        isSortingChanged = true                                    }                                }                                else                                    isSortingChanged = nextSortOrder(column)                            }                            if (isSortingChanged) {                                updateColumnSortIndexes(that);                                updateColumnChanges(that, 'sorting');                                fireColumnsChanged(that)                            }                        },                        getSortDataSourceParameters: function() {                            var that = this,                                sortColumns = [],                                sort = [];                            $.each(that._columns, function() {                                if ((this.dataField || this.selector || this.calculateCellValue) && isDefined(this.sortIndex) && !isDefined(this.groupIndex))                                    sortColumns[this.sortIndex] = this                            });                            $.each(sortColumns, function() {                                var sortOrder = this && this.sortOrder;                                if (isSortOrderValid(sortOrder))                                    sort.push({                                        selector: this.calculateSortValue || this.selector || this.dataField || this.calculateCellValue,                                        desc: this.sortOrder === 'desc'                                    })                            });                            return sort.length > 0 ? sort : null                        },                        getGroupDataSourceParameters: function(useLocalSelector) {                            var group = [];                            $.each(this.getGroupColumns(), function() {                                var selector = this.calculateGroupValue || this.selector || useLocalSelector && this.groupSelector || this.dataField || this.calculateCellValue;                                if (selector)                                    group.push({                                        selector: selector,                                        desc: this.sortOrder === 'desc',                                        isExpanded: !!this.autoExpandGroup                                    })                            });                            return group.length > 0 ? group : null                        },                        refresh: function(updateNewLookupsOnly) {                            var deferreds = [];                            $.each(this._columns, function() {                                var lookup = this.lookup;                                if (lookup) {                                    if (updateNewLookupsOnly && lookup.valueMap)                                        return;                                    if (lookup.update)                                        deferreds.push(lookup.update())                                }                            });                            return $.when.apply($, deferreds)                        },                        updateColumnDataTypes: function(dataSource) {                            var firstItems = getFirstItems(dataSource),                                isLocalData = isLocalDataSource(dataSource),                                rtlEnabled = this.option("rtlEnabled");                            $.each(this._columns, function(index, column) {                                var i,                                    value,                                    dataType,                                    lookupDataType,                                    valueDataType,                                    lookup = column.lookup;                                if (column.calculateCellValue && firstItems.length) {                                    if (!column.dataType || lookup && !lookup.dataType) {                                        for (i = 0; i < firstItems.length; i++) {                                            value = column.calculateCellValue(firstItems[i]);                                            valueDataType = column.dataType || getValueDataType(value);                                            dataType = dataType || valueDataType;                                            if (dataType && valueDataType && dataType !== valueDataType)                                                dataType = "string";                                            if (lookup) {                                                valueDataType = lookup.dataType || getValueDataType(lookup.calculateCellValue(value));                                                lookupDataType = lookupDataType || valueDataType;                                                if (lookupDataType && valueDataType && lookupDataType !== valueDataType)                                                    lookupDataType = "string"                                            }                                        }                                        column.dataType = dataType;                                        if (lookup)                                            lookup.dataType = lookupDataType                                    }                                    if (!column.serializationFormat || lookup && !lookup.serializationFormat)                                        for (i = 0; i < firstItems.length; i++) {                                            value = column.calculateCellValue(firstItems[i], true);                                            column.serializationFormat = column.serializationFormat || getSerializationFormat(column.dataType, value);                                            if (lookup)                                                lookup.serializationFormat = lookup.serializationFormat || getSerializationFormat(lookup.dataType, lookup.calculateCellValue(value, true))                                        }                                }                                if (isLocalData && column.userDataType || !column.dataField)                                    column.selector = column.selector || $.proxy(column, 'calculateCellValue');                                else if (column.userDataType)                                    column.groupSelector = column.groupSelector || $.proxy(column, 'calculateCellValue');                                updateSerializers(column, column.dataType);                                if (lookup)                                    updateSerializers(lookup, lookup.dataType);                                dataType = lookup ? lookup.dataType : column.dataType;                                if (dataType) {                                    column.alignment = column.alignment || getAlignmentByDataType(dataType, rtlEnabled);                                    column.format = column.format || getFormatByDataType(dataType);                                    column.customizeText = column.customizeText || getCustomizeTextByDataType(dataType);                                    if (!isDefined(column.filterOperations))                                        column.filterOperations = !lookup && DATATYPE_OPERATIONS[dataType] || [];                                    column.defaultFilterOperation = column.filterOperations && column.filterOperations[0] || '=';                                    column.defaultSelectedFilterOperation = column.selectedFilterOperation;                                    column.showEditorAlways = isDefined(column.showEditorAlways) ? column.showEditorAlways : dataType === 'boolean' && !column.cellTemplate                                }                            })                        },                        _customizeColumns: function(columns) {                            var that = this,                                customizeColumns = that.option('customizeColumns');                            if (customizeColumns) {                                customizeColumns(columns);                                assignColumns(that, createColumnsFromOptions(that, columns))                            }                        },                        updateColumns: function(dataSource, forceApplying) {                            var that = this,                                sortParameters,                                groupParameters;                            if (!forceApplying)                                that.updateSortingGrouping(dataSource);                            if (!dataSource || dataSource.isLoaded()) {                                sortParameters = dataSource ? dataSource.sort() || [] : that.getSortDataSourceParameters();                                groupParameters = dataSource ? dataSource.group() || [] : that.getGroupDataSourceParameters();                                that._customizeColumns(that._columns);                                updateIndexes(that);                                return $.when(that.refresh(true)).always(function() {                                        if (dataSource) {                                            that.updateColumnDataTypes(dataSource);                                            that._dataSourceApplied = true                                        }                                        if (!equalSortParameters(sortParameters, that.getSortDataSourceParameters()))                                            updateColumnChanges(that, 'sorting');                                        if (!equalSortParameters(groupParameters, that.getGroupDataSourceParameters()))                                            updateColumnChanges(that, 'grouping');                                        updateColumnChanges(that, 'columns');                                        fireColumnsChanged(that)                                    })                            }                        },                        updateSortingGrouping: function(dataSource, fromDataSource) {                            var that = this,                                sortParameters,                                groupParameters,                                columnsGroupParameters,                                columnsSortParameters,                                isColumnsChanged,                                updateSortGroupParameterIndexes = function(columns, sortParameters, indexParameterName) {                                    var i,                                        selector,                                        isExpanded;                                    $.each(columns, function(index, column) {                                        delete column[indexParameterName];                                        if (sortParameters)                                            for (i = 0; i < sortParameters.length; i++) {                                                selector = sortParameters[i].selector;                                                isExpanded = sortParameters[i].isExpanded;                                                if (selector === column.dataField || selector === column.name || selector === column.selector || selector === column.calculateCellValue || selector === column.calculateGroupValue) {                                                    column.sortOrder = column.sortOrder || (sortParameters[i].desc ? 'desc' : 'asc');                                                    if (isExpanded !== undefined)                                                        column.autoExpandGroup = isExpanded;                                                    column[indexParameterName] = i;                                                    break                                                }                                            }                                    })                                };                            if (dataSource) {                                sortParameters = normalizeSortingInfo(dataSource.sort());                                groupParameters = normalizeSortingInfo(dataSource.group());                                columnsGroupParameters = that.getGroupDataSourceParameters();                                columnsSortParameters = that.getSortDataSourceParameters();                                if (!that._columns.length) {                                    $.each(groupParameters, function(index, group) {                                        that._columns.push(group.selector)                                    });                                    $.each(sortParameters, function(index, sort) {                                        that._columns.push(sort.selector)                                    });                                    assignColumns(that, createColumnsFromOptions(that, that._columns))                                }                                if ((fromDataSource || !columnsGroupParameters && !that._hasUserState) && !equalSortParameters(groupParameters, columnsGroupParameters)) {                                    that.__groupingUpdated = true;                                    updateSortGroupParameterIndexes(that._columns, groupParameters, 'groupIndex');                                    if (fromDataSource) {                                        updateColumnChanges(that, 'grouping');                                        isColumnsChanged = true                                    }                                }                                if ((fromDataSource || !columnsSortParameters && !that._hasUserState) && !equalSortParameters(sortParameters, columnsSortParameters)) {                                    that.__sortingUpdated = true;                                    updateSortGroupParameterIndexes(that._columns, sortParameters, 'sortIndex');                                    if (fromDataSource) {                                        updateColumnChanges(that, 'sorting');                                        isColumnsChanged = true                                    }                                }                                if (isColumnsChanged)                                    fireColumnsChanged(that)                            }                        },                        updateFilter: function(dataSource, filter) {                            var that = this,                                isLocalData = isLocalDataSource(dataSource);                            var updateFilterCore = function(filter) {                                    if (!utils.isArray(filter))                                        return;                                    var column,                                        i;                                    if (utils.isString(filter[0])) {                                        column = that.columnOption(filter[0]);                                        if (column && column.calculateCellValue)                                            filter[0] = $.proxy(column, 'calculateCellValue')                                    }                                    for (i = 0; i < filter.length; i++)                                        updateFilterCore(filter[i])                                };                            if (isLocalData)                                updateFilterCore(filter)                        },                        columnCount: function() {                            return this._columns.length                        },                        columnOption: function(identificator, option, value, notFireEvent) {                            var that = this,                                i,                                identificatorOptionName = utils.isString(identificator) && identificator.substr(0, identificator.indexOf(":")),                                columns = identificator < 0 || identificatorOptionName === "command" ? that._commandColumns : that._columns,                                column;                            if (identificator === undefined)                                return;                            if (identificatorOptionName)                                identificator = identificator.substr(identificatorOptionName.length + 1);                            for (i = 0; i < columns.length; i++)                                if (identificatorOptionName) {                                    if ("" + columns[i][identificatorOptionName] === identificator) {                                        column = columns[i];                                        break                                    }                                }                                else if (columns[i].index === identificator || columns[i].name === identificator || columns[i].dataField === identificator || columns[i].caption === identificator) {                                    column = columns[i];                                    break                                }                            if (column) {                                if (arguments.length === 1)                                    return $.extend({}, column);                                if (utils.isString(option))                                    if (arguments.length === 2)                                        return columnOptionCore(that, column, option);                                    else                                        columnOptionCore(that, column, option, value, notFireEvent);                                else if (utils.isObject(option))                                    $.each(option, function(optionName, value) {                                        columnOptionCore(that, column, optionName, value, notFireEvent)                                    });                                updateIndexes(that, column);                                fireColumnsChanged(that)                            }                        },                        clearSorting: function() {                            var that = this,                                columnCount = this.columnCount(),                                i;                            that.beginUpdate();                            for (i = 0; i < columnCount; i++)                                that.columnOption(i, "sortOrder", undefined);                            that.endUpdate()                        },                        clearGrouping: function() {                            var that = this,                                columnCount = this.columnCount(),                                i;                            that.beginUpdate();                            for (i = 0; i < columnCount; i++)                                that.columnOption(i, "groupIndex", undefined);                            that.endUpdate()                        },                        getVisibleIndex: function(index) {                            var i,                                visibleColumns = this.getVisibleColumns();                            for (i = 0; i < visibleColumns.length; i++)                                if (visibleColumns[i].index === index)                                    return i;                            return -1                        },                        addColumn: function(options) {                            var that = this,                                column = createColumn(that, options);                            that._columns.push(column);                            updateIndexes(that, column);                            that.updateColumns(that._dataSource)                        },                        addCommandColumn: function(options) {                            var commandColumns = this._commandColumns,                                i;                            for (i = 0; i < commandColumns.length; i++)                                if (commandColumns[i].command === options.command)                                    return;                            commandColumns.push(options)                        },                        getUserState: function() {                            var columns = this._columns,                                result = [],                                i;                            function handleStateField(index, value) {                                if (columns[i][value] !== undefined)                                    result[i][value] = columns[i][value]                            }                            for (i = 0; i < columns.length; i++) {                                result[i] = {};                                $.each(USER_STATE_FIELD_NAMES, handleStateField)                            }                            return result                        },                        setUserState: function(state) {                            this._columnsUserState = state;                            this._hasUserState = !!state;                            this.init()                        },                        _createCalculatedColumnOptions: function(columnOptions) {                            var calculatedColumnOptions = {},                                dataField = columnOptions.dataField,                                getter;                            if (dataField && utils.isString(dataField)) {                                getter = dataUtils.compileGetter(dataField);                                calculatedColumnOptions = {                                    caption: convertNameToCaption(dataField),                                    calculateCellValue: function(data, skipDeserialization) {                                        var value = getter(data);                                        return this.deserializeValue && !skipDeserialization ? this.deserializeValue(value) : value                                    },                                    setCellValue: function(data, value) {                                        var path = this.dataField.split("."),                                            dotCount = path.length - 1,                                            name,                                            i;                                        if (this.serializeValue)                                            value = this.serializeValue(value);                                        for (i = 0; i < dotCount; i++) {                                            name = path[i];                                            data = data[name] = data[name] || {}                                        }                                        data[path[dotCount]] = value                                    },                                    parseValue: function(text) {                                        var column = this,                                            result,                                            parsedValue;                                        if (column.dataType === 'number') {                                            if (utils.isString(text)) {                                                parsedValue = Globalize.parseFloat(text);                                                if (utils.isNumber(parsedValue))                                                    result = parsedValue                                            }                                            else if (utils.isDefined(text))                                                result = Number(text)                                        }                                        else if (column.dataType === 'boolean') {                                            if (text === column.trueText)                                                result = true;                                            else if (text === column.falseText)                                                result = false                                        }                                        else if (column.dataType === 'date') {                                            parsedValue = Globalize.parseDate(text);                                            if (parsedValue)                                                result = parsedValue                                        }                                        else                                            result = text;                                        return result                                    }                                }                            }                            else                                $.extend(true, calculatedColumnOptions, {                                    allowSorting: false,                                    allowGrouping: false,                                    calculateCellValue: function() {                                        return null                                    }                                });                            if (columnOptions.dataType)                                calculatedColumnOptions.userDataType = columnOptions.dataType;                            if (columnOptions.lookup)                                calculatedColumnOptions.lookup = {                                    calculateCellValue: function(value, skipDeserialization) {                                        value = this.valueMap && this.valueMap[value];                                        return this.deserializeValue && !skipDeserialization ? this.deserializeValue(value) : value                                    },                                    updateValueMap: function() {                                        var calculateValue,                                            calculateDisplayValue,                                            item,                                            i;                                        this.valueMap = {};                                        if (this.items) {                                            calculateValue = dataUtils.compileGetter(this.valueExpr);                                            calculateDisplayValue = dataUtils.compileGetter(this.displayExpr);                                            for (i = 0; i < this.items.length; i++) {                                                item = this.items[i];                                                this.valueMap[calculateValue(item)] = calculateDisplayValue(item)                                            }                                        }                                    },                                    update: function() {                                        var that = this,                                            dataSource = that.dataSource,                                            dataSourceOptions;                                        if (dataSource)                                            if (utils.isObject(dataSource) || utils.isArray(dataSource)) {                                                dataSourceOptions = dataUtils.normalizeDataSourceOptions(dataSource);                                                dataSourceOptions.paginate = false;                                                dataSource = new DX.data.DataSource(dataSourceOptions);                                                return dataSource.load().done(function(data) {                                                        that.items = data;                                                        that.updateValueMap && that.updateValueMap()                                                    })                                            }                                            else                                                DX.log("E1016");                                        else                                            that.updateValueMap && that.updateValueMap()                                    }                                };                            calculatedColumnOptions.resizedCallbacks = $.Callbacks();                            if (columnOptions.resized)                                calculatedColumnOptions.resizedCallbacks.add($.proxy(columnOptions.resized, columnOptions));                            updateSerializers(calculatedColumnOptions, columnOptions.dataType);                            return calculatedColumnOptions                        }                    }            }());        ui.dxDataGrid.ColumnsController = ColumnsController;        dataGrid.registerModule('columns', {            defaultOptions: function() {                return {                        commonColumnSettings: {                            allowFiltering: true,                            allowHiding: true,                            allowSorting: true,                            allowEditing: true,                            encodeHtml: true,                            trueText: Globalize.localize("dxDataGrid-trueText"),                            falseText: Globalize.localize("dxDataGrid-falseText")                        },                        allowColumnReordering: false,                        allowColumnResizing: false,                        columns: undefined,                        regenerateColumnsByVisibleItems: false,                        customizeColumns: null                    }            },            controllers: {columns: ColumnsController}        })    })(jQuery, DevExpress);    /*! Module widgets-web, file ui.dataGrid.selection.js */    (function($, DX) {        var dataGrid = DX.ui.dxDataGrid,            events = DX.ui.events,            utils = DX.utils;        var DATAGRID_EDITOR_CELL_CLASS = "dx-editor-cell",            DATAGRID_ROW_CLASS = "dx-row",            DATAGRID_ROW_SELECTION_CLASS = "dx-selection",            DATAGRID_SELECT_CHECKBOX_CLASS = "dx-select-checkbox",            DATAGRID_CHECKBOXES_HIDDEN_CLASS = "dx-select-checkboxes-hidden",            DATAGRID_COMMAND_SELECT_CLASS = "dx-command-select",            DATAGRID_SELECTION_DISABLED_CLASS = "dx-selection-disabled",            DATAGRID_DATA_ROW_CLASS = "dx-data-row";        $.extend(dataGrid.__internals, {            DATAGRID_ROW_SELECTION_CLASS: DATAGRID_ROW_SELECTION_CLASS,            DATAGRID_SELECTION_DISABLED_CLASS: DATAGRID_SELECTION_DISABLED_CLASS,            DATAGRID_COMMAND_SELECT_CLASS: DATAGRID_COMMAND_SELECT_CLASS        });        var SHOW_CHECKBOXES_MODE = 'selection.showCheckBoxesInMultipleMode';        var SELECTION_MODE = 'selection.mode';        var isSelectable = function(selectionMode) {                return selectionMode === 'single' || selectionMode === 'multiple'            };        dataGrid.SelectionController = dataGrid.Controller.inherit(function() {            var indexOfSelectedItemKey = function(that, key, isSelectAll) {                    var index,                        selectedItemKeys = isSelectAll ? that._unselectedItemKeys : that._selectedItemKeys;                    if (utils.isObject(key)) {                        for (index = 0; index < selectedItemKeys.length; index++)                            if (equalKeys(selectedItemKeys[index], key))                                return index;                        return -1                    }                    else                        return $.inArray(key, selectedItemKeys)                };            var addSelectedItem = function(that, itemData) {                    var key = that.getController('data').keyOf(itemData);                    if (indexOfSelectedItemKey(that, key) === -1) {                        that._selectedItemKeys.push(key);                        that._addedItemKeys.push(key);                        that._selectedItems.push(itemData)                    }                };            var removeSelectedItem = function(that, key) {                    var keyIndex = indexOfSelectedItemKey(that, key);                    if (keyIndex >= 0) {                        that._selectedItemKeys.splice(keyIndex, 1);                        that._removedItemKeys.push(key);                        that._selectedItems.splice(keyIndex, 1)                    }                };            var clearSelectedItems = function(that) {                    setSelectedItems(that, [], [])                };            var setSelectedItems = function(that, keys, items) {                    var i,                        oldSelectedItemKeys = that._selectedItemKeys;                    that._selectedItemKeys = keys;                    that._selectedItems = items;                    that._unselectedItemKeys = [];                    for (i = 0; i < oldSelectedItemKeys.length; i++)                        if ($.inArray(oldSelectedItemKeys[i], keys) === -1)                            that._removedItemKeys.push(oldSelectedItemKeys[i]);                    for (i = 0; i < keys.length; i++)                        if ($.inArray(keys[i], oldSelectedItemKeys) === -1)                            that._addedItemKeys.push(keys[i])                };            var equalKeys = dataGrid.equalKeys;            var resetItemSelectionWhenShiftKeyPressed = function(that) {                    delete that._shiftFocusedItemIndex                };            var isDataItem = function(row) {                    return row && row.rowType === "data" && !row.inserted                };            var changeItemSelectionWhenShiftKeyPressed = function(that, itemIndex, items) {                    var isSelectedItemsChanged = false,                        itemIndexStep,                        index,                        dataController = that.getController('data'),                        isFocusedItemSelected = items[that._focusedItemIndex] && that.isRowSelected(dataController.keyOf(items[that._focusedItemIndex].data));                    var addRemoveSelectedItem = function(that, data, isRemove) {                            if (isRemove)                                removeSelectedItem(that, dataController.keyOf(data));                            else                                addSelectedItem(that, data)                        };                    if (!utils.isDefined(that._shiftFocusedItemIndex))                        that._shiftFocusedItemIndex = that._focusedItemIndex;                    if (that._shiftFocusedItemIndex !== that._focusedItemIndex) {                        itemIndexStep = that._focusedItemIndex < that._shiftFocusedItemIndex ? 1 : -1;                        for (index = that._focusedItemIndex; index !== that._shiftFocusedItemIndex; index += itemIndexStep)                            if (isDataItem(items[index])) {                                addRemoveSelectedItem(that, items[index].data, true);                                isSelectedItemsChanged = true                            }                    }                    if (itemIndex !== that._shiftFocusedItemIndex) {                        itemIndexStep = itemIndex < that._shiftFocusedItemIndex ? 1 : -1;                        for (index = itemIndex; index !== that._shiftFocusedItemIndex; index += itemIndexStep)                            if (isDataItem(items[index])) {                                addRemoveSelectedItem(that, items[index].data, false);                                isSelectedItemsChanged = true                            }                    }                    if (isDataItem(items[that._focusedItemIndex]) && !isFocusedItemSelected) {                        addRemoveSelectedItem(that, items[that._focusedItemIndex].data, false);                        isSelectedItemsChanged = true                    }                    return isSelectedItemsChanged                };            var createSelectedItemsFilterCriteria = function(dataSource, selectedItemKeys, isSelectAll) {                    var keyCriteria,                        i,                        key = dataSource && dataSource.key(),                        criteria = [];                    if (dataSource)                        if (key)                            $.each(selectedItemKeys, function(index, keyValue) {                                if (criteria.length > 0)                                    criteria.push(isSelectAll ? 'and' : 'or');                                if ($.isArray(key)) {                                    keyCriteria = [];                                    for (i = 0; i < key.length; i++) {                                        if (i > 0)                                            keyCriteria.push(isSelectAll ? 'or' : 'and');                                        keyCriteria.push([key[i], isSelectAll ? '<>' : '=', keyValue[key[i]]])                                    }                                    criteria.push(keyCriteria)                                }                                else                                    criteria.push([key, isSelectAll ? '<>' : '=', keyValue])                            });                        else                            criteria = function(item) {                                var i;                                for (i = 0; i < selectedItemKeys.length; i++)                                    if (equalKeys(selectedItemKeys[i], item))                                        return !isSelectAll;                                return isSelectAll                            };                    if (criteria.length > 0 || $.isFunction(criteria))                        return criteria                };            var updateSelectedItems = function(that) {                    var changedItemIndexes = [],                        dataController = that.getController('data'),                        addedItemKeys,                        removedItemKeys;                    if (dataController) {                        $.each(dataController.items(), function(index, row) {                            if (isDataItem(row) && row.isSelected !== that.isRowSelected(row.key))                                changedItemIndexes.push(index)                        });                        if (that.option(SHOW_CHECKBOXES_MODE) === 'onClick')                            if (that._selectedItemKeys.length > 1)                                that.startSelectionWithCheckboxes();                            else if (that._selectedItemKeys.length === 0 && changedItemIndexes.length)                                that.stopSelectionWithCheckboxes();                        if (changedItemIndexes.length)                            dataController.updateItems({                                changeType: 'updateSelection',                                itemIndexes: changedItemIndexes                            });                        addedItemKeys = that._addedItemKeys;                        removedItemKeys = that._removedItemKeys;                        if (addedItemKeys.length || removedItemKeys.length) {                            that._selectedItemsInternalChange = true;                            that.option("selectedRowKeys", that._selectedItemKeys.slice(0));                            that._selectedItemsInternalChange = false;                            that.selectionChanged.fire(that._selectedItemKeys);                            that._addedItemKeys = [];                            that._removedItemKeys = [];                            that.executeAction("onSelectionChanged", {                                selectedRowsData: that._selectedItems,                                selectedRowKeys: that._selectedItemKeys,                                currentSelectedRowKeys: addedItemKeys,                                currentDeselectedRowKeys: removedItemKeys                            })                        }                    }                };            var updateSelectColumn = function(that) {                    var columnsController = that.getController("columns"),                        isSelectColumnVisible = that.isSelectColumnVisible();                    columnsController.addCommandColumn({                        command: 'select',                        visible: isSelectColumnVisible,                        visibleIndex: -1,                        dataType: 'boolean',                        alignment: 'center',                        cssClass: DATAGRID_COMMAND_SELECT_CLASS,                        width: "auto"                    });                    columnsController.columnOption("command:select", "visible", isSelectColumnVisible)                };            return {                    init: function() {                        var that = this;                        that._isSelectionWithCheckboxes = false;                        that._focusedItemIndex = -1;                        that._selectedItemKeys = [];                        that._unselectedItemKeys = [];                        that._selectedItems = [];                        that._addedItemKeys = [];                        that._removedItemKeys = [];                        updateSelectColumn(that);                        that.createAction("onSelectionChanged", {excludeValidators: ["disabled", "readOnly"]})                    },                    callbackNames: function() {                        return ['selectionChanged']                    },                    optionChanged: function(args) {                        var that = this;                        that.callBase(args);                        switch (args.name) {                            case"selection":                                that.init();                                that.getController('columns').updateColumns();                                args.handled = true;                                break;                            case"selectedRowKeys":                                if (utils.isArray(args.value) && !that._selectedItemsInternalChange)                                    that.selectRows(args.value);                                args.handled = true;                                break                        }                    },                    publicMethods: function() {                        return ['selectRows', 'deselectRows', 'selectRowsByIndexes', 'getSelectedRowKeys', 'getSelectedRowsData', 'clearSelection', 'selectAll', 'startSelectionWithCheckboxes', 'stopSelectionWithCheckboxes', 'isRowSelected']                    },                    isRowSelected: function(key) {                        var index = indexOfSelectedItemKey(this, key);                        return index !== -1                    },                    isSelectColumnVisible: function() {                        var showCheckboxesMode = this.option(SHOW_CHECKBOXES_MODE);                        return this.option(SELECTION_MODE) === 'multiple' && (showCheckboxesMode === 'always' || showCheckboxesMode === 'onClick' || this._isSelectionWithCheckboxes)                    },                    isSelectAll: function() {                        var dataController = this.getController('data'),                            items = dataController.items(),                            combinedFilter = dataController.getCombinedFilter(),                            selectedItems = this.getSelectedRowsData(),                            i;                        if (combinedFilter)                            DX.data.query(selectedItems).filter(combinedFilter).enumerate().done(function(items) {                                selectedItems = items                            });                        if (!selectedItems.length) {                            for (i = 0; i < items.length; i++)                                if (items[i].selected)                                    return;                            return false                        }                        else if (selectedItems.length >= dataController.totalCount())                            return true                    },                    selectAll: function() {                        if (this.option(SHOW_CHECKBOXES_MODE) === 'onClick')                            this.startSelectionWithCheckboxes();                        return this.selectedItemKeys([], true, false, true)                    },                    deselectAll: function() {                        return this.selectedItemKeys([], true, true, true)                    },                    clearSelection: function() {                        this.selectedItemKeys([])                    },                    refresh: function() {                        return this.selectedItemKeys(this.option("selectedRowKeys") || [])                    },                    selectedItemKeys: function(value, preserve, isDeselect, isSelectAll) {                        var that = this,                            keys,                            criteria,                            isFunctionCriteria,                            deferred,                            dataController = that.getController('data'),                            dataSource = dataController.dataSource(),                            store = dataSource && dataSource.store(),                            dataSourceFilter,                            filter,                            deselectItems = [];                        if (utils.isDefined(value)) {                            if (store) {                                keys = $.isArray(value) ? $.extend([], value) : [value];                                if (keys.length || isSelectAll) {                                    criteria = createSelectedItemsFilterCriteria(dataSource, keys, isSelectAll);                                    isFunctionCriteria = $.isFunction(criteria);                                    if (criteria || isSelectAll) {                                        if (isSelectAll)                                            dataSourceFilter = dataController.getCombinedFilter();                                        if (criteria && !isFunctionCriteria && dataSourceFilter) {                                            filter = [];                                            filter.push(criteria);                                            filter.push(dataSourceFilter)                                        }                                        else if (dataSourceFilter)                                            filter = dataSourceFilter;                                        else if (criteria && !isFunctionCriteria)                                            filter = criteria;                                        deferred = $.Deferred();                                        if (isDeselect)                                            new DX.data.ArrayStore(that._selectedItems).load({filter: filter}).done(function(items) {                                                deselectItems = items                                            });                                        dataController.setSelectionLoading(true);                                        $.when(deselectItems.length ? deselectItems : store.load({filter: filter})).done(function(items) {                                            new DX.data.ArrayStore(items).load({filter: criteria}).done(deferred.resolve)                                        }).fail($.proxy(deferred.reject, deferred)).always(function() {                                            dataController.setSelectionLoading(false)                                        })                                    }                                }                            }                            deferred = deferred || $.Deferred().resolve([]);                            deferred.done(function(items) {                                var i,                                    key,                                    item,                                    keys = [];                                if (store && items.length > 0)                                    for (i = 0; i < items.length; i++) {                                        item = items[i];                                        key = store.keyOf(item);                                        if (preserve)                                            if (isDeselect)                                                removeSelectedItem(that, key);                                            else                                                addSelectedItem(that, item);                                        else                                            keys.push(key)                                    }                                if (!preserve)                                    setSelectedItems(that, keys, items);                                updateSelectedItems(that)                            });                            return deferred                        }                        else                            return that._selectedItemKeys                    },                    getSelectedRowKeys: function() {                        return this.selectedItemKeys()                    },                    selectRows: function(keys, preserve) {                        return this.selectedItemKeys(keys, preserve)                    },                    deselectRows: function(keys) {                        return this.selectedItemKeys(keys, true, true)                    },                    selectRowsByIndexes: function(indexes) {                        var items = this.getController('data').items(),                            keys = [];                        if (!utils.isArray(indexes))                            indexes = Array.prototype.slice.call(arguments, 0);                        $.each(indexes, function() {                            var item = items[this];                            if (item && item.rowType === 'data')                                keys.push(item.key)                        });                        return this.selectRows(keys)                    },                    getSelectedRowsData: function() {                        return this._selectedItems                    },                    changeItemSelection: function(itemIndex, keys) {                        var that = this,                            dataController = that.getController('data'),                            items = dataController.items(),                            item = items[itemIndex],                            itemData = item && item.data,                            selectionMode = that.option(SELECTION_MODE),                            isSelectedItemsChanged,                            isSelected,                            itemKey;                        if (isSelectable(selectionMode) && isDataItem(item)) {                            itemKey = dataController.keyOf(itemData);                            keys = keys || {};                            if (that.isSelectionWithCheckboxes())                                keys.control = true;                            if (keys.shift && selectionMode === 'multiple' && that._focusedItemIndex >= 0)                                isSelectedItemsChanged = changeItemSelectionWhenShiftKeyPressed(that, itemIndex, items);                            else if (keys.control) {                                resetItemSelectionWhenShiftKeyPressed(that);                                isSelected = that.isRowSelected(itemKey);                                if (selectionMode === 'single')                                    clearSelectedItems(that);                                if (isSelected)                                    removeSelectedItem(that, itemKey);                                else                                    addSelectedItem(that, itemData);                                isSelectedItemsChanged = true                            }                            else {                                resetItemSelectionWhenShiftKeyPressed(that);                                if (that._selectedItemKeys.length !== 1 || !equalKeys(that._selectedItemKeys[0], itemKey)) {                                    setSelectedItems(that, [itemKey], [itemData]);                                    isSelectedItemsChanged = true                                }                            }                            if (isSelectedItemsChanged) {                                that._focusedItemIndex = itemIndex;                                updateSelectedItems(that);                                return true                            }                        }                        return false                    },                    focusedItemIndex: function(itemIndex) {                        var that = this;                        if (utils.isDefined(itemIndex))                            that._focusedItemIndex = itemIndex;                        else                            return that._focusedItemIndex                    },                    isSelectionWithCheckboxes: function() {                        var selectionMode = this.option(SELECTION_MODE),                            showCheckboxesMode = this.option(SHOW_CHECKBOXES_MODE);                        return selectionMode === 'multiple' && (showCheckboxesMode === 'always' || this._isSelectionWithCheckboxes)                    },                    startSelectionWithCheckboxes: function() {                        var that = this,                            isSelectColumnVisible = that.isSelectColumnVisible();                        if (that.option(SELECTION_MODE) === 'multiple' && !that.isSelectionWithCheckboxes()) {                            that._isSelectionWithCheckboxes = true;                            updateSelectColumn(that);                            if (isSelectColumnVisible === that.isSelectColumnVisible() && that.option(SHOW_CHECKBOXES_MODE) === 'onClick')                                updateSelectedItems(that);                            return true                        }                        return false                    },                    stopSelectionWithCheckboxes: function() {                        var that = this;                        if (that._isSelectionWithCheckboxes) {                            that._isSelectionWithCheckboxes = false;                            updateSelectColumn(that);                            return true                        }                        return false                    }                }        }());        $.extend(dataGrid.__internals, {DATAGRID_CHECKBOXES_HIDDEN_CLASS: DATAGRID_CHECKBOXES_HIDDEN_CLASS});        dataGrid.registerModule('selection', {            defaultOptions: function() {                return {                        selection: {                            mode: 'none',                            showCheckBoxesInMultipleMode: 'onClick',                            allowSelectAll: true                        },                        selectedRowKeys: []                    }            },            controllers: {selection: dataGrid.SelectionController},            extenders: {                controllers: {data: {                        setDataSource: function(dataSource) {                            this.callBase(dataSource);                            if (dataSource)                                this.getController('selection').refresh()                        },                        setSelectionLoading: function(isLoading) {                            this._isSelectionLoading = isLoading;                            this._fireLoadingChanged()                        },                        isLoading: function() {                            var isLoading = this.callBase();                            return isLoading || !!this._isSelectionLoading                        },                        pageIndex: function(value) {                            var that = this,                                dataSource = that._dataSource;                            if (dataSource && value && dataSource.pageIndex() !== value)                                that.getController('selection').focusedItemIndex(-1);                            return that.callBase(value)                        },                        _processDataItem: function() {                            var that = this,                                selectionController = that.getController('selection'),                                hasSelectColumn = selectionController.isSelectColumnVisible(),                                dataItem = this.callBase.apply(this, arguments);                            dataItem.isSelected = selectionController.isRowSelected(dataItem.key);                            if (hasSelectColumn && dataItem.values)                                dataItem.values[0] = dataItem.isSelected;                            return dataItem                        },                        refresh: function() {                            return $.when(this.getController('selection').refresh(), this.callBase.apply(this, arguments))                        }                    }},                views: {                    columnHeadersView: {                        _renderCore: function(options) {                            var that = this;                            that.getController('selection').selectionChanged.remove(that._selectionChangedHandler);                            that.callBase(options)                        },                        _getDefaultTemplate: function(column) {                            var that = this,                                groupElement,                                selectionController = that.getController('selection'),                                dataController = that.getController('data');                            if (column.command === "select")                                return function($cell, options) {                                        var column = options.column;                                        if (column.command === 'select') {                                            $cell.addClass(DATAGRID_EDITOR_CELL_CLASS);                                            groupElement = $('<div />').appendTo($cell).addClass(DATAGRID_SELECT_CHECKBOX_CLASS);                                            that.setAria("label", Globalize.localize("dxDataGrid-ariaSelectAll"), $cell);                                            that.getController('editorFactory').createEditor(groupElement, $.extend({}, column, {                                                parentType: "headerRow",                                                value: selectionController.isSelectAll(),                                                setValue: function(value, e) {                                                    if (e.jQueryEvent && selectionController.isSelectAll() !== value) {                                                        if (e.previousValue === undefined || e.previousValue) {                                                            selectionController.deselectAll();                                                            e.component.option('value', false)                                                        }                                                        if (e.previousValue === false)                                                            if (that.option("selection.allowSelectAll"))                                                                selectionController.selectAll();                                                            else                                                                e.component.option('value', false);                                                        e.jQueryEvent.preventDefault()                                                    }                                                }                                            }));                                            $cell.on('dxclick', that.createAction(function(e) {                                                var event = e.jQueryEvent;                                                if (!$(event.target).closest('.' + DATAGRID_SELECT_CHECKBOX_CLASS).length)                                                    $(event.currentTarget).children().trigger('dxclick');                                                event.preventDefault()                                            }));                                            that._selectionChangedHandler = function() {                                                if (that.option("selection.mode") === "multiple")                                                    groupElement.dxCheckBox("instance").option("value", selectionController.isSelectAll())                                            };                                            that._dataChangedHandler = function(e) {                                                if (!e || e.changeType === "refresh")                                                    that._selectionChangedHandler()                                            };                                            dataController.changed.add(that._dataChangedHandler);                                            selectionController.selectionChanged.add(that._selectionChangedHandler)                                        }                                    };                            else                                return that.callBase(column)                        }                    },                    rowsView: {                        _getDefaultTemplate: function(column) {                            var that = this,                                groupElement;                            if (column.command === 'select')                                return function(container, options) {                                        if (options.rowType === 'data' && !options.row.inserted) {                                            container.addClass(DATAGRID_EDITOR_CELL_CLASS);                                            container.on('dxclick', that.createAction(function(e) {                                                var selectionController = that.getController('selection'),                                                    event = e.jQueryEvent,                                                    rowIndex = that.getRowIndex($(event.currentTarget).closest('.' + DATAGRID_ROW_CLASS));                                                if (rowIndex >= 0) {                                                    selectionController.startSelectionWithCheckboxes();                                                    selectionController.changeItemSelection(rowIndex, {shift: event.shiftKey})                                                }                                            }));                                            that.setAria("label", Globalize.localize("dxDataGrid-ariaSelectRow"), container);                                            groupElement = $('<div />').addClass(DATAGRID_SELECT_CHECKBOX_CLASS).appendTo(container);                                            that.getController('editorFactory').createEditor(groupElement, $.extend({}, column, {                                                parentType: "dataRow",                                                value: options.value,                                                setValue: function(value, e) {                                                    if (e && e.jQueryEvent && e.jQueryEvent.type === 'keydown')                                                        container.trigger('dxclick', e)                                                }                                            }))                                        }                                    };                            else                                return that.callBase(column)                        },                        _update: function(change) {                            var that = this,                                tableElements = that._getTableElements();                            if (change.changeType === 'updateSelection') {                                if (tableElements.length > 0) {                                    $.each(tableElements, function(_, tableElement) {                                        $.each(change.itemIndexes || [], function(_, index) {                                            var $row,                                                isSelected;                                            if (change.items[index]) {                                                $row = that._getRowElements($(tableElement)).eq(index);                                                isSelected = !!change.items[index].isSelected;                                                $row.toggleClass(DATAGRID_ROW_SELECTION_CLASS, isSelected).find('.' + DATAGRID_SELECT_CHECKBOX_CLASS).dxCheckBox('option', 'value', isSelected);                                                that.setAria("selected", isSelected, $row)                                            }                                        })                                    });                                    that._updateCheckboxesClass()                                }                            }                            else                                that.callBase(change)                        },                        _createTable: function() {                            var that = this,                                selectionMode = that.option("selection.mode"),                                $table = that.callBase.apply(that, arguments);                            if (selectionMode !== "none")                                $table.on(events.addNamespace("dxhold", "dxDataGridRowsView"), "." + DATAGRID_DATA_ROW_CLASS, that.createAction(function(e) {                                    var selectionController = that.getController('selection'),                                        event = e.jQueryEvent,                                        rowIndex = $(event.target).closest("." + DATAGRID_DATA_ROW_CLASS).index();                                    if (that.option(SHOW_CHECKBOXES_MODE) === 'onLongTap')                                        if (selectionController.isSelectionWithCheckboxes())                                            selectionController.stopSelectionWithCheckboxes();                                        else                                            selectionController.startSelectionWithCheckboxes();                                    else {                                        if (that.option(SHOW_CHECKBOXES_MODE) === 'onClick')                                            selectionController.startSelectionWithCheckboxes();                                        selectionController.changeItemSelection(rowIndex, {control: true})                                    }                                })).on('mousedown selectstart', that.createAction(function(e) {                                    var event = e.jQueryEvent;                                    if (event.shiftKey)                                        event.preventDefault()                                }));                            return $table                        },                        _createRow: function(row) {                            var $row = this.callBase(row),                                isSelected;                            if (row) {                                isSelected = !!row.isSelected;                                $row.toggleClass(DATAGRID_ROW_SELECTION_CLASS, isSelected);                                this.setAria("selected", isSelected, $row)                            }                            return $row                        },                        _rowClick: function(e) {                            var that = this,                                jQueryEvent = e.jQueryEvent,                                isCommandSelect = $(jQueryEvent.target).closest("." + DATAGRID_COMMAND_SELECT_CLASS).length,                                isSelectionDisabled = $(jQueryEvent.target).closest("." + DATAGRID_SELECTION_DISABLED_CLASS).length;                            if (!isCommandSelect) {                                if (!isSelectionDisabled)                                    if (that.getController('selection').changeItemSelection(e.rowIndex, {                                        control: jQueryEvent.ctrlKey,                                        shift: jQueryEvent.shiftKey                                    })) {                                        jQueryEvent.preventDefault();                                        e.handled = true                                    }                                that.callBase(e)                            }                        },                        _renderCore: function(change) {                            this.callBase(change);                            this._updateCheckboxesClass()                        },                        _updateCheckboxesClass: function() {                            var tableElements = this._getTableElements(),                                selectionController = this.getController('selection'),                                isCheckBoxesHidden = selectionController.isSelectColumnVisible() && !selectionController.isSelectionWithCheckboxes();                            $.each(tableElements, function(_, tableElement) {                                $(tableElement).toggleClass(DATAGRID_CHECKBOXES_HIDDEN_CLASS, isCheckBoxesHidden)                            })                        }                    }                }            }        })    })(jQuery, DevExpress);    /*! Module widgets-web, file ui.dataGrid.editorFactory.js */    (function($, DX) {        var dataGrid = DX.ui.dxDataGrid,            utils = DX.utils,            addNamespace = DX.ui.events.addNamespace;        var DATAGRID_CHECKBOX_SIZE_CLASS = "dx-datagrid-checkbox-size",            DATAGRID_CELL_FOCUS_DISABLED_CLASS = "dx-cell-focus-disabled",            DATAGRID_MODULE_NAMESPACE = 'dxDataGridEditorFactory',            DATAGRID_UPDATE_FOCUS_EVENTS = addNamespace('focusin dxpointerdown dxclick', DATAGRID_MODULE_NAMESPACE),            DATAGRID_FOCUS_OVERLAY_CLASS = 'dx-datagrid-focus-overlay',            DATAGRID_FOCUSED_ELEMENT_CLASS = 'dx-focused',            DATAGRID_CONTENT_CLASS = 'dx-datagrid-content',            DATAGRID_POINTER_EVENTS_TARGET_CLASS = "dx-pointer-events-target",            DATAGRID_POINTER_EVENTS_NONE_CLASS = "dx-pointer-events-none",            DX_HIDDEN = "dx-hidden",            TAB_KEY = 9;        dataGrid.EditorFactoryController = dataGrid.ViewController.inherit(function() {            var getResultConfig = function(config, options) {                    return $.extend(config, {                            readOnly: options.readOnly,                            rtlEnabled: options.rtlEnabled,                            disabled: options.disabled                        })                };            var getTextEditorConfig = function(options) {                    return getResultConfig({                            placeholder: options.placeholder,                            width: options.width,                            value: options.value,                            onValueChanged: function(e) {                                var updateValue = function(e) {                                        options && options.setValue(e.value)                                    };                                window.clearTimeout(e.component._valueChangeTimeoutID);                                if (e.jQueryEvent && e.jQueryEvent.type === 'keyup')                                    e.component._valueChangeTimeoutID = window.setTimeout(function() {                                        updateValue(e)                                    }, utils.isDefined(options.updateValueTimeout) ? options.updateValueTimeout : 0);                                else                                    updateValue(e)                            },                            valueChangeEvent: 'change' + (options.parentType === 'filterRow' ? ' keyup' : '')                        }, options)                };            var prepareDateBox = function(options) {                    options.editorName = "dxDateBox";                    options.editorOptions = getResultConfig({                        value: options.value,                        pickerType: "calendar",                        customOverlayCssClass: 'dx-datagrid',                        onValueChanged: function(args) {                            options.setValue(args.value)                        },                        formatString: DX.utils.isString(options.format) && DX.DateTimeFormat[options.format.toLowerCase()] || options.format,                        formatWidthCalculator: null,                        width: "auto"                    }, options)                };            var prepareTextBox = function(options) {                    var config = getTextEditorConfig(options),                        isSearching = options.parentType === 'searchPanel',                        toString = function(value) {                            return DX.utils.isDefined(value) ? value.toString() : ''                        };                    config.value = toString(options.value);                    config.valueChangeEvent += isSearching ? ' keyup search' : '';                    config.mode = isSearching ? 'search' : 'text';                    options.editorName = "dxTextBox";                    options.editorOptions = config                };            var prepareNumberBox = function(options) {                    var config = getTextEditorConfig(options);                    config.value = utils.isDefined(options.value) ? options.value : null;                    options.editorName = "dxNumberBox";                    options.editorOptions = config                };            var prepareBooleanEditor = function(options) {                    if (options.parentType === 'filterRow')                        prepareSelectBox($.extend(options, {lookup: {                                displayExpr: function(data) {                                    if (data === true)                                        return options.trueText || 'true';                                    else if (data === false)                                        return options.falseText || 'false'                                },                                dataSource: [true, false],                                rtlEnabled: options.rtlEnabled,                                disabled: options.disabled                            }}));                    else                        prepareCheckBox(options)                };            var prepareSelectBox = function(options) {                    var lookup = options.lookup,                        displayGetter,                        dataSource,                        postProcess,                        isFilterRow = options.parentType === "filterRow";                    if (lookup) {                        displayGetter = DX.data.utils.compileGetter(lookup.displayExpr);                        if (utils.isObject(lookup.dataSource) || utils.isArray(lookup.dataSource)) {                            dataSource = DX.data.utils.normalizeDataSourceOptions(lookup.dataSource);                            if (isFilterRow) {                                postProcess = dataSource.postProcess;                                dataSource.postProcess = function(items) {                                    if (this.pageIndex() === 0) {                                        items = items.slice(0);                                        items.unshift(null)                                    }                                    if (postProcess)                                        return postProcess.call(this, items);                                    return items                                }                            }                        }                        options.editorName = "dxSelectBox";                        options.editorOptions = getResultConfig({                            searchEnabled: true,                            value: options.value,                            valueExpr: options.lookup.valueExpr,                            showClearButton: lookup.allowClearing && !isFilterRow,                            displayExpr: function(data) {                                if (data === null)                                    return options.showAllText;                                return displayGetter(data)                            },                            dataSource: dataSource,                            onValueChanged: function(e) {                                options.setValue(e.value, e)                            }                        }, options)                    }                };            var prepareCheckBox = function(options) {                    options.editorName = "dxCheckBox";                    options.editorOptions = getResultConfig({                        value: options.value,                        onValueChanged: function(e) {                            options.setValue && options.setValue(e.value, e)                        }                    }, options)                };            var createEditorCore = function(options) {                    if (options.editorName && options.editorOptions && options.editorElement[options.editorName]) {                        if (options.editorName === "dxCheckBox")                            options.editorElement.addClass(DATAGRID_CHECKBOX_SIZE_CLASS);                        options.editorElement[options.editorName](options.editorOptions);                        if (options.editorName === "dxTextBox")                            options.editorElement.dxTextBox("instance").registerKeyHandler("enter", $.noop)                    }                };            return {                    _getFocusedElement: function($dataGridElement) {                        return $dataGridElement.find('[tabindex]:focus, input:focus')                    },                    _updateFocusCore: function() {                        var $focus = this._$focusedElement,                            $dataGridElement = this.component && this.component.element();                        if ($dataGridElement) {                            $focus = this._getFocusedElement($dataGridElement);                            if ($focus.length) {                                if (!$focus.hasClass(DATAGRID_CELL_FOCUS_DISABLED_CLASS))                                    $focus = $focus.closest('.dx-row > td, .' + DATAGRID_CELL_FOCUS_DISABLED_CLASS);                                if ($focus.length && !$focus.hasClass(DATAGRID_CELL_FOCUS_DISABLED_CLASS)) {                                    this.focus($focus);                                    return                                }                            }                        }                        this.loseFocus()                    },                    _updateFocus: function(e) {                        var that = this,                            isFocusOverlay = e && e.jQueryEvent && $(e.jQueryEvent.target).hasClass(DATAGRID_FOCUS_OVERLAY_CLASS);                        that._isFocusOverlay = that._isFocusOverlay || isFocusOverlay;                        clearTimeout(that._updateFocusTimeoutID);                        that._updateFocusTimeoutID = setTimeout(function() {                            delete that._updateFocusTimeoutID;                            if (!that._isFocusOverlay)                                that._updateFocusCore();                            that._isFocusOverlay = false                        })                    },                    _updateFocusOverlaySize: function($element, position) {                        var location = DX.calculatePosition($element, position);                        if (location.h.oversize > 0)                            $element.outerWidth($element.outerWidth() - location.h.oversize);                        if (location.v.oversize > 0)                            $element.outerHeight($element.outerHeight() - location.v.oversize)                    },                    callbackNames: function() {                        return ["focused"]                    },                    focus: function($element, hideBorder) {                        var that = this;                        if ($element === undefined)                            return that._$focusedElement;                        else if ($element)                            setTimeout(function() {                                var $focusOverlay = that._$focusOverlay = that._$focusOverlay || $('<div>').addClass(DATAGRID_FOCUS_OVERLAY_CLASS + " " + DATAGRID_POINTER_EVENTS_TARGET_CLASS),                                    focusOverlayPosition;                                if (hideBorder)                                    that._$focusOverlay && that._$focusOverlay.addClass(DX_HIDDEN);                                else {                                    var align = DevExpress.browser.mozilla ? "right bottom" : "left top",                                        $content = $element.closest('.' + DATAGRID_CONTENT_CLASS);                                    $focusOverlay.removeClass(DX_HIDDEN).appendTo($content).outerWidth($element.outerWidth() + 1).outerHeight($element.outerHeight() + 1);                                    focusOverlayPosition = {                                        my: align,                                        at: align,                                        of: $element,                                        boundary: $content.length && $content                                    };                                    that._updateFocusOverlaySize($focusOverlay, focusOverlayPosition);                                    DX.position($focusOverlay, focusOverlayPosition);                                    $focusOverlay.css('visibility', 'visible')                                }                                that._$focusedElement && that._$focusedElement.removeClass(DATAGRID_FOCUSED_ELEMENT_CLASS);                                $element.addClass(DATAGRID_FOCUSED_ELEMENT_CLASS);                                that._$focusedElement = $element;                                that.focused.fire($element)                            })                    },                    resize: function() {                        var $focusedElement = this._$focusedElement;                        if ($focusedElement)                            this.focus($focusedElement)                    },                    loseFocus: function() {                        this._$focusedElement && this._$focusedElement.removeClass(DATAGRID_FOCUSED_ELEMENT_CLASS);                        this._$focusedElement = null;                        this._$focusOverlay && this._$focusOverlay.addClass(DX_HIDDEN)                    },                    init: function() {                        this.createAction("onEditorPreparing", {                            excludeValidators: ["designMode", "disabled", "readOnly"],                            category: "rendering"                        });                        this.createAction("onEditorPrepared", {                            excludeValidators: ["designMode", "disabled", "readOnly"],                            category: "rendering"                        });                        this._updateFocusHandler = this._updateFocusHandler || this.createAction($.proxy(this._updateFocus, this));                        $(document).on(DATAGRID_UPDATE_FOCUS_EVENTS, this._updateFocusHandler);                        this._attachContainerEventHandlers()                    },                    _attachContainerEventHandlers: function() {                        var that = this,                            $container = that.component && that.component.element(),                            isIE10OrLower = DX.browser.msie && parseInt(DX.browser.version) < 11;                        if ($container) {                            $container.on(addNamespace('keydown', DATAGRID_MODULE_NAMESPACE), function(e) {                                if (e.which === TAB_KEY)                                    that._updateFocusHandler(e)                            });                            isIE10OrLower && $container.on('dxclick dxpointerup dxpointerdown', "." + DATAGRID_POINTER_EVENTS_TARGET_CLASS, $.proxy(that._focusOverlayEventProxy, that))                        }                    },                    _focusOverlayEventProxy: function(e) {                        var $target = $(e.target),                            $currentTarget = $(e.currentTarget),                            element,                            needProxy = $target.hasClass(DATAGRID_POINTER_EVENTS_TARGET_CLASS) || $target.hasClass(DATAGRID_POINTER_EVENTS_NONE_CLASS),                            $focusedElement = this._$focusedElement;                        if (!needProxy || $currentTarget.hasClass(DX_HIDDEN))                            return;                        $currentTarget.addClass(DX_HIDDEN);                        element = $target.get(0).ownerDocument.elementFromPoint(e.clientX, e.clientY);                        $(element).trigger(jQuery.Event(e.type, {                            clientX: e.clientX,                            clientY: e.clientY                        }));                        $currentTarget.removeClass(DX_HIDDEN);                        $focusedElement && $focusedElement.find('input').focus()                    },                    dispose: function() {                        clearTimeout(this._updateFocusTimeoutID);                        $(document).off(DATAGRID_UPDATE_FOCUS_EVENTS, this._updateFocusHandler)                    },                    createEditor: function($container, options) {                        this.component._suppressDeprecatedWarnings();                        var editorPreparing = this.option("editorPreparing"),                            editorPrepared = this.option("editorPrepared");                        this.component._resumeDeprecatedWarnings();                        options.rtlEnabled = this.option('rtlEnabled');                        options.disabled = options.disabled || this.option("disabled");                        options.cancel = false;                        options.editorElement = $container;                        if (options.lookup)                            prepareSelectBox(options);                        else                            switch (options.dataType) {                                case'date':                                    prepareDateBox(options);                                    break;                                case'boolean':                                    prepareBooleanEditor(options);                                    break;                                case'number':                                    prepareNumberBox(options);                                    break;                                default:                                    prepareTextBox(options);                                    break                            }                        editorPreparing && editorPreparing($container, options);                        this.executeAction("onEditorPreparing", options);                        if (options.cancel)                            return;                        createEditorCore(options);                        editorPrepared && editorPrepared($container, options);                        this.executeAction("onEditorPrepared", options)                    }                }        }());        $.extend(dataGrid.__internals, {DATAGRID_FOCUSED_ELEMENT_CLASS: DATAGRID_FOCUSED_ELEMENT_CLASS});        dataGrid.registerModule('editorFactory', {            defaultOptions: function() {                return {}            },            controllers: {editorFactory: dataGrid.EditorFactoryController}        })    })(jQuery, DevExpress);    /*! Module widgets-web, file ui.dataGrid.columnsView.js */    (function($, DX, undefined) {        var ui = DX.ui,            utils = DX.utils,            dataGrid = ui.dxDataGrid;        var DATAGRID_SCROLL_CONTAINER_CLASS = "dx-datagrid-scroll-container",            DATAGRID_ROW_CLASS = "dx-row",            DATAGRID_GROUP_SPACE_CLASS = "dx-datagrid-group-space",            DATAGRID_GROUP_ROW_CLASS = "dx-group-row",            DATAGRID_CONTENT_CLASS = "dx-datagrid-content",            DATAGRID_TABLE_CLASS = "dx-datagrid-table",            DATAGRID_CELL_CONTENT_CLASS = "dx-datagrid-text-content",            DATAGRID_COLUMN_INDICATORS_CLASS = "dx-column-indicators",            DATAGRID_TABLE_FIXED_CLASS = "dx-datagrid-table-fixed",            DATAGRID_INDICATOR_ALIGNMENT_CLASS = "dx-indicator-alignment-",            DATAGRID_HEADER_ROW_CLASS = "dx-header-row",            DATAGRID_CELL_HINT_VISIBLE = "dxCellHintVisible",            indicatorNamesClass = {                sort: "dx-sort",                headerFilter: "dx-header-filter"            };        var appendElementTemplate = {render: function(element, container) {                    container.append(element)                }};        dataGrid.getWidths = function($tableElement) {            var cells,                result = [],                width,                clientRect;            if ($tableElement) {                cells = $tableElement.children('tbody').children('tr').filter(':not(.' + DATAGRID_GROUP_ROW_CLASS + ')').first().find('td');                $.each(cells, function(index, item) {                    width = $(item).outerWidth(true);                    if (item.getBoundingClientRect) {                        clientRect = item.getBoundingClientRect();                        if (clientRect.width > width)                            width = Math.ceil(clientRect.width)                    }                    result.push(width)                })            }            return result        };        dataGrid.ColumnsView = dataGrid.View.inherit({            _getColumnAlignment: function(alignment) {                var rtlEnabled = this.option('rtlEnabled');                return alignment !== 'center' ? alignment : rtlEnabled ? 'right' : 'left'            },            _applyColumnState: function(options) {                var that = this,                    $span,                    columnAlignment,                    indicatorAlignment,                    column = options.column,                    $rootElement = options.rootElement,                    $indicatorsContainer = $rootElement.find("." + DATAGRID_COLUMN_INDICATORS_CLASS),                    nameClass = indicatorNamesClass[options.name],                    getIndicatorAlignment = function(columnAlignment) {                        return columnAlignment === 'right' ? 'left' : 'right'                    };                columnAlignment = that._getColumnAlignment(column.alignment);                indicatorAlignment = getIndicatorAlignment(columnAlignment);                $span = $('<span />').addClass(nameClass);                if (!$indicatorsContainer.length)                    $indicatorsContainer = $("<div/>").addClass(DATAGRID_COLUMN_INDICATORS_CLASS);                $indicatorsContainer.append($span).css('float', options.showColumnLines ? indicatorAlignment : column.alignment !== 'center' ? columnAlignment : null);                if (!options.showColumnLines)                    $indicatorsContainer.addClass(DATAGRID_INDICATOR_ALIGNMENT_CLASS + columnAlignment).appendTo($rootElement);                else                    $indicatorsContainer.prependTo($rootElement);                return $span            },            _updateIndicatorHeights: function(indicatorName) {                var that = this,                    columnElements = that.getColumnElements(),                    $cell,                    i;                if (columnElements)                    for (i = 0; i < columnElements.length; i++) {                        $cell = columnElements.eq(i);                        that._updateIndicatorHeight($cell, indicatorName)                    }            },            _updateIndicatorHeight: function($cell, indicatorName) {                var $textContent = $cell.find('.' + DATAGRID_CELL_CONTENT_CLASS),                    $indicator = $cell.find('.' + indicatorNamesClass[indicatorName]);                if ($indicator.length) {                    $indicator.height("auto");                    $indicator.height($textContent.height() || $cell.height())                }            },            _updateIndicators: function(indicatorName) {                var that = this,                    columns = that.getColumns(),                    $cells = that.getColumnElements(),                    i;                for (i = 0; i < columns.length; i++)                    that._updateIndicator($cells.eq(i), columns[i], indicatorName);                that._updateIndicatorHeights(indicatorName)            },            _updateIndicator: function($cell, column, indicatorName) {                if (!column.command)                    return this._applyColumnState({                            name: indicatorName,                            rootElement: $cell,                            column: column,                            showColumnLines: this.option('showColumnLines')                        })            },            _updateCell: function($cell, parameters) {                if (parameters.rowType)                    this._cellPrepared($cell, parameters)            },            _createCell: function(column) {                return $("<td/>").css('text-align', column.alignment || 'left').toggleClass(column.cssClass, !utils.isDefined(column.groupIndex)).attr('role', 'gridcell').toggleClass(DATAGRID_GROUP_SPACE_CLASS, column.command === "expand")            },            _createRow: function(row) {                return $("<tr />").addClass(DATAGRID_ROW_CLASS).attr('role', 'row')            },            _createTable: function(columns) {                var that = this,                    $table = $('<table />').addClass(DATAGRID_TABLE_CLASS).addClass(DATAGRID_TABLE_FIXED_CLASS).attr('role', 'grid');                if (columns) {                    $table.append(that._createColGroup(columns));                    if (DX.devices.real().ios)                        $table.append("<thead><tr></tr></thead>")                }                if (that.option("cellHintEnabled"))                    $table.on("mousemove", ".dx-row > td", this.createAction(function(args) {                        var e = args.jQueryEvent,                            $element = $(e.target),                            $cell = $(e.currentTarget),                            $row = $cell.parent(),                            isDataRow = $row.hasClass('dx-data-row'),                            $cells = $row.children(),                            visibleColumns = that._columnsController.getVisibleColumns(),                            visibleColumnIndex = $cells.index($cell),                            column = visibleColumns[visibleColumnIndex];                        if (!isDataRow || isDataRow && column && !column.cellTemplate) {                            if ($element.data(DATAGRID_CELL_HINT_VISIBLE)) {                                $element.removeAttr("title");                                $element.data(DATAGRID_CELL_HINT_VISIBLE, false)                            }                            if ($element[0].scrollWidth > $element[0].clientWidth && !$element.attr("title")) {                                $element.attr("title", $element.text());                                $element.data(DATAGRID_CELL_HINT_VISIBLE, true)                            }                        }                    }));                return $table            },            _createColGroup: function(columns) {                var i,                    j,                    colgroupElement = $('<colgroup />'),                    colspan,                    columnsLength = columns.length;                for (i = 0; i < columnsLength; i++) {                    colspan = columns[i].colspan || 1;                    for (j = 0; j < colspan; j++)                        colgroupElement.append(this._createCol(columns[i]))                }                return colgroupElement            },            _createCol: function(column) {                return $('<col />').width(column.visibleWidth || column.width)            },            renderDelayedTemplates: function() {                var templateParameters,                    delayedTemplates = this._delayedTemplates;                while (delayedTemplates.length) {                    templateParameters = delayedTemplates.shift();                    templateParameters.template.render(templateParameters.options, templateParameters.container);                    if (templateParameters.options.column)                        this._updateCell(templateParameters.container, templateParameters.options)                }            },            _processTemplate: function(template, options) {                var that = this,                    renderingTemplate;                if ($.isFunction(template))                    renderingTemplate = {render: function(options, container) {                            template(container, options)                        }};                else {                    if (!that._templatesCache[template])                        that._templatesCache[template] = that.getTemplate(template);                    renderingTemplate = that._templatesCache[template]                }                return renderingTemplate            },            _renderTemplate: function(container, template, options) {                var that = this,                    renderingTemplate = that._processTemplate(template, options);                if (renderingTemplate)                    if (options.denyRenderToDetachedContainer || renderingTemplate.denyRenderToDetachedContainer)                        that._delayedTemplates.push({                            template: renderingTemplate,                            container: container,                            options: options                        });                    else {                        renderingTemplate.render(options, container);                        return true                    }                return false            },            _appendRow: function($table, $row) {                var that = this;                if (that.option("rowTemplate") && that._delayedTemplates.length && $row)                    that._delayedTemplates.push({                        container: $table,                        template: appendElementTemplate,                        options: $row                    });                else                    $table.append($row)            },            _renderCore: function(change) {                var $root = this.element().parent();                if (!$root || $root.parent().length)                    this.renderDelayedTemplates()            },            _renderTable: function(options) {                options = options || {};                var that = this,                    $table;                options.columns = that._columnsController.getVisibleColumns();                $table = that._createTable(options.columns);                that._renderRows($table, options);                return $table            },            _renderRows: function($table, options) {                var that = this,                    i,                    rows = that._getRows(options.change);                for (i = 0; i < rows.length; i++)                    that._renderRow($table, $.extend({row: rows[i]}, options))            },            _renderRow: function($table, options) {                var that = this,                    $row;                $row = that._createRow(options.row);                that._renderCells($row, options);                that._appendRow($table, $row);                that._rowPrepared($row, $.extend({columns: options.columns}, options.row))            },            _renderCells: function($row, options) {                var that = this,                    i,                    columnIndex = 0,                    row = options.row,                    columns = options.columns;                for (i = 0; i < columns.length; i++) {                    that._renderCell($row, $.extend({                        column: columns[i],                        columnIndex: columnIndex,                        value: row.values && row.values[columnIndex]                    }, options));                    if (utils.isDefined(columns[i].colspan))                        columnIndex += columns[i].colspan;                    else                        columnIndex++                }            },            _renderCell: function($row, options) {                var that = this,                    cellOptions = that._getCellOptions(options),                    column = options.column,                    $cell;                $cell = that._createCell(column);                if (!utils.isDefined(column.command))                    that.setAria("label", Globalize.localize("dxDataGrid-ariaColumn") + " " + column.caption + ", " + Globalize.localize("dxDataGrid-ariaValue") + " " + cellOptions.text, $cell);                that._renderCellContent($cell, cellOptions);                $row.append($cell);                return $cell            },            _renderCellContent: function($cell, options) {                var template = this._getCellTemplate(options);                if (!template || this._renderTemplate($cell, template, options))                    this._updateCell($cell, options)            },            _getCellTemplate: function(options){},            _getRows: function() {                return []            },            _getCellOptions: function(options) {                return {                        column: options.column,                        columnIndex: options.columnIndex,                        rowType: options.row.rowType                    }            },            _cellPrepared: function($cell, options) {                var that = this,                    cellPrepared,                    extendOptions = function(event) {                        return {                                cellElement: $(event.target).closest('td'),                                jQueryEvent: event,                                eventType: event.type                            }                    };                if (that.option("onCellClick"))                    $cell.on("dxclick", function(e) {                        that.executeAction("onCellClick", $.extend({}, options, extendOptions(e)))                    });                if (that.option("onCellHoverChanged")) {                    $cell.on("mouseover", function(e) {                        that.executeAction("onCellHoverChanged", $.extend({}, options, extendOptions(e)))                    });                    $cell.on("mouseout", function(e) {                        that.executeAction("onCellHoverChanged", $.extend({}, options, extendOptions(e)))                    })                }                this.component._suppressDeprecatedWarnings();                cellPrepared = that.option("cellPrepared");                this.component._resumeDeprecatedWarnings();                cellPrepared && cellPrepared($cell, options);                options.cellElement = $cell;                that.executeAction("onCellPrepared", options)            },            _rowPrepared: function($row, options) {                var that = this,                    rowPrepared;                this.component._suppressDeprecatedWarnings();                rowPrepared = that.option("rowPrepared");                this.component._resumeDeprecatedWarnings();                rowPrepared && rowPrepared($row, options);                options.rowElement = $row;                this.executeAction("onRowPrepared", options)            },            _columnOptionChanged: function(e) {                var optionNames = e.optionNames;                if (dataGrid.checkChanges(optionNames, ['width', 'visibleWidth'])) {                    var visibleColumns = this._columnsController.getVisibleColumns();                    var widths = $.map(visibleColumns, function(column) {                            return column.visibleWidth || column.width || 'auto'                        });                    this.setColumnWidths(widths);                    return                }                this.render()            },            _getTableElements: function() {                return this._tableElement || $()            },            _getTableElement: function() {                return this._tableElement            },            _setTableElement: function(tableElement) {                this._tableElement = tableElement            },            optionChanged: function(args) {                this.callBase(args);                switch (args.name) {                    case'cellHintEnabled':                    case'onCellPrepared':                    case'onRowPrepared':                    case'onCellHoverChanged':                        this.render();                        this.component.resize();                        args.handled = true;                        break                }            },            init: function() {                var that = this;                that._columnsController = that.getController('columns');                that._dataController = that.getController('data');                that._delayedTemplates = [];                that._templatesCache = {};                that.createAction("onCellClick");                that.createAction("onCellHoverChanged", {excludeValidators: ["disabled", "readOnly"]});                that.createAction("onCellPrepared", {                    excludeValidators: ["designMode", "disabled", "readOnly"],                    category: "rendering"                });                that.createAction("onRowPrepared", {                    excludeValidators: ["designMode", "disabled", "readOnly"],                    category: "rendering"                });                that._columnsController.columnsChanged.add($.proxy(that._columnOptionChanged, that));                that._dataController && that._dataController.changed.add($.proxy(that._handleDataChanged, that))            },            _handleDataChanged: function(e){},            scrollOffset: function(pos) {                var that = this,                    $element = that.element(),                    $scrollContainer = $element && $element.find('.' + DATAGRID_SCROLL_CONTAINER_CLASS);                if (pos === undefined)                    return $scrollContainer && $scrollContainer.scrollLeft();                else if (that._scrollLeft !== pos) {                    that._scrollLeft = pos;                    $scrollContainer && $scrollContainer.scrollLeft(pos)                }            },            wrapTableInScrollContainer: function($table) {                return $('<div/>').addClass(DATAGRID_CONTENT_CLASS).addClass(DATAGRID_SCROLL_CONTAINER_CLASS).append($table)            },            getColumnWidths: function() {                var that = this,                    result = [],                    tableElement = that._getTableElement();                if (tableElement)                    result = dataGrid.getWidths(tableElement);                return result            },            setColumnWidths: function(widths) {                var $cols,                    i,                    j,                    columnIndex,                    columns,                    tableElements = this._getTableElements(true);                if (tableElements.length && widths)                    for (i = 0; i < tableElements.length; i++) {                        columnIndex = 0;                        $cols = $(tableElements[i]).find('col');                        columns = this.getColumns($(tableElements[i]));                        for (j = 0; j < columns.length; j++) {                            if (columns[j].colspan) {                                columnIndex += columns[j].colspan;                                continue                            }                            $cols.eq(columnIndex).width(widths[columnIndex] || 'auto');                            columnIndex++                        }                    }            },            getCellElements: function(rowIndex) {                var $row = this._getRowElements().eq(rowIndex);                return $row.children()            },            getCellElement: function(rowIndex, columnIdentificator) {                var that = this,                    $cells = that.getCellElements(rowIndex),                    $cell,                    columnsController = that._columnsController,                    columnIndex,                    columnVisibleIndex = columnIdentificator;                if (utils.isString(columnIdentificator)) {                    columnIndex = columnsController.columnOption(columnIdentificator, 'index');                    columnVisibleIndex = columnsController.getVisibleIndex(columnIndex)                }                if ($cells.length && columnVisibleIndex >= 0)                    $cell = $cells.eq(columnVisibleIndex);                if ($cell && $cell.length)                    return $cell            },            getColumnElements: function(){},            getColumns: function() {                return this._columnsController.getVisibleColumns()            },            getCell: function(cellPosition) {                var row,                    tableElement = this._getTableElement();                if (tableElement && tableElement.length === 1) {                    row = tableElement[0].rows[cellPosition.rowIndex];                    return row ? $(row.cells[cellPosition.columnIndex]) : null                }            },            getRowsCount: function() {                var tableElement = this._getTableElement();                if (tableElement && tableElement.length === 1)                    return tableElement[0].rows.length;                return 0            },            _getRowElements: function(tableElement) {                tableElement = tableElement || this._getTableElement();                return tableElement && tableElement.children('tbody').children('.' + DATAGRID_ROW_CLASS) || $()            },            getRowIndex: function($row) {                return this._getRowElements().index($row)            },            getBoundingRect: function(){},            getName: function(){}        });        $.extend(dataGrid.__internals, {            DATAGRID_INDICATOR_ALIGNMENT_CLASS: DATAGRID_INDICATOR_ALIGNMENT_CLASS,            DATAGRID_GROUP_SPACE_CLASS: DATAGRID_GROUP_SPACE_CLASS,            DATAGRID_CELL_CONTENT_CLASS: DATAGRID_CELL_CONTENT_CLASS,            DATAGRID_ROW_CLASS: DATAGRID_ROW_CLASS,            DATAGRID_GROUP_ROW_CLASS: DATAGRID_GROUP_ROW_CLASS,            DATAGRID_TABLE_CLASS: DATAGRID_TABLE_CLASS,            DATAGRID_TABLE_FIXED_CLASS: DATAGRID_TABLE_FIXED_CLASS,            DATAGRID_SCROLL_CONTAINER_CLASS: DATAGRID_SCROLL_CONTAINER_CLASS,            DATAGRID_COLUMN_INDICATORS_CLASS: DATAGRID_COLUMN_INDICATORS_CLASS,            DATAGRID_HEADER_ROW_CLASS: DATAGRID_HEADER_ROW_CLASS        })    })(jQuery, DevExpress);    /*! Module widgets-web, file ui.dataGrid.columnChooserModule.js */    (function($, DX) {        var ui = DX.ui,            utils = DX.utils,            dataGrid = ui.dxDataGrid;        var DATAGRID_COLUMN_CHOOSER_CLASS = 'dx-datagrid-column-chooser',            DATAGRID_COLUMN_CHOOSER_BUTTON_CLASS = 'dx-datagrid-column-chooser-button',            DATAGRID_COLUMN_CHOOSER_ICON_NAME = 'column-chooser',            DATAGRID_COLUMN_CHOOSER_ITEM_CLASS = "dx-column-chooser-item",            DATAGRID_COLUMN_CHOOSER_MESSAGE_CLASS = "dx-column-chooser-message",            DATAGRID_HEADERS_DRAG_ACTION_CLASS = "dx-datagrid-drag-action";        dataGrid.ColumnChooserController = dataGrid.ViewController.inherit({            renderShowColumnChooserButton: function($element) {                var that = this,                    columnChooserEnabled = that.option("columnChooser.enabled"),                    $showColumnChooserButton = $element.find("." + DATAGRID_COLUMN_CHOOSER_BUTTON_CLASS),                    $columnChooserButton;                if (columnChooserEnabled)                    if (!$showColumnChooserButton.length) {                        $columnChooserButton = $('<div />').addClass(DATAGRID_COLUMN_CHOOSER_BUTTON_CLASS).appendTo($element);                        that._createComponent($columnChooserButton, "dxButton", {                            icon: DATAGRID_COLUMN_CHOOSER_ICON_NAME,                            onClick: function() {                                that.getView("columnChooserView").showColumnChooser()                            },                            hint: that.option("columnChooser.title"),                            _templates: {}                        })                    }                    else                        $showColumnChooserButton.show();                else                    $showColumnChooserButton.hide()            },            getPosition: function() {                var rowsView = this.getView("rowsView");                return {                        my: "right bottom",                        at: "right bottom",                        of: rowsView && rowsView.element(),                        collision: 'fit',                        offset: "-2 -2",                        boundaryOffset: "2 2"                    }            }        });        dataGrid.ColumnChooserView = dataGrid.ColumnsView.inherit({            _updateItems: function() {                var chooserColumns = this._columnsController.getChooserColumns(),                    columnChooserOptions = this.option("columnChooser"),                    $content = this._popupContainer.content(),                    scrollableInstance = this._createComponent($content, "dxScrollable", dataGrid.createScrollableOptions(this));                this._renderColumnChooserItems($content, chooserColumns);                if (!chooserColumns.length)                    $('<span />').addClass(DATAGRID_COLUMN_CHOOSER_MESSAGE_CLASS).text(columnChooserOptions ? columnChooserOptions.emptyPanelText : "").appendTo(scrollableInstance.content())            },            _initializePopupContainer: function() {                var that = this,                    $element = that.element().addClass(DATAGRID_COLUMN_CHOOSER_CLASS),                    columnChooserOptions = that.option("columnChooser"),                    theme = DevExpress.ui.themes.current(),                    isGenericTheme = theme && theme.indexOf("generic") > -1,                    isAndroid5Theme = theme && theme.indexOf("android5") > -1,                    dxPopupOptions = {                        visible: false,                        shading: false,                        showCloseButton: false,                        dragEnabled: true,                        buttons: [{                                text: columnChooserOptions.title,                                toolbar: "top",                                location: isGenericTheme || isAndroid5Theme ? "before" : "center"                            }],                        position: that.getController("columnChooser").getPosition(),                        width: columnChooserOptions.width,                        height: columnChooserOptions.height,                        rtlEnabled: that.option('rtlEnabled'),                        container: columnChooserOptions.container                    };                if (isGenericTheme)                    $.extend(dxPopupOptions, {showCloseButton: true});                else                    dxPopupOptions.buttons[dxPopupOptions.buttons.length] = {shortcut: "cancel"};                if (!utils.isDefined(this._popupContainer)) {                    that._popupContainer = that._createComponent($element, "dxPopup", dxPopupOptions);                    that._popupContainer.on("optionChanged", function(args) {                        if (args.name === "visible")                            that.renderCompleted.fire()                    })                }                else                    this._popupContainer.option(dxPopupOptions)            },            _renderCore: function() {                if (this._popupContainer)                    this._updateItems()            },            _renderColumnChooserItems: function($container, chooserColumns) {                var dxScrollable = $container.dxScrollable("instance"),                    $scrollableContainer = dxScrollable.content(),                    $item;                $scrollableContainer.empty();                $.each(chooserColumns, function(index, chooserColumn) {                    $item = $('<div />').addClass(chooserColumn.cssClass).addClass(DATAGRID_COLUMN_CHOOSER_ITEM_CLASS).toggleClass(DATAGRID_HEADERS_DRAG_ACTION_CLASS, chooserColumn.allowHiding).text(chooserColumn.caption).appendTo($scrollableContainer)                });                dxScrollable.update()            },            getColumnElements: function() {                var $content = this._popupContainer && this._popupContainer.content();                return $content && $content.find('.' + DATAGRID_COLUMN_CHOOSER_ITEM_CLASS)            },            getName: function() {                return 'columnChooser'            },            getColumns: function() {                return this._columnsController.getChooserColumns()            },            allowDragging: function(column) {                return this.isColumnChooserVisible() && column && column.allowHiding            },            getBoundingRect: function() {                var that = this,                    container = that._popupContainer && that._popupContainer._container(),                    offset;                if (container && container.is(':visible')) {                    offset = container.offset();                    return {                            left: offset.left,                            top: offset.top,                            right: offset.left + container.outerWidth(),                            bottom: offset.top + container.outerHeight()                        }                }                return null            },            showColumnChooser: function() {                this._isPopupContainerShown = true;                if (!this._popupContainer) {                    this._initializePopupContainer();                    this.render()                }                this._popupContainer.show()            },            hideColumnChooser: function() {                if (this._popupContainer) {                    this._popupContainer.hide();                    this._isPopupContainerShown = false                }            },            isColumnChooserVisible: function() {                var popupContainer = this._popupContainer;                return popupContainer && popupContainer.option("visible")            },            publicMethods: function() {                return ['showColumnChooser', 'hideColumnChooser']            }        });        $.extend(dataGrid.__internals, {            DATAGRID_COLUMN_CHOOSER_CLASS: DATAGRID_COLUMN_CHOOSER_CLASS,            DATAGRID_COLUMN_CHOOSER_ITEM_CLASS: DATAGRID_COLUMN_CHOOSER_ITEM_CLASS,            DATAGRID_COLUMN_CHOOSER_BUTTON_CLASS: DATAGRID_COLUMN_CHOOSER_BUTTON_CLASS,            DATAGRID_COLUMN_CHOOSER_MESSAGE_CLASS: DATAGRID_COLUMN_CHOOSER_MESSAGE_CLASS        });        dataGrid.registerModule('columnChooser', {            defaultOptions: function() {                return {columnChooser: {                            enabled: false,                            width: 250,                            height: 260,                            title: Globalize.localize("dxDataGrid-columnChooserTitle"),                            emptyPanelText: Globalize.localize("dxDataGrid-columnChooserEmptyText"),                            container: undefined                        }}            },            controllers: {columnChooser: dataGrid.ColumnChooserController},            views: {columnChooserView: dataGrid.ColumnChooserView},            extenders: {views: {headerPanel: {                        _renderShowColumnChooserButton: function() {                            this.getController("columnChooser").renderShowColumnChooserButton(this.element())                        },                        _renderCore: function() {                            this.callBase();                            this._renderShowColumnChooserButton()                        },                        optionChanged: function(args) {                            switch (args.name) {                                case'columnChooser':                                    this._renderShowColumnChooserButton();                                    args.handled = true;                                    break;                                default:                                    this.callBase(args)                            }                        },                        isVisible: function() {                            var that = this,                                columnChooserEnabled = that.option('columnChooser.enabled');                            return that.callBase() || columnChooserEnabled                        }                    }}}        })    })(jQuery, DevExpress);    /*! Module widgets-web, file ui.dataGrid.editing.js */    (function($, DX) {        var dataGrid = DX.ui.dxDataGrid,            events = DX.ui.events,            addNamespace = events.addNamespace,            utils = DX.utils,            getIndexByKey = dataGrid.getIndexByKey;        var DATAGRID_LINK_CLASS = "dx-link",            DATAGRID_EDITOR_CELL_CLASS = "dx-editor-cell",            DATAGRID_ROW_SELECTED = "dx-selection",            DATAGRID_EDIT_ROW = "dx-edit-row",            DATAGRID_EDIT_BUTTON_CLASS = "dx-edit-button",            DATAGRID_INSERT_INDEX = "__DX_INSERT_INDEX__",            DATAGRID_ROW_REMOVED = "dx-row-removed",            DATAGRID_ROW_INSERTED = "dx-row-inserted",            DATAGRID_ROW_MODIFIED = "dx-row-modified",            DATAGRID_CELL_MODIFIED = "dx-cell-modified",            DATAGRID_CELL_HIGHLIGHT_OUTLINE = "dx-highlight-outline",            DATAGRID_EDITING_NAMESPACE = "dxDataGridEditing",            DATAGRID_FOCUS_OVERLAY_CLASS = "dx-datagrid-focus-overlay",            DATAGRID_READONLY_CLASS = "dx-datagrid-readonly",            DATAGRID_DATA_ROW_CLASS = "dx-data-row",            CHECKBOX_CLASS = "dx-checkbox",            DATAGRID_EDITOR_INLINE_BLOCK = "dx-editor-inline-block",            DATAGRID_CELL_FOCUS_DISABLED_CLASS = "dx-cell-focus-disabled",            DATAGRID_EDIT_MODE_BATCH = "batch",            DATAGRID_EDIT_MODE_ROW = "row",            DATAGRID_EDIT_MODE_CELL = "cell",            DATA_EDIT_DATA_INSERT_TYPE = "insert",            DATA_EDIT_DATA_UPDATE_TYPE = "update",            DATA_EDIT_DATA_REMOVE_TYPE = "remove",            DATAGRID_POINTER_EVENTS_NONE_CLASS = "dx-pointer-events-none",            DATAGRID_POINTER_EVENTS_TARGET_CLASS = "dx-pointer-events-target";        var getEditMode = function(that) {                var editMode = that.option('editing.editMode');                if (editMode === DATAGRID_EDIT_MODE_BATCH || editMode === DATAGRID_EDIT_MODE_CELL)                    return editMode;                return DATAGRID_EDIT_MODE_ROW            };        dataGrid.EditingController = dataGrid.ViewController.inherit(function() {            var getDefaultEditorTemplate = function(that) {                    return function(container, options) {                            var $editor = $('<div/>').appendTo(container);                            that.getController('editorFactory').createEditor($editor, $.extend({}, options.column, {                                value: options.value,                                setValue: options.setValue,                                row: options.row,                                parentType: 'dataRow',                                width: null,                                readOnly: options.setValue === undefined                            }))                        }                };            var getDataController = function(that) {                    return that.getController('data')                };            return {                    init: function() {                        var that = this;                        that._insertIndex = 1;                        that._editRowIndex = -1;                        that._editData = [];                        that._editColumnIndex = -1;                        that._columnsController = that.getController("columns");                        that.createAction("onInitNewRow", {excludeValidators: ["disabled", "readOnly"]});                        that.createAction("onRowInserting", {excludeValidators: ["disabled", "readOnly"]});                        that.createAction("onRowInserted", {excludeValidators: ["disabled", "readOnly"]});                        that.createAction("onEditingStart", {excludeValidators: ["disabled", "readOnly"]});                        that.createAction("onRowUpdating", {excludeValidators: ["disabled", "readOnly"]});                        that.createAction("onRowUpdated", {excludeValidators: ["disabled", "readOnly"]});                        that.createAction("onRowRemoving", {excludeValidators: ["disabled", "readOnly"]});                        that.createAction("onRowRemoved", {excludeValidators: ["disabled", "readOnly"]});                        if (!that._saveEditorHandler) {                            that._saveEditorHandler = that.createAction(function(e) {                                var event = e.jQueryEvent,                                    visibleColumns,                                    isEditorPopup,                                    isDomElement,                                    isFocusOverlay,                                    $targetCell,                                    allowEditing,                                    cellIndex,                                    isDataRow;                                if (getEditMode(that) !== DATAGRID_EDIT_MODE_ROW && that.isEditing() && !that._editCellInProgress) {                                    isEditorPopup = $(event.target).closest('.dx-overlay-wrapper').length;                                    isDomElement = $(event.target).closest(document).length;                                    isFocusOverlay = $(event.target).hasClass(DATAGRID_FOCUS_OVERLAY_CLASS);                                    isDataRow = $(event.target).closest('.' + DATAGRID_DATA_ROW_CLASS).length;                                    visibleColumns = that._columnsController.getVisibleColumns();                                    $targetCell = $(event.target).closest('td');                                    cellIndex = $targetCell[0] && $targetCell[0].cellIndex;                                    allowEditing = visibleColumns[cellIndex] && visibleColumns[cellIndex].allowEditing;                                    if ((!isDataRow || isDataRow && !allowEditing) && !isEditorPopup && !isFocusOverlay && isDomElement)                                        that.closeEditCell()                                }                            });                            $(document).on('dxclick', that._saveEditorHandler)                        }                        that._updateEditColumn();                        that._updateEditButtons()                    },                    getEditMode: function() {                        return getEditMode(this)                    },                    getFirstEditableColumnIndex: function() {                        var columnsController = this.getController("columns"),                            visibleColumns = columnsController.getVisibleColumns(),                            columnIndex;                        $.each(visibleColumns, function(index, column) {                            if (column.allowEditing) {                                columnIndex = index;                                return false                            }                        });                        return columnIndex                    },                    getFirstEditableCellInRow: function(rowIndex) {                        return this.getView('rowsView').getCellElement(rowIndex ? rowIndex : 0, this.getFirstEditableColumnIndex())                    },                    getIndexByKey: function(key, items) {                        return getIndexByKey(key, items)                    },                    hasChanges: function() {                        var that = this,                            result = false;                        $.each(that._editData, function(_, editData) {                            result = result || !!editData.type                        });                        return result                    },                    dispose: function() {                        this.callBase();                        $(document).off('dxclick', this._saveEditorHandler)                    },                    optionChanged: function(args) {                        if (args.name === "editing") {                            this.init();                            args.handled = true                        }                        else                            this.callBase(args)                    },                    publicMethods: function() {                        return ['insertRow', 'editRow', 'editCell', 'closeEditCell', 'removeRow', 'saveEditData', 'undeleteRow', 'cancelEditData']                    },                    refresh: function() {                        if (getEditMode(this) === DATAGRID_EDIT_MODE_ROW || getEditMode(this) === DATAGRID_EDIT_MODE_CELL)                            this.init();                        else {                            this._editRowIndex = -1;                            this._editColumnIndex = -1                        }                    },                    isEditing: function() {                        return this._editRowIndex > -1                    },                    isEditRow: function(rowIndex) {                        return getEditMode(this) === DATAGRID_EDIT_MODE_ROW && this._editRowIndex === rowIndex                    },                    isEditCell: function(rowIndex, columnIndex) {                        return this._editRowIndex === rowIndex && this._editColumnIndex === columnIndex                    },                    processItems: function(items, changeType) {                        var that = this,                            editData = that._editData,                            i,                            key,                            data;                        that.update();                        for (i = 0; i < editData.length; i++) {                            key = editData[i].key;                            data = {key: key};                            if (editData[i].type === DATA_EDIT_DATA_INSERT_TYPE && key.pageIndex === that._pageIndex) {                                data[DATAGRID_INSERT_INDEX] = key[DATAGRID_INSERT_INDEX];                                items.splice(key.rowIndex, 0, data)                            }                        }                        return items                    },                    processDataItem: function(item, columns, generateDataValues) {                        var that = this,                            editIndex,                            editData,                            data,                            key = item.data[DATAGRID_INSERT_INDEX] ? item.data.key : item.key,                            editMode = getEditMode(that);                        editIndex = getIndexByKey(key, that._editData);                        if (editIndex >= 0) {                            editData = that._editData[editIndex];                            data = editData.data;                            switch (editData.type) {                                case DATA_EDIT_DATA_INSERT_TYPE:                                    item.inserted = true;                                    item.key = key;                                    item.data = data;                                    break;                                case DATA_EDIT_DATA_UPDATE_TYPE:                                    item.modified = true;                                    item.data = $.extend(true, {}, item.data, data);                                    item.modifiedValues = generateDataValues(data, columns);                                    break;                                case DATA_EDIT_DATA_REMOVE_TYPE:                                    if (editMode === DATAGRID_EDIT_MODE_BATCH)                                        item.data = $.extend(true, {}, item.data, data);                                    item.removed = true;                                    break                            }                        }                    },                    insertRow: function() {                        var that = this,                            dataController = getDataController(that),                            rowsView = that.getView('rowsView'),                            param = {data: {}},                            insertKey = {                                pageIndex: dataController.pageIndex(),                                rowIndex: rowsView ? rowsView.getTopVisibleItemIndex() : 0                            },                            oldEditRowIndex = that._editRowIndex,                            editMode = getEditMode(that),                            $firstCell;                        that.refresh();                        if (editMode !== DATAGRID_EDIT_MODE_BATCH) {                            if (that._insertIndex > 1)                                return;                            that._editRowIndex = insertKey.rowIndex                        }                        that.executeAction("onInitNewRow", param);                        insertKey[DATAGRID_INSERT_INDEX] = that._insertIndex++;                        that._addEditData({                            key: insertKey,                            data: param.data,                            type: DATA_EDIT_DATA_INSERT_TYPE                        });                        dataController.updateItems({                            changeType: 'update',                            rowIndices: [oldEditRowIndex, insertKey.rowIndex]                        });                        $firstCell = that.getFirstEditableCellInRow();                        that._delayedInputFocus($firstCell, function() {                            var $cell = that.getFirstEditableCellInRow();                            $cell && $cell.trigger("dxclick")                        });                        that._afterInsertRow({                            key: insertKey,                            data: param.data                        })                    },                    _isEditingStart: function(options) {                        this.executeAction("onEditingStart", options);                        return options.cancel                    },                    editRow: function(rowIndex) {                        var that = this,                            dataController = getDataController(that),                            items = dataController.items(),                            item = items[rowIndex],                            params = {                                data: item.data,                                cancel: false                            },                            oldEditRowIndex = that._editRowIndex,                            $firstCell;                        if (rowIndex === oldEditRowIndex)                            return true;                        if (!item.inserted)                            params.key = item.key;                        if (that._isEditingStart(params))                            return;                        that.init();                        that._pageIndex = dataController.pageIndex();                        that._editRowIndex = items[0].inserted ? rowIndex - 1 : rowIndex;                        that._addEditData({                            data: {},                            key: item.key,                            oldData: item.data                        });                        dataController.updateItems({                            changeType: 'update',                            rowIndices: [oldEditRowIndex, rowIndex]                        });                        $firstCell = that.getFirstEditableCellInRow(that._editRowIndex);                        that._delayedInputFocus($firstCell, function() {                            $firstCell && that.component.focus($firstCell)                        })                    },                    editCell: function(rowIndex, columnIndex) {                        var that = this,                            dataController = getDataController(that),                            items = dataController.items(),                            item = items[rowIndex],                            params = {                                data: item && item.data,                                cancel: false,                                column: that._columnsController.getVisibleColumns()[columnIndex]                            },                            editMode = getEditMode(that),                            oldEditRowIndex = that._editRowIndex,                            oldEditColumnIndex = that._editColumnIndex,                            columns = that._columnsController.getVisibleColumns(),                            isCellEditingAllowed = params.column && params.column.allowEditing,                            showEditorAlways = params.column && params.column.showEditorAlways,                            $editCell;                        if (isCellEditingAllowed && item && item.rowType === 'data' && !item.removed && editMode !== DATAGRID_EDIT_MODE_ROW) {                            if (that.isEditCell(rowIndex, columnIndex))                                return true;                            if (editMode === DATAGRID_EDIT_MODE_CELL && !item.inserted && that.hasChanges()) {                                that.saveEditData();                                if (that.hasChanges())                                    return true                            }                            if (!item.inserted)                                params.key = item.key;                            if (that._isEditingStart(params))                                return true;                            that._editRowIndex = rowIndex;                            that._editColumnIndex = columnIndex;                            that._pageIndex = dataController.pageIndex();                            that._addEditData({                                data: {},                                key: item.key,                                oldData: item.data                            });                            if (!showEditorAlways || columns[oldEditColumnIndex] && !columns[oldEditColumnIndex].showEditorAlways) {                                that._editCellInProgress = true;                                dataController.updateItems({                                    changeType: 'update',                                    rowIndices: [oldEditRowIndex, that._editRowIndex]                                })                            }                            $editCell = that.getView("rowsView").getCellElement(that._editRowIndex, that._editColumnIndex);                            that._delayedInputFocus($editCell, function() {                                that._editCellInProgress = false                            });                            return true                        }                        return false                    },                    _delayedInputFocus: function($cell, afterFocusCallback) {                        setTimeout(function() {                            $cell && $cell.find('[tabindex], input').focus();                            afterFocusCallback && afterFocusCallback()                        })                    },                    removeRow: function(rowIndex) {                        var that = this,                            editingOptions = that.option("editing"),                            editingTexts = editingOptions && editingOptions.texts,                            confirmDeleteTitle = editingTexts && editingTexts.confirmDeleteTitle,                            isBatchMode = editingOptions && editingOptions.editMode === DATAGRID_EDIT_MODE_BATCH,                            confirmDeleteMessage = editingTexts && editingTexts.confirmDeleteMessage,                            dataController = getDataController(that),                            removeByKey,                            showDialogTitle,                            oldEditRowIndex = that._editRowIndex,                            item = dataController.items()[rowIndex],                            key = item && item.key;                        if (item) {                            removeByKey = function(key) {                                that.refresh();                                var editIndex = getIndexByKey(key, that._editData);                                if (editIndex >= 0)                                    if (that._editData[editIndex].type === DATA_EDIT_DATA_INSERT_TYPE)                                        that._editData.splice(editIndex, 1);                                    else                                        that._editData[editIndex].type = DATA_EDIT_DATA_REMOVE_TYPE;                                else                                    that._addEditData({                                        key: key,                                        oldData: item.data,                                        type: DATA_EDIT_DATA_REMOVE_TYPE                                    });                                if (isBatchMode)                                    dataController.updateItems({                                        changeType: 'update',                                        rowIndices: [oldEditRowIndex, rowIndex]                                    });                                else                                    that.saveEditData()                            };                            if (isBatchMode || !confirmDeleteMessage)                                removeByKey(key);                            else {                                showDialogTitle = utils.isDefined(confirmDeleteTitle) && confirmDeleteTitle.length > 0;                                DX.ui.dialog.confirm(confirmDeleteMessage, confirmDeleteTitle, showDialogTitle).done(function(confirmResult) {                                    if (confirmResult)                                        removeByKey(key)                                })                            }                        }                    },                    undeleteRow: function(rowIndex) {                        var that = this,                            dataController = getDataController(that),                            item = dataController.items()[rowIndex],                            oldEditRowIndex = that._editRowIndex,                            key = item && item.key;                        if (item) {                            var editIndex = getIndexByKey(key, that._editData),                                editData;                            if (editIndex >= 0) {                                editData = that._editData[editIndex];                                if ($.isEmptyObject(editData.data))                                    that._editData.splice(editIndex, 1);                                else                                    editData.type = DATA_EDIT_DATA_UPDATE_TYPE;                                dataController.updateItems({                                    changeType: 'update',                                    rowIndices: [oldEditRowIndex, rowIndex]                                })                            }                        }                    },                    _saveEditDataCore: function(deferreds, processedKeys) {                        var that = this,                            store = getDataController(that).store();                        $.each(that._editData, function(index, editData) {                            var data = editData.data,                                oldData = editData.oldData,                                key = editData.key,                                type = editData.type,                                deferred,                                doneDeferred,                                params;                            if (that._beforeSaveEditData(editData, index))                                return;                            switch (type) {                                case DATA_EDIT_DATA_REMOVE_TYPE:                                    params = {                                        data: oldData,                                        key: key,                                        cancel: false                                    };                                    that.executeAction("onRowRemoving", params);                                    if (params.cancel)                                        return;                                    deferred = store.remove(key);                                    break;                                case DATA_EDIT_DATA_INSERT_TYPE:                                    params = {                                        data: data,                                        cancel: false                                    };                                    that.executeAction("onRowInserting", params);                                    if (params.cancel)                                        return;                                    deferred = store.insert(params.data);                                    break;                                case DATA_EDIT_DATA_UPDATE_TYPE:                                    params = {                                        newData: data,                                        oldData: oldData,                                        key: key,                                        cancel: false                                    };                                    that.executeAction("onRowUpdating", params);                                    if (params.cancel)                                        return;                                    deferred = store.update(key, params.newData);                                    break                            }                            if (deferred) {                                doneDeferred = $.Deferred();                                deferred.always(function() {                                    processedKeys.push(key)                                }).always(doneDeferred.resolve);                                deferreds.push(doneDeferred.promise())                            }                        })                    },                    _processSaveEditDataResult: function(results, processedKeys) {                        var that = this,                            dataController = getDataController(that),                            i,                            arg,                            editIndex,                            isError,                            editMode = getEditMode(that);                        for (i = 0; i < results.length; i++) {                            arg = results[i];                            editIndex = getIndexByKey(processedKeys[i], that._editData);                            if (that._editData[editIndex]) {                                isError = arg && arg instanceof Error;                                if (isError) {                                    that._editData[editIndex].error = arg;                                    dataController.dataErrorOccurred.fire(arg);                                    if (editMode !== DATAGRID_EDIT_MODE_BATCH)                                        return false                                }                                else                                    that._editData.splice(editIndex, 1)                            }                        }                        return true                    },                    _fireSaveEditDataEvents: function(editData) {                        var that = this;                        $.each(editData, function(_, itemData) {                            var data = itemData.data,                                key = itemData.key,                                type = itemData.type,                                params = {                                    key: key,                                    data: data                                };                            if (itemData.error)                                params.error = itemData.error;                            switch (type) {                                case DATA_EDIT_DATA_REMOVE_TYPE:                                    that.executeAction("onRowRemoved", $.extend({}, params, {data: itemData.oldData}));                                    break;                                case DATA_EDIT_DATA_INSERT_TYPE:                                    that.executeAction("onRowInserted", params);                                    break;                                case DATA_EDIT_DATA_UPDATE_TYPE:                                    that.executeAction("onRowUpdated", params);                                    break                            }                        })                    },                    saveEditData: function() {                        var that = this,                            processedKeys = [],                            deferreds = [],                            dataController = getDataController(that),                            rowIndex = that._editRowIndex,                            editData = $.extend({}, that._editData),                            editMode = getEditMode(that);                        var resetEditIndices = function(that) {                                that._editColumnIndex = -1;                                that._editRowIndex = -1                            };                        if (that._beforeSaveEditData())                            return;                        that._saveEditDataCore(deferreds, processedKeys);                        if (deferreds.length) {                            $.when.apply($, deferreds).done(function() {                                if (that._processSaveEditDataResult(arguments, processedKeys)) {                                    resetEditIndices(that);                                    $.when(dataController.refresh()).always(function() {                                        that._fireSaveEditDataEvents(editData);                                        that._afterSaveEditData()                                    })                                }                            });                            return                        }                        if (editMode === DATAGRID_EDIT_MODE_ROW) {                            if (!that.hasChanges())                                that.cancelEditData()                        }                        else {                            resetEditIndices(that);                            dataController.updateItems(rowIndex >= 0 && {                                changeType: 'update',                                rowIndices: [rowIndex]                            })                        }                        that._afterSaveEditData()                    },                    _updateEditColumn: function() {                        var that = this,                            editing = that.option('editing'),                            isEditColumnVisible = editing && ((editing.editEnabled || editing.insertEnabled) && getEditMode(that) === DATAGRID_EDIT_MODE_ROW || editing.removeEnabled);                        that._columnsController.addCommandColumn({                            command: 'edit',                            visible: isEditColumnVisible,                            cssClass: "dx-command-edit",                            width: "auto"                        });                        that._columnsController.columnOption("command:edit", "visible", isEditColumnVisible)                    },                    _updateEditButtons: function() {                        var that = this,                            saveChangesButton = that._saveChangesButton,                            cancelChangesButton = that._cancelChangesButton,                            hasChanges = that.hasChanges();                        if (saveChangesButton)                            saveChangesButton.option('disabled', !hasChanges);                        if (cancelChangesButton)                            cancelChangesButton.option('disabled', !hasChanges)                    },                    cancelEditData: function() {                        var that = this,                            dataController = getDataController(that);                        that._beforeCancelEditData();                        that.init();                        dataController.updateItems()                    },                    closeEditCell: function() {                        var that = this,                            editMode = getEditMode(that),                            oldEditRowIndex = that._editRowIndex,                            dataController = getDataController(that);                        if (editMode !== DATAGRID_EDIT_MODE_ROW)                            setTimeout(function() {                                if (editMode === DATAGRID_EDIT_MODE_CELL && that.hasChanges())                                    that.saveEditData();                                else if (oldEditRowIndex >= 0) {                                    that._editRowIndex = -1;                                    that._editColumnIndex = -1;                                    dataController.updateItems({                                        changeType: 'update',                                        rowIndices: [oldEditRowIndex]                                    })                                }                            })                    },                    update: function() {                        var that = this,                            dataController = getDataController(that);                        if (that._pageIndex !== dataController.pageIndex()) {                            that.refresh();                            that._pageIndex = dataController.pageIndex()                        }                        that._updateEditButtons()                    },                    updateFieldValue: function(options, value) {                        var that = this,                            data = {},                            rowKey = options.key,                            $cellElement = options.cellElement,                            params;                        if (rowKey !== undefined && options.column.setCellValue) {                            $cellElement && $cellElement.addClass(DATAGRID_CELL_MODIFIED);                            options.value = value;                            options.column.setCellValue(data, value);                            params = {                                data: data,                                key: rowKey,                                oldData: options.data,                                type: DATA_EDIT_DATA_UPDATE_TYPE                            };                            that._addEditData(params);                            that._updateEditButtons()                        }                    },                    _addEditData: function(options) {                        var that = this,                            editDataIndex = getIndexByKey(options.key, that._editData);                        if (editDataIndex < 0) {                            editDataIndex = that._editData.length;                            that._editData.push(options)                        }                        if (that._editData[editDataIndex]) {                            options.type = that._editData[editDataIndex].type || options.type;                            $.extend(true, that._editData[editDataIndex], {                                data: options.data,                                type: options.type                            })                        }                        return editDataIndex                    },                    getColumnTemplate: function(options) {                        var that = this,                            column = options.column,                            rowIndex = options.row && options.row.rowIndex,                            template,                            editingOptions,                            editingTexts,                            editEnabled = that.option("editing.editEnabled"),                            isRowMode = getEditMode(that) === DATAGRID_EDIT_MODE_ROW,                            isRowEditing = that.isEditRow(rowIndex),                            isCellEditing = that.isEditCell(rowIndex, options.columnIndex);                        if ((column.showEditorAlways || column.allowEditing && column.setCellValue && (isRowEditing || isCellEditing)) && options.rowType === 'data' && !utils.isDefined(column.command)) {                            if (column.allowEditing && (editEnabled || isRowEditing || isCellEditing) && (isRowMode && isRowEditing || !isRowMode))                                options.setValue = function(value) {                                    that.updateFieldValue(options, value)                                };                            template = column.editCellTemplate || getDefaultEditorTemplate(that)                        }                        else if (column.command === 'edit' && options.rowType === 'data')                            template = function(container, options) {                                var createLink = function(container, text, methodName, options) {                                        var $link = $('<a />').addClass(DATAGRID_LINK_CLASS).text(text).on(addNamespace('dxclick', DATAGRID_EDITING_NAMESPACE), that.createAction(function(params) {                                                var e = params.jQueryEvent;                                                e.stopPropagation();                                                setTimeout(function() {                                                    options.row && that[methodName](options.row.rowIndex)                                                })                                            }));                                        options.rtlEnabled ? container.prepend($link, " ") : container.append($link, " ")                                    };                                container.css('text-align', 'center');                                options.rtlEnabled = that.option('rtlEnabled');                                editingOptions = that.option("editing") || {};                                editingTexts = editingOptions.texts || {};                                if (options.row && options.row.rowIndex === that._editRowIndex && isRowMode) {                                    createLink(container, editingTexts.saveRowChanges, 'saveEditData', options);                                    createLink(container, editingTexts.cancelRowChanges, 'cancelEditData', options)                                }                                else {                                    if (editingOptions.editEnabled && isRowMode)                                        createLink(container, editingTexts.editRow, 'editRow', options);                                    if (editingOptions.removeEnabled)                                        if (options.row.removed)                                            createLink(container, editingTexts.undeleteRow, 'undeleteRow', options);                                        else                                            createLink(container, editingTexts.deleteRow, 'removeRow', options)                                }                            };                        return template                    },                    renderEditButtons: function(rootElement) {                        var that = this,                            insertButton = rootElement.find('.' + DATAGRID_EDIT_BUTTON_CLASS),                            editingOptions = that.option("editing") || {},                            editingTexts = that.option("editing.texts") || {},                            titleButtonTextByClassNames = {                                cancel: editingTexts.cancelAllChanges,                                save: editingTexts.saveAllChanges,                                addrow: editingTexts.addRow                            };                        var createEditButton = function(rootElement, className, methodName) {                                return $('<div />').addClass(DATAGRID_EDIT_BUTTON_CLASS).addClass("dx-datagrid-" + className + "-button").appendTo(rootElement).dxButton({                                        icon: "edit-button-" + className,                                        onClick: function(options) {                                            var e = options.jQueryEvent;                                            e.stopPropagation();                                            that[methodName]()                                        },                                        hint: titleButtonTextByClassNames && titleButtonTextByClassNames[className]                                    }).dxButton('instance')                            };                        if (insertButton.length)                            insertButton.remove();                        if ((editingOptions.editEnabled || editingOptions.insertEnabled || editingOptions.removeEnabled) && getEditMode(that) === DATAGRID_EDIT_MODE_BATCH) {                            that._cancelChangesButton = createEditButton(rootElement, "cancel", 'cancelEditData');                            that._saveChangesButton = createEditButton(rootElement, "save", 'saveEditData');                            that._updateEditButtons()                        }                        if (editingOptions.insertEnabled)                            createEditButton(rootElement, "addrow", 'insertRow')                    },                    createHighlightCell: function($cell) {                        var $highlight = $cell.find("." + DATAGRID_CELL_HIGHLIGHT_OUTLINE);                        if (!$highlight.length)                            $cell.wrapInner($("<div>").addClass(DATAGRID_CELL_HIGHLIGHT_OUTLINE + " " + DATAGRID_POINTER_EVENTS_TARGET_CLASS))                    },                    _afterInsertRow: function(options){},                    _beforeEditCell: function(){},                    _beforeSaveEditData: function(editData, editIndex){},                    _afterSaveEditData: function(){},                    _beforeCancelEditData: function(){}                }        }());        dataGrid.registerModule('editing', {            defaultOptions: function() {                return {editing: {                            editMode: 'row',                            insertEnabled: false,                            editEnabled: false,                            removeEnabled: false,                            texts: {                                editRow: Globalize.localize("dxDataGrid-editingEditRow"),                                saveAllChanges: Globalize.localize("dxDataGrid-editingSaveAllChanges"),                                saveRowChanges: Globalize.localize("dxDataGrid-editingSaveRowChanges"),                                cancelAllChanges: Globalize.localize("dxDataGrid-editingCancelAllChanges"),                                cancelRowChanges: Globalize.localize("dxDataGrid-editingCancelRowChanges"),                                addRow: Globalize.localize("dxDataGrid-editingAddRow"),                                deleteRow: Globalize.localize("dxDataGrid-editingDeleteRow"),                                undeleteRow: Globalize.localize("dxDataGrid-editingUndeleteRow"),                                confirmDeleteMessage: Globalize.localize("dxDataGrid-editingConfirmDeleteMessage"),                                confirmDeleteTitle: Globalize.localize("dxDataGrid-editingConfirmDeleteTitle")                            }                        }}            },            controllers: {editing: dataGrid.EditingController},            extenders: {                controllers: {data: {                        init: function() {                            this._editingController = this.getController('editing');                            this.callBase()                        },                        reload: function() {                            this._editingController.refresh();                            return this.callBase()                        },                        _processItems: function(items, changeType) {                            items = this._editingController.processItems(items, changeType);                            return this.callBase(items, changeType)                        },                        _processDataItem: function(dataItem, options) {                            this._editingController.processDataItem(dataItem, options.visibleColumns, this._generateDataValues);                            return this.callBase(dataItem, options)                        }                    }},                views: {                    rowsView: {                        _getColumnTemplate: function(options) {                            var that = this,                                template = that.getController('editing').getColumnTemplate(options);                            return template || that.callBase(options)                        },                        _createTable: function() {                            var that = this,                                editing = that.option("editing"),                                $table = that.callBase.apply(that, arguments);                            if (editing && editing.editMode !== DATAGRID_EDIT_MODE_ROW && editing.editEnabled)                                $table.on(events.addNamespace("dxhold", "dxDataGridRowsView"), "td:not(." + DATAGRID_EDITOR_CELL_CLASS + ")", that.createAction(function(e) {                                    var editingController = that.getController("editing");                                    if (editingController.isEditing())                                        editingController.closeEditCell()                                }));                            return $table                        },                        _createRow: function(row) {                            var $row = this.callBase(row),                                editingController,                                isEditRow,                                isRowRemoved,                                isRowInserted,                                isRowModified;                            if (row) {                                editingController = this.getController('editing');                                isEditRow = editingController.isEditRow(row.rowIndex);                                isRowRemoved = !!row.removed;                                isRowInserted = !!row.inserted;                                isRowModified = !!row.modified;                                if (getEditMode(this) === DATAGRID_EDIT_MODE_BATCH)                                    $row.toggleClass(DATAGRID_ROW_REMOVED, isRowRemoved);                                else                                    $row.toggleClass(DATAGRID_EDIT_ROW, isEditRow);                                $row.toggleClass(DATAGRID_ROW_INSERTED, isRowInserted);                                $row.toggleClass(DATAGRID_ROW_MODIFIED, isRowModified);                                if (isEditRow || isRowInserted || isRowRemoved)                                    $row.removeClass(DATAGRID_ROW_SELECTED)                            }                            return $row                        },                        _rowClick: function(e) {                            var that = this,                                editingController = that.getController('editing'),                                $targetCell = $(e.jQueryEvent.target).closest('td'),                                columnIndex = that.getCellIndex($targetCell),                                editEnabled = that.option("editing.editEnabled");                            if ($targetCell.hasClass(DATAGRID_POINTER_EVENTS_NONE_CLASS))                                return;                            if (!(editEnabled && editingController.editCell(e.rowIndex, columnIndex)) && !editingController.isEditRow(e.rowIndex))                                that.callBase(e)                        },                        _cellPrepared: function($cell, parameters) {                            var modifiedValues = parameters.row && (parameters.row.inserted ? parameters.row.values : parameters.row.modifiedValues),                                columnIndex = parameters.columnIndex,                                alignment = parameters.column.alignment,                                editingController = this.getController('editing'),                                editMode = editingController.getEditMode();                            parameters.isEditing = editingController.isEditCell(parameters.rowIndex, parameters.columnIndex) || editingController.isEditRow(parameters.rowIndex) && parameters.column.allowEditing;                            if (!utils.isDefined(parameters.column.command) && (parameters.isEditing || parameters.column.showEditorAlways)) {                                $cell.addClass(DATAGRID_EDITOR_CELL_CLASS).toggleClass(DATAGRID_READONLY_CLASS, !parameters.setValue);                                if (alignment)                                    $cell.find('input').first().css('text-align', alignment)                            }                            if ($cell.children('.' + CHECKBOX_CLASS).length === 1)                                $cell.addClass(DATAGRID_EDITOR_INLINE_BLOCK).toggleClass(DATAGRID_CELL_FOCUS_DISABLED_CLASS, !!parameters.column.command);                            if (editMode === DATAGRID_EDIT_MODE_BATCH || editMode === DATAGRID_EDIT_MODE_CELL && parameters.row.inserted)                                if (modifiedValues && modifiedValues[columnIndex] !== undefined && parameters.column && parameters.column.allowEditing) {                                    editingController.createHighlightCell($cell);                                    $cell.addClass(DATAGRID_CELL_MODIFIED)                                }                                else if (parameters.setValue)                                    editingController.createHighlightCell($cell, true);                            this.callBase.apply(this, arguments)                        },                        _update: function(change) {                            this.callBase(change);                            if (change.changeType === 'updateSelection')                                this._getTableElement().children('tbody').children('.' + DATAGRID_EDIT_ROW).removeClass(DATAGRID_ROW_SELECTED)                        }                    },                    headerPanel: {                        _renderCore: function() {                            this.callBase();                            this.getController('editing').renderEditButtons(this.element())                        },                        isVisible: function() {                            var that = this,                                editingOptions = that.getController('editing').option('editing');                            return that.callBase() || editingOptions && (editingOptions.insertEnabled || (editingOptions.editEnabled || editingOptions.removeEnabled) && editingOptions.editMode === DATAGRID_EDIT_MODE_BATCH)                        }                    }                }            }        });        $.extend(dataGrid.__internals, {            DATAGRID_LINK_CLASS: DATAGRID_LINK_CLASS,            DATAGRID_EDITOR_CELL_CLASS: DATAGRID_EDITOR_CELL_CLASS,            DATAGRID_EDIT_ROW: DATAGRID_EDIT_ROW,            DATAGRID_EDIT_BUTTON_CLASS: DATAGRID_EDIT_BUTTON_CLASS,            DATAGRID_CELL_MODIFIED: DATAGRID_CELL_MODIFIED,            DATAGRID_ROW_REMOVED: DATAGRID_ROW_REMOVED,            DATAGRID_ROW_INSERTED: DATAGRID_ROW_INSERTED,            DATAGRID_ROW_MODIFIED: DATAGRID_ROW_MODIFIED,            DATAGRID_CELL_HIGHLIGHT_OUTLINE: DATAGRID_CELL_HIGHLIGHT_OUTLINE,            DATAGRID_FOCUS_OVERLAY_CLASS: DATAGRID_FOCUS_OVERLAY_CLASS,            DATAGRID_READONLY_CLASS: DATAGRID_READONLY_CLASS,            DATAGRID_CELL_FOCUS_DISABLED_CLASS: DATAGRID_CELL_FOCUS_DISABLED_CLASS        })    })(jQuery, DevExpress);    /*! Module widgets-web, file ui.dataGrid.validationModule.js */    (function($, DX) {        var dataGrid = DX.ui.dxDataGrid,            utils = DX.utils;        var DATAGRID_INVALIDATE_CLASS = "dx-datagrid-invalid",            DATAGRID_INVALID_MESSAGE_CLASS = "dx-invalid-message",            DATAGRID_INVALID_MESSAGE_ALWAYS_CLASS = "dx-invalid-message-always",            DATAGRID_INSERT_INDEX = "__DX_INSERT_INDEX__",            DATAGRID_EDIT_MODE_ROW = "row",            DATAGRID_EDIT_MODE_BATCH = "batch",            DATAGRID_EDIT_MODE_CELL = "cell";        dataGrid.ValidatingController = dataGrid.Controller.inherit(function() {            return {                    init: function() {                        this._editingController = this.getController("editing");                        this.createAction("onRowValidating")                    },                    _rowValidating: function(editData, validate) {                        var that = this,                            brokenRules = validate ? validate.brokenRules || validate.brokenRule && [validate.brokenRule] : [],                            isValid = validate ? validate.isValid : editData.isValid,                            parameters = {                                brokenRules: brokenRules,                                isValid: isValid,                                key: editData.key,                                newData: editData.data,                                oldData: editData.oldData,                                errorText: null                            };                        that.executeAction("onRowValidating", parameters);                        editData.isValid = parameters.isValid;                        editData.errorText = parameters.errorText;                        return parameters                    },                    validate: function(isFull) {                        var that = this,                            isValid = true,                            editingController = that._editingController;                        isFull = isFull || editingController.getEditMode() === DATAGRID_EDIT_MODE_ROW;                        if (that._isValidationInProgress)                            return false;                        that._isValidationInProgress = true;                        if (isFull)                            $.each(editingController._editData, function(index, editData) {                                var validationResult;                                if (editData.type) {                                    validationResult = that.validateGroup(editData);                                    if (!validationResult.isValid)                                        $.each(validationResult.brokenRules, function() {                                            if (this.validator.option("adapter").getValue() === undefined)                                                editingController.updateFieldValue({                                                    key: editData.key,                                                    column: this.column                                                }, null, true)                                        });                                    isValid = isValid && validationResult.isValid                                }                            });                        else if (that._currentCellValidator)                            isValid = that.validateGroup(that._currentCellValidator._findGroup()).isValid;                        that._isValidationInProgress = false;                        return isValid                    },                    validateGroup: function(editData) {                        var that = this,                            validateGroup = DX.validationEngine.getGroupConfig(editData),                            validationResults;                        if (validateGroup && validateGroup.validators.length)                            validationResults = DX.validationEngine.validateGroup(editData);                        return that._rowValidating(editData, validationResults)                    },                    updateEditData: function(editData) {                        this.setDisableApplyValidationResults(true);                        editData.isValid = DX.validationEngine.getGroupConfig(editData) ? DX.validationEngine.validateGroup(editData).isValid : true;                        this.setDisableApplyValidationResults(false)                    },                    setValidator: function(validator) {                        this._currentCellValidator = validator                    },                    getValidator: function() {                        return this._currentCellValidator                    },                    removeValidators: function(editIndex) {                        var that = this,                            editingController = that._editingController;                        $.each(editingController._editData, function(index, editData) {                            var validateGroup = DX.validationEngine.getGroupConfig(editData);                            if (!utils.isDefined(editIndex) || editIndex === index)                                if (validateGroup)                                    for (var i = 0; i < validateGroup.validators.length; i++) {                                        validateGroup.validators[i]._dispose();                                        i--                                    }                        })                    },                    createValidator: function(parameters, $container) {                        var that = this,                            editingController = that._editingController,                            column = parameters.column,                            editData,                            editIndex = editingController.getIndexByKey(parameters.key, editingController._editData),                            defaultValidationResult = function(options) {                                if (options.brokenRule) {                                    options.brokenRule.columnIndex = column.index;                                    options.brokenRule.column = column                                }                                if ($container && !that.getDisableApplyValidationResults()) {                                    !options.isValid && editingController.createHighlightCell($container, true);                                    $container.toggleClass(DATAGRID_INVALIDATE_CLASS, !options.isValid)                                }                            };                        if (editIndex < 0 && column.showEditorAlways)                            editIndex = editingController._addEditData({key: parameters.key});                        if (editIndex >= 0) {                            editData = editingController._editData[editIndex];                            return new DX.ui.dxValidator($container || {}, {                                    name: column.caption,                                    validationRules: $.extend(true, [], column.validationRules),                                    validationGroup: editData,                                    adapter: {                                        getValue: function() {                                            return parameters.value                                        },                                        applyValidationResults: defaultValidationResult                                    }                                })                        }                    },                    setDisableApplyValidationResults: function(flag) {                        this._disableApplyValidationResults = flag                    },                    getDisableApplyValidationResults: function() {                        return this._disableApplyValidationResults                    }                }        }());        dataGrid.registerModule('validating', {            defaultOptions: function() {                return {}            },            controllers: {validating: dataGrid.ValidatingController},            extenders: {                controllers: {                    data: {reload: function() {                            var d = this.callBase(),                                editingController = this.getController("editing");                            return d.done(function() {                                    editingController.resetRowAndPageIndeces(true)                                })                        }},                    editing: {                        _addEditData: function(options) {                            var that = this,                                validatingController = that.getController("validating"),                                editDataIndex = that.callBase(options),                                editData;                            if (editDataIndex >= 0) {                                editData = that._editData[editDataIndex];                                validatingController.updateEditData(editData)                            }                            return editDataIndex                        },                        _updateRowAndPageIndices: function() {                            var that = this,                                startInsertIndex = that.getView('rowsView').getTopVisibleItemIndex(),                                rowIndex = startInsertIndex;                            $.each(that._editData, function(_, editData) {                                if (!editData.isValid && editData.pageIndex !== that._pageIndex) {                                    editData.pageIndex = that._pageIndex;                                    if (editData.type === "insert")                                        editData.rowIndex = startInsertIndex;                                    else                                        editData.rowIndex = rowIndex;                                    rowIndex++                                }                            })                        },                        resetRowAndPageIndeces: function(alwaysRest) {                            var that = this;                            $.each(that._editData, function(_, editData) {                                if (editData.pageIndex !== that._pageIndex || alwaysRest) {                                    delete editData.pageIndex;                                    delete editData.rowIndex                                }                            })                        },                        init: function() {                            var that = this;                            that.callBase();                            that.getController("data").changed.add(function(change) {                                if (that.option("scrolling.mode") === "standard")                                    that.resetRowAndPageIndeces();                                $.each(that._editData, function(_, editData) {                                    if (change && change.changeType === 'prepend')                                        editData.rowIndex += change.items.length                                })                            })                        },                        processItems: function(items, changeType) {                            var that = this,                                dataController = that.getController("data"),                                i,                                editData = that._editData,                                itemsCount = items.length,                                insertCount = 0,                                getIndexByEditData = function(editData, items) {                                    var index = -1,                                        isInsert = editData.type === "insert",                                        key = editData.key;                                    $.each(items, function(i, item) {                                        if (dataGrid.equalKeys(key, isInsert ? item : dataController.keyOf(item))) {                                            index = i;                                            return false                                        }                                    });                                    return index                                },                                addInValidItem = function(editData) {                                    var data = {key: editData.key},                                        index = getIndexByEditData(editData, items),                                        rowIndex;                                    if (index >= 0 && that.option("scrolling.mode") === "standard")                                        return;                                    editData.rowIndex = editData.rowIndex > itemsCount ? editData.rowIndex % itemsCount : editData.rowIndex;                                    rowIndex = editData.rowIndex;                                    data[DATAGRID_INSERT_INDEX] = 1;                                    if (index >= 0) {                                        items.splice(index, 1);                                        rowIndex -= insertCount                                    }                                    items.splice(rowIndex, 0, data);                                    insertCount++                                };                            that.update();                            if (that.getEditMode() === DATAGRID_EDIT_MODE_BATCH && changeType !== "prepend" && changeType !== "append")                                for (i = 0; i < editData.length; i++)                                    if (editData[i].type && editData[i].pageIndex === that._pageIndex && editData[i].key.pageIndex !== that._pageIndex)                                        addInValidItem(editData[i]);                            return that.callBase(items, changeType)                        },                        processDataItem: function(item, columns, generateDataValues) {                            var that = this,                                editIndex,                                editData,                                isInserted = item.data[DATAGRID_INSERT_INDEX],                                key = isInserted ? item.data.key : item.key,                                editMode = that.getEditMode();                            if (editMode === DATAGRID_EDIT_MODE_BATCH && isInserted && key) {                                editIndex = dataGrid.getIndexByKey(key, that._editData);                                if (editIndex >= 0) {                                    editData = that._editData[editIndex];                                    if (editData.type !== "insert") {                                        item.data = $.extend(true, {}, editData.oldData, editData.data);                                        item.key = key                                    }                                }                            }                            that.callBase.apply(that, arguments)                        },                        _afterInsertRow: function(options) {                            var validatingController = this.getController("validating"),                                hiddenColumns = this.getController("columns").getHiddenColumns();                            $.each(hiddenColumns, function(_, column) {                                if (utils.isArray(column.validationRules))                                    validatingController.createValidator({                                        column: column,                                        key: options.key,                                        value: options.data[column.dataField]                                    })                            });                            this.callBase(options)                        },                        _beforeSaveEditData: function(editData, editIndex) {                            var that = this,                                isValid,                                isFullValid,                                result = that.callBase.apply(that, arguments),                                validatingController = that.getController("validating");                            if (editData) {                                isValid = editData.type === "remove" || editData.isValid;                                if (isValid)                                    validatingController.removeValidators(editIndex);                                else if (utils.isDefined(that._hasInvalidRules))                                    that._hasInvalidRules = true;                                result = result || !isValid                            }                            else {                                isFullValid = validatingController.validate(true);                                that._updateRowAndPageIndices();                                if (that.getEditMode() === DATAGRID_EDIT_MODE_CELL) {                                    isValid = validatingController.validate();                                    if (isValid && that._hasInvalidRules) {                                        that.cancelEditData();                                        that._hasInvalidRules = false;                                        result = true                                    }                                    else if (!isFullValid) {                                        that._hasInvalidRules = true;                                        result = true                                    }                                }                            }                            return result                        },                        _afterSaveEditData: function() {                            var that = this;                            $.each(that._editData, function(_, editData) {                                that._showErrorRow(editData)                            })                        },                        _beforeCancelEditData: function() {                            var validatingController = this.getController("validating");                            validatingController.removeValidators();                            this.callBase()                        },                        _showErrorRow: function(editData) {                            var errorHandling = this.getController("errorHandling"),                                items = this.getController("data").items(),                                rowIndex = this.getIndexByKey(editData.key, items);                            if (!editData.isValid && editData.errorText && rowIndex >= 0)                                errorHandling && errorHandling.renderErrorRow(editData.errorText, rowIndex)                        },                        createHighlightCell: function($cell, skipValidation) {                            var isValid = true,                                validator;                            if (!skipValidation) {                                validator = $cell.data("dxValidator");                                if (validator)                                    isValid = validator.validate().isValid                            }                            if (isValid)                                this.callBase($cell)                        },                        updateFieldValue: function(options, value, skipInvalidRules) {                            var that = this;                            that.callBase.apply(that, arguments);                            if (!skipInvalidRules)                                that._hasInvalidRules = false                        }                    },                    editorFactory: {                        loseFocus: function(skipValidator) {                            if (!skipValidator)                                this.getController('validating').setValidator(null);                            this.callBase()                        },                        focus: function($element) {                            var that = this,                                hideBorder = false,                                rowsView = that.getView("rowsView"),                                $tdElement = $element && $element.closest("td"),                                validator = $tdElement && $tdElement.data("dxValidator"),                                validatingController = that.getController('validating'),                                $tooltip = $tdElement && $tdElement.closest(".dx-datagrid-rowsview").find(".dx-tooltip"),                                column = $tdElement && that.getController("columns").getVisibleColumns()[$tdElement.index()];                            $tooltip && $tooltip.remove();                            if (validator) {                                var value = validator.option("adapter").getValue();                                validatingController.setValidator(validator);                                if (value !== undefined) {                                    var validationResult = validator.validate();                                    if (!validationResult.isValid) {                                        var alignment = column.alignment;                                        hideBorder = true;                                        $("<div/>").addClass(DATAGRID_INVALID_MESSAGE_CLASS).addClass(DATAGRID_INVALID_MESSAGE_ALWAYS_CLASS).text(validationResult.brokenRule.message).appendTo($tdElement).dxTooltip({                                            target: $tdElement,                                            container: $tdElement,                                            visible: true,                                            closeOnOutsideClick: false,                                            closeOnTargetScroll: false,                                            arrowPosition: {                                                offset: alignment === "left" ? "5 0" : "-5 0",                                                my: "bottom " + alignment,                                                at: "top " + alignment                                            },                                            position: {                                                collision: "fit flip",                                                boundary: rowsView.element(),                                                boundaryOffset: "0 0",                                                offset: "0 -9",                                                my: "top " + alignment,                                                at: "bottom " + alignment                                            },                                            onPositioned: function() {                                                rowsView.element() && rowsView.updateFreeSpaceRowHeight()                                            }                                        })                                    }                                }                            }                            !hideBorder && rowsView.element() && rowsView.updateFreeSpaceRowHeight();                            return that.callBase($element, hideBorder)                        }                    }                },                views: {rowsView: {                        updateFreeSpaceRowHeight: function() {                            var that = this,                                $rowElements = that._getRowElements(),                                $freeSpaceRowElements = that._getFreeSpaceRowElements(),                                $freeSpaceRowElement = $freeSpaceRowElements.first(),                                $tooltipContent = that.element().find(".dx-invalid-message .dx-overlay-content");                            that.callBase();                            if ($tooltipContent.length && $freeSpaceRowElement && $rowElements.length === 1 && (!$freeSpaceRowElement.is(":visible") || $tooltipContent.outerHeight() > $freeSpaceRowElement.outerHeight())) {                                $freeSpaceRowElements.show();                                $freeSpaceRowElements.height($tooltipContent.outerHeight())                            }                        },                        _cellPrepared: function($cell, parameters) {                            var validatingController = this.getController("validating"),                                column = parameters.column;                            if (utils.isArray(column.validationRules))                                validatingController.createValidator(parameters, $cell);                            this.callBase.apply(this, arguments)                        }                    }}            }        })    })(jQuery, DevExpress);    /*! Module widgets-web, file ui.dataGrid.dataController.js */    (function($, DX, undefined) {        var ui = DX.ui,            dataGrid = ui.dxDataGrid,            utils = DX.utils;        dataGrid.proxyMethod = function(instance, methodName, defaultResult) {            if (!instance[methodName])                instance[methodName] = function() {                    var dataSource = this._dataSource;                    return dataSource ? dataSource[methodName].apply(dataSource, arguments) : defaultResult                }        };        dataGrid.combineFilters = function(filters, operation) {            var resultFilter = [],                i;            operation = operation || 'and';            for (i = 0; i < filters.length; i++) {                if (!filters[i])                    continue;                if (resultFilter.length)                    resultFilter.push(operation);                resultFilter.push(filters[i])            }            if (resultFilter.length === 1)                resultFilter = resultFilter[0];            if (resultFilter.length)                return resultFilter        };        dataGrid.DataController = dataGrid.Controller.inherit({}).include(ui.DataHelperMixin).inherit(function() {            var members = {                    init: function() {                        var that = this;                        that._items = [];                        that._columnsController = that.getController('columns');                        that._columnsChangedHandler = $.proxy(that._handleColumnsChanged, that);                        that._dataChangedHandler = $.proxy(that._handleDataChanged, that);                        that._loadingChangedHandler = $.proxy(that._handleLoadingChanged, that);                        that._loadErrorHandler = $.proxy(that._handleLoadError, that);                        that._customizeStoreLoadOptionsHandler = $.proxy(that._handleCustomizeStoreLoadOptions, that);                        that._columnsController.columnsChanged.add(that._columnsChangedHandler);                        that._isLoading = false;                        that._isCustomLoading = false;                        that._refreshDataSource();                        that.createAction('onDataErrorOccurred');                        that.dataErrorOccurred.add(function(error) {                            return that.executeAction('onDataErrorOccurred', {error: error})                        })                    },                    callbackNames: function() {                        return ['changed', 'loadingChanged', 'dataErrorOccurred', 'pageIndexChanged', 'pageSizeChanged', 'filterChanged', 'dataSourceChanged']                    },                    callbackFlags: function(name) {                        if (name === 'dataErrorOccurred')                            return 'stopOnFalse'                    },                    publicMethods: function() {                        return ['beginCustomLoading', 'endCustomLoading', 'refresh', 'filter', 'clearFilter', 'getCombinedFilter', 'keyOf', 'byKey', 'getDataByKeys', 'pageIndex', 'pageSize', 'pageCount', 'totalCount', '_disposeDataSource', 'getKeyByRowIndex', 'getRowIndexByKey']                    },                    optionChanged: function(args) {                        var that = this;                        function handled() {                            args.handled = true                        }                        function reload() {                            that._columnsController.reset();                            that._refreshDataSource()                        }                        switch (args.name) {                            case'loadingTimeout':                            case'remoteOperations':                                handled();                                break;                            case'dataSource':                            case'scrolling':                            case'paging':                                handled();                                reload();                                break;                            case'rtlEnabled':                                reload();                                break;                            default:                                that.callBase(args)                        }                    },                    isReady: function() {                        return !this._isLoading                    },                    getCombinedFilter: function() {                        return this.combinedFilter()                    },                    combinedFilter: function(filter) {                        var that = this,                            dataSource = that._dataSource,                            columnsController = that._columnsController,                            additionalFilter;                        if (dataSource) {                            if (filter === undefined)                                filter = dataSource.filter();                            additionalFilter = that._calculateAdditionalFilter();                            if (additionalFilter)                                if (columnsController.isDataSourceApplied() || columnsController.isAllDataTypesDefined())                                    filter = dataGrid.combineFilters([additionalFilter, filter]);                            columnsController.updateFilter(dataSource, filter)                        }                        return filter                    },                    _handleCustomizeStoreLoadOptions: function(e) {                        var columnsController = this._columnsController,                            dataSource = this._dataSource,                            storeLoadOptions = e.storeLoadOptions;                        if (this._isLoadingAll) {                            storeLoadOptions.isLoadingAll = true;                            delete storeLoadOptions.skip;                            delete storeLoadOptions.take                        }                        storeLoadOptions.filter = this.combinedFilter(storeLoadOptions.filter);                        if (!columnsController.isDataSourceApplied())                            columnsController.updateColumnDataTypes(dataSource);                        this._columnsUpdating = true;                        columnsController.updateSortingGrouping(dataSource, !this._isFirstLoading);                        this._columnsUpdating = false;                        storeLoadOptions.sort = columnsController.getSortDataSourceParameters();                        storeLoadOptions.group = columnsController.getGroupDataSourceParameters();                        dataSource.sort(storeLoadOptions.sort);                        dataSource.group(storeLoadOptions.group);                        e.group = columnsController.getGroupDataSourceParameters(true);                        this._isFirstLoading = false                    },                    _handleColumnsChanged: function(e) {                        var that = this,                            changeTypes = e.changeTypes,                            optionNames = e.optionNames,                            filterValue,                            filterValues;                        var updateItemsHandler = function() {                                that._columnsController.columnsChanged.remove(updateItemsHandler);                                that.updateItems()                            };                        if (changeTypes.sorting || changeTypes.grouping) {                            if (that._dataSource && !that._columnsUpdating) {                                that._dataSource.group(that._columnsController.getGroupDataSourceParameters());                                that._dataSource.sort(that._columnsController.getSortDataSourceParameters());                                that.reload()                            }                        }                        else if (changeTypes.columns) {                            if (optionNames.filterValues || optionNames.filterValue || optionNames.selectedFilterOperation)                                if (this.option("filterRow.applyFilter") !== "onClick" || optionNames.filterValues) {                                    filterValue = that._columnsController.columnOption(e.columnIndex, 'filterValue');                                    filterValues = that._columnsController.columnOption(e.columnIndex, 'filterValues');                                    if (utils.isArray(filterValues) || e.columnIndex === undefined || utils.isDefined(filterValue) || !optionNames.selectedFilterOperation || optionNames.filterValue)                                        that._applyFilter()                                }                            if (!that._needApplyFilter && !dataGrid.checkChanges(optionNames, ['width', 'visibleWidth', 'filterValue', 'selectedFilterOperation', 'filterValues']))                                that._columnsController.columnsChanged.add(updateItemsHandler)                        }                    },                    _handleDataChanged: function(e) {                        var that = this,                            dataSource = that._dataSource,                            columnsController = that._columnsController,                            isAllDataTypesDefined = columnsController.isAllDataTypesDefined();                        if (dataSource && !that._isDataSourceApplying && !that._isLoadingAll) {                            that._isDataSourceApplying = true;                            $.when(that._columnsController.applyDataSource(dataSource)).done(function() {                                if (that._isLoading)                                    that._handleLoadingChanged(false);                                that._isDataSourceApplying = false;                                var additionalFilter = that._calculateAdditionalFilter(),                                    needApplyFilter = that._needApplyFilter;                                that._needApplyFilter = false;                                if (needApplyFilter && additionalFilter && additionalFilter.length && !isAllDataTypesDefined) {                                    DX.log("W1005", that.component.NAME);                                    that._applyFilter()                                }                                else                                    that.updateItems(e)                            });                            if (that._isDataSourceApplying)                                that._handleLoadingChanged(true);                            that._needApplyFilter = !that._columnsController.isDataSourceApplied()                        }                    },                    _handleLoadingChanged: function(isLoading) {                        this._isLoading = isLoading;                        this._fireLoadingChanged()                    },                    _handleLoadError: function(e) {                        this.dataErrorOccurred.fire(e)                    },                    _initDataSource: function() {                        var that = this,                            dataSource = this.option("dataSource"),                            pageIndex = this.option("paging.pageIndex"),                            pageSize = this.option("paging.pageSize"),                            scrollingMode = that.option('scrolling.mode'),                            pagingEnabled = this.option("paging.enabled"),                            appendMode = scrollingMode === 'infinite',                            virtualMode = scrollingMode === 'virtual',                            oldDataSource = this._dataSource;                        that.callBase();                        dataSource = that._dataSource;                        that._dataSource = oldDataSource;                        that._isFirstLoading = true;                        if (dataSource) {                            dataSource.requireTotalCount(!appendMode);                            if (pagingEnabled !== undefined)                                dataSource.paginate(pagingEnabled || virtualMode || appendMode);                            if (pageSize !== undefined)                                dataSource.pageSize(pageSize);                            if (pageIndex !== undefined)                                dataSource.pageIndex(pageIndex);                            that.setDataSource(dataSource)                        }                    },                    _loadDataSource: function() {                        var dataSource = this._dataSource;                        dataSource && dataSource.load()                    },                    _processItems: function(items) {                        var that = this,                            visibleColumns = that._columnsController.getVisibleColumns(),                            options = {                                visibleColumns: visibleColumns,                                dataIndex: 0                            },                            result = [];                        $.each(items, function(index, item) {                            if (utils.isDefined(item)) {                                item = that._processItem(item, options);                                result.push(item)                            }                        });                        return result                    },                    _processItem: function(item, options) {                        item = this._generateDataItem(item);                        item = this._processDataItem(item, options);                        item.dataIndex = options.dataIndex++;                        return item                    },                    _generateDataItem: function(data) {                        return {                                rowType: 'data',                                data: data,                                key: this.keyOf(data)                            }                    },                    _processDataItem: function(dataItem, options) {                        dataItem.values = this._generateDataValues(dataItem.data, options.visibleColumns);                        return dataItem                    },                    _generateDataValues: function(data, columns) {                        var values = [];                        $.each(columns, function() {                            var value = null;                            if (this.command)                                value = null;                            else if (this.calculateCellValue)                                value = this.calculateCellValue(data);                            else if (this.dataField)                                value = data[this.dataField];                            values.push(value)                        });                        return values                    },                    _updateItemsCore: function(change) {                        var that = this,                            items,                            dataSource = that._dataSource,                            changeType = change.changeType;                        if (dataSource) {                            items = change.items || dataSource.items();                            items = that._processItems(items.slice(0), changeType);                            change.items = items;                            change.changeType = changeType || 'refresh';                            switch (changeType) {                                case'prepend':                                    that._items.unshift.apply(that._items, items);                                    break;                                case'append':                                    that._items.push.apply(that._items, items);                                    break;                                case'update':                                    var rowIndices = change.rowIndices.slice(0),                                        rowIndexCorrection = 0;                                    rowIndices.sort(function(a, b) {                                        return a - b                                    });                                    for (var i = 0; i < rowIndices.length; i++)                                        if (rowIndices[i] < 0 || rowIndices[i - 1] === rowIndices[i]) {                                            rowIndices.splice(i, 1);                                            i--                                        }                                    change.items = [];                                    change.rowIndices = [];                                    change.changeTypes = [];                                    var equalItems = function(item1, item2) {                                            return dataGrid.equalKeys(item1.key, item2.key) && item1.rowType === item2.rowType                                        };                                    $.each(rowIndices, function(index, rowIndex) {                                        var oldItem,                                            newItem,                                            oldNextItem,                                            newNextItem;                                        rowIndex += rowIndexCorrection;                                        change.rowIndices.push(rowIndex);                                        oldItem = that._items[rowIndex];                                        oldNextItem = that._items[rowIndex + 1];                                        newItem = items[rowIndex];                                        newNextItem = items[rowIndex + 1];                                        if (newItem)                                            change.items.push(newItem);                                        if (oldItem && newItem && equalItems(oldItem, newItem)) {                                            changeType = 'update';                                            that._items[rowIndex] = newItem;                                            if (oldItem.visible !== newItem.visible)                                                change.items.splice(-1, 1, {visible: newItem.visible})                                        }                                        else if (newItem && !oldItem || newNextItem && equalItems(oldItem, newNextItem)) {                                            changeType = 'insert';                                            that._items.splice(rowIndex, 0, newItem);                                            rowIndexCorrection++                                        }                                        else if (oldItem && !newItem || oldNextItem && equalItems(newItem, oldNextItem)) {                                            changeType = 'remove';                                            that._items.splice(rowIndex, 1);                                            rowIndexCorrection--                                        }                                        change.changeTypes.push(changeType)                                    });                                    break;                                default:                                    that._items = items.slice(0);                                    break                            }                            $.each(that._items, function(index, item) {                                item.rowIndex = index                            })                        }                    },                    updateItems: function(change) {                        var that = this;                        change = change || {};                        if (that._dataSource && that._columnsController.isDataSourceApplied()) {                            that._updateItemsCore(change);                            that.changed.fire(change)                        }                    },                    isLoading: function() {                        return this._isLoading || this._isCustomLoading                    },                    _fireLoadingChanged: function(messageText) {                        this.loadingChanged.fire(this.isLoading(), messageText)                    },                    _calculateAdditionalFilter: function() {                        return null                    },                    _applyFilter: function() {                        var that = this,                            dataSource = that._dataSource;                        if (dataSource) {                            dataSource.pageIndex(0);                            return that.reload().done($.proxy(that.filterChanged, 'fire'))                        }                    },                    filter: function(filterExpr) {                        var dataSource = this._dataSource;                        if (arguments.length === 0)                            return dataSource ? dataSource.filter() : undefined;                        filterExpr = arguments.length > 1 ? Array.prototype.slice.call(arguments, 0) : filterExpr;                        if (dataSource)                            dataSource.filter(filterExpr);                        this._applyFilter()                    },                    clearFilter: function(filterName) {                        var that = this,                            columnsController = that._columnsController,                            clearColumnOption = function(optionName) {                                var columnCount = columnsController.columnCount(),                                    index;                                for (index = 0; index < columnCount; index++)                                    columnsController.columnOption(index, optionName, undefined)                            };                        that.component.beginUpdate();                        if (arguments.length > 0)                            switch (filterName) {                                case"dataSource":                                    that.filter(null);                                    break;                                case"search":                                    that.searchByText("");                                    break;                                case"header":                                    clearColumnOption("filterValues");                                    break;                                case"row":                                    clearColumnOption("filterValue");                                    break                            }                        else {                            that.filter(null);                            that.searchByText("");                            clearColumnOption("filterValue");                            clearColumnOption("filterValues")                        }                        that.component.endUpdate()                    },                    _fireDataSourceChanged: function() {                        var that = this;                        var changedHandler = function() {                                that.changed.remove(changedHandler);                                that.dataSourceChanged.fire()                            };                        that.changed.add(changedHandler)                    },                    _getDataSourceAdapterType: function(remoteOperations) {                        return remoteOperations && remoteOperations.filtering && remoteOperations.sorting && remoteOperations.paging ? dataGrid.DataSourceAdapterServer : dataGrid.DataSourceAdapterClient                    },                    _createDataSourceAdapterCore: function(dataSource, remoteOperations) {                        var dataSourceAdapterType,                            dataSourceAdapter;                        if (remoteOperations === 'auto')                            remoteOperations = !(dataSource.store() instanceof DX.data.ArrayStore);                        if (remoteOperations === true)                            remoteOperations = {                                filtering: true,                                sorting: true,                                paging: true                            };                        dataSourceAdapterType = this._getDataSourceAdapterType(remoteOperations);                        dataSourceAdapter = new dataSourceAdapterType(this.component);                        dataSourceAdapter.init(dataSource, remoteOperations);                        return dataSourceAdapter                    },                    _createDataSourceAdapter: function(dataSource) {                        var remoteOperations = this.option("remoteOperations");                        return this._createDataSourceAdapterCore(dataSource, remoteOperations)                    },                    setDataSource: function(dataSource) {                        var that = this;                        if (that._dataSource) {                            that._dataSource.changed.remove(that._dataChangedHandler);                            that._dataSource.loadingChanged.remove(that._loadingChangedHandler);                            that._dataSource.loadError.remove(that._loadErrorHandler);                            that._dataSource.customizeStoreLoadOptions.remove(that._customizeStoreLoadOptionsHandler);                            that._dataSource.dispose(that._isSharedDataSource)                        }                        if (dataSource)                            dataSource = that._createDataSourceAdapter(dataSource);                        that._dataSource = dataSource;                        if (dataSource) {                            that._fireDataSourceChanged();                            that._isLoading = !dataSource.isLoaded();                            that._needApplyFilter = true;                            dataSource.changed.add(that._dataChangedHandler);                            dataSource.loadingChanged.add(that._loadingChangedHandler);                            dataSource.loadError.add(that._loadErrorHandler);                            dataSource.customizeStoreLoadOptions.add(that._customizeStoreLoadOptionsHandler)                        }                    },                    items: function() {                        return this._items                    },                    isEmpty: function() {                        return !this.items().length                    },                    pageCount: function() {                        return this._dataSource ? this._dataSource.pageCount() : 1                    },                    dataSource: function() {                        return this._dataSource                    },                    store: function() {                        var dataSource = this._dataSource;                        return dataSource && dataSource.store()                    },                    loadAll: function(data) {                        var that = this,                            d = $.Deferred(),                            dataSource = that._dataSource;                        if (dataSource)                            if (data) {                                var options = {                                        data: data,                                        loadOptions: {                                            isLoadingAll: true,                                            group: dataSource.group(),                                            sort: dataSource.sort()                                        }                                    };                                dataSource._handleDataLoaded(options);                                d.resolve(that._processItems(options.data), options.totalAggregates)                            }                            else if (!that.isLoading()) {                                that._isLoadingAll = true;                                dataSource.load(true).done(function(items) {                                    items = that._processItems(items.slice(0));                                    d.resolve(items)                                }).fail(d.reject).always(function() {                                    that._isLoadingAll = false                                })                            }                            else                                d.reject();                        else                            d.resolve([]);                        return d                    },                    getKeyByRowIndex: function(rowIndex) {                        var item = this.items()[rowIndex];                        if (item)                            return item.key                    },                    getRowIndexByKey: function(key) {                        return dataGrid.getIndexByKey(key, this.items())                    },                    keyOf: function(data) {                        var store = this.store();                        if (store)                            return store.keyOf(data)                    },                    byKey: function(key) {                        var store = this.store(),                            rowIndex = this.getRowIndexByKey(key),                            result;                        if (!store)                            return;                        if (rowIndex >= 0)                            result = $.Deferred().resolve(this.items()[rowIndex].data);                        return result || store.byKey(key)                    },                    getDataByKeys: function(rowKeys) {                        var that = this,                            result = $.Deferred(),                            deferreds = [],                            data = [];                        $.each(rowKeys, function(index, key) {                            deferreds.push(that.byKey(key).done(function(keyData) {                                data[index] = keyData                            }))                        });                        $.when.apply($, deferreds).always(function() {                            result.resolve(data)                        });                        return result                    },                    pageIndex: function(value) {                        var that = this,                            dataSource = that._dataSource;                        if (dataSource) {                            if (value !== undefined)                                if (dataSource.pageIndex() !== value) {                                    dataSource.pageIndex(value);                                    return dataSource.load().done($.proxy(that.pageIndexChanged, 'fire'))                                }                            return dataSource.pageIndex()                        }                        return 0                    },                    pageSize: function(value) {                        var that = this,                            pagingOptions = that.option("paging"),                            dataSource = that._dataSource;                        if (value === undefined)                            return dataSource ? dataSource.pageSize() : 0;                        if (dataSource)                            if (dataSource.pageSize() !== value) {                                dataSource.pageIndex(0);                                dataSource.pageSize(value);                                if (pagingOptions)                                    pagingOptions.pageSize = value;                                return dataSource.reload().done($.proxy(that.pageSizeChanged, 'fire'))                            }                    },                    beginCustomLoading: function(messageText) {                        this._isCustomLoading = true;                        this._fireLoadingChanged(messageText)                    },                    endCustomLoading: function() {                        this._isCustomLoading = false;                        this._fireLoadingChanged()                    },                    refresh: function() {                        var that = this,                            d = $.Deferred();                        $.when(this._columnsController.refresh()).always(function() {                            $.when(that.reload()).done(d.resolve).fail(d.reject)                        });                        return d                    },                    _disposeDataSource: function() {                        this.setDataSource(null)                    }                };            dataGrid.proxyMethod(members, 'load');            dataGrid.proxyMethod(members, 'reload');            dataGrid.proxyMethod(members, 'itemsCount', 0);            dataGrid.proxyMethod(members, 'totalItemsCount', 0);            dataGrid.proxyMethod(members, 'hasKnownLastPage', true);            dataGrid.proxyMethod(members, 'isLoaded', false);            dataGrid.proxyMethod(members, 'totalCount', 0);            return members        }());        dataGrid.registerModule('data', {            defaultOptions: function() {                return {                        loadingTimeout: 0,                        dataSource: null,                        onDataErrorOccurred: null,                        remoteOperations: 'auto',                        paging: {                            enabled: true,                            pageSize: undefined,                            pageIndex: undefined                        }                    }            },            controllers: {data: ui.dxDataGrid.DataController}        })    })(jQuery, DevExpress);    /*! Module widgets-web, file ui.dataGrid.dataSourceAdapter.js */    (function($, DX) {        var ui = DX.ui,            dataGrid = ui.dxDataGrid;        dataGrid.DataSourceAdapterServer = dataGrid.Controller.inherit(function() {            return {                    init: function(dataSource, remoteOperations) {                        var that = this;                        that._dataSource = dataSource;                        that._remoteOperations = remoteOperations;                        that._isLastPage = !dataSource.isLastPage();                        that._hasLastPage = false;                        that._currentTotalCount = 0;                        that.changed = $.Callbacks();                        that.loadingChanged = $.Callbacks();                        that.loadError = $.Callbacks();                        that.customizeStoreLoadOptions = $.Callbacks();                        that._dataChangedHandler = $.proxy(that._handleDataChanged, that);                        that._dataLoadingHandler = $.proxy(that._handleDataLoading, that);                        that._dataLoadedHandler = $.proxy(that._handleDataLoaded, that);                        that._loadingChangedHandler = $.proxy(that._handleLoadingChanged, that);                        that._loadErrorHandler = $.proxy(that._handleLoadError, that);                        dataSource.on("changed", that._dataChangedHandler);                        dataSource.on("customizeStoreLoadOptions", that._dataLoadingHandler);                        dataSource.on("customizeLoadResult", that._dataLoadedHandler);                        dataSource.on("loadingChanged", that._loadingChangedHandler);                        dataSource.on("loadError", that._loadErrorHandler);                        $.each(dataSource, function(memberName, member) {                            if (!that[memberName] && $.isFunction(member))                                that[memberName] = function() {                                    return this._dataSource[memberName].apply(this._dataSource, arguments)                                }                        })                    },                    dispose: function(isSharedDataSource) {                        var that = this,                            dataSource = that._dataSource;                        dataSource.off("changed", that._dataChangedHandler);                        dataSource.off("customizeStoreLoadOptions", that._dataLoadingHandler);                        dataSource.off("customizeLoadResult", that._dataLoadedHandler);                        dataSource.off("loadingChanged", that._loadingChangedHandler);                        dataSource.off("loadError", that._loadErrorHandler);                        if (!isSharedDataSource)                            dataSource.dispose()                    },                    refresh: function(storeLoadOptions, isReload) {                        var that = this,                            dataSource = that._dataSource;                        if (isReload) {                            that._currentTotalCount = 0;                            that._isLastPage = !dataSource.paginate();                            that._hasLastPage = that._isLastPage                        }                    },                    _handleDataLoading: function(options) {                        var that = this;                        that.customizeStoreLoadOptions.fire(options);                        options.delay = this.option("loadingTimeout");                        options.originalStoreLoadOptions = options.storeLoadOptions;                        var isReload = !that.isLoaded() && !that._isRefreshing;                        that._isRefreshing = true;                        $.when(that.refresh(options.storeLoadOptions, isReload)).always(function() {                            if (that._lastOperationId === options.operationId)                                that.load();                            that._isRefreshing = false                        });                        that._dataSource.cancel(that._lastOperationId);                        that._lastOperationId = options.operationId;                        if (that._isRefreshing)                            that._dataSource.cancel(that._lastOperationId)                    },                    _handleDataLoaded: function(options) {                        options.storeLoadOptions = options.originalStoreLoadOptions                    },                    _handleLoadingChanged: function(isLoading) {                        this.loadingChanged.fire(isLoading)                    },                    _handleLoadError: function(error) {                        this.changed.fire({                            changeType: 'loadError',                            error: error                        });                        this.loadError.fire(error)                    },                    _handleDataChanged: function(args) {                        var that = this,                            currentTotalCount,                            dataSource = that._dataSource,                            itemsCount = that.itemsCount();                        that._isLastPage = !itemsCount || !that.pageSize() || itemsCount < that.pageSize();                        if (that._isLastPage)                            that._hasLastPage = true;                        if (dataSource.totalCount() >= 0) {                            if (dataSource.pageIndex() >= that.pageCount()) {                                dataSource.pageIndex(that.pageCount() - 1);                                dataSource.load()                            }                        }                        else {                            currentTotalCount = dataSource.pageIndex() * that.pageSize() + itemsCount;                            that._currentTotalCount = Math.max(that._currentTotalCount, currentTotalCount);                            if (itemsCount === 0 && dataSource.pageIndex() >= that.pageCount()) {                                dataSource.pageIndex(that.pageCount() - 1);                                dataSource.load()                            }                        }                        if (!dataSource.isLoading())                            this.changed.fire(args)                    },                    isLastPage: function() {                        return this._isLastPage                    },                    totalCount: function() {                        return parseInt(this._currentTotalCount || this._dataSource.totalCount())                    },                    itemsCount: function() {                        return this._dataSource.items().length                    },                    totalItemsCount: function() {                        return this.totalCount()                    },                    pageSize: function() {                        var dataSource = this._dataSource;                        if (!arguments.length && !dataSource.paginate())                            return 0;                        return dataSource.pageSize.apply(dataSource, arguments)                    },                    pageCount: function() {                        var that = this,                            count = that.totalItemsCount(),                            pageSize = that.pageSize();                        if (pageSize && count > 0)                            return Math.max(1, Math.ceil(count / pageSize));                        return 1                    },                    hasKnownLastPage: function() {                        return this._hasLastPage || this._dataSource.totalCount() >= 0                    }                }        }());        dataGrid.DataSourceAdapterClient = dataGrid.DataSourceAdapterServer.inherit({            _handleDataLoading: function(options) {                this.callBase(options);                var remoteOperations = this._remoteOperations || {},                    loadOptions = options.loadOptions = options.storeLoadOptions;                options.storeLoadOptions = {userData: loadOptions.userData};                if (remoteOperations.filtering) {                    options.storeLoadOptions.filter = loadOptions.filter;                    delete loadOptions.filter                }                if (remoteOperations.sorting) {                    options.storeLoadOptions.sort = loadOptions.sort;                    delete loadOptions.sort                }                this._handleDataLoadingCore(options)            },            _handleDataLoadingCore: function(){},            _handleDataLoaded: function(options) {                var callBase = this.callBase,                    loadOptions = options.loadOptions;                if (!loadOptions) {                    this._dataSource.cancel(options.operationId);                    return                }                options.skip = loadOptions.skip;                options.take = loadOptions.take;                delete loadOptions.skip;                delete loadOptions.take;                new DX.data.ArrayStore(options.data).load(loadOptions).done(function(data) {                    options.data = data;                    if (loadOptions.requireTotalCount)                        options.extra = options.extra || {totalCount: data.length}                });                this._handleDataLoadedCore(options);                callBase.apply(this, arguments)            },            _handleDataLoadedCore: function(options) {                if (options.skip !== undefined)                    options.data = options.data.slice(options.skip);                if (options.take !== undefined)                    options.data = options.data.slice(0, options.take)            }        })    })(jQuery, DevExpress);    /*! Module widgets-web, file ui.dataGrid.groupingModule.js */    (function($, DX) {        var ui = DX.ui,            dataGrid = ui.dxDataGrid,            utils = DX.utils,            normalizeSortingInfo = DX.data.utils.normalizeSortingInfo;        var DATAGRID_GROUP_PANEL_CLASS = "dx-datagrid-group-panel",            DATAGRID_GROUP_PANEL_MESSAGE_CLASS = "dx-group-panel-message",            DATAGRID_GROUP_PANEL_ITEM_CLASS = "dx-group-panel-item",            DATAGRID_GROUP_OPENED_CLASS = "dx-datagrid-group-opened",            DATAGRID_GROUP_CLOSED_CLASS = "dx-datagrid-group-closed",            DATAGRID_EXPAND_CLASS = "dx-datagrid-expand",            DATAGRID_SELECTION_DISABLED_CLASS = "dx-selection-disabled";        var GroupingDataSourceAdapterExtender = function() {                var findGroupInfoByKey = function(groupsInfo, key) {                        var i;                        for (i = 0; i < groupsInfo.length; i++)                            if (DX.data.utils.keysEqual(null, groupsInfo[i].key, key))                                return groupsInfo[i]                    };                var getGroupInfoIndexByOffset = function(groupsInfo, offset) {                        var index;                        for (index = 0; index < groupsInfo.length; index++)                            if (groupsInfo[index].offset > offset)                                break;                        return index                    };                var updateGroupInfoOffsets = function(groupsInfo) {                        var groupInfo,                            index,                            newIndex;                        for (index = 0; index < groupsInfo.length; index++) {                            groupInfo = groupsInfo[index];                            if (groupInfo.data && groupInfo.data.offset !== groupInfo.offset) {                                groupsInfo.splice(index, 1);                                groupInfo.offset = groupInfo.data.offset;                                newIndex = getGroupInfoIndexByOffset(groupsInfo, groupInfo.offset);                                groupsInfo.splice(newIndex, 0, groupInfo);                                if (newIndex > index)                                    index--                            }                        }                    };                var cleanGroupsInfo = function(groupsInfo, groupIndex, groupsCount) {                        var i;                        for (i = 0; i < groupsInfo.length; i++)                            if (groupIndex + 1 >= groupsCount)                                groupsInfo[i].children = [];                            else                                cleanGroupsInfo(groupsInfo[i].children, groupIndex + 1, groupsCount)                    };                return {                        init: function() {                            this.callBase.apply(this, arguments);                            this.reset()                        },                        reset: function() {                            this._groupsInfo = [];                            this._totalCountCorrection = 0                        },                        totalItemsCount: function() {                            var that = this,                                totalCount = that.callBase();                            return totalCount > 0 && that._dataSource.group() && that._dataSource.requireTotalCount() ? totalCount + that._totalCountCorrection : totalCount                        },                        itemsCount: function() {                            return this._dataSource.group() ? this._itemsCount || 0 : this.callBase()                        },                        updateTotalItemsCount: function(totalCountCorrection) {                            this._totalCountCorrection = totalCountCorrection || 0                        },                        _isGroupItemCountable: function(item) {                            return !this._isVirtualPaging() || !item.isContinuation                        },                        _isVirtualPaging: function() {                            var scrollingMode = this.option("scrolling.mode");                            return scrollingMode === 'virtual' || scrollingMode === 'infinite'                        },                        updateItemsCount: function(data, groupsCount) {                            function calculateItemsCount(that, items, groupsCount) {                                var i,                                    result = 0;                                if (items)                                    if (!groupsCount)                                        result = items.length;                                    else                                        for (i = 0; i < items.length; i++) {                                            if (that._isGroupItemCountable(items[i]))                                                result++;                                            result += calculateItemsCount(that, items[i].items, groupsCount - 1)                                        }                                return result                            }                            this._itemsCount = calculateItemsCount(this, data, groupsCount)                        },                        foreachGroups: function(callback, childrenAtFirst, foreachCollapsedGroups) {                            var that = this;                            function foreachGroupsCore(groupsInfo, callback, childrenAtFirst, parents) {                                var i,                                    callbackResult,                                    callbackResults = [];                                function executeCallback(callback, data, parents, callbackResults) {                                    var callbackResult = data && callback(data, parents);                                    callbackResults.push(callbackResult);                                    return callbackResult                                }                                for (i = 0; i < groupsInfo.length; i++) {                                    parents.push(groupsInfo[i].data);                                    if (!childrenAtFirst && executeCallback(callback, groupsInfo[i].data, parents, callbackResults) === false)                                        return false;                                    if (!groupsInfo[i].data || groupsInfo[i].data.isExpanded || foreachCollapsedGroups) {                                        callbackResult = foreachGroupsCore(groupsInfo[i].children, callback, childrenAtFirst, parents);                                        callbackResults.push(callbackResult);                                        if (callbackResult === false)                                            return false                                    }                                    if (childrenAtFirst && executeCallback(callback, groupsInfo[i].data, parents, callbackResults) === false)                                        return false;                                    parents.pop()                                }                                return $.when.apply($, callbackResults).always(function() {                                        updateGroupInfoOffsets(groupsInfo)                                    })                            }                            return foreachGroupsCore(that._groupsInfo, callback, childrenAtFirst, [])                        },                        findGroupInfo: function(path) {                            var that = this,                                pathIndex,                                groupInfo,                                groupsInfo = that._groupsInfo;                            for (pathIndex = 0; groupsInfo && pathIndex < path.length; pathIndex++) {                                groupInfo = findGroupInfoByKey(groupsInfo, path[pathIndex]);                                groupsInfo = groupInfo && groupInfo.children                            }                            return groupInfo && groupInfo.data                        },                        addGroupInfo: function(groupInfoData) {                            var that = this,                                index,                                groupInfo,                                path = groupInfoData.path,                                pathIndex,                                groupsInfo = that._groupsInfo;                            for (pathIndex = 0; pathIndex < path.length; pathIndex++) {                                groupInfo = findGroupInfoByKey(groupsInfo, path[pathIndex]);                                if (!groupInfo) {                                    groupInfo = {                                        key: path[pathIndex],                                        offset: groupInfoData.offset,                                        children: []                                    };                                    index = getGroupInfoIndexByOffset(groupsInfo, groupInfoData.offset);                                    groupsInfo.splice(index, 0, groupInfo)                                }                                if (pathIndex === path.length - 1) {                                    groupInfo.data = groupInfoData;                                    updateGroupInfoOffsets(groupsInfo)                                }                                groupsInfo = groupInfo.children                            }                        },                        allowCollapseAll: function() {                            return true                        },                        isRowExpanded: function(key) {                            var groupInfo = this.findGroupInfo(key);                            return groupInfo ? groupInfo.isExpanded : !this.allowCollapseAll()                        },                        collapseAll: function(groupIndex) {                            if (!this.allowCollapseAll()) {                                DX.log("E1018");                                return false                            }                            return this._collapseExpandAll(groupIndex, false)                        },                        expandAll: function(groupIndex) {                            return this._collapseExpandAll(groupIndex, true)                        },                        _collapseExpandAll: function(groupIndex, isExpand) {                            var that = this,                                dataSource = that._dataSource,                                group = dataSource.group(),                                groups = normalizeSortingInfo(group || []),                                i;                            if (groups.length) {                                for (i = 0; i < groups.length; i++)                                    if (groupIndex === undefined || groupIndex === i)                                        groups[i].isExpanded = isExpand;                                    else if (group && group[i])                                        groups[i].isExpanded = group[i].isExpanded;                                dataSource.group(groups);                                that.foreachGroups(function(groupInfo, parents) {                                    if (groupIndex === undefined || groupIndex === parents.length - 1)                                        groupInfo.isExpanded = isExpand                                }, false, true)                            }                            return true                        },                        refresh: function(storeLoadOptions) {                            this.callBase.apply(this, arguments);                            var that = this,                                groupIndex,                                oldGroups = normalizeSortingInfo(that._group || []),                                groups = normalizeSortingInfo(storeLoadOptions.group || []),                                groupsCount = Math.min(oldGroups.length, groups.length);                            that._group = storeLoadOptions.group;                            for (groupIndex = 0; groupIndex < groupsCount; groupIndex++)                                if (oldGroups[groupIndex].selector !== groups[groupIndex].selector) {                                    groupsCount = groupIndex;                                    break                                }                            if (!groupsCount)                                that.reset();                            else                                cleanGroupsInfo(that._groupsInfo, 0, groupsCount)                        },                        changeRowExpand: function(path) {                            var that = this,                                dataSource = that._dataSource;                            if (dataSource.group()) {                                dataSource._changeLoadingCount(1);                                return that._changeRowExpandCore(path).always(function() {                                        dataSource._changeLoadingCount(-1)                                    })                            }                        }                    }            }();        dataGrid.DataSourceAdapterClient = dataGrid.DataSourceAdapterClient.inherit(GroupingDataSourceAdapterExtender);        dataGrid.DataSourceAdapterServer = dataGrid.DataSourceAdapterServer.inherit(GroupingDataSourceAdapterExtender);        var GroupingDataControllerExtender = function() {                return {                        init: function() {                            var that = this;                            that.callBase();                            that.createAction('onRowExpanding');                            that.createAction('onRowExpanded');                            that.createAction('onRowCollapsing');                            that.createAction('onRowCollapsed')                        },                        _processItems: function(items) {                            var groupColumns = this._columnsController.getGroupColumns();                            if (items.length && groupColumns.length)                                items = this._processGroupItems(items, groupColumns.length);                            return this.callBase(items)                        },                        _processItem: function(item, options) {                            if (utils.isDefined(item.groupIndex) && utils.isString(item.rowType) && item.rowType.indexOf("group") === 0) {                                item = this._processGroupItem(item, options);                                options.dataIndex = 0                            }                            else                                item = this.callBase.apply(this, arguments);                            return item                        },                        _processGroupItem: function(item, options) {                            return item                        },                        _processGroupItems: function(items, groupsCount, options) {                            var that = this,                                scrollingMode,                                i,                                item,                                resultItems,                                path;                            if (!options) {                                scrollingMode = that.option('scrolling.mode');                                options = {                                    collectContinuationItems: scrollingMode !== 'virtual' && scrollingMode !== 'infinite',                                    resultItems: [],                                    path: []                                }                            }                            resultItems = options.resultItems;                            path = options.path;                            if (options.data)                                if (options.collectContinuationItems || !options.data.isContinuation)                                    resultItems.push({                                        rowType: 'group',                                        data: options.data,                                        groupIndex: path.length - 1,                                        isExpanded: !!options.data.items,                                        key: path,                                        values: path                                    });                            if (items)                                if (groupsCount === 0)                                    resultItems.push.apply(resultItems, items);                                else                                    for (i = 0; i < items.length; i++) {                                        item = items[i];                                        if (item) {                                            options.data = item;                                            options.path = path.concat(item.key);                                            that._processGroupItems(item.items, groupsCount - 1, options);                                            options.data = undefined;                                            options.path = path                                        }                                    }                            return resultItems                        },                        publicMethods: function() {                            return this.callBase().concat(['collapseAll', 'expandAll', 'isRowExpanded', 'expandRow', 'collapseRow'])                        },                        collapseAll: function(groupIndex) {                            var dataSource = this._dataSource;                            if (dataSource && dataSource.collapseAll(groupIndex)) {                                dataSource.pageIndex(0);                                dataSource.reload()                            }                        },                        expandAll: function(groupIndex) {                            var dataSource = this._dataSource;                            if (dataSource && dataSource.expandAll(groupIndex)) {                                dataSource.pageIndex(0);                                dataSource.reload()                            }                        },                        changeRowExpand: function(key) {                            var that = this,                                expanded = that.isRowExpanded(key),                                args = {                                    key: key,                                    expanded: expanded                                };                            that.executeAction(expanded ? "onRowCollapsing" : "onRowExpanding", args);                            if (!args.cancel)                                return $.when(that._changeRowExpandCore(key)).done(function() {                                        args.expanded = !expanded;                                        that.executeAction(expanded ? "onRowCollapsed" : "onRowExpanded", args)                                    })                        },                        _changeRowExpandCore: function(key) {                            var that = this,                                dataSource = this._dataSource,                                d;                            if (!dataSource)                                return;                            d = $.Deferred();                            $.when(dataSource.changeRowExpand(key)).done(function() {                                that.load().done(d.resolve).fail(d.reject)                            }).fail(d.reject);                            return d                        },                        isRowExpanded: function(key) {                            var dataSource = this._dataSource;                            return dataSource && dataSource.isRowExpanded(key)                        },                        expandRow: function(key) {                            if (!this.isRowExpanded(key))                                this.changeRowExpand(key)                        },                        collapseRow: function(key) {                            if (this.isRowExpanded(key))                                this.changeRowExpand(key)                        },                        optionChanged: function(args) {                            if (args.name === "grouping")                                args.name = "dataSource";                            this.callBase(args)                        }                    }            }();        var GroupingHeaderPanelExtender = function() {                return {                        _renderGroupPanel: function() {                            var that = this,                                $element = that.element(),                                groupPanelOptions = that.option("groupPanel"),                                $groupPanel,                                groupColumns = that.getController('columns').getGroupColumns();                            $groupPanel = $element.find('.' + DATAGRID_GROUP_PANEL_CLASS);                            if (groupPanelOptions && groupPanelOptions.visible) {                                if (!$groupPanel.length)                                    $groupPanel = $('<div />').addClass(DATAGRID_GROUP_PANEL_CLASS).prependTo($element);                                else                                    $groupPanel.show();                                that._renderGroupPanelItems($groupPanel, groupColumns);                                if (groupPanelOptions.allowColumnDragging && !groupColumns.length)                                    $('<div />').addClass(DATAGRID_GROUP_PANEL_MESSAGE_CLASS).text(groupPanelOptions.emptyPanelText).appendTo($groupPanel)                            }                            else                                $groupPanel.hide()                        },                        _renderGroupPanelItems: function($groupPanel, groupColumns) {                            var that = this;                            $groupPanel.empty();                            $.each(groupColumns, function(index, groupColumn) {                                that._createGroupPanelItem($groupPanel, groupColumn)                            })                        },                        _createGroupPanelItem: function($rootElement, groupColumn) {                            return $('<div />').addClass(groupColumn.cssClass).addClass(DATAGRID_GROUP_PANEL_ITEM_CLASS).appendTo($rootElement).text(groupColumn.caption)                        },                        _renderCore: function() {                            this.callBase.apply(this, arguments);                            this._renderGroupPanel()                        },                        allowDragging: function(column) {                            var groupPanelOptions = this.option("groupPanel");                            return groupPanelOptions && groupPanelOptions.visible && groupPanelOptions.allowColumnDragging && column && column.allowGrouping                        },                        getColumnElements: function() {                            var $element = this.element();                            return $element && $element.find('.' + DATAGRID_GROUP_PANEL_ITEM_CLASS)                        },                        getColumns: function() {                            return this.getController('columns').getGroupColumns()                        },                        getBoundingRect: function() {                            var that = this,                                $element = that.element(),                                offset;                            if ($element && $element.find('.' + DATAGRID_GROUP_PANEL_CLASS).length) {                                offset = $element.offset();                                return {                                        top: offset.top,                                        bottom: offset.top + $element.height()                                    }                            }                            return null                        },                        getName: function() {                            return 'group'                        },                        isVisible: function() {                            return this.callBase() || this.option('groupPanel.visible')                        },                        optionChanged: function(args) {                            if (args.name === "groupPanel") {                                this._renderGroupPanel();                                args.handled = true                            }                            else                                this.callBase(args)                        }                    }            }();        dataGrid.GroupingHeaderPanelExtender = GroupingHeaderPanelExtender;        var GroupingRowsViewExtender = function() {                return {                        _rowClick: function(e) {                            var that = this,                                dataController = that.getController('data'),                                $expandElement = $(e.jQueryEvent.target).closest('.' + DATAGRID_EXPAND_CLASS),                                key;                            if ($expandElement.length) {                                key = dataController.getKeyByRowIndex(e.rowIndex);                                dataController.changeRowExpand(key);                                e.jQueryEvent.preventDefault();                                e.handled = true                            }                            that.callBase(e)                        },                        _getDefaultTemplate: function(column) {                            var that = this;                            if (column.command === "expand")                                return function(container, options) {                                        if (utils.isDefined(options.value) && !(options.data && options.data.isContinuation) && !options.row.inserted) {                                            container.addClass(DATAGRID_EXPAND_CLASS).addClass(DATAGRID_SELECTION_DISABLED_CLASS);                                            $("<div>").addClass(options.value ? DATAGRID_GROUP_OPENED_CLASS : DATAGRID_GROUP_CLOSED_CLASS).appendTo(container);                                            that.setAria("label", options.value ? Globalize.localize("dxDataGrid-ariaCollapse") : Globalize.localize("dxDataGrid-ariaExpand"), container)                                        }                                    };                            return that.callBase(column)                        }                    }            }();        $.extend(dataGrid.__internals, {            DATAGRID_GROUP_PANEL_CLASS: DATAGRID_GROUP_PANEL_CLASS,            DATAGRID_GROUP_PANEL_MESSAGE_CLASS: DATAGRID_GROUP_PANEL_MESSAGE_CLASS,            DATAGRID_GROUP_PANEL_ITEM_CLASS: DATAGRID_GROUP_PANEL_ITEM_CLASS,            DATAGRID_GROUP_OPENED_CLASS: DATAGRID_GROUP_OPENED_CLASS,            DATAGRID_GROUP_CLOSED_CLASS: DATAGRID_GROUP_CLOSED_CLASS,            DATAGRID_EXPAND_CLASS: DATAGRID_EXPAND_CLASS,            DATAGRID_SELECTION_DISABLED_CLASS: DATAGRID_SELECTION_DISABLED_CLASS        });        dataGrid.registerModule('grouping', {            defaultOptions: function() {                return {                        grouping: {                            autoExpandAll: true,                            allowCollapsing: true,                            groupContinuesMessage: Globalize.localize("dxDataGrid-groupContinuesMessage"),                            groupContinuedMessage: Globalize.localize("dxDataGrid-groupContinuedMessage")                        },                        groupPanel: {                            visible: false,                            emptyPanelText: Globalize.localize("dxDataGrid-groupPanelEmptyText"),                            allowColumnDragging: true                        }                    }            },            extenders: {                controllers: {data: GroupingDataControllerExtender},                views: {                    headerPanel: GroupingHeaderPanelExtender,                    rowsView: GroupingRowsViewExtender                }            }        })    })(jQuery, DevExpress);    /*! Module widgets-web, file ui.dataGrid.grouping.server.js */    (function($, DX) {        var dataUtils = DX.data.utils,            dataGrid = DX.ui.dxDataGrid,            normalizeSortingInfo = dataGrid.normalizeSortingInfo,            keysEqual = dataUtils.keysEqual;        var loadTotalCount = function(store, options) {                var d = $.Deferred(),                    loadOptions = $.extend({                        skip: 0,                        take: 1,                        requireTotalCount: true                    }, options);                store.load(loadOptions).done(function(data, extra) {                    if (extra && isFinite(extra.totalCount))                        d.resolve(extra.totalCount);                    else                        store.totalCount(options).done($.proxy(d.resolve, d)).fail($.proxy(d.reject, d))                }).fail($.proxy(d.reject, d));                return d            };        dataGrid.DataSourceAdapterServer = dataGrid.DataSourceAdapterServer.inherit(function() {            var foreachCollapsedGroups = function(that, callback) {                    return that.foreachGroups(function(groupInfo) {                            if (!groupInfo.isExpanded)                                return callback(groupInfo)                        })                };            var correctSkipLoadOption = function(that, skip) {                    var skipCorrection = 0,                        resultSkip = skip || 0;                    if (skip) {                        foreachCollapsedGroups(that, function(groupInfo) {                            if (groupInfo.offset - skipCorrection >= skip)                                return false;                            skipCorrection += groupInfo.count - 1                        });                        resultSkip += skipCorrection                    }                    return resultSkip                };            var processGroupItems = function(that, items, path, offset, skipFirstItem, take) {                    var i,                        item,                        offsetInfo,                        removeLastItemsCount = 0,                        needRemoveFirstItem = false;                    for (i = 0; i < items.length; i++) {                        item = items[i];                        if (item.items !== undefined) {                            path.push(item.key);                            var groupInfo = that.findGroupInfo(path);                            if (groupInfo && !groupInfo.isExpanded) {                                item.collapsedItems = item.items;                                item.items = null;                                offset += groupInfo.count;                                take--;                                if (take < 0)                                    removeLastItemsCount++;                                if (skipFirstItem)                                    needRemoveFirstItem = true                            }                            else if (item.items) {                                offsetInfo = processGroupItems(that, item.items, path, offset, skipFirstItem, take);                                if (skipFirstItem)                                    if (offsetInfo.offset - offset > 1)                                        item.isContinuation = true;                                    else                                        needRemoveFirstItem = true;                                offset = offsetInfo.offset;                                take = offsetInfo.take;                                if (take < 0)                                    if (item.items.length)                                        item.isContinuationOnNextPage = true;                                    else                                        removeLastItemsCount++                            }                            path.pop()                        }                        else {                            if (skipFirstItem)                                needRemoveFirstItem = true;                            offset++;                            take--;                            if (take < 0)                                removeLastItemsCount++                        }                        skipFirstItem = false                    }                    if (needRemoveFirstItem)                        items.splice(0, 1);                    if (removeLastItemsCount)                        items.splice(-removeLastItemsCount, removeLastItemsCount);                    return {                            offset: offset,                            take: take                        }                };            var pathEquals = function(path1, path2) {                    var i;                    if (path1.length !== path2.length)                        return false;                    for (i = 0; i < path1.length; i++)                        if (!keysEqual(null, path1[i], path2[i]))                            return false;                    return true                };            var updateGroupOffsets = function(that, items, path, offset, additionalGroupInfo) {                    var i,                        item;                    if (!items)                        return;                    for (i = 0; i < items.length; i++) {                        item = items[i];                        if ('key' in item && item.items !== undefined) {                            path.push(item.key);                            if (additionalGroupInfo && pathEquals(additionalGroupInfo.path, path) && !item.isContinuation)                                additionalGroupInfo.offset = offset;                            var groupInfo = that.findGroupInfo(path);                            if (groupInfo && !groupInfo.isExpanded) {                                if (!item.isContinuation) {                                    groupInfo.offset = offset;                                    offset += groupInfo.count                                }                            }                            else                                offset = updateGroupOffsets(that, item.items, path, offset, additionalGroupInfo);                            path.pop()                        }                        else                            offset++                    }                    return offset                };            var removeGroupLoadOption = function(storeLoadOptions) {                    var groups,                        sorts;                    if (storeLoadOptions.group) {                        groups = normalizeSortingInfo(storeLoadOptions.group);                        sorts = normalizeSortingInfo(storeLoadOptions.sort);                        storeLoadOptions.sort = dataUtils.arrangeSortingInfo(groups, sorts);                        delete storeLoadOptions.group                    }                };            var createGroupFilter = function(path, storeLoadOptions) {                    var groups = normalizeSortingInfo(storeLoadOptions.group),                        i,                        filter = [];                    for (i = 0; i < path.length; i++)                        filter.push([groups[i].selector, '=', path[i]]);                    if (storeLoadOptions.filter)                        filter.push(storeLoadOptions.filter);                    return dataGrid.combineFilters(filter)                };            var createNotGroupFilter = function(path, storeLoadOptions, group) {                    var groups = normalizeSortingInfo(group || storeLoadOptions.group),                        i,                        j,                        filterElement,                        filter = [];                    for (i = 0; i < path.length; i++) {                        filterElement = [];                        for (j = 0; j <= i; j++)                            filterElement.push([groups[j].selector, i === j ? '<>' : '=', path[j]]);                        filter.push(dataGrid.combineFilters(filterElement))                    }                    filter = dataGrid.combineFilters(filter, "or");                    return dataGrid.combineFilters([filter, storeLoadOptions.filter])                };            var createOffsetFilter = function(path, storeLoadOptions) {                    var groups = normalizeSortingInfo(storeLoadOptions.group),                        i,                        j,                        filterElement,                        filter = [];                    for (i = 0; i < path.length; i++) {                        filterElement = [];                        for (j = 0; j <= i; j++)                            filterElement.push([groups[j].selector, i === j ? groups[j].desc ? '>' : '<' : '=', path[j]]);                        if (filter.length)                            filter.push('or');                        filter.push(filterElement)                    }                    if (storeLoadOptions.filter)                        filter.push(storeLoadOptions.filter);                    return filter                };            return {                    _handleDataLoading: function(options) {                        this.callBase(options);                        var that = this,                            storeLoadOptions = options.storeLoadOptions,                            loadOptions,                            collapsedPaths = [],                            collapsedItemsCount = 0,                            skipFirstItem = false,                            take,                            group = storeLoadOptions.group,                            skipCorrection = 0;                        removeGroupLoadOption(storeLoadOptions);                        options.group = options.group || group;                        if (storeLoadOptions.isLoadingAll)                            return;                        loadOptions = $.extend({}, storeLoadOptions);                        loadOptions.skip = correctSkipLoadOption(that, storeLoadOptions.skip);                        if (loadOptions.skip && loadOptions.take && group) {                            loadOptions.skip--;                            loadOptions.take++;                            skipFirstItem = true                        }                        if (loadOptions.take && group) {                            take = loadOptions.take;                            loadOptions.take++                        }                        foreachCollapsedGroups(that, function(groupInfo) {                            if (groupInfo.offset >= loadOptions.skip + loadOptions.take + skipCorrection)                                return false;                            else if (groupInfo.offset >= loadOptions.skip + skipCorrection && groupInfo.count) {                                skipCorrection += groupInfo.count - 1;                                collapsedPaths.push(groupInfo.path);                                collapsedItemsCount += groupInfo.count                            }                        });                        $.each(collapsedPaths, function() {                            loadOptions.filter = createNotGroupFilter(this, loadOptions, group)                        });                        options.storeLoadOptions = loadOptions;                        options.collapsedPaths = collapsedPaths;                        options.collapsedItemsCount = collapsedItemsCount;                        options.skip = loadOptions.skip || 0;                        options.skipFirstItem = skipFirstItem;                        options.take = take                    },                    _handleDataLoaded: function(options) {                        var that = this,                            data = options.data,                            pathIndex,                            query,                            collapsedPaths = options.collapsedPaths,                            groups = normalizeSortingInfo(options.group),                            groupCount = groups.length;                        function appendCollapsedPath(data, path, groups) {                            if (!data || !path.length || !groups.length)                                return;                            var i,                                keyValue,                                pathValue = dataUtils.toComparable(path[0], true);                            for (i = 0; i < data.length; i++) {                                keyValue = dataUtils.toComparable(data[i].key, true);                                if (groups[0].desc ? pathValue >= keyValue : pathValue <= keyValue)                                    break                            }                            if (!data.length || pathValue !== keyValue)                                data.splice(i, 0, {                                    key: path[0],                                    items: []                                });                            appendCollapsedPath(data[i].items, path.slice(1), groups.slice(1))                        }                        this.callBase(options);                        if (groupCount) {                            query = DX.data.query(data);                            DX.data.utils.multiLevelGroup(query, groups).enumerate().done(function(groupedData) {                                data = groupedData                            });                            if (collapsedPaths)                                for (pathIndex = 0; pathIndex < collapsedPaths.length; pathIndex++)                                    appendCollapsedPath(data, collapsedPaths[pathIndex], groups);                            if (!options.storeLoadOptions.isLoadingAll) {                                processGroupItems(that, data, [], options.skip, options.skipFirstItem, options.take);                                that.updateItemsCount(data, groupCount)                            }                            options.data = data;                            if (options.collapsedItemsCount && options.extra && options.extra.totalCount >= 0)                                options.extra.totalCount += options.collapsedItemsCount                        }                    },                    updateTotalItemsCount: function() {                        var itemsCountCorrection = 0;                        foreachCollapsedGroups(this, function(groupInfo) {                            if (groupInfo.count)                                itemsCountCorrection -= groupInfo.count - 1                        });                        this.callBase(itemsCountCorrection)                    },                    _changeRowExpandCore: function(path) {                        var that = this,                            dataSource = that._dataSource,                            basePageIndex = that.basePageIndex && that.basePageIndex() || that.pageIndex(),                            dataSourceItems = that.items(),                            offset = correctSkipLoadOption(that, basePageIndex * that.pageSize()),                            groupInfo = that.findGroupInfo(path),                            groupCountQuery;                        if (groupInfo && !groupInfo.isExpanded)                            groupCountQuery = $.Deferred().resolve(groupInfo.count);                        else                            groupCountQuery = loadTotalCount(dataSource.store(), {filter: createGroupFilter(path, {                                    filter: dataSource.filter(),                                    group: dataSource.group()                                })});                        return $.when(groupCountQuery).done(function(count) {                                count = parseInt(count.length ? count[0] : count);                                if (groupInfo) {                                    updateGroupOffsets(that, dataSourceItems, [], offset);                                    groupInfo.isExpanded = !groupInfo.isExpanded;                                    groupInfo.count = count                                }                                else {                                    groupInfo = {                                        offset: -1,                                        count: count,                                        path: path,                                        isExpanded: false                                    };                                    updateGroupOffsets(that, dataSourceItems, [], offset, groupInfo);                                    if (groupInfo.offset >= 0)                                        that.addGroupInfo(groupInfo)                                }                                that.updateTotalItemsCount()                            }).fail($.proxy(dataSource.loadError.fire, dataSource.loadError))                    },                    allowCollapseAll: function() {                        return false                    },                    refresh: function(storeLoadOptions, isReload) {                        var that = this,                            dataSource = that._dataSource,                            store = dataSource.store();                        this.callBase.apply(this, arguments);                        if (isReload)                            return foreachCollapsedGroups(that, function(groupInfo) {                                    var groupCountQuery = loadTotalCount(store, {filter: createGroupFilter(groupInfo.path, storeLoadOptions)}),                                        groupOffsetQuery = loadTotalCount(store, {filter: createOffsetFilter(groupInfo.path, storeLoadOptions)});                                    dataSource._changeLoadingCount(1);                                    return $.when(groupOffsetQuery, groupCountQuery).done(function(offset, count) {                                            offset = parseInt(offset.length ? offset[0] : offset);                                            count = parseInt(count.length ? count[0] : count);                                            groupInfo.offset = offset;                                            if (groupInfo.count !== count) {                                                groupInfo.count = count;                                                that.updateTotalItemsCount()                                            }                                        }).fail($.proxy(that._dataSource.loadError.fire, that._dataSource.loadError)).always(function() {                                            dataSource._changeLoadingCount(-1)                                        })                                })                    }                }        }());        $.extend(DX.ui.dxDataGrid.__internals, {loadTotalCount: loadTotalCount})    })(jQuery, DevExpress);    /*! Module widgets-web, file ui.dataGrid.grouping.client.js */    (function($, DX) {        var dataGrid = DX.ui.dxDataGrid,            normalizeSortingInfo = dataGrid.normalizeSortingInfo;        dataGrid.DataSourceAdapterClient = dataGrid.DataSourceAdapterClient.inherit(function() {            var foreachExpandedGroups = function(that, callback) {                    return that.foreachGroups(function(groupInfo, parents) {                            if (groupInfo.isExpanded)                                return callback(groupInfo, parents)                        }, true)                };            var processGroupItems = function(that, items, path, groupsCount) {                    var i,                        item;                    if (!groupsCount)                        return;                    for (i = 0; i < items.length; i++) {                        item = items[i];                        if (item.items !== undefined) {                            path.push(item.key);                            var groupInfo = that.findGroupInfo(path);                            if (!groupInfo || !groupInfo.isExpanded) {                                item.collapsedItems = item.items;                                item.items = null                            }                            else                                processGroupItems(that, item.items, path, groupsCount - 1);                            path.pop()                        }                    }                };            var updateGroupInfos = function(that, items, groupsCount, offset) {                    return updateGroupInfosCore(that, items, 0, groupsCount, [], offset)                };            var updateGroupInfosCore = function(that, items, groupIndex, groupsCount, path, offset) {                    var item,                        totalCount = 0,                        i,                        groupInfo;                    if (groupIndex >= groupsCount)                        return items.length;                    for (i = 0; i < items.length; i++) {                        item = items[i];                        if (item) {                            path.push(item.key);                            groupInfo = that.findGroupInfo(path);                            if (!groupInfo)                                that.addGroupInfo({                                    isExpanded: that._isGroupExpanded(groupIndex),                                    path: path.slice(0),                                    offset: offset + i,                                    count: item.items.length                                });                            else {                                groupInfo.count = item.items.length;                                groupInfo.offset = offset + i                            }                            totalCount += updateGroupInfosCore(that, item.items, groupIndex + 1, groupsCount, path, 0);                            path.pop()                        }                    }                    return totalCount                };            var isGroupExpanded = function(groups, groupIndex) {                    return groups && groups.length && groups[groupIndex] && !!groups[groupIndex].isExpanded                };            var getTotalOffset = function(groupInfos, pageSize, offset) {                    var groupIndex,                        groupSize,                        totalOffset = offset;                    for (groupIndex = 0; groupIndex < groupInfos.length; groupIndex++) {                        groupSize = groupInfos[groupIndex].offset + 1;                        if (groupIndex > 0) {                            groupSize += groupInfos[groupIndex - 1].childrenTotalCount;                            if (pageSize)                                groupSize += getContinuationGroupCount(totalOffset, pageSize, groupSize, groupIndex - 1) * groupIndex                        }                        totalOffset += groupSize                    }                    return totalOffset                };            var getContinuationGroupCount = function(groupOffset, pageSize, groupSize, groupIndex) {                    groupIndex = groupIndex || 0;                    if (pageSize > 1 && groupSize > 0) {                        var pageOffset = groupOffset - Math.floor(groupOffset / pageSize) * pageSize || pageSize;                        pageOffset += groupSize - groupIndex - 2;                        if (pageOffset < 0)                            pageOffset += pageSize;                        return Math.floor(pageOffset / (pageSize - groupIndex - 1))                    }                    return 0                };            DX.ui.dxDataGrid.getContinuationGroupCount = getContinuationGroupCount;            return {                    updateTotalItemsCount: function(options) {                        var totalItemsCount = 0,                            totalCount = options.extra && options.extra.totalCount || 0,                            pageSize = this.pageSize(),                            isVirtualPaging = this._isVirtualPaging();                        foreachExpandedGroups(this, function(groupInfo, parents) {                            groupInfo.childrenTotalCount = 0                        });                        foreachExpandedGroups(this, function(groupInfo, parents) {                            var totalOffset = getTotalOffset(parents, isVirtualPaging ? 0 : pageSize, totalItemsCount),                                count = groupInfo.count + groupInfo.childrenTotalCount;                            if (!isVirtualPaging)                                count += getContinuationGroupCount(totalOffset, pageSize, count, parents.length - 1);                            if (parents[parents.length - 2])                                parents[parents.length - 2].childrenTotalCount += count;                            else                                totalItemsCount += count                        });                        this.callBase(totalItemsCount - totalCount + options.data.length)                    },                    _isGroupExpanded: function(groupIndex) {                        var groups = this._dataSource.group();                        return isGroupExpanded(groups, groupIndex)                    },                    _updatePagingOptions: function(options) {                        var that = this,                            isVirtualPaging = that._isVirtualPaging(),                            pageSize = that.pageSize(),                            skips = [],                            takes = [],                            skipChildrenTotalCount = 0,                            childrenTotalCount = 0;                        if (options.take) {                            foreachExpandedGroups(this, function(groupInfo) {                                groupInfo.childrenTotalCount = 0;                                groupInfo.skipChildrenTotalCount = 0                            });                            foreachExpandedGroups(that, function(groupInfo, parents) {                                var skip,                                    take,                                    takeCorrection = 0,                                    parentTakeCorrection = 0,                                    totalOffset = getTotalOffset(parents, isVirtualPaging ? 0 : pageSize, childrenTotalCount),                                    continuationGroupCount = 0,                                    skipContinuationGroupCount = 0,                                    groupInfoCount = groupInfo.count + groupInfo.childrenTotalCount,                                    childrenGroupInfoCount = groupInfoCount;                                skip = options.skip - totalOffset;                                if (totalOffset <= options.skip + options.take && groupInfoCount) {                                    take = options.take;                                    if (!isVirtualPaging) {                                        continuationGroupCount = getContinuationGroupCount(totalOffset, pageSize, groupInfoCount, parents.length - 1);                                        groupInfoCount += continuationGroupCount * parents.length;                                        childrenGroupInfoCount += continuationGroupCount;                                        if (pageSize && skip >= 0) {                                            takeCorrection = parents.length;                                            parentTakeCorrection = parents.length - 1;                                            skipContinuationGroupCount = Math.floor(skip / pageSize)                                        }                                    }                                    if (skip >= 0) {                                        if (totalOffset + groupInfoCount > options.skip)                                            skips.unshift(skip - skipContinuationGroupCount * takeCorrection - groupInfo.skipChildrenTotalCount);                                        if (totalOffset + groupInfoCount >= options.skip + take)                                            takes.unshift(take - takeCorrection - groupInfo.childrenTotalCount + groupInfo.skipChildrenTotalCount)                                    }                                    else if (totalOffset + groupInfoCount >= options.skip + take)                                        takes.unshift(take + skip - groupInfo.childrenTotalCount)                                }                                if (totalOffset <= options.skip)                                    if (parents[parents.length - 2])                                        parents[parents.length - 2].skipChildrenTotalCount += Math.min(childrenGroupInfoCount, skip + 1 - skipContinuationGroupCount * parentTakeCorrection);                                    else                                        skipChildrenTotalCount += Math.min(childrenGroupInfoCount, skip + 1);                                if (totalOffset <= options.skip + take) {                                    groupInfoCount = Math.min(childrenGroupInfoCount, skip + take - (skipContinuationGroupCount + 1) * parentTakeCorrection);                                    if (parents[parents.length - 2])                                        parents[parents.length - 2].childrenTotalCount += groupInfoCount;                                    else                                        childrenTotalCount += groupInfoCount                                }                            });                            options.skip -= skipChildrenTotalCount;                            options.take -= childrenTotalCount - skipChildrenTotalCount                        }                        options.skips = skips;                        options.takes = takes                    },                    _changeRowExpandCore: function(path) {                        var that = this,                            groupInfo = that.findGroupInfo(path);                        if (groupInfo) {                            groupInfo.isExpanded = !groupInfo.isExpanded;                            return $.Deferred().resolve()                        }                        return $.Deferred().reject()                    },                    _handleDataLoadedCore: function(options) {                        var that = this,                            callBase = that.callBase,                            groupCount = normalizeSortingInfo(options.loadOptions.group).length,                            totalCount,                            skips,                            takes,                            i,                            item,                            items;                        if (options.loadOptions.isLoadingAll) {                            callBase.call(that, options);                            return                        }                        totalCount = updateGroupInfos(that, options.data, groupCount, 0);                        if (groupCount && options.extra)                            options.extra.totalCount = totalCount;                        that.updateTotalItemsCount(options);                        that._updatePagingOptions(options);                        callBase.call(that, options);                        skips = options.skips;                        takes = options.takes;                        items = options.data;                        for (i = 0; items && i < groupCount; i++) {                            item = items[0];                            items = item && item.items;                            if (items && skips[i] !== undefined) {                                item.isContinuation = true;                                items = items.slice(skips[i]);                                item.items = items                            }                        }                        items = options.data;                        for (i = 0; items && i < groupCount; i++) {                            item = items[items.length - 1];                            items = item && item.items;                            if (items && takes[i] !== undefined && items.length > takes[i]) {                                item.isContinuationOnNextPage = true;                                items = items.slice(0, takes[i]);                                item.items = items                            }                        }                        processGroupItems(that, options.data, [], groupCount);                        that.updateItemsCount(options.data, groupCount)                    },                    refresh: function(storeLoadOptions) {                        var that = this,                            oldGroups = normalizeSortingInfo(that._group),                            isExpanded,                            groupIndex;                        function handleGroup(groupInfo, parents) {                            if (parents.length === groupIndex + 1)                                groupInfo.isExpanded = isExpanded                        }                        for (groupIndex = 0; groupIndex < oldGroups.length; groupIndex++) {                            isExpanded = isGroupExpanded(storeLoadOptions.group, groupIndex);                            if (isGroupExpanded(that._group, groupIndex) !== isExpanded)                                that.foreachGroups(handleGroup)                        }                        that.callBase.apply(this, arguments);                        that.foreachGroups(function(groupInfo) {                            groupInfo.count = 0                        })                    }                }        }())    })(jQuery, DevExpress);    /*! Module widgets-web, file ui.dataGrid.virtualScrollingModule.js */    (function($, DX) {        var ui = DX.ui,            dataGrid = ui.dxDataGrid;        var DATAGRID_TABLE_CLASS = "dx-datagrid-table",            DATAGRID_ROW_CLASS = "dx-row",            DATAGRID_FREESPACE_CLASS = "dx-freespace-row",            DATAGRID_COLUMN_LINES_CLASS = "dx-column-lines",            DATAGRID_BOTTOM_LOAD_PANEL_CLASS = "dx-datagrid-bottom-load-panel",            DATAGRID_TABLE_CONTENT_CLASS = "dx-datagrid-table-content",            DATAGRID_GROUP_SPACE_CLASS = "dx-datagrid-group-space",            DATAGRID_SCROLLABLE_CONTAINER = "dx-scrollable-container",            DATAGRID_SCROLLABLE_CONTENT = "dx-scrollable-content",            DATAGRID_CONTENT_CLASS = "dx-datagrid-content",            SCROLLING_MODE_INFINITE = 'infinite',            SCROLLING_MODE_VIRTUAL = 'virtual',            PIXELS_LIMIT = 250000;        var VirtualScrollingDataSourceAdapterExtender = function() {                var getPreloadPageCount = function(that) {                        return that.option('scrolling.preloadEnabled') ? 2 : 1                    };                var isVirtualMode = function(that) {                        return !that._isLoadingAll && that.option('scrolling.mode') === SCROLLING_MODE_VIRTUAL                    };                var isAppendMode = function(that) {                        return !that._isLoadingAll && that.option('scrolling.mode') === SCROLLING_MODE_INFINITE                    };                var getBasePageIndex = function(that) {                        return that._cache[0] ? that._cache[0].pageIndex : -1                    };                var updateLoading = function(that) {                        var basePageIndex = getBasePageIndex(that);                        if (isVirtualMode(that))                            if (basePageIndex < 0 || that._viewportItemIndex >= 0 && (basePageIndex * that.pageSize() > that._viewportItemIndex || basePageIndex * that.pageSize() + that.itemsCount() < that._viewportItemIndex + that._viewportSize) && that._dataSource.isLoading()) {                                if (!that._isLoading) {                                    that._isLoading = true;                                    that.loadingChanged.fire(true)                                }                            }                            else if (that._isLoading) {                                that._isLoading = false;                                that.loadingChanged.fire(false)                            }                    };                var processDelayChanged = function(that, changed) {                        if (that._isDelayChanged) {                            that._isDelayChanged = false;                            changed.call(that)                        }                    };                var processChanged = function(that, changed, changeType, isDelayChanged) {                        var dataSource = that._dataSource,                            items = dataSource.items();                        if (changeType === 'append')                            that._items.push.apply(that._items, items);                        else if (changeType === 'prepend')                            that._items.unshift.apply(that._items, items);                        else                            that._items = items;                        updateLoading(that);                        that._lastPageIndex = that.pageIndex();                        that._isDelayChanged = isDelayChanged;                        that._isLoadingAll = false;                        if (!isDelayChanged)                            changed.call(that, changeType && {                                changeType: changeType,                                items: items                            })                    };                return {                        init: function(dataSource) {                            var that = this;                            that.callBase.apply(that, arguments);                            that._isLoading = true;                            that._pageIndex = dataSource.pageIndex();                            that._lastPageIndex = that._pageIndex;                            that._viewportSize = 0;                            that._viewportItemIndex = -1;                            that._userPageSize = that.option("paging.pageSize");                            that._items = [];                            that._isLoaded = true;                            that._cache = [];                            if (dataSource.isLoaded())                                that._handleDataChanged()                        },                        _handleLoadingChanged: function(isLoading) {                            var that = this;                            if (!isVirtualMode(that)) {                                that._isLoading = isLoading;                                that.callBase.apply(that, arguments)                            }                        },                        _handleLoadError: function() {                            var that = this;                            that._isLoadingAll = false;                            that._isLoading = false;                            that.loadingChanged.fire(false);                            that.callBase.apply(that, arguments)                        },                        _handleDataChanged: function() {                            var that = this,                                basePageIndex,                                callBase = that.callBase,                                dataSource = that._dataSource,                                lastCacheLength = that._cache.length,                                changeType,                                cacheItem;                            if (isVirtualMode(that)) {                                basePageIndex = getBasePageIndex(that);                                if (basePageIndex >= 0)                                    if (basePageIndex + that._cache.length === dataSource.pageIndex());                                    else if (basePageIndex - 1 === dataSource.pageIndex());                                    else                                        that._cache = [];                                cacheItem = {                                    pageIndex: dataSource.pageIndex(),                                    itemsCount: that.itemsCount(true)                                };                                processDelayChanged(that, callBase);                                if (basePageIndex === dataSource.pageIndex() + 1) {                                    changeType = 'prepend';                                    that._cache.unshift(cacheItem)                                }                                else {                                    changeType = 'append';                                    that._cache.push(cacheItem)                                }                                processChanged(that, callBase, that._cache.length > 1 ? changeType : undefined, lastCacheLength === 0);                                that.load().done(function() {                                    processDelayChanged(that, callBase)                                })                            }                            else                                processChanged(that, callBase, isAppendMode(that) && dataSource.pageIndex() !== 0 ? 'append' : undefined)                        },                        items: function() {                            return this._items                        },                        itemsCount: function(isBase) {                            var itemsCount = 0;                            if (!isBase && isVirtualMode(this))                                $.each(this._cache, function() {                                    itemsCount += this.itemsCount                                });                            else                                itemsCount = this.callBase();                            return itemsCount                        },                        virtualItemsCount: function() {                            var that = this,                                pageIndex,                                itemsCount = 0,                                beginItemsCount,                                endItemsCount;                            if (isVirtualMode(that)) {                                pageIndex = getBasePageIndex(that);                                if (pageIndex < 0)                                    pageIndex = 0;                                beginItemsCount = pageIndex * that.pageSize();                                itemsCount = that._cache.length * that.pageSize();                                endItemsCount = Math.max(0, that.totalItemsCount() - itemsCount - beginItemsCount);                                return {                                        begin: beginItemsCount,                                        end: endItemsCount                                    }                            }                        },                        setViewportItemIndex: function(itemIndex) {                            var that = this,                                pageSize = that.pageSize(),                                pageCount = that.pageCount(),                                virtualMode = isVirtualMode(that),                                appendMode = isAppendMode(that),                                totalItemsCount = that.totalItemsCount(),                                lastPageSize,                                needLoad = that._viewportItemIndex < 0,                                maxPageIndex,                                newPageIndex;                            that._viewportItemIndex = itemIndex;                            if (pageSize && (virtualMode || appendMode) && totalItemsCount >= 0) {                                if (that._viewportSize && itemIndex + that._viewportSize >= totalItemsCount)                                    if (that.hasKnownLastPage()) {                                        newPageIndex = pageCount - 1;                                        lastPageSize = totalItemsCount % pageSize;                                        if (newPageIndex > 0 && lastPageSize > 0 && lastPageSize < pageSize / 2)                                            newPageIndex--                                    }                                    else                                        newPageIndex = pageCount;                                else {                                    newPageIndex = Math.floor(itemIndex / pageSize);                                    maxPageIndex = pageCount - 1;                                    newPageIndex = Math.max(newPageIndex, 0);                                    newPageIndex = Math.min(newPageIndex, maxPageIndex)                                }                                if (that.pageIndex() !== newPageIndex || needLoad) {                                    that.pageIndex(newPageIndex);                                    that.load()                                }                            }                        },                        setViewportSize: function(size) {                            var that = this,                                pageSize;                            if (that._viewportSize !== size) {                                that._viewportSize = size;                                if ((isVirtualMode(that) || isAppendMode(that)) && !that._userPageSize) {                                    pageSize = Math.ceil(size / 5) * 10;                                    if (pageSize !== that.pageSize()) {                                        that.pageSize(pageSize);                                        that.reload()                                    }                                }                            }                        },                        getViewportSize: function() {                            return this._viewportSize                        },                        pageIndex: function(pageIndex) {                            if (isVirtualMode(this) || isAppendMode(this)) {                                if (pageIndex !== undefined)                                    this._pageIndex = pageIndex;                                return this._pageIndex                            }                            else                                return this._dataSource.pageIndex(pageIndex)                        },                        basePageIndex: function() {                            var basePageIndex = getBasePageIndex(this);                            return basePageIndex > 0 ? basePageIndex : 0                        },                        load: function(isLoadingAll) {                            var basePageIndex = getBasePageIndex(this),                                pageIndexForLoad = -1,                                dataSource = this._dataSource,                                result;                            var loadCore = function(that, pageIndex) {                                    var dataSource = that._dataSource;                                    if (pageIndex === that.pageIndex() || !dataSource.isLoading() && pageIndex < that.pageCount() || !that.hasKnownLastPage() && pageIndex === that.pageCount()) {                                        dataSource.pageIndex(pageIndex);                                        return dataSource.load()                                    }                                };                            this._isLoadingAll = isLoadingAll;                            if (isVirtualMode(this)) {                                if (basePageIndex < 0 || !this._cache[this._pageIndex - basePageIndex])                                    pageIndexForLoad = this._pageIndex;                                if (basePageIndex >= 0 && pageIndexForLoad < 0 && this._viewportItemIndex >= 0 && basePageIndex + this._cache.length <= this._pageIndex + getPreloadPageCount(this))                                    pageIndexForLoad = basePageIndex + this._cache.length;                                if (pageIndexForLoad >= 0)                                    result = loadCore(this, pageIndexForLoad);                                updateLoading(this)                            }                            else if (isAppendMode(this)) {                                if (!dataSource.isLoaded() || this.pageIndex() === this.pageCount()) {                                    dataSource.pageIndex(this.pageIndex());                                    result = dataSource.load()                                }                            }                            else                                result = dataSource.load();                            if (!result && this._lastPageIndex !== this.pageIndex())                                this.changed.fire({changeType: 'pageIndex'});                            return result || $.Deferred().resolve()                        },                        isLoading: function() {                            return this._isLoading                        },                        isLoaded: function() {                            return this._dataSource.isLoaded() && this._isLoaded                        },                        changeRowExpand: function() {                            this._cache = [];                            updateLoading(this);                            return this.callBase.apply(this, arguments)                        },                        refresh: function(storeLoadOptions, isReload) {                            var that = this,                                dataSource = that._dataSource;                            if (isReload) {                                that._cache = [];                                that._isLoaded = false;                                updateLoading(that);                                that._isLoaded = true;                                if (isAppendMode(that)) {                                    that.pageIndex(0);                                    dataSource.pageIndex(0);                                    storeLoadOptions.pageIndex = 0;                                    storeLoadOptions.skip = 0                                }                                else {                                    dataSource.pageIndex(that.pageIndex());                                    if (dataSource.paginate())                                        storeLoadOptions.skip = that.pageIndex() * that.pageSize()                                }                            }                            return that.callBase.apply(that, arguments)                        }                    }            }();        dataGrid.DataSourceAdapterServer = dataGrid.DataSourceAdapterServer.inherit(VirtualScrollingDataSourceAdapterExtender);        dataGrid.DataSourceAdapterClient = dataGrid.DataSourceAdapterClient.inherit(VirtualScrollingDataSourceAdapterExtender);        var VirtualScrollingRowsViewExtender = function() {                return {                        _renderCore: function() {                            var that = this;                            that.callBase.apply(that, arguments);                            that._updateContentPosition()                        },                        _renderContent: function(contentElement, tableElement) {                            var that = this,                                virtualItemsCount = that._dataController.virtualItemsCount();                            if (virtualItemsCount) {                                tableElement.addClass(DATAGRID_TABLE_CONTENT_CLASS);                                if (!contentElement.children().length)                                    contentElement.append(tableElement);                                else                                    contentElement.children().first().replaceWith(tableElement);                                if (contentElement.children('table').length === 1) {                                    contentElement.append(that._createTable());                                    that._contentHeight = 0                                }                                return contentElement                            }                            else                                return that.callBase.apply(that, arguments)                        },                        _updateContent: function(contentElement, change, tableElement) {                            var that = this,                                contentTable,                                changeType = change && change.changeType;                            if (changeType === 'append' || changeType === 'prepend') {                                contentTable = contentElement.children().first();                                tableElement.children('tbody').children('tr')[changeType === 'append' ? 'appendTo' : 'prependTo'](contentTable)                            }                            else                                that.callBase.apply(that, arguments);                            that._updateBottomLoading()                        },                        _updateContentPosition: function() {                            var that = this,                                contentElement,                                contentHeight,                                $tables,                                $contentTable,                                virtualTable,                                rowHeight = that._rowHeight || 20,                                virtualItemsCount = that._dataController.virtualItemsCount(),                                isRenderVirtualTableContentRequired;                            if (virtualItemsCount) {                                contentElement = that._findContentElement();                                $tables = contentElement.children();                                $contentTable = $tables.first();                                virtualTable = $tables.eq(1);                                DX.translator.move($contentTable, {top: Math.floor(virtualItemsCount.begin * rowHeight)});                                contentHeight = (virtualItemsCount.begin + virtualItemsCount.end) * rowHeight + $contentTable.outerHeight();                                isRenderVirtualTableContentRequired = that._contentHeight !== contentHeight || contentHeight === 0 || !that._isTableLinesDisplaysCorrect(virtualTable) || !that._isColumnElementsEqual($contentTable.find("col"), virtualTable.find("col"));                                if (isRenderVirtualTableContentRequired) {                                    that._contentHeight = contentHeight;                                    that._renderVirtualTableContent(virtualTable, contentHeight)                                }                                return true                            }                            return false                        },                        _isTableLinesDisplaysCorrect: function(table) {                            var hasColumnLines = table.find("." + DATAGRID_COLUMN_LINES_CLASS).length > 0;                            return hasColumnLines === this.option('showColumnLines')                        },                        _isColumnElementsEqual: function($columns, $virtualColumns) {                            var result = $columns.length === $virtualColumns.length;                            if (result)                                $.each($columns, function(index, element) {                                    if (element.style.width !== $virtualColumns[index].style.width) {                                        result = false;                                        return result                                    }                                });                            return result                        },                        _renderVirtualTableContent: function(container, height) {                            var that = this,                                columns = that._columnsController.getVisibleColumns(),                                html = that._createColGroup(columns).prop('outerHTML'),                                freeSpaceCellsHtml = '',                                i,                                columnLinesClass = that.option('showColumnLines') ? DATAGRID_COLUMN_LINES_CLASS : '',                                createFreeSpaceRowHtml = function(height) {                                    return '<tr style="height:' + height + 'px;" class="' + DATAGRID_FREESPACE_CLASS + ' ' + DATAGRID_ROW_CLASS + ' ' + columnLinesClass + '" >' + freeSpaceCellsHtml + '</tr>'                                };                            for (i = 0; i < columns.length; i++)                                freeSpaceCellsHtml += columns[i].command === "expand" ? '<td class="' + DATAGRID_GROUP_SPACE_CLASS + '"/>' : '<td />';                            while (height > PIXELS_LIMIT) {                                html += createFreeSpaceRowHtml(PIXELS_LIMIT);                                height -= PIXELS_LIMIT                            }                            html += createFreeSpaceRowHtml(height);                            container.addClass(DATAGRID_TABLE_CLASS);                            container.html(html)                        },                        _findBottomLoadPanel: function() {                            var $bottomLoadPanel = this.element().find('.' + DATAGRID_BOTTOM_LOAD_PANEL_CLASS);                            if ($bottomLoadPanel.length)                                return $bottomLoadPanel                        },                        _updateBottomLoading: function() {                            var that = this,                                scrollingMode = that.option("scrolling.mode"),                                virtualMode = scrollingMode === SCROLLING_MODE_VIRTUAL,                                appendMode = scrollingMode === SCROLLING_MODE_INFINITE,                                showBottomLoading = !that._dataController.hasKnownLastPage() && that._dataController.isLoaded() && (virtualMode || appendMode),                                bottomLoadPanelElement = that._findBottomLoadPanel();                            if (showBottomLoading) {                                if (!bottomLoadPanelElement)                                    $('<div />').addClass(DATAGRID_BOTTOM_LOAD_PANEL_CLASS).append($('<div />').dxLoadIndicator()).appendTo(that._findContentElement())                            }                            else if (bottomLoadPanelElement)                                bottomLoadPanelElement.remove()                        },                        _handleScroll: function(e) {                            var that = this;                            if (that._hasHeight && that._rowHeight)                                that._dataController.setViewportItemIndex(e.scrollOffset.top / that._rowHeight);                            that.callBase.apply(that, arguments)                        },                        _renderScrollableCore: function($element) {                            var that = this;                            that.callBase.apply(that, arguments);                            that._subscribeToWindowScrollEvents($element)                        },                        _subscribeToWindowScrollEvents: function($element) {                            var that = this,                                $componentContainer = that.component.element(),                                $scrollElement;                            if (!$componentContainer)                                return;                            if (!that._windowScrollEvents) {                                that._windowScrollEvents = true;                                var createWindowScrollHandler = function($scrollElement, oldHandler) {                                        var handler = function(e) {                                                var scrollTop = $scrollElement.scrollTop();                                                if (!that._hasHeight && that._rowHeight) {                                                    scrollTop -= $element.offset().top;                                                    scrollTop = scrollTop > 0 ? scrollTop : 0;                                                    that._scrollTop = scrollTop;                                                    that._dataController.setViewportItemIndex(scrollTop / that._rowHeight)                                                }                                            };                                        if (oldHandler)                                            return function(e) {                                                    handler(e);                                                    oldHandler(e)                                                };                                        return handler                                    };                                var subscribeToScrollEvents = function($scrollElement) {                                        var dxScrollable = $scrollElement.data("dxScrollable"),                                            scrollHandler,                                            oldScrollHandler;                                        if (dxScrollable) {                                            oldScrollHandler = dxScrollable.option('onScroll');                                            scrollHandler = createWindowScrollHandler($scrollElement, oldScrollHandler);                                            dxScrollable.option('onScroll', scrollHandler);                                            that.on("disposing", function() {                                                if (dxScrollable.option('onScroll') === scrollHandler)                                                    dxScrollable.option('onScroll', oldScrollHandler)                                            })                                        }                                        else if ($scrollElement.is(document) || $scrollElement.css("overflow-y") === "auto") {                                            if ($scrollElement.is(document))                                                $scrollElement = $(window);                                            scrollHandler = createWindowScrollHandler($scrollElement);                                            $scrollElement.on('scroll', scrollHandler);                                            that.on("disposing", function() {                                                $scrollElement.off('scroll', scrollHandler)                                            })                                        }                                    };                                for ($scrollElement = that.component.element().parent(); $scrollElement.length; $scrollElement = $scrollElement.parent())                                    subscribeToScrollEvents($scrollElement)                            }                        },                        _needUpdateRowHeight: function(itemsCount) {                            var that = this;                            return that.callBase.apply(that, arguments) || itemsCount > 0 && that.option('scrolling.mode') === SCROLLING_MODE_INFINITE                        },                        _updateRowHeight: function() {                            var that = this,                                lastRowHeight = that._rowHeight,                                viewportHeight;                            that.callBase.apply(that, arguments);                            if (!lastRowHeight && that._rowHeight) {                                that._updateContentPosition();                                viewportHeight = that._hasHeight ? that.element().outerHeight() : $(window).outerHeight();                                that._dataController.setViewportSize(Math.round(viewportHeight / that._rowHeight))                            }                        },                        setLoading: function(isLoading, messageText) {                            var that = this,                                callBase = that.callBase,                                hasBottomLoadPanel = !!that._findBottomLoadPanel() && that._dataController.isLoaded();                            if (hasBottomLoadPanel)                                isLoading = false;                            callBase.call(that, isLoading, messageText)                        },                        _getTableElements: function(isVirtualTable) {                            var result = this.callBase();                            if (isVirtualTable && this.option("scrolling.mode") === "virtual")                                result = result.add(this.element().find("> ." + DATAGRID_SCROLLABLE_CONTAINER + " > ." + DATAGRID_SCROLLABLE_CONTENT + "> ." + DATAGRID_CONTENT_CLASS).children(":not(." + DATAGRID_TABLE_CONTENT_CLASS + ")"));                            return result                        }                    }            }();        $.extend(dataGrid.__internals, {            DATAGRID_BOTTOM_LOAD_PANEL_CLASS: DATAGRID_BOTTOM_LOAD_PANEL_CLASS,            DATAGRID_TABLE_CONTENT_CLASS: DATAGRID_TABLE_CONTENT_CLASS        });        dataGrid.registerModule('virtualScrolling', {            defaultOptions: function() {                return {scrolling: {                            mode: 'standard',                            preloadEnabled: false,                            useNativeScrolling: 'auto'                        }}            },            extenders: {                controllers: {data: function() {                        var members = {};                        dataGrid.proxyMethod(members, "virtualItemsCount");                        dataGrid.proxyMethod(members, "setViewportSize");                        dataGrid.proxyMethod(members, "setViewportItemIndex");                        return members                    }()},                views: {rowsView: VirtualScrollingRowsViewExtender}            }        })    })(jQuery, DevExpress);    /*! Module widgets-web, file ui.dataGrid.columnHeadersView.js */    (function($, DX) {        var ui = DX.ui,            utils = DX.utils,            dataGrid = ui.dxDataGrid;        var DATAGRID_CELL_CONTENT_CLASS = "dx-datagrid-text-content",            DATAGRID_HEADERS_CLASS = "dx-datagrid-headers",            DATAGRID_HEADER_ROW_CLASS = "dx-header-row",            DATAGRID_NOWRAP_CLASS = "dx-datagrid-nowrap",            DATAGRID_COLUMN_LINES_CLASS = "dx-column-lines",            DATAGRID_CONTEXT_MENU_SORT_ASC_ICON = "context-menu-sort-asc",            DATAGRID_CONTEXT_MENU_SORT_DESC_ICON = "context-menu-sort-desc",            DATAGRID_CONTEXT_MENU_SORT_NONE_ICON = "context-menu-sort-none",            DATAGRID_CELL_FOCUS_DISABLED_CLASS = "dx-cell-focus-disabled";        var createCellContent = function($cell, column, showColumnLines) {                var $content = $('<div />').addClass(DATAGRID_CELL_CONTENT_CLASS);                if (showColumnLines)                    $content.appendTo($cell);                else                    $content.css("float", column.alignment || 'left').prependTo($cell);                return $content            };        dataGrid.ColumnHeadersView = dataGrid.ColumnsView.inherit({            _getDefaultTemplate: function(column) {                var that = this,                    template,                    showColumnLines = that.option("showColumnLines");                if (column.command)                    template = function($container, options) {                        var column = options.column;                        $container.html(' ');                        $container.addClass(column.cssClass)                    };                else                    template = function($container, options) {                        var $content = createCellContent($container, options.column, showColumnLines);                        $content.text(column.caption)                    };                return template            },            _getHeaderTemplate: function(column) {                return column.headerCellTemplate || this._getDefaultTemplate(column)            },            _processTemplate: function(template, options) {                var that = this,                    resultTemplate,                    column = options.column,                    renderingTemplate = this.callBase(template);                if (renderingTemplate && column.headerCellTemplate)                    resultTemplate = {render: function(options, $container) {                            var $content = createCellContent($container, options.column, that.option("showColumnLines"));                            renderingTemplate.render(options, $content)                        }};                else                    resultTemplate = renderingTemplate;                return resultTemplate            },            _handleDataChanged: function(e) {                if (this._isGroupingChanged) {                    this._isGroupingChanged = false;                    this.render()                }            },            _renderCell: function($row, options) {                var $cell = this.callBase($row, options);                if (options.row.rowType === "header") {                    $cell.addClass(DATAGRID_CELL_FOCUS_DISABLED_CLASS);                    if (!utils.isDefined(options.column.command))                        this.setAria({                            role: "columnheader",                            label: options.column.caption + " " + Globalize.localize("dxDataGrid-ariaColumn")                        }, $cell)                }                return $cell            },            _createRow: function(row) {                var $row = this.callBase(row).toggleClass(DATAGRID_COLUMN_LINES_CLASS, this.option('showColumnLines'));                if (row.rowType === "header")                    $row.addClass(DATAGRID_HEADER_ROW_CLASS);                return $row            },            _renderCore: function() {                var that = this,                    $container = that.element(),                    scrollLeft = that._scrollLeft;                $container.addClass(DATAGRID_HEADERS_CLASS).toggleClass(DATAGRID_NOWRAP_CLASS, !!that.option("columnAutoWidth") || !that.option("wordWrapEnabled")).empty();                that._setTableElement(that._renderTable());                that._scrollLeft = 0;                that.scrollOffset(scrollLeft)            },            _renderTable: function() {                var $table = this.callBase.apply(this, arguments),                    $content = this.element();                this.wrapTableInScrollContainer($table).appendTo($content);                return $table            },            _getRows: function() {                var result = [];                if (this.option('showColumnHeaders'))                    result.push({rowType: "header"});                return result            },            _getCellTemplate: function(options) {                if (options.rowType === "header")                    return this._getHeaderTemplate(options.column)            },            _afterRender: function($root) {                this.processSizeChanged()            },            _columnOptionChanged: function(e) {                var changeTypes = e.changeTypes,                    optionNames = e.optionNames;                if (changeTypes.grouping) {                    this._isGroupingChanged = true;                    return                }                this.callBase(e);                if (optionNames.width || optionNames.visibleWidth)                    this.resizeCompleted.fire()            },            _isElementVisible: function(elementOptions) {                return elementOptions && elementOptions.visible            },            getHeadersRowHeight: function() {                var tableElement = this._getTableElement();                if (tableElement) {                    var $headerRow = tableElement.find('.' + DATAGRID_HEADER_ROW_CLASS).first();                    return $headerRow && $headerRow.height()                }                return 0            },            setColumnWidths: function(widths) {                var that = this,                    scrollLeft = that._scrollLeft;                that.callBase(widths);                that._scrollLeft = 0;                that.scrollOffset(scrollLeft)            },            processSizeChanged: function() {                var that = this,                    $element = that.element();                if (!utils.isDefined(that._headersHeight) || that._headersHeight !== $element.height()) {                    that._headersHeight = $element.height();                    that.sizeChanged.fire()                }            },            getHeaderElement: function(index) {                var columnElements = this.getColumnElements();                return columnElements && columnElements.eq(index)            },            getColumnElements: function() {                if (this.option("showColumnHeaders"))                    return this.getCellElements(0)            },            allowDragging: function(column, draggingPanels) {                var i,                    columns = this.getColumns(),                    draggableColumnCount = 0,                    draggingPanel,                    allowDrag = function(column) {                        return column.allowReordering || column.allowGrouping || column.allowHiding                    };                for (i = 0; i < columns.length; i++)                    if (allowDrag(columns[i]))                        draggableColumnCount++;                if (draggableColumnCount <= 1)                    return false;                else if (!draggingPanels)                    return (this.option("allowColumnReordering") || this._columnsController.isColumnOptionUsed("allowReordering")) && column && column.allowReordering;                for (i = 0; i < draggingPanels.length; i++) {                    draggingPanel = draggingPanels[i];                    if (draggingPanel && draggingPanel.allowDragging(column))                        return true                }                return false            },            getBoundingRect: function() {                var that = this,                    offset,                    $columnElements = that.getColumnElements();                if ($columnElements && $columnElements.length) {                    offset = that._getTableElement().offset();                    return {top: offset.top}                }                return null            },            getName: function() {                return 'headers'            },            getColumnCount: function() {                var $columnElements = this.getColumnElements();                return $columnElements ? $columnElements.length : 0            },            init: function() {                var that = this;                that.callBase();                that._scrollerWidth = 0;                that.sizeChanged = $.Callbacks()            },            isVisible: function() {                return this.option('showColumnHeaders')            },            setScrollerSpacing: function(width) {                var that = this,                    $element = that.element(),                    rtlEnabled = that.option("rtlEnabled");                that._scrollerWidth = width;                $element && $element.css(rtlEnabled ? {paddingLeft: width} : {paddingRight: width})            },            optionChanged: function(args) {                var that = this;                switch (args.name) {                    case'showColumnHeaders':                    case'wordWrapEnabled':                    case'showColumnLines':                        that.render();                        args.handled = true;                        break;                    default:                        that.callBase(args)                }            },            getHeight: function() {                var that = this,                    $element = that.element();                return $element ? $element.height() : 0            },            getContextMenuItems: function($targetElement) {                var that = this,                    $cell,                    column,                    onItemClick,                    sortingOptions;                if ($targetElement.closest("." + DATAGRID_HEADER_ROW_CLASS).length) {                    $cell = $targetElement.closest("td");                    column = $cell.length && that.getColumns($targetElement)[$cell[0].cellIndex];                    sortingOptions = that.option("sorting");                    if (sortingOptions && sortingOptions.mode !== "none" && column && column.allowSorting) {                        onItemClick = function(params) {                            setTimeout(function() {                                that._columnsController.changeSortOrder(column.index, params.itemData.value)                            })                        };                        return [{                                    text: sortingOptions.ascendingText,                                    value: "asc",                                    disabled: column.sortOrder === "asc",                                    icon: DATAGRID_CONTEXT_MENU_SORT_ASC_ICON,                                    onItemClick: onItemClick                                }, {                                    text: sortingOptions.descendingText,                                    value: "desc",                                    disabled: column.sortOrder === "desc",                                    icon: DATAGRID_CONTEXT_MENU_SORT_DESC_ICON,                                    onItemClick: onItemClick                                }, {                                    text: sortingOptions.clearText,                                    value: "none",                                    disabled: !column.sortOrder,                                    icon: DATAGRID_CONTEXT_MENU_SORT_NONE_ICON,                                    onItemClick: onItemClick                                }]                    }                    return []                }            }        });        $.extend(dataGrid.__internals, {            DATAGRID_CELL_CONTENT_CLASS: DATAGRID_CELL_CONTENT_CLASS,            DATAGRID_HEADERS_CLASS: DATAGRID_HEADERS_CLASS,            DATAGRID_HEADER_ROW_CLASS: DATAGRID_HEADER_ROW_CLASS,            DATAGRID_NOWRAP_CLASS: DATAGRID_NOWRAP_CLASS        });        dataGrid.registerModule('columnHeaders', {            defaultOptions: function() {                return {                        showColumnHeaders: true,                        cellHintEnabled: true                    }            },            views: {columnHeadersView: dataGrid.ColumnHeadersView}        })    })(jQuery, DevExpress);    /*! Module widgets-web, file ui.dataGrid.filterRow.js */    (function($, DX) {        var ui = DX.ui,            utils = DX.utils,            dataGrid = ui.dxDataGrid;        var OPERATION_ICONS = {                '=': 'filter-operation-equals',                '<>': 'filter-operation-not-equals',                '<': 'filter-operation-less',                '<=': 'filter-operation-less-equal',                '>': 'filter-operation-greater',                '>=': 'filter-operation-greater-equal',                'default': 'filter-operation-default',                notcontains: 'filter-operation-not-contains',                contains: 'filter-operation-contains',                startswith: 'filter-operation-starts-with',                endswith: 'filter-operation-ends-with'            };        var FILTERING_TIMEOUT = 700,            DATAGRID_CLASS = "dx-datagrid",            DATAGRID_FILTER_ROW_CLASS = "dx-datagrid-filter-row",            DATAGRID_MENU_CLASS = "dx-menu",            DATAGRID_MENU_IMAGE_CLASS = 'dx-menu-image',            DATAGRID_CELL_CONTENT_CLASS = "dx-datagrid-text-content",            DATAGRID_EDITOR_WITH_MENU_CLASS = "dx-editor-with-menu",            DATAGRID_EDITOR_CONTAINER_CLASS = "dx-editor-container",            DATAGRID_EDITOR_CELL_CLASS = "dx-editor-cell",            DATAGRID_FILTER_MENU = "dx-filter-menu",            DATAGRID_APPLY_BUTTON_CLASS = "dx-apply-button",            DATAGRID_HIGHLIGHT_OUTLINE_CLASS = "dx-highlight-outline",            DATAGRID_FOCUSED_CLASS = "dx-focused",            DATAGRID_CELL_FOCUS_DISABLED_CLASS = "dx-cell-focus-disabled",            TEXTEDITOR_CLASS = "dx-texteditor";        var ColumnHeadersViewFilterRowExtender = {                _columnOptionChanged: function(e) {                    var that = this,                        optionNames = e.optionNames,                        visibleIndex,                        column,                        $cell,                        $editor,                        componentNames,                        editor,                        $menu;                    if (dataGrid.checkChanges(optionNames, ['filterValue', 'selectedFilterOperation']) && e.columnIndex !== undefined) {                        visibleIndex = that.getController('columns').getVisibleIndex(e.columnIndex);                        column = that.getController('columns').columnOption(e.columnIndex);                        $cell = that.element().find('.' + DATAGRID_FILTER_ROW_CLASS).children().eq(visibleIndex);                        $editor = $cell.find("." + TEXTEDITOR_CLASS);                        if (optionNames.filterValue)                            if ($editor.length) {                                componentNames = $editor.data("dxComponents");                                editor = componentNames.length && $editor.data(componentNames[0]);                                if (editor instanceof ui.Editor)                                    editor && editor.option("value", column.filterValue)                            }                        if (optionNames.selectedFilterOperation)                            if (visibleIndex >= 0 && column) {                                $menu = $cell.find('.' + DATAGRID_MENU_CLASS);                                if ($menu.length)                                    that._updateFilterOperationChooser($menu, column, $editor.parent())                            }                        return                    }                    that.callBase(e)                },                isFilterRowVisible: function() {                    return this._isElementVisible(this.option('filterRow'))                },                isVisible: function() {                    return this.callBase() || this.isFilterRowVisible()                },                init: function() {                    this.callBase();                    this._applyFilterViewController = this.getController("applyFilter")                },                _createRow: function(row) {                    var $row = this.callBase(row);                    if (row.rowType === "filter")                        $row.addClass(DATAGRID_FILTER_ROW_CLASS);                    return $row                },                _getRows: function() {                    var result = this.callBase();                    if (this.isFilterRowVisible())                        result.push({rowType: "filter"});                    return result                },                _renderCellContent: function($cell, options) {                    var that = this,                        column = options.column,                        columnsController = that._columnsController,                        $container,                        $editorContainer,                        $editor;                    var updateFilterValue = function(that, column, value) {                            if (value === '')                                value = undefined;                            if (!utils.isDefined(column.filterValue) && !utils.isDefined(value))                                return;                            that._applyFilterViewController.setHighLight($editorContainer, column.filterValue !== value);                            column.filterValue = value;                            columnsController.columnOption(column.index, 'filterValue', value)                        };                    if (options.rowType === "filter")                        if (column.command)                            $cell.html(' ');                        else if (column.allowFiltering) {                            that.setAria("label", Globalize.localize("dxDataGrid-ariaColumn") + " " + column.caption + ", " + Globalize.localize("dxDataGrid-ariaFilterCell"), $cell);                            $cell.addClass(DATAGRID_EDITOR_CELL_CLASS);                            $container = $('<div />').appendTo($cell),                            $editorContainer = $('<div />').addClass(DATAGRID_EDITOR_CONTAINER_CLASS).appendTo($container),                            $editor = $('<div />').appendTo($editorContainer);                            that.getController('editorFactory').createEditor($editor, $.extend({}, column, {                                value: columnsController.isDataSourceApplied() ? column.filterValue : undefined,                                setValue: function(value) {                                    updateFilterValue(that, column, value)                                },                                parentType: "filterRow",                                showAllText: that.option('filterRow.showAllText'),                                updateValueTimeout: that.option("filterRow.applyFilter") === "onClick" ? 0 : FILTERING_TIMEOUT,                                width: null                            }));                            if (column.alignment)                                $cell.find('input').first().css('text-align', column.alignment);                            if (column.filterOperations && column.filterOperations.length)                                that._renderFilterOperationChooser($container, column, $editorContainer)                        }                    that.callBase($cell, options)                },                _updateFilterOperationChooser: function($menu, column, $editorContainer) {                    var that = this,                        isCellWasFocused;                    $menu.dxMenu({                        activeStateEnabled: false,                        selectionMode: "single",                        cssClass: DATAGRID_CLASS + " " + DATAGRID_CELL_FOCUS_DISABLED_CLASS + " " + DATAGRID_FILTER_MENU,                        showFirstSubmenuMode: 'onHover',                        hideSubmenuOnMouseLeave: true,                        items: [{                                disabled: column.filterOperations && column.filterOperations.length ? false : true,                                icon: OPERATION_ICONS[column.selectedFilterOperation || "default"],                                selectable: false,                                items: that._getFilterOperationMenuItems(column)                            }],                        onItemClick: function(properties) {                            var selectedFilterOperation = properties.itemData.name;                            if (properties.itemData.items)                                return;                            if (selectedFilterOperation)                                that._columnsController.columnOption(column.index, 'selectedFilterOperation', selectedFilterOperation);                            else                                that._columnsController.columnOption(column.index, {                                    selectedFilterOperation: column.defaultSelectedFilterOperation,                                    filterValue: undefined                                });                            that._applyFilterViewController.setHighLight($editorContainer, true);                            that._focusEditor($editorContainer)                        },                        onSubmenuShown: function() {                            isCellWasFocused = that._isEditorFocused($editorContainer);                            that.getController('editorFactory').loseFocus()                        },                        onSubmenuHiding: function(e) {                            $menu.blur();                            $menu.dxMenu("instance").option("focusedElement", null);                            isCellWasFocused && that._focusEditor($editorContainer)                        },                        rtlEnabled: that.option('rtlEnabled')                    })                },                _isEditorFocused: function($container) {                    return $container.hasClass(DATAGRID_FOCUSED_CLASS) || $container.parents("." + DATAGRID_FOCUSED_CLASS).length                },                _focusEditor: function($container, showCellFocus) {                    this.getController('editorFactory').focus($container);                    $container.find("input").focus()                },                _renderFilterOperationChooser: function($container, column, $editorContainer) {                    var that = this,                        $menu;                    if (that.option("filterRow.showOperationChooser")) {                        $container.addClass(DATAGRID_EDITOR_WITH_MENU_CLASS);                        $menu = $('<div />').prependTo($container);                        that._updateFilterOperationChooser($menu, column, $editorContainer)                    }                },                _getFilterOperationMenuItems: function(column) {                    var that = this,                        result = [{}],                        filterRowOptions = that.option("filterRow"),                        operationDescriptions = filterRowOptions && filterRowOptions.operationDescriptions || {};                    if (column.filterOperations && column.filterOperations.length) {                        result = $.map(column.filterOperations, function(value) {                            return {                                    name: value,                                    selected: (column.selectedFilterOperation || column.defaultFilterOperation) === value,                                    text: operationDescriptions[value],                                    icon: OPERATION_ICONS[value]                                }                        });                        result.push({                            name: null,                            text: filterRowOptions && filterRowOptions.resetOperationText,                            icon: OPERATION_ICONS['default']                        })                    }                    return result                },                optionChanged: function(args) {                    var that = this;                    switch (args.name) {                        case'filterRow':                        case'showColumnLines':                        case'disabled':                            that.render();                            args.handled = true;                            break;                        default:                            that.callBase(args);                            break                    }                }            };        var DataControllerFilterRowExtender = {_calculateAdditionalFilter: function() {                    var that = this,                        filters = [that.callBase()],                        columns = that._columnsController.getVisibleColumns();                    $.each(columns, function() {                        var filter;                        if (this.allowFiltering && this.calculateFilterExpression && utils.isDefined(this.filterValue)) {                            filter = this.calculateFilterExpression(this.filterValue, this.selectedFilterOperation || this.defaultFilterOperation);                            filters.push(filter)                        }                    });                    return dataGrid.combineFilters(filters)                }};        var ColumnsControllerFilterRowExtender = {_createCalculatedColumnOptions: function(columnOptions) {                    var calculatedColumnOptions = this.callBase(columnOptions);                    if (columnOptions.dataField)                        $.extend(calculatedColumnOptions, {                            calculateFilterExpression: function(value, selectedFilterOperation, filterInterval) {                                var column = this,                                    dataField = column.dataField,                                    filter = null;                                if (column.dataType === 'string' && !column.lookup)                                    filter = [dataField, selectedFilterOperation || 'contains', value];                                else if (column.dataType === 'date' && utils.isDate(value)) {                                    var dateStart,                                        dateEnd;                                    switch (filterInterval) {                                        case"year":                                            dateStart = new Date(value.getFullYear(), 0, 1),                                            dateEnd = new Date(value.getFullYear() + 1, 0, 1);                                            break;                                        case"month":                                            dateStart = new Date(value.getFullYear(), value.getMonth(), 1),                                            dateEnd = new Date(value.getFullYear(), value.getMonth() + 1, 1);                                            break;                                        default:                                            dateStart = new Date(value.getFullYear(), value.getMonth(), value.getDate()),                                            dateEnd = new Date(value.getFullYear(), value.getMonth(), value.getDate() + 1)                                    }                                    switch (selectedFilterOperation) {                                        case'<':                                            return [dataField, '<', dateStart];                                        case'<=':                                            return [dataField, '<', dateEnd];                                        case'>':                                            return [dataField, '>=', dateEnd];                                        case'>=':                                            return [dataField, '>=', dateStart];                                        case'<>':                                            return [[dataField, '<', dateStart], 'or', [dataField, '>=', dateEnd]];                                        default:                                            return [[dataField, '>=', dateStart], 'and', [dataField, '<', dateEnd]]                                    }                                }                                else                                    filter = [dataField, selectedFilterOperation || '=', value];                                return filter                            },                            allowFiltering: true                        });                    else                        $.extend(calculatedColumnOptions, {allowFiltering: !!columnOptions.calculateFilterExpression});                    return calculatedColumnOptions                }};        dataGrid.ApplyFilterViewController = dataGrid.ViewController.inherit({            _isOnClick: function() {                return this.option("filterRow.applyFilter") === "onClick"            },            _getHeaderPanel: function() {                if (!this._headerPanel)                    this._headerPanel = this.getView("headerPanel");                return this._headerPanel            },            setHighLight: function($element, value) {                if (this._isOnClick()) {                    $element && $element.toggleClass(DATAGRID_HIGHLIGHT_OUTLINE_CLASS, value);                    this._getHeaderPanel().enableApplyButton(value)                }            },            removeHighLights: function() {                if (this._isOnClick()) {                    var columnHeadersView = this.getView("columnHeadersView");                    columnHeadersView.element().find("." + DATAGRID_FILTER_ROW_CLASS + " ." + DATAGRID_HIGHLIGHT_OUTLINE_CLASS).removeClass(DATAGRID_HIGHLIGHT_OUTLINE_CLASS);                    this._getHeaderPanel().enableApplyButton(false)                }            }        });        dataGrid.registerModule('filterRow', {            defaultOptions: function() {                return {filterRow: {                            visible: false,                            showOperationChooser: true,                            showAllText: Globalize.localize("dxDataGrid-filterRowShowAllText"),                            resetOperationText: Globalize.localize("dxDataGrid-filterRowResetOperationText"),                            applyFilter: "auto",                            applyFilterText: Globalize.localize("dxDataGrid-applyFilterText"),                            operationDescriptions: {                                '=': Globalize.localize("dxDataGrid-filterRowOperationEquals"),                                '<>': Globalize.localize("dxDataGrid-filterRowOperationNotEquals"),                                '<': Globalize.localize("dxDataGrid-filterRowOperationLess"),                                '<=': Globalize.localize("dxDataGrid-filterRowOperationLessOrEquals"),                                '>': Globalize.localize("dxDataGrid-filterRowOperationGreater"),                                '>=': Globalize.localize("dxDataGrid-filterRowOperationGreaterOrEquals"),                                startswith: Globalize.localize("dxDataGrid-filterRowOperationStartsWith"),                                contains: Globalize.localize("dxDataGrid-filterRowOperationContains"),                                notcontains: Globalize.localize("dxDataGrid-filterRowOperationNotContains"),                                endswith: Globalize.localize("dxDataGrid-filterRowOperationEndsWith")                            }                        }}            },            controllers: {applyFilter: dataGrid.ApplyFilterViewController},            extenders: {                controllers: {                    data: DataControllerFilterRowExtender,                    columns: ColumnsControllerFilterRowExtender                },                views: {                    columnHeadersView: ColumnHeadersViewFilterRowExtender,                    headerPanel: {                        _isShowApplyFilterButton: function() {                            var filterRowOptions = this.option("filterRow");                            return filterRowOptions && filterRowOptions.visible && filterRowOptions.applyFilter === "onClick"                        },                        _renderCore: function() {                            var that = this,                                disabled = that._applyButton ? that._applyButton.option("disabled") : true;                            that.callBase();                            that._$applyButton && that._$applyButton.remove();                            if (this._isShowApplyFilterButton()) {                                that._$applyButton = $("<div>").addClass(DATAGRID_APPLY_BUTTON_CLASS).dxButton({                                    disabled: disabled,                                    hint: that.option("filterRow.applyFilterText"),                                    icon: "apply-filter",                                    onClick: function() {                                        that._dataController._applyFilter();                                        that._applyFilterViewController.removeHighLights()                                    }                                }).appendTo(that.element());                                that._applyButton = that._$applyButton.dxButton("instance")                            }                        },                        init: function() {                            this.callBase();                            this._dataController = this.getController("data");                            this._applyFilterViewController = this.getController("applyFilter")                        },                        enableApplyButton: function(value) {                            this._applyButton && this._applyButton.option("disabled", !value)                        },                        isVisible: function() {                            return this.callBase() || this._isShowApplyFilterButton()                        },                        optionChanged: function(args) {                            if (args.name === "filterRow") {                                this.render();                                args.handled = true                            }                            else                                this.callBase(args)                        }                    }                }            }        });        $.extend(dataGrid.__internals, {            DATAGRID_FILTER_ROW_CLASS: DATAGRID_FILTER_ROW_CLASS,            DATAGRID_MENU_CLASS: DATAGRID_MENU_CLASS,            DATAGRID_MENU_IMAGE_CLASS: DATAGRID_MENU_IMAGE_CLASS,            DATAGRID_CELL_CONTENT_CLASS: DATAGRID_CELL_CONTENT_CLASS,            DATAGRID_EDITOR_WITH_MENU_CLASS: DATAGRID_EDITOR_WITH_MENU_CLASS,            DATAGRID_EDITOR_CONTAINER_CLASS: DATAGRID_EDITOR_CONTAINER_CLASS,            DATAGRID_HIGHLIGHT_OUTLINE_CLASS: DATAGRID_HIGHLIGHT_OUTLINE_CLASS,            DATAGRID_APPLY_BUTTON_CLASS: DATAGRID_APPLY_BUTTON_CLASS        });        dataGrid.ColumnHeadersViewFilterRowExtender = ColumnHeadersViewFilterRowExtender;        dataGrid.DataControllerFilterRowExtender = DataControllerFilterRowExtender    })(jQuery, DevExpress);    /*! Module widgets-web, file ui.dataGrid.headerPanel.js */    (function($, DX) {        var ui = DX.ui,            dataGrid = ui.dxDataGrid;        var DATAGRID_HEADER_PANEL_CLASS = "dx-datagrid-header-panel";        dataGrid.HeaderPanel = dataGrid.ColumnsView.inherit({            _renderCore: function() {                this.element().addClass(DATAGRID_HEADER_PANEL_CLASS)            },            getHeaderPanel: function() {                return this.element()            },            getHeight: function() {                var $element = this.element();                return $element ? $element.outerHeight(true) : 0            },            isVisible: function() {                return false            },            optionChanged: function(args) {                var that = this;                switch (args.name) {                    case'disabled':                        that.render();                        args.handled = true;                        break;                    default:                        that.callBase(args)                }            }        });        $.extend(dataGrid.__internals, {DATAGRID_HEADER_PANEL_CLASS: DATAGRID_HEADER_PANEL_CLASS});        dataGrid.registerModule('headerPanel', {            defaultOptions: function() {                return {}            },            views: {headerPanel: dataGrid.HeaderPanel}        })    })(jQuery, DevExpress);    /*! Module widgets-web, file ui.dataGrid.headerFilter.js */    (function($, DX) {        var ui = DX.ui,            dataGrid = ui.dxDataGrid,            utils = DX.utils;        var DATAGRID_HEADER_FILTER_CLASS = "dx-header-filter",            DATAGRID_HEADER_FILTER_MENU_CLASS = "dx-header-filter-menu",            DATAGRID_HEADER_FILTER_SPACE_CLASS = "dx-header-filter-space",            DATAGRID_CELL_CONTENT_CLASS = "dx-datagrid-text-content";        dataGrid.HeaderFilterController = dataGrid.ViewController.inherit({            init: function() {                this._columnsController = this.getController("columns");                this._dataController = this.getController("data");                this._headerFilterView = this.getView("headerFilterView")            },            getDataSource: function(column) {                var that = this,                    cutoffLevel,                    group,                    headerFilterOptions = that.option("headerFilter"),                    store = that._dataController.dataSource().store();                var processGroupItems = function(groupItems, level, currentLevel, path) {                        var value,                            formatOptions;                        currentLevel = currentLevel || 0;                        path = path || [];                        for (var i = 0; i < groupItems.length; i++) {                            value = groupItems[i].key;                            if (column.lookup)                                value = column.lookup.calculateCellValue(value);                            if (column.dataType === "date")                                formatOptions = currentLevel === 1 ? {format: {                                        format: 'month',                                        dateType: 'full'                                    }} : {};                            else                                formatOptions = column;                            groupItems[i].text = dataGrid.formatValue(value, formatOptions);                            path.push(groupItems[i].key);                            if (path.length === 1)                                groupItems[i].filterValue = path[0];                            else                                groupItems[i].filterValue = path.join("/");                            if ($.inArray(groupItems[i].filterValue, column.filterValues) > -1 ^ column.filterType === "exclude")                                groupItems[i].selected = true;                            delete groupItems[i].key;                            if ("items" in groupItems[i])                                if (currentLevel === level || !groupItems[i].text) {                                    delete groupItems[i].items;                                    if (!groupItems[i].text)                                        groupItems[i].text = headerFilterOptions.texts.emptyValue                                }                                else                                    processGroupItems(groupItems[i].items, level, currentLevel + 1, path);                            path.pop()                        }                    };                if (column.dataType === "date") {                    group = [function(data) {                            var value = column.calculateCellValue(data);                            return value && value.getFullYear()                        }, function(data) {                            var value = column.calculateCellValue(data);                            return value && value.getMonth() + 1                        }, function(data) {                            var value = column.calculateCellValue(data);                            return value && value.getDate()                        }];                    cutoffLevel = 2                }                else {                    group = $.proxy(column.calculateCellValue, column);                    cutoffLevel = 0                }                return {                        filter: that._dataController.getCombinedFilter(),                        store: store,                        postProcess: function(data) {                            var result;                            new DX.data.ArrayStore(data).load({                                filter: this.filter(),                                group: group                            }).done(function(data) {                                result = data                            });                            processGroupItems(result, cutoffLevel);                            return result                        }                    }            },            getCurrentColumn: function() {                return this._currentColumn            },            showHeaderFilterMenu: function(columnIndex) {                var that = this,                    column = that._columnsController.getColumns()[columnIndex];                if (column) {                    var visibleIndex = that._columnsController.getVisibleIndex(columnIndex),                        isGroupColumn = column && utils.isDefined(column.groupIndex),                        view = isGroupColumn ? that.getView("headerPanel") : that.getView("columnHeadersView"),                        $columnElement = view.getColumnElements().eq(isGroupColumn ? column.groupIndex : visibleIndex);                    that._currentColumn = column;                    var options = $.extend({}, column, {                            type: column.dataType === "date" ? "tree" : "list",                            apply: function() {                                that._currentColumn = null;                                that._columnsController.columnOption(columnIndex, {                                    filterValues: this.filterValues,                                    filterType: this.filterType                                })                            },                            cancel: function() {                                that._currentColumn = null                            }                        });                    options.dataSource = that.getDataSource(options),                    that._headerFilterView.showHeaderFilterMenu($columnElement, options)                }            },            hideHeaderFilterMenu: function() {                this._headerFilterView.hideHeaderFilterMenu()            }        });        dataGrid.HeaderFilterView = dataGrid.View.inherit({            getPopupContainer: function() {                return this._popupContainer            },            getListContainer: function() {                return this._listContainer            },            applyHeaderFilter: function(options) {                var that = this,                    list = that.getListContainer(),                    isSelectAll = list.element().find(".dx-checkbox").eq(0).hasClass("dx-checkbox-checked"),                    filterValues = [];                var fillSelectedItemKeys = function(filterValues, items, isExclude) {                        $.each(items, function() {                            if (!!this.selected ^ isExclude)                                filterValues.push(this.filterValue);                            else if (this.items && this.items.length)                                fillSelectedItemKeys(filterValues, this.items)                        })                    };                if (!isSelectAll) {                    if (options.type === "tree") {                        fillSelectedItemKeys(filterValues, list.option("items"), options.filterType === 'exclude');                        options.filterValues = filterValues                    }                    options.apply()                }                else if (utils.isArray(options.filterValues)) {                    options.filterValues = [];                    options.apply()                }                that.hideHeaderFilterMenu()            },            showHeaderFilterMenu: function($columnElement, options) {                var that = this,                    popupContainer;                if (options) {                    that._initializePopupContainer(options);                    popupContainer = that.getPopupContainer();                    that.hideHeaderFilterMenu();                    that.updatePopup($columnElement, options);                    popupContainer.show()                }            },            hideHeaderFilterMenu: function() {                var headerFilterMenu = this.getPopupContainer();                headerFilterMenu && headerFilterMenu.hide()            },            updatePopup: function($element, options) {                var that = this,                    alignment = options.alignment === "right" ? "left" : "right";                if (that._popupContainer) {                    that._cleanPopupContent();                    that._popupContainer.option("position", {                        my: alignment + " top",                        at: alignment + " bottom",                        of: $element,                        collision: "flip"                    })                }            },            _cleanPopupContent: function() {                this._popupContainer && this._popupContainer.content().empty()            },            _initializePopupContainer: function(options) {                var that = this,                    $element = that.element(),                    headerFilterOptions = that.option("headerFilter"),                    dxPopupOptions = {                        width: headerFilterOptions && headerFilterOptions.width || 250,                        height: headerFilterOptions && headerFilterOptions.height || 300,                        visible: false,                        shading: false,                        showTitle: false,                        showCloseButton: false,                        closeOnTargetScroll: true,                        closeOnOutsideClick: true,                        onShown: function() {                            that._initializeListContainer(options)                        },                        buttons: [{                                toolbar: "bottom",                                location: "after",                                widget: "button",                                options: {                                    text: headerFilterOptions.texts.ok,                                    onClick: function() {                                        that.applyHeaderFilter(options)                                    }                                }                            }, {                                toolbar: "bottom",                                location: "after",                                widget: "button",                                options: {                                    text: headerFilterOptions.texts.cancel,                                    onClick: function() {                                        that.hideHeaderFilterMenu();                                        options.cancel && options.cancel()                                    }                                }                            }],                        rtlEnabled: that.option('rtlEnabled')                    };                if (!utils.isDefined(that._popupContainer))                    that._popupContainer = that._createComponent($element, "dxPopup", dxPopupOptions);                else                    that._popupContainer.option(dxPopupOptions)            },            _initializeListContainer: function(options) {                var that = this,                    $content = that._popupContainer.content(),                    widgetOptions = {                        dataSource: options.dataSource,                        onContentReady: function() {                            that.renderCompleted.fire()                        }                    };                if (options.type === "tree")                    that._listContainer = that._createComponent($("<div/>").appendTo($content), "dxTreeView", $.extend(widgetOptions, {                        showCheckBoxes: true,                        selectAllEnabled: true,                        keyExpr: "id"                    }));                else                    that._listContainer = that._createComponent($("<div/>").appendTo($content), "dxList", $.extend(widgetOptions, {                        pageLoadMode: "scrollBottom",                        pullRefreshEnabled: true,                        showSelectionControls: true,                        selectionMode: "all",                        onSelectionChanged: function(e) {                            var items = e.component.option("items"),                                selectedItems = e.component.option("selectedItems");                            if (!e.component._selectedItemsUpdating)                                if (selectedItems.length === 0 && items.length) {                                    options.filterType = "include";                                    options.filterValues = []                                }                                else if (selectedItems.length === items.length) {                                    options.filterType = "exclude";                                    options.filterValues = []                                }                            $.each(items, function(index, item) {                                var selected = $.inArray(item, selectedItems) >= 0,                                    oldSelected = !!item.selected,                                    filterValueIndex;                                if (oldSelected !== selected) {                                    item.selected = selected;                                    options.filterValues = options.filterValues || [];                                    filterValueIndex = $.inArray(item.filterValue, options.filterValues);                                    if (filterValueIndex >= 0)                                        options.filterValues.splice(filterValueIndex, 1);                                    if (selected ^ options.filterType === "exclude")                                        options.filterValues.push(item.filterValue)                                }                            })                        },                        onContentReady: function(e) {                            var component = e.component,                                items = component.option("items"),                                selectedItems = component.option("selectedItems"),                                selectAllCheckBox = e.element.find(".dx-list-select-all-checkbox").dxCheckBox("instance");                            $.each(items, function() {                                if (this.selected)                                    selectedItems.push(this)                            });                            component._selectedItemsUpdating = true;                            component.option("selectedItems", selectedItems);                            component._selectedItemsUpdating = false;                            if (options.filterValues && options.filterValues.length)                                selectAllCheckBox.option("value", undefined)                        }                    }))            },            _renderCore: function(options) {                this.element().addClass(DATAGRID_HEADER_FILTER_MENU_CLASS)            },            init: function() {                this._headerFilterController = this.getController("headerFilter")            }        });        var headerFilterMixin = dataGrid.headerFilterMixin = {                _applyColumnState: function(options) {                    var rootElement = options.rootElement,                        column = options.column;                    if (options.name === "headerFilter") {                        rootElement.find('.' + DATAGRID_HEADER_FILTER_CLASS + ', ' + '.' + DATAGRID_HEADER_FILTER_SPACE_CLASS).remove();                        var $headerFilterIndicator = this.callBase(options).css("float", this._getColumnAlignment(column.alignment) === "right" ? "left" : "right");                        $headerFilterIndicator.toggleClass("dx-header-filter-empty", !column.filterValues || !column.filterValues.length);                        return $headerFilterIndicator                    }                    return this.callBase(options)                },                optionChanged: function(args) {                    if (args.name === "headerFilter") {                        this.render();                        args.handled = true                    }                    else                        this.callBase(args)                }            };        var ColumnHeadersViewHeaderFilterExtender = $.extend({}, headerFilterMixin, {                _renderCellContent: function($cell, options) {                    var that = this,                        $headerFilterIndicator,                        column = options.column;                    if (!column.command && !utils.isDefined(column.groupIndex) && column.allowFiltering && that.option("headerFilter.visible") && options.rowType === "header") {                        $headerFilterIndicator = that._applyColumnState({                            name: 'headerFilter',                            rootElement: $cell,                            column: column,                            showColumnLines: that.option('showColumnLines')                        });                        that._subscribeToIndicatorEvent($headerFilterIndicator, column, 'headerFilter')                    }                    that.callBase($cell, options)                },                _subscribeToIndicatorEvent: function($indicator, column, indicatorName) {                    var that = this;                    if (indicatorName === "headerFilter")                        $indicator.on("dxclick", that.createAction(function(e) {                            var event = e.jQueryEvent;                            event.stopPropagation();                            that.getController("headerFilter").showHeaderFilterMenu(column.index)                        }))                },                _updateIndicator: function($cell, column, indicatorName) {                    var $indicator = this.callBase($cell, column, indicatorName);                    $indicator && this._subscribeToIndicatorEvent($indicator, column, indicatorName)                },                _resizeCore: function() {                    this.callBase();                    this._updateIndicatorHeights('headerFilter')                },                _columnOptionChanged: function(e) {                    var optionNames = e.optionNames;                    if (dataGrid.checkChanges(optionNames, ["filterValues", "filterType"])) {                        this._updateIndicators("headerFilter");                        return                    }                    this.callBase(e)                },                _afterRender: function() {                    this.callBase.apply(this, arguments);                    this._updateIndicatorHeights('headerFilter')                }            });        var HeaderPanelHeaderFilterExtender = $.extend({}, headerFilterMixin, {                _createGroupPanelItem: function($rootElement, groupColumn) {                    var that = this,                        $item = that.callBase.apply(that, arguments),                        $headerFilterIndicator;                    if (!groupColumn.command && groupColumn.allowFiltering && that.option("headerFilter.visible")) {                        $headerFilterIndicator = that._applyColumnState({                            name: 'headerFilter',                            rootElement: $item,                            column: {alignment: that.option("rtlEnabled") ? 'right' : 'left'},                            showColumnLines: true                        });                        $headerFilterIndicator.on("dxclick", that.createAction(function(e) {                            var event = e.jQueryEvent;                            event.stopPropagation();                            that.getController("headerFilter").showHeaderFilterMenu(groupColumn.index)                        }))                    }                    return $item                },                _renderGroupPanelItems: function($groupPanel, groupColumns) {                    this.callBase.apply(this, arguments);                    this._updateIndicatorHeights('headerFilter')                },                _resizeCore: function() {                    this.callBase();                    this._updateIndicatorHeights('headerFilter')                }            });        var DataControllerFilterRowExtender = {_calculateAdditionalFilter: function() {                    var that = this,                        filters = [that.callBase()],                        columns = that._columnsController.getVisibleColumns(),                        headerFilterController = that.getController("headerFilter"),                        currentColumn = headerFilterController.getCurrentColumn();                    if (currentColumn && currentColumn.filterValues && currentColumn.filterValues.length)                        return;                    $.each(columns, function(_, column) {                        var filter;                        if (column.allowFiltering && column.calculateFilterExpression && utils.isArray(column.filterValues) && column.filterValues.length) {                            var filterValues = [];                            var isExclude = column.filterType === "exclude";                            $.each(column.filterValues, function(_, filterValue) {                                var value = filterValue,                                    values,                                    filterIntervals,                                    dateInterval;                                if (column.dataType === "date" && utils.isDefined(value)) {                                    values = ("" + value).split("/");                                    filterIntervals = ["year", "month", "day"];                                    dateInterval = filterIntervals[values.length - 1];                                    value = new Date(values[0], (values[1] || 1) - 1, values[2] || 1)                                }                                else if (column.deserializeValue)                                    value = column.deserializeValue(value);                                filter = column.calculateFilterExpression(value, isExclude ? "<>" : "=", dateInterval);                                if (filterValues.length > 0)                                    filterValues.push(isExclude ? "and" : "or");                                filterValues.push(filter)                            });                            filters.push(filterValues)                        }                    });                    return dataGrid.combineFilters(filters)                }};        dataGrid.registerModule('headerFilter', {            defaultOptions: function() {                return {headerFilter: {                            visible: false,                            width: 252,                            height: 300,                            texts: {                                emptyValue: Globalize.localize("dxDataGrid-headerFilterEmptyValue"),                                ok: Globalize.localize("dxDataGrid-headerFilterOK"),                                cancel: Globalize.localize("dxDataGrid-headerFilterCancel")                            }                        }}            },            controllers: {headerFilter: dataGrid.HeaderFilterController},            views: {headerFilterView: dataGrid.HeaderFilterView},            extenders: {                controllers: {data: DataControllerFilterRowExtender},                views: {                    columnHeadersView: ColumnHeadersViewHeaderFilterExtender,                    headerPanel: HeaderPanelHeaderFilterExtender                }            }        });        $.extend(dataGrid.__internals, {            DATAGRID_HEADER_FILTER_CLASS: DATAGRID_HEADER_FILTER_CLASS,            DATAGRID_HEADER_FILTER_MENU_CLASS: DATAGRID_HEADER_FILTER_MENU_CLASS,            DATAGRID_HEADER_FILTER_SPACE_CLASS: DATAGRID_HEADER_FILTER_SPACE_CLASS,            DATAGRID_CELL_CONTENT_CLASS: DATAGRID_CELL_CONTENT_CLASS        })    })(jQuery, DevExpress);    /*! Module widgets-web, file ui.dataGrid.sortingModule.js */    (function($, DX) {        var ui = DX.ui,            dataGrid = ui.dxDataGrid,            events = ui.events,            utils = DX.utils;        var DATAGRID_SORT_CLASS = "dx-sort",            DATAGRID_SORT_SPACE_CLASS = "dx-sort-space",            DATAGRID_SORTUP_CLASS = "dx-sort-up",            DATAGRID_SORTDOWN_CLASS = "dx-sort-down",            DATAGRID_HEADERS_ACTION_CLASS = "dx-datagrid-action",            DATAGRID_CELL_CONTENT_CLASS = "dx-datagrid-text-content",            DATAGRID_INDICATOR_ALIGNMENT_CLASS = "dx-indicator-alignment-",            DATAGRID_COLUMN_INDICATORS_CLASS = "dx-column-indicators",            COLUMN_HEADERS_VIEW_NAMESPACE = 'dxDataGridColumnHeadersView',            DATAGRID_BORDER_COLLAPSE_CORRECTION = 1;        var sortingMixin = dataGrid.sortingMixin = {                _applyColumnState: function(options) {                    var that = this,                        sortingMode = that.option('sorting.mode'),                        rootElement = options.rootElement,                        column = options.column,                        $indicatorsContainer = rootElement.find("." + DATAGRID_COLUMN_INDICATORS_CLASS),                        getSortIndicatorAlignment = function(columnAlignment) {                            return columnAlignment === 'right' ? 'left' : 'right'                        };                    if (options.name === 'sort') {                        if ((sortingMode === 'single' || sortingMode === 'multiple') && column.allowSorting)                            options.rootElement.addClass(DATAGRID_HEADERS_ACTION_CLASS);                        rootElement.find('.' + DATAGRID_SORT_CLASS + ', ' + '.' + DATAGRID_SORT_SPACE_CLASS).remove();                        !$indicatorsContainer.children().length && $indicatorsContainer.remove();                        if (utils.isDefined(column.sortOrder)) {                            var columnAlignment = that._getColumnAlignment(column.alignment),                                sortIndicatorAlignment = getSortIndicatorAlignment(columnAlignment),                                ariaSortState = column.sortOrder === 'asc' ? 'ascending' : 'descending';                            that.setAria("sort", ariaSortState, rootElement);                            if (column.alignment === "center")                                $('<span />').addClass(DATAGRID_SORT_SPACE_CLASS).toggleClass(DATAGRID_INDICATOR_ALIGNMENT_CLASS + sortIndicatorAlignment, !options.showColumnLines).css("float", columnAlignment).prependTo(rootElement);                            var $sortIndicator = that.callBase(options).toggleClass(DATAGRID_SORTUP_CLASS, column.sortOrder === 'asc').toggleClass(DATAGRID_SORTDOWN_CLASS, column.sortOrder === 'desc');                            return $sortIndicator                        }                        else                            that.setAria("sort", "none", rootElement)                    }                    else                        return that.callBase(options)                },                _updateIndicator: function($cell, column, indicatorName) {                    if (indicatorName === "sort" && utils.isDefined(column.groupIndex))                        return;                    this.callBase.apply(this, arguments)                }            };        var ColumnHeadersViewSortingExtender = $.extend({}, sortingMixin, {                _updateIndicatorHeight: function($cell, indicatorName) {                    this.callBase($cell, indicatorName);                    !this.option('showColumnLines') && this._setColumnTextWidth($cell, $cell.outerWidth())                },                _setColumnTextWidth: function($column, columnWidth) {                    var $sortElement = $column.find("." + DATAGRID_SORT_CLASS),                        indicatorOuterWidth = $sortElement.outerWidth(),                        columnPaddings = $column.outerWidth() - $column.width(),                        columnContentIndent = indicatorOuterWidth + columnPaddings;                    $column.find("." + DATAGRID_CELL_CONTENT_CLASS).css("max-width", columnWidth - columnContentIndent - DATAGRID_BORDER_COLLAPSE_CORRECTION)                },                _renderCellContent: function($cell, options) {                    var that = this,                        column = options.column;                    if (!column.command && options.rowType === "header") {                        $cell.on(events.addNamespace("dxclick", COLUMN_HEADERS_VIEW_NAMESPACE), that.createAction(function(e) {                            var keyName = null,                                event = e.jQueryEvent;                            setTimeout(function() {                                if (event.shiftKey)                                    keyName = "shift";                                else if (event.ctrlKey)                                    keyName = "ctrl";                                if (column && !utils.isDefined(column.groupIndex))                                    that._columnsController.changeSortOrder(column.index, keyName)                            })                        }));                        that._applyColumnState({                            name: 'sort',                            rootElement: $cell,                            column: column,                            showColumnLines: that.option('showColumnLines')                        })                    }                    that.callBase($cell, options)                },                _columnOptionChanged: function(e) {                    var changeTypes = e.changeTypes,                        optionNames = e.optionNames;                    if (changeTypes.length === 1 && changeTypes.sorting) {                        this._updateIndicators("sort");                        return                    }                    this.callBase(e);                    if (optionNames.width || optionNames.visibleWidth)                        this._updateIndicatorHeights('sort')                },                _resizeCore: function() {                    this.callBase();                    this._updateIndicatorHeights('sort')                },                _afterRender: function() {                    this.callBase.apply(this, arguments);                    this._updateIndicatorHeights('sort')                },                optionChanged: function(args) {                    var that = this;                    switch (args.name) {                        case'sorting':                            that.render();                            args.handled = true;                            break;                        default:                            that.callBase(args)                    }                }            });        var HeaderPanelSortingExtender = $.extend({}, sortingMixin, {                _createGroupPanelItem: function($rootElement, groupColumn) {                    var that = this,                        $item = that.callBase.apply(that, arguments);                    $item.on(events.addNamespace("dxclick", "dxDataGridHeaderPanel"), that.createAction(function(e) {                        setTimeout(function() {                            that.getController('columns').changeSortOrder(groupColumn.index)                        })                    }));                    that._applyColumnState({                        name: 'sort',                        rootElement: $item,                        column: {                            alignment: that.option("rtlEnabled") ? 'right' : 'left',                            allowSorting: groupColumn.allowSorting,                            sortOrder: groupColumn.sortOrder === 'desc' ? 'desc' : 'asc'                        },                        showColumnLines: true                    });                    return $item                },                _renderGroupPanelItems: function($groupPanel, groupColumns) {                    this.callBase.apply(this, arguments);                    this._updateIndicatorHeights('sort')                },                _resizeCore: function() {                    this.callBase();                    this._updateIndicatorHeights('sort')                },                optionChanged: function(args) {                    var that = this;                    switch (args.name) {                        case'sorting':                            that.render();                            args.handled = true;                            break;                        default:                            that.callBase(args)                    }                }            });        dataGrid.registerModule('sorting', {            defaultOptions: function() {                return {sorting: {                            mode: 'single',                            ascendingText: Globalize.localize("dxDataGrid-sortingAscendingText"),                            descendingText: Globalize.localize("dxDataGrid-sortingDescendingText"),                            clearText: Globalize.localize("dxDataGrid-sortingClearText")                        }}            },            extenders: {views: {                    columnHeadersView: ColumnHeadersViewSortingExtender,                    headerPanel: HeaderPanelSortingExtender                }}        });        $.extend(dataGrid.__internals, {            DATAGRID_SORT_CLASS: DATAGRID_SORT_CLASS,            DATAGRID_SORTUP_CLASS: DATAGRID_SORTUP_CLASS,            DATAGRID_SORTDOWN_CLASS: DATAGRID_SORTDOWN_CLASS,            DATAGRID_HEADERS_ACTION_CLASS: DATAGRID_HEADERS_ACTION_CLASS,            DATAGRID_BORDER_COLLAPSE_CORRECTION: DATAGRID_BORDER_COLLAPSE_CORRECTION        })    })(jQuery, DevExpress);    /*! Module widgets-web, file ui.dataGrid.search.js */    (function($, DX) {        var ui = DX.ui,            utils = DX.utils,            dataGrid = ui.dxDataGrid;        var DATAGRID_SEARCH_PANEL_CLASS = "dx-datagrid-search-panel",            DATAGRID_SEARCH_TEXT_CLASS = "dx-datagrid-search-text",            FILTERING_TIMEOUT = 700;        function allowSearch(column) {            return utils.isDefined(column.allowSearch) ? column.allowSearch : column.allowFiltering        }        dataGrid.registerModule('search', {            defaultOptions: function() {                return {searchPanel: {                            visible: false,                            width: 160,                            placeholder: Globalize.localize("dxDataGrid-searchPanelPlaceholder"),                            highlightSearchText: true,                            text: ""                        }}            },            extenders: {                controllers: {data: function() {                        var calculateSearchFilter = function(that, text) {                                var i,                                    column,                                    columns = that._columnsController.getColumns(),                                    filterValue,                                    lookup,                                    filters = [];                                if (!text)                                    return null;                                function onQueryDone(items) {                                    var i,                                        valueGetter = DX.data.utils.compileGetter(lookup.valueExpr),                                        value;                                    for (i = 0; i < items.length; i++) {                                        value = valueGetter(items[i]);                                        filters.push(column.calculateFilterExpression(value))                                    }                                }                                for (i = 0; i < columns.length; i++) {                                    column = columns[i];                                    if (allowSearch(column) && column.calculateFilterExpression) {                                        lookup = column.lookup;                                        if (lookup && lookup.items) {                                            filterValue = column.parseValue.call(lookup, text);                                            DX.data.query(lookup.items).filter(column.calculateFilterExpression.call({                                                dataField: lookup.displayExpr,                                                dataType: lookup.dataType                                            }, filterValue)).enumerate().done(onQueryDone)                                        }                                        else {                                            filterValue = column.parseValue ? column.parseValue(text) : text;                                            if (filterValue !== undefined)                                                filters.push(column.calculateFilterExpression(filterValue))                                        }                                    }                                }                                return dataGrid.combineFilters(filters, 'or')                            };                        return {                                publicMethods: function() {                                    return this.callBase().concat(['searchByText'])                                },                                _calculateAdditionalFilter: function() {                                    var that = this,                                        filter = that.callBase(),                                        searchFilter = calculateSearchFilter(that, that.option("searchPanel.text"));                                    return dataGrid.combineFilters([filter, searchFilter])                                },                                searchByText: function(text) {                                    this.option("searchPanel.text", text)                                },                                optionChanged: function(args) {                                    var that = this;                                    switch (args.fullName) {                                        case"searchPanel.text":                                        case"searchPanel":                                            that._applyFilter();                                            args.handled = true;                                            break;                                        default:                                            that.callBase(args)                                    }                                }                            }                    }()},                views: {                    headerPanel: function() {                        var getSearchPanelOptions = function(that) {                                return that.option('searchPanel')                            };                        return {                                _renderSearchPanel: function() {                                    var that = this,                                        $element = that.element(),                                        dataController = that.getController('data'),                                        searchPanelOptions = getSearchPanelOptions(that);                                    if (searchPanelOptions && searchPanelOptions.visible) {                                        if (!that._$searchPanel) {                                            that._$searchPanel = $('<div/>').addClass(DATAGRID_SEARCH_PANEL_CLASS).prependTo($element);                                            that.setAria("label", Globalize.localize("dxDataGrid-ariaSearchInGrid"), that._$searchPanel)                                        }                                        else                                            that._$searchPanel.show();                                        that.getController('editorFactory').createEditor(that._$searchPanel, {                                            width: searchPanelOptions.width,                                            placeholder: searchPanelOptions.placeholder,                                            parentType: "searchPanel",                                            value: that.option("searchPanel.text"),                                            updateValueTimeout: FILTERING_TIMEOUT,                                            setValue: function(value) {                                                dataController.searchByText(value)                                            }                                        });                                        that.resize()                                    }                                    else                                        that._$searchPanel && that._$searchPanel.hide()                                },                                _renderCore: function() {                                    this.callBase();                                    this._renderSearchPanel()                                },                                focus: function() {                                    var textBox = this._$searchPanel.dxTextBox("instance");                                    if (textBox)                                        textBox.focus()                                },                                isVisible: function() {                                    var searchPanelOptions = getSearchPanelOptions(this);                                    return this.callBase() || searchPanelOptions && searchPanelOptions.visible                                },                                optionChanged: function(args) {                                    if (args.name === "searchPanel") {                                        this._renderSearchPanel();                                        args.handled = true                                    }                                    else                                        this.callBase(args)                                }                            }                    }(),                    rowsView: {                        _highlightSearchText: function(cellElement, isEquals) {                            var that = this,                                $parent,                                searchHTML,                                searchText = that.option("searchPanel.text");                            if (searchText && that.option("searchPanel.highlightSearchText")) {                                searchHTML = $('<div>').text(searchText).html();                                $parent = cellElement.parent();                                if (!$parent.length)                                    $parent = $('<div>').append(cellElement);                                $.each($parent.find(":dxicontains('" + searchText + "')"), function(index, element) {                                    $.each($(element).contents(), function(index, content) {                                        if (content.nodeType !== 3)                                            return;                                        var highlightSearchTextInTextNode = function($content, searchText) {                                                var $searchTextSpan = $('<span />').addClass(DATAGRID_SEARCH_TEXT_CLASS),                                                    text = $content.text(),                                                    index = text.toLowerCase().indexOf(searchText.toLowerCase());                                                if (index >= 0) {                                                    if ($content[0].textContent)                                                        $content[0].textContent = text.substr(0, index);                                                    else                                                        $content[0].nodeValue = text.substr(0, index);                                                    $content.after($searchTextSpan.text(text.substr(index, searchText.length)));                                                    $content = $(document.createTextNode(text.substr(index + searchText.length))).insertAfter($searchTextSpan);                                                    return highlightSearchTextInTextNode($content, searchText)                                                }                                            };                                        if (isEquals) {                                            if ($(content).text().toLowerCase() === searchText.toLowerCase())                                                $(this).replaceWith($('<span />').addClass(DATAGRID_SEARCH_TEXT_CLASS).text($(content).text()))                                        }                                        else                                            highlightSearchTextInTextNode($(content), searchText)                                    })                                })                            }                        },                        _renderRows: function($table, options) {                            this.callBase($table, options);                            if (this.option("rowTemplate"))                                this._highlightSearchText($table)                        },                        _updateCell: function($cell, parameters) {                            var that = this,                                column = parameters.column,                                isEquals = column.dataType !== "string";                            if (allowSearch(column))                                that._highlightSearchText($cell, isEquals);                            that.callBase($cell, parameters)                        }                    }                }            }        });        dataGrid.__internals = $.extend({}, dataGrid.__internals, {            DATAGRID_SEARCH_PANEL_CLASS: DATAGRID_SEARCH_PANEL_CLASS,            DATAGRID_SEARCH_TEXT_CLASS: DATAGRID_SEARCH_TEXT_CLASS        })    })(jQuery, DevExpress);    /*! Module widgets-web, file ui.dataGrid.rowsView.js */    (function($, DX) {        var ui = DX.ui,            utils = DX.utils,            dataGrid = ui.dxDataGrid;        var DATAGRID_CELL_CONTENT_CLASS = "dx-datagrid-text-content",            DATAGRID_GROUP_ROW_CLASS = "dx-group-row",            DATAGRID_ROWS_VIEW_CLASS = "dx-datagrid-rowsview",            DATAGRID_TABLE_CLASS = "dx-datagrid-table",            DATAGRID_DATA_ROW_CLASS = "dx-data-row",            DATAGRID_FREESPACE_CLASS = "dx-freespace-row",            DATAGRID_NODATA_TEXT_CLASS = "dx-datagrid-nodata",            DATAGRID_CONTENT_CLASS = "dx-datagrid-content",            DATAGRID_NOWRAP_CLASS = "dx-datagrid-nowrap",            DATAGRID_ROW_LINES_CLASS = "dx-row-lines",            DATAGRID_COLUMN_LINES_CLASS = "dx-column-lines",            DATAGRID_ROW_ALTERNATION_CLASS = "dx-row-alt",            DATAGRID_LOADPANEL_HIDE_TIMEOUT = 200;        var createScrollableOptions = function(that) {                var useNativeScrolling = that.option("scrolling.useNativeScrolling");                var options = {                        direction: "both",                        rtlEnabled: that.option("rtlEnabled") || DX.rtlEnabled,                        disabled: that.option("disabled"),                        bounceEnabled: false,                        useKeyboard: false                    };                if (useNativeScrolling === undefined)                    useNativeScrolling = true;                if (useNativeScrolling !== 'auto') {                    options.useNative = !!useNativeScrolling;                    options.useSimulatedScrollbar = !useNativeScrolling                }                return options            };        dataGrid.createScrollableOptions = createScrollableOptions;        dataGrid.RowsView = dataGrid.ColumnsView.inherit({            _getDefaultTemplate: function(column) {                switch (column.command) {                    case"empty":                        return function(container) {                                container.html(' ')                            };                    default:                        return function(container, options) {                                var isDataTextEmpty = !options.text && options.rowType === "data",                                    text = isDataTextEmpty ? " " : options.text;                                if (column.encodeHtml && !isDataTextEmpty)                                    container.text(text);                                else                                    container.html(text)                            }                }            },            _getDefaultGroupTemplate: function() {                var that = this,                    summaryTexts = that.option("summary.texts");                return function(container, options) {                        var data = options.data,                            text = options.column.caption + ": " + options.text;                        if (options.summaryItems && options.summaryItems.length)                            text += " " + dataGrid.getGroupRowSummaryText(options.summaryItems, summaryTexts);                        if (data)                            if (options.groupContinuedMessage && options.groupContinuesMessage)                                text += ' (' + options.groupContinuedMessage + '. ' + options.groupContinuesMessage + ')';                            else if (options.groupContinuesMessage)                                text += ' (' + options.groupContinuesMessage + ')';                            else if (options.groupContinuedMessage)                                text += ' (' + options.groupContinuedMessage + ')';                        container.text(text)                    }            },            _update: function(change){},            _getColumnTemplate: function(options) {                var that = this,                    column = options.column,                    template;                if (options.rowType === 'group' && column.groupIndex !== undefined)                    template = column.groupCellTemplate || that._getDefaultGroupTemplate();                else                    template = column.cellTemplate || that._getDefaultTemplate(column);                return template            },            _getCellTemplate: function(options) {                return this._getColumnTemplate(options)            },            _createRow: function(row) {                var $row = this.callBase(row),                    isGroup,                    isDataRow,                    isRowExpanded;                if (row) {                    isGroup = row.rowType === 'group';                    isDataRow = row.rowType === 'data';                    $row.toggleClass(DATAGRID_DATA_ROW_CLASS, isDataRow).toggleClass(DATAGRID_ROW_ALTERNATION_CLASS, isDataRow && row.dataIndex % 2 === 1 && this.option('rowAlternationEnabled')).toggleClass(DATAGRID_ROW_LINES_CLASS, isDataRow && this.option('showRowLines')).toggleClass(DATAGRID_COLUMN_LINES_CLASS, this.option('showColumnLines')).toggleClass(DATAGRID_GROUP_ROW_CLASS, isGroup);                    if (isGroup) {                        isRowExpanded = row.isExpanded;                        this.setAria({                            role: "rowgroup",                            expanded: utils.isDefined(isRowExpanded) && isRowExpanded.toString()                        }, $row)                    }                }                return $row            },            _createTable: function() {                var that = this;                return that.callBase.apply(that, arguments).on("dxclick", '.dx-row', that.createAction(function(e) {                        var jQueryEvent = e.jQueryEvent;                        if (!$(jQueryEvent.target).closest('a').length) {                            e.rowIndex = that.getRowIndex(jQueryEvent.currentTarget);                            e.rowElement = $(jQueryEvent.currentTarget);                            that._rowClick(e)                        }                    }))            },            _renderScrollable: function($table) {                var that = this,                    $element = that.element();                if (!$element.children().length)                    $element.append('<div />');                that._renderLoadPanel($element);                that._renderScrollableCore($element)            },            _handleScroll: function(e) {                var that = this;                that._scrollTop = e.scrollOffset.top;                that._scrollLeft = e.scrollOffset.left;                that.scrollOffsetChanged.fire(e.scrollOffset)            },            _renderScrollableCore: function($element) {                var that = this,                    dxScrollableOptions = createScrollableOptions(that),                    scrollHandler = $.proxy(that._handleScroll, that);                dxScrollableOptions.onScroll = scrollHandler;                dxScrollableOptions.onStop = scrollHandler;                $element.dxScrollable(dxScrollableOptions);                that._scrollable = $element.data('dxScrollable');                that._scrollableContainer = that._scrollable._$container            },            _renderLoadPanel: function($element) {                var that = this,                    loadPanelOptions;                if ($element.dxLoadPanel) {                    that._loadPanel && that._loadPanel.element().remove();                    loadPanelOptions = that.option("loadPanel");                    if (loadPanelOptions && loadPanelOptions.enabled) {                        loadPanelOptions = $.extend({                            shading: false,                            message: loadPanelOptions.text,                            position: {of: $element},                            container: $element                        }, loadPanelOptions);                        that._loadPanel = that._createComponent($('<div />').appendTo($element.parent()), "dxLoadPanel", loadPanelOptions)                    }                    else                        that._loadPanel = null                }            },            _renderContent: function(contentElement, tableElement) {                contentElement.replaceWith($('<div>').addClass(DATAGRID_CONTENT_CLASS).append(tableElement));                return this._findContentElement()            },            _updateContent: function(contentElement, change, newTableElement) {                var that = this,                    tableElement = that._getTableElement(),                    changeType = change && change.changeType,                    executors = [];                switch (changeType) {                    case'update':                        $.each(change.rowIndices, function(index, rowIndex) {                            var $newRowElement = that._getRowElements(newTableElement).eq(index),                                changeType = change.changeTypes[index],                                item = change.items && change.items[index];                            executors.push(function() {                                var $rowsElement = that._getRowElements(),                                    $rowElement = $rowsElement.eq(rowIndex);                                switch (changeType) {                                    case'update':                                        if (utils.isDefined(item.visible) && item.visible !== $rowElement.is(":visible"))                                            $rowElement.toggle(item.visible);                                        else                                            $rowElement.replaceWith($newRowElement);                                        break;                                    case'insert':                                        if (!$rowsElement.length)                                            $newRowElement.prependTo(tableElement);                                        else if ($rowElement.length)                                            $newRowElement.insertBefore($rowElement);                                        else                                            $newRowElement.insertAfter($rowsElement.last());                                        break;                                    case'remove':                                        $rowElement.remove();                                        break                                }                            })                        });                        $.each(executors, function() {                            this()                        });                        break;                    default:                        that._setTableElement(newTableElement);                        contentElement.addClass(DATAGRID_CONTENT_CLASS);                        that._renderContent(contentElement, newTableElement);                        break                }            },            _renderFreeSpaceRow: function(tableElement) {                var that = this,                    i,                    freeSpaceRowElement = that._createRow(),                    columns = this.getColumns();                freeSpaceRowElement.addClass(DATAGRID_FREESPACE_CLASS).toggleClass(DATAGRID_COLUMN_LINES_CLASS, that.option('showColumnLines'));                for (i = 0; i < columns.length; i++)                    freeSpaceRowElement.append(that._createCell(columns[i]));                that._appendRow(tableElement, freeSpaceRowElement)            },            _needUpdateRowHeight: function(itemsCount) {                return itemsCount > 0 && !this._rowHeight            },            _updateRowHeight: function() {                var that = this,                    tableElement = that._getTableElement(),                    tableHeight,                    itemsCount = that._dataController.items().length,                    $freeSpaceRowElement;                if (tableElement && that._needUpdateRowHeight(itemsCount)) {                    tableHeight = tableElement.outerHeight();                    $freeSpaceRowElement = that._getFreeSpaceRowElements().first();                    if ($freeSpaceRowElement && $freeSpaceRowElement.is(':visible'))                        tableHeight -= $freeSpaceRowElement.outerHeight();                    that._rowHeight = tableHeight / itemsCount                }            },            _findContentElement: function() {                var $element = this.element(),                    $scrollableContent;                if ($element) {                    $scrollableContent = $element.find('.dx-scrollable-content');                    if (!$scrollableContent)                        $scrollableContent = $element;                    return $scrollableContent.children().first()                }            },            _getRowElements: function(tableElement) {                var $rows = this.callBase(tableElement);                return $rows && $rows.not('.' + DATAGRID_FREESPACE_CLASS)            },            _getFreeSpaceRowElements: function() {                var tableElements = this._getTableElements();                return tableElements && tableElements.children('tbody').children('.' + DATAGRID_FREESPACE_CLASS)            },            _getNoDataText: function() {                return this.option("noDataText")            },            _updateNoDataText: function($element) {                $element = $element || this.element();                var noDataElement = $element.find('.' + DATAGRID_NODATA_TEXT_CLASS),                    isVisible = this._dataController.isEmpty(),                    isLoading = this._dataController.isLoading(),                    rtlEnabled = this.option("rtlEnabled"),                    noDataElementCSSConfig = {};                if (!noDataElement.length)                    noDataElement = $('<span>').addClass(DATAGRID_NODATA_TEXT_CLASS).hide().appendTo($element);                noDataElement.text(this._getNoDataText());                noDataElementCSSConfig = {                    marginTop: -Math.floor(noDataElement.height() / 2),                    marginRight: rtlEnabled ? -Math.floor(noDataElement.width() / 2) : 0,                    marginLeft: rtlEnabled ? 0 : -Math.floor(noDataElement.width() / 2)                };                noDataElement.css(noDataElementCSSConfig);                if (isVisible && !isLoading)                    noDataElement.show();                else                    noDataElement.hide()            },            _rowClick: function(e) {                var item = this._dataController.items()[e.rowIndex] || {};                this.executeAction("onRowClick", $.extend({                    columns: this.getColumns(),                    evaluate: function(expr) {                        var getter = DX.data.utils.compileGetter(expr);                        return getter(item.data)                    }                }, e, item))            },            _getGroupCellOptions: function(options) {                var columnIndex = (options.row.groupIndex || 0) + options.columnsCountBeforeGroups;                return {                        columnIndex: columnIndex,                        colspan: options.columns.length - columnIndex - 1                    }            },            _renderCells: function($row, options) {                if (options.row.rowType === 'group')                    this._renderGroupedCells($row, options);                else if (options.row.values)                    this.callBase($row, options)            },            _renderGroupedCells: function($row, options) {                var $groupCell,                    row = options.row,                    i,                    columns = options.columns,                    rowIndex = row.rowIndex,                    isExpanded,                    groupColumn,                    groupColumnAlignment,                    groupCellOptions = this._getGroupCellOptions(options);                for (i = 0; i <= groupCellOptions.columnIndex; i++) {                    if (i === groupCellOptions.columnIndex && columns[i].allowCollapsing && options.scrollingMode !== "infinite")                        isExpanded = !!row.isExpanded;                    else                        isExpanded = null;                    this._renderCell($row, {                        value: isExpanded,                        row: row,                        rowIndex: rowIndex,                        column: {                            command: "expand",                            cssClass: columns[i].cssClass                        },                        columnIndex: i                    })                }                groupColumnAlignment = this.option("rtlEnabled") ? "right" : "left";                groupColumn = $.extend({}, columns[groupCellOptions.columnIndex], {                    command: null,                    cssClass: null,                    alignment: groupColumnAlignment                });                $groupCell = this._renderCell($row, {                    value: row.values[row.groupIndex],                    row: row,                    rowIndex: rowIndex,                    column: groupColumn,                    columnIndex: groupCellOptions.columnIndex                });                $groupCell.attr('colspan', groupCellOptions.colspan)            },            _renderRows: function($table, options) {                var that = this,                    i,                    columns = options.columns,                    columnsCountBeforeGroups = 0,                    scrollingMode = that.option("scrolling.mode");                for (i = 0; i < columns.length; i++)                    if (columns[i].command === 'expand') {                        columnsCountBeforeGroups = i;                        break                    }                that.callBase($table, $.extend({                    scrollingMode: scrollingMode,                    columnsCountBeforeGroups: columnsCountBeforeGroups                }, options));                that._renderFreeSpaceRow($table)            },            _renderRow: function($table, options) {                var that = this,                    row = options.row,                    rowTemplate = that.option("rowTemplate");                if ((row.rowType === "data" || row.rowType === "group") && !utils.isDefined(row.groupIndex) && rowTemplate)                    that._renderTemplate($table, rowTemplate, $.extend({columns: options.columns}, row));                else                    that.callBase($table, options)            },            _renderTable: function(options) {                var $table = this.callBase(options);                if (!utils.isDefined(this._getTableElement())) {                    this._setTableElement($table);                    this._renderScrollable($table)                }                return $table            },            _renderCore: function(change) {                var that = this,                    $table,                    $content,                    $element = that.element();                $element.addClass(DATAGRID_ROWS_VIEW_CLASS).toggleClass(DATAGRID_NOWRAP_CLASS, !that.option("wordWrapEnabled"));                $table = that._renderTable({change: change});                $content = that._findContentElement();                that._updateContent($content, change, $table);                that.callBase(change);                that._lastColumnWidths = null            },            _getRows: function(change) {                return change && change.items || this._dataController.items()            },            _getCellOptions: function(options) {                var that = this,                    parameters,                    column = options.column,                    row = options.row,                    data = row.data,                    summaryCells = row && row.summaryCells,                    value = options.value,                    displayValue = dataGrid.getDisplayValue(column, value),                    groupingOptions = that.option('grouping'),                    scrollingMode = that.option('scrolling.mode');                parameters = $.extend(this.callBase(options), {                    value: value,                    displayValue: displayValue,                    row: row,                    key: row.key,                    data: data,                    rowType: row.rowType,                    values: row.values,                    text: !utils.isDefined(column.command) && dataGrid.formatValue(displayValue, column),                    rowIndex: row.rowIndex,                    summaryItems: summaryCells && summaryCells[options.columnIndex],                    resized: column.resizedCallbacks                });                if (utils.isDefined(column.groupIndex) && scrollingMode !== 'virtual' && scrollingMode !== 'infinite') {                    parameters.groupContinuesMessage = data && data.isContinuationOnNextPage && groupingOptions && groupingOptions.groupContinuesMessage;                    parameters.groupContinuedMessage = data && data.isContinuation && groupingOptions && groupingOptions.groupContinuedMessage                }                return parameters            },            getRow: function(index) {                var rows = this._getRowElements();                if (rows.length > index)                    return $(rows[index])            },            getCell: function(cellPosition, rows) {                var $rows = rows || this._getRowElements(),                    cells;                if ($rows.length > 0 && cellPosition.rowIndex >= 0) {                    cellPosition.rowIndex = cellPosition.rowIndex < $rows.length ? cellPosition.rowIndex : $rows.length - 1;                    cells = $rows[cellPosition.rowIndex].cells;                    if (cells && cells.length > 0)                        return $(cells[cells.length > cellPosition.columnIndex ? cellPosition.columnIndex : cells.length - 1])                }            },            getCellIndex: function($cell) {                var cellIndex = $cell.length ? $cell[0].cellIndex : -1;                return cellIndex            },            updateFreeSpaceRowHeight: function() {                var that = this,                    elementHeight,                    contentElement = that._findContentElement(),                    freeSpaceRowElements = that._getFreeSpaceRowElements(),                    contentHeight = 0,                    freespaceRowCount,                    scrollingMode,                    resultHeight;                if (freeSpaceRowElements && contentElement) {                    freeSpaceRowElements.hide();                    elementHeight = that.element().height();                    contentHeight = contentElement.outerHeight();                    resultHeight = elementHeight - contentHeight - that.getScrollbarWidth(true);                    if (that._dataController.items().length > 0) {                        if (resultHeight > 0 || !that._dataController.items().length) {                            freeSpaceRowElements.height(resultHeight);                            freeSpaceRowElements.show()                        }                        else if (!that._hasHeight) {                            freespaceRowCount = that._dataController.pageSize() - that._dataController.items().length;                            scrollingMode = that.option('scrolling.mode');                            if (freespaceRowCount > 0 && that._dataController.pageCount() > 1 && scrollingMode !== 'virtual' && scrollingMode !== 'infinite') {                                freeSpaceRowElements.height(freespaceRowCount * that._rowHeight);                                freeSpaceRowElements.show()                            }                        }                    }                    else {                        freeSpaceRowElements.height(0);                        freeSpaceRowElements.show()                    }                }            },            _columnOptionChanged: function(e) {                var optionNames = e.optionNames;                if (e.changeTypes.grouping)                    return;                if (optionNames.width || optionNames.visibleWidth) {                    this.callBase(e);                    this._fireColumnResizedCallbacks()                }            },            getScrollable: function() {                return this._scrollable            },            callbackNames: function() {                return ['scrollOffsetChanged']            },            init: function() {                var that = this,                    dataController = that.getController('data');                that.callBase();                that._editorFactoryController = that.getController("editorFactory");                that._rowHeight = 0;                that._scrollTop = 0;                that._scrollLeft = 0;                that._hasHeight = false;                dataController.loadingChanged.add(function(isLoading, messageText) {                    that.setLoading(isLoading, messageText)                });                that.createAction("onRowClick");                var scrollToCurrentPageHandler = function() {                        that.scrollToPage(dataController.pageIndex())                    };                dataController.pageIndexChanged.add(scrollToCurrentPageHandler);                dataController.pageSizeChanged.add(scrollToCurrentPageHandler);                dataController.filterChanged.add(scrollToCurrentPageHandler);                dataController.dataSourceChanged.add(function() {                    that._handleScroll({scrollOffset: {                            top: that._scrollTop,                            left: that._scrollLeft                        }})                })            },            _handleDataChanged: function(change) {                var that = this;                switch (change.changeType) {                    case'refresh':                    case'prepend':                    case'append':                    case'update':                        that.render(null, change);                        break;                    default:                        that._update(change);                        break                }            },            publicMethods: function() {                return ['isScrollbarVisible', 'getTopVisibleRowData', 'getScrollbarWidth', 'getCellElement']            },            contentWidth: function() {                return this.element().width() - this.getScrollbarWidth()            },            getScrollbarWidth: function(isHorizontal) {                var scrollableContainer = this._scrollableContainer && this._scrollableContainer.get(0),                    scrollbarWidth = 0;                if (scrollableContainer)                    if (!isHorizontal)                        scrollbarWidth = scrollableContainer.offsetWidth - scrollableContainer.clientWidth;                    else                        scrollbarWidth = scrollableContainer.offsetHeight - scrollableContainer.clientHeight;                return scrollbarWidth            },            _fireColumnResizedCallbacks: function() {                var that = this,                    lastColumnWidths = that._lastColumnWidths || [],                    columnWidths = [],                    columns = that.getColumns(),                    i;                for (i = 0; i < columns.length; i++) {                    columnWidths[i] = columns[i].visibleWidth;                    if (columns[i].resizedCallbacks && !utils.isDefined(columns[i].groupIndex) && lastColumnWidths[i] !== columnWidths[i])                        columns[i].resizedCallbacks.fire(columnWidths[i])                }                that._lastColumnWidths = columnWidths            },            _resizeCore: function() {                var that = this,                    dxScrollable;                that.callBase();                that._fireColumnResizedCallbacks();                that._updateRowHeight();                that._updateNoDataText();                that.updateFreeSpaceRowHeight();                dxScrollable = that.element().data('dxScrollable');                if (dxScrollable)                    dxScrollable.update();                that.setLoading(that._dataController.isLoading())            },            scrollToPage: function(pageIndex) {                var that = this,                    scrollingMode = that.option('scrolling.mode'),                    dataController = that._dataController,                    pageSize = dataController ? dataController.pageSize() : 0,                    scrollPosition;                if (scrollingMode === 'virtual' || scrollingMode === 'infinite')                    scrollPosition = pageIndex * that._rowHeight * pageSize;                else                    scrollPosition = 0;                that.scrollTo({                    y: scrollPosition,                    x: that._scrollLeft                })            },            scrollTo: function(location) {                var $element = this.element(),                    dxScrollable = $element && $element.data('dxScrollable');                if (dxScrollable)                    dxScrollable.scrollTo(location)            },            height: function(height) {                var that = this,                    $element = this.element(),                    freeSpaceRowElements;                if (utils.isDefined(height)) {                    that._hasHeight = height !== 'auto';                    if ($element)                        $element.height(height);                    freeSpaceRowElements = this._getFreeSpaceRowElements();                    freeSpaceRowElements && freeSpaceRowElements.hide()                }                else                    return $element ? $element.height() : 0            },            setLoading: function(isLoading, messageText) {                var that = this,                    loadPanel = that._loadPanel,                    dataController = that._dataController,                    loadPanelOptions = that.option("loadPanel") || {},                    animation = dataController.isLoaded() ? loadPanelOptions.animation : null,                    visibilityOptions;                if (loadPanel) {                    visibilityOptions = {                        message: messageText || loadPanelOptions.text,                        animation: animation,                        visible: isLoading                    };                    clearTimeout(that._hideLoadingTimeoutID);                    if (loadPanel.option('visible') && !isLoading)                        that._hideLoadingTimeoutID = setTimeout(function() {                            loadPanel.option(visibilityOptions)                        }, DATAGRID_LOADPANEL_HIDE_TIMEOUT);                    else                        loadPanel.option(visibilityOptions);                    that._updateNoDataText()                }            },            isScrollbarVisible: function() {                var $element = this.element();                return $element ? this._findContentElement().outerHeight() - $element.height() > 0 : false            },            setRowsOpacity: function(columnIndex, value) {                var that = this,                    $rows = that._getRowElements().not('.' + DATAGRID_GROUP_ROW_CLASS) || [];                $.each($rows, function(_, row) {                    $(row).children().eq(columnIndex).css({opacity: value})                })            },            getTopVisibleItemIndex: function() {                var that = this,                    itemIndex = 0,                    prevOffsetTop = 0,                    offsetTop = 0,                    rowElements,                    scrollPosition = that._scrollTop,                    contentElementOffsetTop = that._findContentElement().offset().top,                    items = that._dataController.items(),                    tableElement = that._getTableElement();                if (items.length && tableElement) {                    rowElements = tableElement.children('tbody').children('.dx-row:visible, .dx-error-row').not('.' + DATAGRID_FREESPACE_CLASS);                    for (itemIndex = 0; itemIndex < items.length; itemIndex++) {                        prevOffsetTop = offsetTop;                        offsetTop = rowElements.eq(itemIndex).offset().top - contentElementOffsetTop;                        if (offsetTop > scrollPosition) {                            if (scrollPosition * 2 < offsetTop + prevOffsetTop && itemIndex)                                itemIndex--;                            break                        }                    }                    if (itemIndex && itemIndex === items.length)                        itemIndex--                }                return itemIndex            },            getTopVisibleRowData: function() {                var itemIndex = this.getTopVisibleItemIndex(),                    items = this._dataController.items();                if (items[itemIndex])                    return items[itemIndex].data            },            optionChanged: function(args) {                var that = this;                that.callBase(args);                switch (args.name) {                    case'wordWrapEnabled':                    case'hoverStateEnabled':                    case'showColumnLines':                    case'showRowLines':                    case'rowAlternationEnabled':                    case'rowTemplate':                        that.render();                        that.component.resize();                        args.handled = true;                        break;                    case'scrolling':                        that._rowHeight = null;                        that._tableElement = null;                        args.handled = true;                        break;                    case'rtlEnabled':                        that._rowHeight = null;                        that._tableElement = null;                        break;                    case"disabled":                    case'loadPanel':                        that._tableElement = null;                        that.render();                        that.component.resize();                        args.handled = true;                        break;                    case'noDataText':                        that._updateNoDataText();                        args.handled = true;                        break                }            },            dispose: function() {                clearTimeout(this._hideLoadingTimeoutID)            },            setScrollerSpacing: function(){}        });        $.extend(dataGrid.__internals, {            DATAGRID_CELL_CONTENT_CLASS: DATAGRID_CELL_CONTENT_CLASS,            DATAGRID_GROUP_ROW_CLASS: DATAGRID_GROUP_ROW_CLASS,            DATAGRID_ROWS_VIEW_CLASS: DATAGRID_ROWS_VIEW_CLASS,            DATAGRID_TABLE_CLASS: DATAGRID_TABLE_CLASS,            DATAGRID_FREESPACE_CLASS: DATAGRID_FREESPACE_CLASS,            DATAGRID_NODATA_TEXT_CLASS: DATAGRID_NODATA_TEXT_CLASS,            DATAGRID_NOWRAP_CLASS: DATAGRID_NOWRAP_CLASS,            DATAGRID_ROW_LINES_CLASS: DATAGRID_ROW_LINES_CLASS,            DATAGRID_COLUMN_LINES_CLASS: DATAGRID_COLUMN_LINES_CLASS,            DATAGRID_ROW_ALTERNATION_CLASS: DATAGRID_ROW_ALTERNATION_CLASS        });        dataGrid.registerModule('rows', {            defaultOptions: function() {                return {                        hoverStateEnabled: false,                        loadPanel: {                            enabled: true,                            text: Globalize.localize("Loading"),                            width: 200,                            height: 70,                            showIndicator: true,                            indicatorSrc: "",                            showPane: true                        },                        rowTemplate: null,                        columnAutoWidth: false,                        noDataText: Globalize.localize("dxDataGrid-noDataText"),                        wordWrapEnabled: false,                        showColumnLines: true,                        showRowLines: false,                        rowAlternationEnabled: false,                        activeStateEnabled: false                    }            },            views: {rowsView: dataGrid.RowsView}        })    })(jQuery, DevExpress);    /*! Module widgets-web, file ui.dataGrid.pager.js */    (function($, DX) {        var ui = DX.ui,            utils = DX.utils,            dataGrid = ui.dxDataGrid;        var DATAGRID_PAGER_CLASS = "dx-datagrid-pager";        var MAX_PAGES_COUNT = 10;        dataGrid.PagerView = dataGrid.View.inherit({            init: function() {                var that = this,                    dataController = that.getController('data');                that._isVisible = false;                dataController.changed.add(function() {                    that.render()                })            },            _getPager: function() {                var $element = this.element();                return $element && $element.data('dxPager')            },            _renderCore: function() {                var that = this,                    $element = that.element().addClass(DATAGRID_PAGER_CLASS),                    pagerOptions = that.option('pager') || {},                    dataController = that.getController('data'),                    options = {                        maxPagesCount: MAX_PAGES_COUNT,                        pageIndex: dataController.pageIndex() + 1,                        pageCount: dataController.pageCount(),                        pageSize: dataController.pageSize(),                        showPageSizes: pagerOptions.showPageSizeSelector,                        showInfo: pagerOptions.showInfo,                        showNavigationButtons: pagerOptions.showNavigationButtons,                        pageSizes: that.getPageSizes(),                        hasKnownLastPage: dataController.hasKnownLastPage(),                        pageIndexChanged: function(pageIndex) {                            if (dataController.pageIndex() !== pageIndex - 1)                                setTimeout(function() {                                    dataController.pageIndex(pageIndex - 1)                                })                        },                        pageSizeChanged: function(pageSize) {                            setTimeout(function() {                                dataController.pageSize(pageSize)                            })                        }                    };                if (utils.isDefined(pagerOptions.infoText))                    options.infoText = pagerOptions.infoText;                that._createComponent($element, "dxPager", options)            },            getPageSizes: function() {                var that = this,                    dataController = that.getController('data'),                    pagerOptions = that.option('pager'),                    allowedPageSizes = pagerOptions && pagerOptions.allowedPageSizes,                    pageSize = dataController.pageSize();                if (!utils.isDefined(that._pageSizes) || $.inArray(pageSize, that._pageSizes) === -1) {                    that._pageSizes = [];                    if (pagerOptions)                        if ($.isArray(allowedPageSizes))                            that._pageSizes = allowedPageSizes;                        else if (allowedPageSizes && pageSize > 1)                            that._pageSizes = [Math.floor(pageSize / 2), pageSize, pageSize * 2]                }                return that._pageSizes            },            isVisible: function() {                var that = this,                    dataController = that.getController('data'),                    pagerOptions = that.option('pager'),                    pagerVisible = pagerOptions && pagerOptions.visible,                    scrolling = that.option('scrolling');                if (that._isVisible)                    return true;                if (pagerVisible === 'auto')                    if (scrolling && (scrolling.mode === 'virtual' || scrolling.mode === 'infinite'))                        pagerVisible = false;                    else                        pagerVisible = dataController.pageCount() > 1 || dataController.isLoaded() && !dataController.hasKnownLastPage();                that._isVisible = pagerVisible;                return pagerVisible            },            getHeight: function() {                var pager = this._getPager();                return pager && this.isVisible() ? pager.getHeight() : 0            },            optionChanged: function(args) {                var that = this,                    name = args.name,                    isPager = name === "pager",                    isPaging = name === "paging",                    isScrolling = name === "scrolling";                if (isPager || isPaging || isScrolling) {                    if (isPager || isPaging)                        that._pageSizes = null;                    that._isVisible = false;                    that.render();                    if (isPager && that.component)                        that.component.resize();                    args.handled = true                }            }        });        dataGrid.registerModule('pager', {            defaultOptions: function() {                return {pager: {                            visible: 'auto',                            showPageSizeSelector: false,                            allowedPageSizes: 'auto'                        }}            },            views: {pagerView: dataGrid.PagerView}        })    })(jQuery, DevExpress);    /*! Module widgets-web, file ui.dataGrid.gridView.js */    (function($, DX) {        var dataGrid = DX.ui.dxDataGrid,            utils = DX.utils;        var DATAGRID_CLASS = "dx-datagrid",            DATAGRID_HIDDEN_CLASS = "dx-hidden",            DATAGRID_TABLE_CLASS = "dx-datagrid-table",            DATAGRID_BORDERS_CLASS = "dx-datagrid-borders",            DATAGRID_TABLE_FIXED_CLASS = "dx-datagrid-table-fixed",            DATAGRID_COLUMN_HEADERS_HIDDEN = "dx-datagrid-headers-hidden",            DATAGRID_IMPORTANT_MARGIN_CLASS = "dx-datagrid-important-margin",            EMPTY_GRID_ROWS_HEIGHT = 100,            LOADPANEL_MARGIN = 50,            VIEW_NAMES = ['columnsSeparatorView', 'blockSeparatorView', 'trackerView', 'headerPanel', 'columnHeadersView', 'rowsView', 'footerView', 'columnChooserView', 'pagerView', 'draggingHeaderView', 'contextMenuView', 'errorView', 'headerFilterView'];        var isPercentWidth = function(width) {                return utils.isString(width) && width.slice(-1) === '%'            };        var mergeArraysByMaxValue = function(values1, values2) {                var result = [],                    i;                if (values1 && values2 && values1.length && values1.length === values2.length)                    for (i = 0; i < values1.length; i++)                        result.push(values1[i] > values2[i] ? values1[i] : values2[i]);                else if (values1)                    result = values1;                return result            };        dataGrid.ResizingController = dataGrid.ViewController.inherit({            _initPostRenderHandlers: function() {                var that = this;                if (!that._refreshSizesHandler) {                    that._refreshSizesHandler = function(e) {                        that._dataController.changed.remove(that._refreshSizesHandler);                        var changeType = e && e.changeType;                        if (!e || changeType === 'refresh' || changeType === 'prepend' || changeType === 'append' || changeType === 'update')                            that.resize();                        if (changeType) {                            utils.triggerShownEvent(that.getView("rowsView").element());                            that.component._fireContentReadyAction()                        }                    };                    that._dataController.changed.add(function() {                        that._dataController.changed.add(that._refreshSizesHandler)                    });                    that._columnHeadersView.sizeChanged.add(that._refreshSizesHandler)                }            },            _getBestFitWidths: function() {                var that = this,                    rowsColumnWidths = that._rowsView.getColumnWidths(),                    headerColumnWidths = that._columnHeadersView && that._columnHeadersView.getColumnWidths(),                    footerColumnWidths = that._footerView && that._footerView.getColumnWidths(),                    resultWidths;                resultWidths = mergeArraysByMaxValue(rowsColumnWidths, headerColumnWidths);                resultWidths = mergeArraysByMaxValue(resultWidths, footerColumnWidths);                return resultWidths            },            _setVisibleWidths: function(visibleColumns, widths) {                var columnsController = this._columnsController;                columnsController.beginUpdate();                $.each(visibleColumns, function(index, column) {                    var columnId = column.command ? "command:" + column.command : column.index;                    columnsController.columnOption(columnId, 'visibleWidth', widths[index])                });                columnsController.endUpdate()            },            _toggleBestFitMode: function(isBestFit) {                var $element = this.component.element();                $element.find('.' + DATAGRID_TABLE_CLASS).toggleClass(DATAGRID_TABLE_FIXED_CLASS, !isBestFit);                $element.find('input').toggleClass(DATAGRID_HIDDEN_CLASS, isBestFit)            },            _synchronizeColumns: function() {                var that = this,                    columnsController = that._columnsController,                    visibleColumns = columnsController.getVisibleColumns(),                    columnAutoWidth = that.option("columnAutoWidth"),                    needBestFit = columnAutoWidth,                    lastWidthReseted = false,                    resultWidths = [],                    normalizeWidthsByExpandColumns = function() {                        var expandColumnWidth;                        $.each(visibleColumns, function(index, column) {                            if (column.command === "expand")                                expandColumnWidth = resultWidths[index]                        });                        $.each(visibleColumns, function(index, column) {                            if (column.command === "expand" && expandColumnWidth)                                resultWidths[index] = expandColumnWidth                        })                    };                !needBestFit && $.each(visibleColumns, function(index, column) {                    if (column.width === "auto") {                        needBestFit = true;                        return false                    }                });                that._setVisibleWidths(visibleColumns, []);                if (needBestFit) {                    that._toggleBestFitMode(true);                    resultWidths = that._getBestFitWidths();                    $.each(visibleColumns, function(index, column) {                        var columnId = column.command ? "command:" + column.command : column.index;                        columnsController.columnOption(columnId, 'bestFitWidth', resultWidths[index], true)                    })                }                $.each(visibleColumns, function(index) {                    if (this.width !== 'auto')                        if (this.width)                            resultWidths[index] = this.width;                        else if (!columnAutoWidth)                            resultWidths[index] = undefined                });                lastWidthReseted = that._correctColumnWidths(resultWidths, visibleColumns);                if (columnAutoWidth) {                    normalizeWidthsByExpandColumns();                    that._processStretch(resultWidths, visibleColumns)                }                if (needBestFit)                    that._toggleBestFitMode(false);                if (needBestFit || lastWidthReseted)                    that._setVisibleWidths(visibleColumns, resultWidths)            },            _correctColumnWidths: function(resultWidths, visibleColumns) {                var that = this,                    hasPercentWidth = false,                    hasAutoWidth = false,                    lastWidthReseted = false,                    $element = that.component.element(),                    hasWidth = that._hasWidth,                    lastColumnIndex;                $.each(visibleColumns, function(index) {                    if (this.width !== 'auto')                        if (this.width)                            resultWidths[index] = this.width;                        else                            hasAutoWidth = true;                    if (isPercentWidth(this.width))                        hasPercentWidth = true                });                if ($element && that._maxWidth) {                    delete that._maxWidth;                    $element.css('max-width', '')                }                if (!hasAutoWidth && resultWidths.length) {                    var contentWidth = that._rowsView.contentWidth();                    var totalWidth = that._getTotalWidth(resultWidths, contentWidth);                    if (totalWidth <= contentWidth) {                        lastColumnIndex = resultWidths.length - 1;                        while (lastColumnIndex >= 0 && visibleColumns[lastColumnIndex] && visibleColumns[lastColumnIndex].command)                            lastColumnIndex--;                        if (lastColumnIndex >= 0) {                            resultWidths[lastColumnIndex] = 'auto';                            lastWidthReseted = true;                            if (!hasWidth && !hasPercentWidth) {                                that._maxWidth = totalWidth;                                $element.css('max-width', that._maxWidth)                            }                        }                    }                }                return lastWidthReseted            },            _processStretch: function(resultSizes, visibleColumns) {                var groupSize = this._rowsView.contentWidth(),                    tableSize = this._getTotalWidth(resultSizes, groupSize),                    unusedIndexes = {length: 0},                    diff,                    diffElement,                    onePixelElementsCount,                    i;                if (!resultSizes.length)                    return;                $.each(visibleColumns, function(index) {                    if (this.width) {                        unusedIndexes[index] = true;                        unusedIndexes.length++                    }                });                diff = groupSize - tableSize;                diffElement = Math.floor(diff / (resultSizes.length - unusedIndexes.length));                onePixelElementsCount = diff - diffElement * (resultSizes.length - unusedIndexes.length);                if (diff >= 0)                    for (i = 0; i < resultSizes.length; i++) {                        if (unusedIndexes[i])                            continue;                        resultSizes[i] += diffElement;                        if (onePixelElementsCount) {                            resultSizes[i]++;                            onePixelElementsCount--                        }                    }            },            _getTotalWidth: function(widths, groupWidth) {                var result = 0,                    width,                    i;                for (i = 0; i < widths.length; i++) {                    width = widths[i];                    if (width)                        result += isPercentWidth(width) ? parseInt(width) * groupWidth / 100 : parseInt(width)                }                return Math.round(result)            },            updateSize: function($rootElement) {                var that = this,                    $groupElement,                    width;                if (that._hasHeight === undefined && $rootElement && $rootElement.closest(document).length) {                    $groupElement = $rootElement.children('.' + DATAGRID_CLASS);                    if ($groupElement.length)                        $groupElement.detach();                    that._hasHeight = !!$rootElement.height();                    width = $rootElement.width();                    $rootElement.addClass(DATAGRID_IMPORTANT_MARGIN_CLASS);                    that._hasWidth = $rootElement.width() === width;                    $rootElement.removeClass(DATAGRID_IMPORTANT_MARGIN_CLASS);                    if ($groupElement.length)                        $groupElement.appendTo($rootElement)                }            },            publicMethods: function() {                return ["resize", "updateDimensions"]            },            resize: function() {                this.updateDimensions()            },            updateDimensions: function() {                var that = this,                    dataController = that._dataController,                    $rootElement = that.component.element(),                    rootElementHeight = $rootElement && ($rootElement.get(0).clientHeight || $rootElement.height()),                    loadPanelOptions = that.option('loadPanel'),                    height = that.option('height'),                    rowsViewHeight,                    editorFactory = that.getController('editorFactory'),                    $testDiv;                that._initPostRenderHandlers();                that.updateSize($rootElement);                if (height && that._hasHeight ^ height !== 'auto') {                    $testDiv = $('<div>').height(height).appendTo($rootElement);                    that._hasHeight = !!$testDiv.height();                    $testDiv.remove()                }                if (that._hasHeight && rootElementHeight > 0 && that.option('scrolling')) {                    rowsViewHeight = rootElementHeight;                    $.each(that.getViews(), function() {                        if (this.isVisible() && this.getHeight)                            rowsViewHeight -= this.getHeight()                    })                }                else if (!that._hasHeight && dataController.items().length === 0)                    rowsViewHeight = loadPanelOptions && loadPanelOptions.visible ? loadPanelOptions.height + LOADPANEL_MARGIN : EMPTY_GRID_ROWS_HEIGHT;                else                    rowsViewHeight = 'auto';                that._rowsView.height(rowsViewHeight);                that._columnHeadersView.setScrollerSpacing(that._rowsView.getScrollbarWidth());                that._rowsView.setScrollerSpacing();                that._synchronizeColumns();                $.each(VIEW_NAMES, function(index, viewName) {                    var view = that.getView(viewName);                    if (view)                        view.resize()                });                editorFactory && editorFactory.resize()            },            optionChanged: function(args) {                switch (args.name) {                    case"width":                    case"height":                        this.component._renderDimensions();                        this.resize();                    default:                        this.callBase(args)                }            },            init: function() {                var that = this;                that._dataController = that.getController('data');                that._columnsController = that.getController('columns');                that._columnHeadersView = that.getView('columnHeadersView');                that._footerView = that.getView("footerView");                that._rowsView = that.getView('rowsView');                that._footerView = that.getView('footerView');                that._rowsView.scrollOffsetChanged.add(function(e) {                    that._columnHeadersView.scrollOffset(e.left);                    that._footerView.scrollOffset(e.left)                })            }        });        dataGrid.GridView = dataGrid.View.inherit({            init: function() {                var that = this;                that._dataController = that.getController('data');                that._rowsView = that.getView('rowsView')            },            getView: function(name) {                return this.component._views[name]            },            element: function() {                return this._groupElement            },            optionChanged: function(args) {                var that = this;                if (utils.isDefined(that._groupElement) && args.name === "showBorders") {                    that._groupElement.toggleClass(DATAGRID_BORDERS_CLASS, !!args.value);                    args.handled = true                }                else                    that.callBase(args)            },            render: function($rootElement) {                var that = this,                    groupElement = that._groupElement || $('<div />').addClass(DATAGRID_CLASS).toggleClass(DATAGRID_BORDERS_CLASS, !!that.option("showBorders"));                that.component.setAria({                    role: "application",                    label: Globalize.localize("dxDataGrid-ariaDataGrid")                }, $rootElement);                that._rootElement = $rootElement || that._rootElement;                that._groupElement = groupElement;                $.each(VIEW_NAMES, function(index, viewName) {                    var view = that.getView(viewName);                    if (view)                        view.render(groupElement)                });                that.update()            },            update: function() {                var that = this,                    $rootElement = that._rootElement,                    $groupElement = that._groupElement,                    resizingController = that.getController('resizing');                if ($rootElement && $groupElement) {                    if (!$groupElement.parent().length) {                        resizingController.updateSize($rootElement);                        $groupElement.appendTo($rootElement);                        that._rowsView.renderDelayedTemplates()                    }                    resizingController.resize();                    if (that._dataController.isLoaded())                        that.component._fireContentReadyAction()                }            }        });        dataGrid.registerModule("gridView", {            defaultOptions: function() {                return {showBorders: false}            },            controllers: {resizing: dataGrid.ResizingController},            views: {gridView: dataGrid.GridView}        });        $.extend(dataGrid.__internals, {            viewNames: VIEW_NAMES,            DATAGRID_CLASS: DATAGRID_CLASS,            DATAGRID_COLUMN_HEADERS_HIDDEN: DATAGRID_COLUMN_HEADERS_HIDDEN,            DATAGRID_BORDERS_CLASS: DATAGRID_BORDERS_CLASS        })    })(jQuery, DevExpress);    /*! Module widgets-web, file ui.dataGrid.columnsResizingReorderingModule.js */    (function($, DX) {        var ui = DX.ui,            events = ui.events,            addNamespace = events.addNamespace,            utils = DX.utils,            dataGrid = ui.dxDataGrid,            fx = DX.fx;        var DATAGRID_COLUMNS_SEPARATOR_CLASS = "dx-datagrid-columns-separator",            DATAGRID_COLUMNS_SEPARATOR_TRANSPARENT = "dx-datagrid-columns-separator-transparent",            DATAGRID_DRAGGING_HEADER_CLASS = "dx-datagrid-drag-header",            DATAGRID_CELL_CONTENT_CLASS = "dx-datagrid-text-content",            DATAGRID_HEADERS_DRAG_ACTION_CLASS = "dx-datagrid-drag-action",            DATAGRID_TRACKER_CLASS = "dx-datagrid-tracker",            DATAGRID_BLOCK_SEPARATOR_CLASS = "dx-block-separator",            DATAGRID_HEADERS_DROP_HIGHLIGHT_CLASS = 'dx-datagrid-drop-highlight',            DATAGRID_HEADER_ROW_CLASS = "dx-header-row",            WIDGET_CLASS = "dx-widget",            DATAGRID_MODULE_NAMESPACE = "dxDataGridResizingReordering",            COLUMNS_SEPARATOR_TOUCH_TRACKER_WIDTH = 10,            DRAGGING_DELTA = 5;        var allowResizing = function(that) {                return that.option("allowColumnResizing") || that.getController("columns").isColumnOptionUsed("allowResizing")            };        var allowReordering = function(that) {                return that.option("allowColumnReordering") || that.getController("columns").isColumnOptionUsed("allowReordering")            };        dataGrid.getPointsByColumns = function(items, pointCreated, isVertical) {            var cellsLength = items.length,                cancel = false,                i,                point,                item,                offset,                result = [],                rtlEnabled,                columnIndex = 0;            for (i = 0; i <= cellsLength; i++) {                if (i < cellsLength) {                    item = items.eq(columnIndex);                    offset = item.offset();                    rtlEnabled = item.css('direction') === 'rtl'                }                point = {                    index: i,                    x: offset ? offset.left + (!isVertical && rtlEnabled ^ i === cellsLength ? item.outerWidth() : 0) : 0,                    y: offset ? offset.top + (isVertical && i === cellsLength ? item.outerHeight() : 0) : 0,                    columnIndex: columnIndex                };                if (pointCreated)                    cancel = pointCreated(point);                if (!cancel)                    result.push(point);                columnIndex++            }            return result        };        dataGrid.TrackerView = dataGrid.View.inherit({            _renderCore: function(options) {                this.callBase();                this.element().addClass(DATAGRID_TRACKER_CLASS);                this.hide()            },            init: function() {                var that = this,                    $element;                that.callBase();                that.getController("tablePosition").positionChanged.add(function(position) {                    $element = that.element();                    if ($element && $element.hasClass(DATAGRID_TRACKER_CLASS)) {                        $element.css({top: position.top});                        $element.height(position.height)                    }                })            },            isVisible: function() {                return allowResizing(this)            },            show: function() {                this.element().show()            },            hide: function() {                this.element().hide()            },            setHeight: function(value) {                this.element().height(value)            }        });        dataGrid.SeparatorView = dataGrid.View.inherit({            _renderSeparator: function(){},            _renderCore: function(options) {                this.callBase(options);                this._isShown = true;                this._renderSeparator();                this.hide()            },            show: function() {                this._isShown = true            },            hide: function() {                this._isShown = false            },            height: function(value) {                var $element = this.element();                if ($element)                    if (utils.isDefined(value))                        $element.height(value);                    else                        return $element.height()            },            width: function(value) {                var $element = this.element();                if ($element)                    if (utils.isDefined(value))                        $element.width(value);                    else                        return $element.width()            }        });        dataGrid.ColumnsSeparatorView = dataGrid.SeparatorView.inherit({            _renderSeparator: function() {                this.callBase();                var $element = this.element();                $element.addClass(DATAGRID_COLUMNS_SEPARATOR_CLASS)            },            _subscribeToEvent: function() {                var that = this,                    $element;                that.getController("tablePosition").positionChanged.add(function(position) {                    $element = that.element();                    if ($element) {                        $element.css({top: position.top});                        $element.height(position.height)                    }                })            },            isVisible: function() {                return this.option('showColumnHeaders') && (allowReordering(this) || allowResizing(this))            },            init: function() {                this.callBase();                this._isTransparent = allowResizing(this);                if (this.isVisible())                    this._subscribeToEvent()            },            show: function() {                var that = this,                    $element = this.element();                if ($element && !that._isShown)                    if (that._isTransparent)                        $element.removeClass(DATAGRID_COLUMNS_SEPARATOR_TRANSPARENT);                    else                        $element.show();                this.callBase()            },            hide: function() {                var $element = this.element();                if ($element && this._isShown)                    if (this._isTransparent)                        $element.addClass(DATAGRID_COLUMNS_SEPARATOR_TRANSPARENT);                    else                        $element.hide();                this.callBase()            },            moveByX: function(outerX) {                var $element = this.element();                if ($element) {                    $element.css("left", outerX - this._parentElement().offset().left);                    this._testPosx = outerX                }            },            changeCursor: function(cursorName) {                cursorName = utils.isDefined(cursorName) ? cursorName : "";                var $element = this.element();                if ($element) {                    $element.css('cursor', cursorName);                    this._testCursorName = cursorName                }            }        });        dataGrid.BlockSeparatorView = dataGrid.SeparatorView.inherit({            _renderSeparator: function() {                this.callBase();                this.element().addClass(DATAGRID_BLOCK_SEPARATOR_CLASS).html(' ')            },            hide: function() {                var that = this,                    $parent = this._parentElement(),                    $element = this.element();                if ($element && this._isShown)                    $element.hide();                if ($parent && !$parent.children('.' + DATAGRID_BLOCK_SEPARATOR_CLASS).length)                    $parent.prepend(that.element());                that.callBase()            },            isVisible: function() {                var groupPanelOptions = this.option("groupPanel"),                    columnChooserOptions = this.option('columnChooser');                return groupPanelOptions && groupPanelOptions.visible || columnChooserOptions && columnChooserOptions.enabled            },            show: function(targetLocation) {                var that = this,                    $element = this.element(),                    startAnimate = function(toOptions) {                        fx.stop($element, true);                        fx.animate($element, {                            type: "slide",                            from: {                                width: 0,                                display: toOptions.display                            },                            to: toOptions,                            duration: 300,                            easing: "swing"                        })                    };                if ($element && !that._isShown)                    switch (targetLocation) {                        case"group":                            startAnimate({                                width: "50px",                                display: "inline-block"                            });                            break;                        case"columnChooser":                            startAnimate({                                width: "100%",                                display: "block"                            });                            break;                        default:                            $element.show()                    }                that.callBase()            }        });        dataGrid.DraggingHeaderView = dataGrid.View.inherit({            _isDragging: false,            _getDropOptions: function() {                var that = this;                if (that._dragOptions)                    return {                            sourceColumnIndex: that._dragOptions.columnIndex,                            sourceColumnElement: that._dragOptions.columnElement,                            sourceLocation: that._dragOptions.sourceLocation,                            targetColumnIndex: that._dropColumnIndex,                            targetLocation: that._dropLocation                        }            },            _dropHeader: function(args) {                var e = args.jQueryEvent,                    that = e.data.that,                    controller = that._controller;                that.element().hide();                if (controller && that._isDragging)                    controller.drop(that._getDropOptions());                that.element().appendTo(that._parentElement());                that._dragOptions = null;                that._isDragging = false;                document.onselectstart = that._onSelectStart || null            },            _getDraggingPanelByPos: function(pos) {                var that = this,                    result;                $.each(that._dragOptions.draggingPanels, function(index, draggingPanel) {                    if (draggingPanel) {                        var boundingRect = draggingPanel.getBoundingRect();                        if (boundingRect && (boundingRect.bottom === undefined || pos.y < boundingRect.bottom) && (boundingRect.top === undefined || pos.y > boundingRect.top) && (boundingRect.left === undefined || pos.x > boundingRect.left) && (boundingRect.right === undefined || pos.x < boundingRect.right)) {                            result = draggingPanel;                            return false                        }                    }                });                return result            },            _pointCreated: function(point, columns, location, sourceColumn) {                var targetColumn = columns[point.columnIndex],                    prevColumn = columns[point.columnIndex - 1];                switch (location) {                    case"columnChooser":                        return true;                    case"headers":                        return sourceColumn && !sourceColumn.allowReordering || (!targetColumn || !targetColumn.allowReordering) && (!prevColumn || !prevColumn.allowReordering);                    default:                        return columns.length === 0                }            },            _moveHeader: function(args) {                var e = args.jQueryEvent,                    that = e.data.that,                    columnElements,                    pointsByColumns,                    newLeft,                    newTop,                    moveDeltaX,                    moveDeltaY,                    eventData = events.eventData(e),                    targetDraggingPanel,                    controller = that._controller,                    isResizing = that._columnsResizerViewController ? that._columnsResizerViewController.isResizing() : false,                    i,                    params,                    dragOptions = that._dragOptions,                    isVerticalOrientation,                    centerPosition,                    axisName,                    rtlEnabled;                if (that._isDragging && !isResizing) {                    moveDeltaX = Math.abs(eventData.x - dragOptions.columnElement.offset().left - dragOptions.deltaX);                    moveDeltaY = Math.abs(eventData.y - dragOptions.columnElement.offset().top - dragOptions.deltaY);                    if (that.element().is(':visible') || moveDeltaX > DRAGGING_DELTA || moveDeltaY > DRAGGING_DELTA) {                        that.element().show();                        newLeft = eventData.x - dragOptions.deltaX;                        newTop = eventData.y - dragOptions.deltaY;                        that.element().offset({                            left: newLeft,                            top: newTop                        });                        targetDraggingPanel = that._getDraggingPanelByPos(eventData);                        if (targetDraggingPanel) {                            rtlEnabled = that.option('rtlEnabled');                            isVerticalOrientation = targetDraggingPanel.getName() === 'columnChooser';                            axisName = isVerticalOrientation ? 'y' : 'x';                            columnElements = targetDraggingPanel.getColumnElements() || [];                            pointsByColumns = dataGrid.getPointsByColumns(columnElements, function(point) {                                return that._pointCreated(point, targetDraggingPanel.getColumns(), targetDraggingPanel.getName(), dragOptions.sourceColumn)                            }, axisName === 'y');                            that._dropLocation = targetDraggingPanel.getName();                            if (pointsByColumns.length > 0)                                for (i = 0; i < pointsByColumns.length; i++) {                                    centerPosition = pointsByColumns[i + 1] && (pointsByColumns[i][axisName] + pointsByColumns[i + 1][axisName]) / 2;                                    if (centerPosition === undefined || (rtlEnabled && axisName === 'x' ? eventData[axisName] > centerPosition : eventData[axisName] < centerPosition)) {                                        that._dropColumnIndex = pointsByColumns[i].columnIndex;                                        params = that._getDropOptions();                                        if (columnElements[i])                                            params.targetColumnElement = columnElements.eq(i);                                        else {                                            params.targetColumnElement = columnElements.last();                                            params.isLast = true                                        }                                        params.posX = pointsByColumns[i].x;                                        controller.dock(params);                                        break                                    }                                }                            else {                                that._dropColumnIndex = -1;                                params = that._getDropOptions();                                controller.dock(params)                            }                        }                    }                    e.preventDefault()                }            },            _subscribeToEvents: function(rootElement) {                var that = this;                that._moveHeaderAction = this.createAction(this._moveHeader);                that._dropHeaderAction = this.createAction(this._dropHeader);                $(document).on(addNamespace('dxpointermove', DATAGRID_MODULE_NAMESPACE), {                    that: that,                    rootElement: rootElement                }, that._moveHeaderAction);                that.element().on(addNamespace('dxpointerup', DATAGRID_MODULE_NAMESPACE), {that: that}, that._dropHeaderAction);                $(document).on(addNamespace('dxpointerup', DATAGRID_MODULE_NAMESPACE), {that: that}, that._dropHeaderAction)            },            _renderCore: function() {                this.element().addClass(DATAGRID_DRAGGING_HEADER_CLASS + ' ' + DATAGRID_CELL_CONTENT_CLASS + ' ' + WIDGET_CLASS).css('display', 'none')            },            _afterRender: function($parent) {                this._unsubscribeFromEvents();                this._subscribeToEvents($parent)            },            _unsubscribeFromEvents: function() {                if (this._dropHeaderAction) {                    this.element().off(addNamespace('dxpointerup', DATAGRID_MODULE_NAMESPACE), this._dropHeaderAction);                    $(document).off(addNamespace('dxpointerup', DATAGRID_MODULE_NAMESPACE), this._dropHeaderAction)                }                if (this._moveHeaderAction)                    $(document).off(addNamespace('dxpointermove', DATAGRID_MODULE_NAMESPACE), this._moveHeaderAction)            },            dispose: function() {                var element = this.element();                this._dragOptions = null;                this._unsubscribeFromEvents();                element && element.parent().find('.' + DATAGRID_DRAGGING_HEADER_CLASS).remove()            },            isVisible: function() {                var columnsController = this.getController("columns"),                    commonColumnSettings = columnsController.getCommonSettings();                return this.option('showColumnHeaders') && (allowReordering(this) || commonColumnSettings.allowGrouping || commonColumnSettings.allowHiding)            },            init: function() {                this.callBase();                this._controller = this.getController("draggingHeader");                this._columnsResizerViewController = this.getController("columnsResizer")            },            drag: function(options) {                var that = this,                    columnElement = options.columnElement;                that._dragOptions = options;                that._isDragging = true;                that._dropColumnIndex = options.columnIndex;                that._dropLocation = options.sourceLocation;                that._onSelectStart = document.onselectstart;                document.onselectstart = function() {                    return false                };                that.element().css({                    textAlign: columnElement && columnElement.css('text-align'),                    height: columnElement && columnElement.height(),                    width: columnElement && columnElement.width(),                    whiteSpace: columnElement && columnElement.css('white-space')                }).addClass(DATAGRID_HEADERS_DRAG_ACTION_CLASS).text(options.sourceColumn.caption);                that.element().appendTo($(document.body))            }        });        dataGrid.ColumnsResizerViewController = dataGrid.ViewController.inherit({            _isHeadersRowArea: function(posY) {                if (this._columnHeadersView) {                    var element = this._columnHeadersView.element(),                        headersRowHeight,                        offsetTop;                    if (element) {                        offsetTop = element.offset().top;                        headersRowHeight = this._columnHeadersView.getHeadersRowHeight();                        return posY >= offsetTop && posY <= offsetTop + headersRowHeight                    }                }                return false            },            _pointCreated: function(point, cellsLength, columns) {                var currentColumn,                    nextColumn;                if (point.index > 0 && point.index < cellsLength) {                    point.columnIndex -= 1;                    currentColumn = columns[point.columnIndex] || {};                    nextColumn = columns[point.columnIndex + 1] || {};                    return !(currentColumn.allowResizing && nextColumn.allowResizing)                }                return true            },            _getTargetPoint: function(pointsByColumns, currentX, deltaX) {                if (pointsByColumns)                    for (var i = 0; i < pointsByColumns.length; i++)                        if (pointsByColumns[i].x - deltaX <= currentX && currentX <= pointsByColumns[i].x + deltaX)                            return pointsByColumns[i];                return null            },            _moveSeparator: function(args) {                var e = args.jQueryEvent,                    that = e.data,                    pointsByColumns = that._pointsByColumns,                    columnsSeparatorWidth = that._columnsSeparatorView.width(),                    columnsSeparatorOffset = that._columnsSeparatorView.element().offset(),                    deltaX = columnsSeparatorWidth / 2,                    parentOffsetLeft = that._$parentContainer.offset().left,                    eventData = events.eventData(e);                if (that._isResizing) {                    if (parentOffsetLeft <= eventData.x && eventData.x <= parentOffsetLeft + that._$parentContainer.width())                        if (that._updateColumnsWidthIfNeeded(that._targetPoint.columnIndex, eventData.x)) {                            that._columnsSeparatorView.moveByX(that._targetPoint.x + (eventData.x - that._resizingInfo.startPosX));                            that._tablePositionController.update();                            e.preventDefault()                        }                }                else if (that._isHeadersRowArea(eventData.y)) {                    that._targetPoint = that._getTargetPoint(pointsByColumns, eventData.x, columnsSeparatorWidth);                    that._isReadyResizing = false;                    that._columnsSeparatorView.changeCursor();                    if (that._targetPoint && columnsSeparatorOffset.top <= eventData.y && columnsSeparatorOffset.top + that._columnsSeparatorView.height() >= eventData.y) {                        that._columnsSeparatorView.changeCursor('col-resize');                        that._columnsSeparatorView.moveByX(that._targetPoint.x - deltaX);                        that._isReadyResizing = true;                        e.preventDefault()                    }                }                else {                    that._isReadyResizing = false;                    that._columnsSeparatorView.changeCursor()                }            },            _endResizing: function(args) {                var e = args.jQueryEvent,                    that = e.data;                if (that._isResizing) {                    that._updatePointsByColumns();                    that._resizingInfo = null;                    that._columnsSeparatorView.hide();                    that._columnsSeparatorView.changeCursor();                    that._trackerView.hide();                    that._isReadyResizing = false;                    that._isResizing = false                }            },            _setupResizingInfo: function(posX) {                var that = this,                    currentHeader = that._columnHeadersView.getHeaderElement(that._targetPoint.columnIndex),                    nextHeader = that._columnHeadersView.getHeaderElement(that._targetPoint.columnIndex + 1);                that._resizingInfo = {                    startPosX: posX,                    currentColumnWidth: currentHeader && currentHeader.length > 0 ? currentHeader.outerWidth() : 0,                    nextColumnWidth: nextHeader && nextHeader.length > 0 ? nextHeader.outerWidth() : 0                }            },            _startResizing: function(args) {                var e = args.jQueryEvent,                    that = e.data,                    eventData = events.eventData(e);                if (events.isTouchEvent(e))                    if (that._isHeadersRowArea(eventData.y)) {                        that._targetPoint = that._getTargetPoint(that._pointsByColumns, eventData.x, COLUMNS_SEPARATOR_TOUCH_TRACKER_WIDTH);                        if (that._targetPoint) {                            that._columnsSeparatorView.moveByX(that._targetPoint.x - that._columnsSeparatorView.width() / 2);                            that._isReadyResizing = true                        }                    }                    else                        that._isReadyResizing = false;                if (that._isReadyResizing) {                    if (that._targetPoint)                        that._testColumnIndex = that._targetPoint.columnIndex;                    that._setupResizingInfo(eventData.x);                    that._columnsSeparatorView.show();                    that._trackerView.show();                    that._isResizing = true;                    e.preventDefault()                }            },            _generatePointsByColumns: function() {                var that = this,                    columns = that._columnsController ? that._columnsController.getVisibleColumns() : [],                    cells = that._columnHeadersView.getColumnElements(),                    pointsByColumns = [];                if (cells && cells.length > 0)                    pointsByColumns = dataGrid.getPointsByColumns(cells, function(point) {                        return that._pointCreated(point, cells.length, columns)                    });                that._pointsByColumns = pointsByColumns            },            _unsubscribeFromEvents: function() {                this._moveSeparatorHandler && this._$parentContainer.off(addNamespace('dxpointermove', DATAGRID_MODULE_NAMESPACE), this._moveSeparatorHandler);                this._startResizingHandler && this._$parentContainer.off(addNamespace('dxpointerdown', DATAGRID_MODULE_NAMESPACE), this._startResizingHandler);                if (this._endResizingHandler) {                    this._columnsSeparatorView.element().off(addNamespace('dxpointerup', DATAGRID_MODULE_NAMESPACE), this._endResizingHandler);                    $(document).off(addNamespace('dxpointerup', DATAGRID_MODULE_NAMESPACE), this._endResizingHandler)                }            },            _subscribeToEvents: function() {                this._moveSeparatorHandler = this.createAction(this._moveSeparator);                this._startResizingHandler = this.createAction(this._startResizing);                this._endResizingHandler = this.createAction(this._endResizing);                this._$parentContainer.on(addNamespace('dxpointermove', DATAGRID_MODULE_NAMESPACE), this, this._moveSeparatorHandler);                this._$parentContainer.on(addNamespace('dxpointerdown', DATAGRID_MODULE_NAMESPACE), this, this._startResizingHandler);                this._columnsSeparatorView.element().on(addNamespace('dxpointerup', DATAGRID_MODULE_NAMESPACE), this, this._endResizingHandler);                $(document).on(addNamespace('dxpointerup', DATAGRID_MODULE_NAMESPACE), this, this._endResizingHandler)            },            _updateColumnsWidthIfNeeded: function(columnIndex, posX) {                var deltaX,                    isUpdated = false,                    nextCellWidth,                    columnsController = this._columnsController,                    visibleColumns = columnsController.getVisibleColumns(),                    columnsSeparatorWidth = this._columnsSeparatorView.width(),                    column,                    nextColumn,                    cellWidth;                deltaX = posX - this._resizingInfo.startPosX;                if (this.option("rtlEnabled"))                    deltaX = -deltaX;                cellWidth = this._resizingInfo.currentColumnWidth + deltaX;                nextCellWidth = this._resizingInfo.nextColumnWidth - deltaX;                isUpdated = !(cellWidth <= columnsSeparatorWidth || nextCellWidth <= columnsSeparatorWidth);                if (isUpdated) {                    column = visibleColumns[columnIndex];                    nextColumn = visibleColumns[columnIndex + 1];                    columnsController.beginUpdate();                    column && columnsController.columnOption(column.index, 'visibleWidth', undefined);                    nextColumn && columnsController.columnOption(nextColumn.index, 'visibleWidth', undefined);                    column && columnsController.columnOption(column.index, 'width', Math.floor(cellWidth));                    nextColumn && columnsController.columnOption(nextColumn.index, 'width', Math.floor(nextCellWidth));                    columnsController.endUpdate()                }                return isUpdated            },            _updatePointsByColumns: function() {                var i,                    point,                    rtlEnabled = this.option("rtlEnabled"),                    headerElement;                for (i = 0; i < this._pointsByColumns.length; i++) {                    point = this._pointsByColumns[i];                    headerElement = this._columnHeadersView.getHeaderElement(point.columnIndex + 1);                    if (headerElement && headerElement.length > 0)                        point.x = headerElement.offset().left + (rtlEnabled ? headerElement.outerWidth() : 0)                }            },            isResizing: function() {                return this._isResizing            },            init: function() {                var that = this,                    gridView,                    previousScrollbarVisibility,                    generatePointsByColumnsScrollHandler = function(offset) {                        if (that._scrollLeft !== offset.left) {                            that._scrollLeft = offset.left;                            that._generatePointsByColumns()                        }                    },                    generatePointsByColumnsHandler = function() {                        that._generatePointsByColumns()                    };                that.callBase();                if (allowResizing(that)) {                    that._columnsSeparatorView = that.getView("columnsSeparatorView");                    that._columnHeadersView = that.getView("columnHeadersView");                    that._trackerView = that.getView("trackerView");                    that._rowsView = that.getView("rowsView");                    that._columnsController = that.getController("columns");                    that._tablePositionController = that.getController("tablePosition");                    that._$parentContainer = that._columnsSeparatorView.component.element();                    that._columnHeadersView.renderCompleted.add(generatePointsByColumnsHandler);                    that._columnHeadersView.resizeCompleted.add(generatePointsByColumnsHandler);                    that._columnsSeparatorView.renderCompleted.add(function() {                        that._unsubscribeFromEvents();                        that._subscribeToEvents()                    });                    that._rowsView.renderCompleted.add(function() {                        that._rowsView.scrollOffsetChanged.remove(generatePointsByColumnsScrollHandler);                        that._rowsView.scrollOffsetChanged.add(generatePointsByColumnsScrollHandler)                    });                    gridView = that.getView("gridView");                    previousScrollbarVisibility = that._rowsView.getScrollbarWidth() !== 0;                    that.getController("tablePosition").positionChanged.add(function() {                        if (that._isResizing && !that._rowsView.isResizing) {                            var scrollbarVisibility = that._rowsView.getScrollbarWidth() !== 0;                            if (previousScrollbarVisibility !== scrollbarVisibility) {                                previousScrollbarVisibility = scrollbarVisibility;                                gridView.resize()                            }                            else {                                that._rowsView.updateFreeSpaceRowHeight();                                that._columnHeadersView.processSizeChanged()                            }                        }                    })                }            },            dispose: function() {                this._unsubscribeFromEvents()            }        });        dataGrid.TablePositionViewController = dataGrid.ViewController.inherit({            update: function() {                var $element = this._columnHeadersView.element(),                    columnsHeadersHeight = this._columnHeadersView ? this._columnHeadersView.getHeight() : 0,                    rowsHeight = this._rowsView ? this._rowsView.height() - this._rowsView.getScrollbarWidth(true) : 0;                this.positionChanged.fire({                    height: columnsHeadersHeight + rowsHeight,                    top: $element && $element.length > 0 ? Math.floor($element[0].offsetTop) : 0                })            },            init: function() {                var that = this;                that.callBase();                that._columnHeadersView = this.getView("columnHeadersView");                that._rowsView = this.getView("rowsView");                that._pagerView = this.getView("pagerView");                that._rowsView.resizeCompleted.add(function() {                    that.update()                })            },            ctor: function(component) {                this.callBase(component);                this.positionChanged = $.Callbacks()            }        });        dataGrid.DraggingHeaderViewController = dataGrid.ViewController.inherit({            _subscribeToEvent: function(draggingHeader, draggingPanels) {                var that = this;                $.each(draggingPanels, function(_, draggingPanel) {                    if (draggingPanel) {                        var columnElements = draggingPanel.getColumnElements() || [],                            nameDraggingPanel = draggingPanel.getName(),                            columns = draggingPanel.getColumns() || [];                        $.each(columnElements, function(index, columnElement) {                            var $columnElement = $(columnElement);                            $columnElement.off(addNamespace('dxpointerdown', DATAGRID_MODULE_NAMESPACE));                            $columnElement.removeClass(DATAGRID_HEADERS_DRAG_ACTION_CLASS);                            if (draggingPanel.allowDragging(columns[index], draggingPanels)) {                                $columnElement.addClass(DATAGRID_HEADERS_DRAG_ACTION_CLASS);                                $columnElement.on(addNamespace('dxpointerdown', DATAGRID_MODULE_NAMESPACE), that.createAction(function(args) {                                    var e = args.jQueryEvent,                                        eventData = events.eventData(e);                                    e.preventDefault();                                    e.stopPropagation();                                    draggingHeader.drag({                                        deltaX: eventData.x - $(e.currentTarget).offset().left,                                        deltaY: eventData.y - $(e.currentTarget).offset().top,                                        sourceColumn: columns[index],                                        columnIndex: index,                                        columnElement: $columnElement,                                        sourceLocation: nameDraggingPanel,                                        draggingPanels: draggingPanels                                    })                                }))                            }                        })                    }                })            },            _getSeparator: function(targetLocation) {                return targetLocation === "headers" ? this._columnsSeparatorView : this._blockSeparatorView            },            hideSeparators: function() {                var blockSeparator = this._blockSeparatorView,                    columnsSeparator = this._columnsSeparatorView;                this._animationColumnIndex = null;                blockSeparator && blockSeparator.hide();                columnsSeparator && columnsSeparator.hide()            },            init: function() {                var that = this,                    subscribeToEvent;                that.callBase();                that._columnsController = that.getController("columns");                that._columnHeadersView = that.getView("columnHeadersView");                that._columnsSeparatorView = that.getView("columnsSeparatorView");                that._draggingHeaderView = that.getView("draggingHeaderView");                that._rowsView = that.getView('rowsView');                that._blockSeparatorView = that.getView("blockSeparatorView");                that._headerPanelView = that.getView("headerPanel");                that._columnChooserView = that.getView("columnChooserView");                subscribeToEvent = function() {                    if (that._draggingHeaderView)                        that._subscribeToEvent(that._draggingHeaderView, [that._columnChooserView, that._columnHeadersView, that._headerPanelView])                };                that._columnHeadersView.renderCompleted.add(subscribeToEvent);                that._headerPanelView && that._headerPanelView.renderCompleted.add(subscribeToEvent);                that._columnChooserView && that._columnChooserView.renderCompleted.add(subscribeToEvent)            },            allowDrop: function(parameters) {                return this._columnsController.allowMoveColumn(parameters.sourceColumnIndex, parameters.targetColumnIndex, parameters.sourceLocation, parameters.targetLocation)            },            dock: function(parameters) {                var that = this,                    targetColumnIndex = parameters.targetColumnIndex,                    sourceLocation = parameters.sourceLocation,                    sourceColumnIndex = parameters.sourceColumnIndex,                    sourceColumnElement = parameters.sourceColumnElement,                    targetLocation = parameters.targetLocation,                    separator = that._getSeparator(targetLocation),                    hasTargetColumnIndex = targetColumnIndex >= 0;                var showSeparator = function() {                        if (that._animationColumnIndex !== targetColumnIndex) {                            that.hideSeparators();                            separator.element()[parameters.isLast ? 'insertAfter' : 'insertBefore'](parameters.targetColumnElement);                            that._animationColumnIndex = targetColumnIndex;                            separator.show(targetLocation)                        }                    };                that._columnHeadersView.element().find('.' + DATAGRID_HEADER_ROW_CLASS).toggleClass(DATAGRID_HEADERS_DROP_HIGHLIGHT_CLASS, sourceLocation !== 'headers' && targetLocation === 'headers' && !hasTargetColumnIndex);                if (separator) {                    if (sourceColumnElement) {                        sourceColumnElement.css({opacity: 0.5});                        if (sourceLocation === 'headers')                            that._rowsView.setRowsOpacity(sourceColumnIndex, 0.5)                    }                    if (that.allowDrop(parameters) && hasTargetColumnIndex)                        if (targetLocation === 'group' || targetLocation === 'columnChooser')                            showSeparator();                        else {                            that.hideSeparators();                            separator.moveByX(parameters.posX - separator.width());                            separator.show()                        }                    else                        that.hideSeparators()                }            },            drop: function(parameters) {                var sourceColumnElement = parameters.sourceColumnElement;                if (sourceColumnElement) {                    sourceColumnElement.css({opacity: ''});                    this._rowsView.setRowsOpacity(parameters.sourceColumnIndex, '');                    this._columnHeadersView.element().find('.' + DATAGRID_HEADER_ROW_CLASS).removeClass(DATAGRID_HEADERS_DROP_HIGHLIGHT_CLASS)                }                if (this.allowDrop(parameters)) {                    var separator = this._getSeparator(parameters.targetLocation);                    if (separator)                        separator.hide();                    this._columnsController.moveColumn(parameters.sourceColumnIndex, parameters.targetColumnIndex, parameters.sourceLocation, parameters.targetLocation)                }            }        });        dataGrid.__internals = $.extend({}, dataGrid.__internals, {            DATAGRID_COLUMNS_SEPARATOR_CLASS: DATAGRID_COLUMNS_SEPARATOR_CLASS,            DATAGRID_COLUMNS_SEPARATOR_TRANSPARENT: DATAGRID_COLUMNS_SEPARATOR_TRANSPARENT,            DATAGRID_DRAGGING_HEADER_CLASS: DATAGRID_DRAGGING_HEADER_CLASS,            DATAGRID_HEADERS_DRAG_ACTION_CLASS: DATAGRID_HEADERS_DRAG_ACTION_CLASS,            DATAGRID_CELL_CONTENT_CLASS: DATAGRID_CELL_CONTENT_CLASS,            DATAGRID_TRACKER_CLASS: DATAGRID_TRACKER_CLASS,            DATAGRID_MODULE_NAMESPACE: DATAGRID_MODULE_NAMESPACE,            DATAGRID_HEADERS_DROP_HIGHLIGHT_CLASS: DATAGRID_HEADERS_DROP_HIGHLIGHT_CLASS,            WIDGET_CLASS: WIDGET_CLASS        });        dataGrid.registerModule("columnsResizingReordering", {            views: {                columnsSeparatorView: dataGrid.ColumnsSeparatorView,                blockSeparatorView: dataGrid.BlockSeparatorView,                draggingHeaderView: dataGrid.DraggingHeaderView,                trackerView: dataGrid.TrackerView            },            controllers: {                draggingHeader: dataGrid.DraggingHeaderViewController,                tablePosition: dataGrid.TablePositionViewController,                columnsResizer: dataGrid.ColumnsResizerViewController            }        })    })(jQuery, DevExpress);    /*! Module widgets-web, file ui.dataGrid.contextMenuView.js */    (function($, DX) {        var ui = DX.ui,            dataGrid = ui.dxDataGrid;        var DATAGRID_CLASS = "dx-datagrid",            DATAGRID_CONTEXT_MENU = "dx-context-menu",            viewName = {                columnHeadersView: "header",                rowsView: "content",                footerView: "footer"            },            VIEW_NAMES = ["columnHeadersView", "rowsView", "footerView"];        dataGrid.ContextMenuController = dataGrid.ViewController.inherit({            init: function() {                this.createAction("onContextMenuPreparing")            },            getContextMenuItems: function($targetElement) {                var that = this,                    view,                    options,                    rowIndex,                    columnIndex,                    $targetRowElement,                    $targetCellElement,                    menuItems;                $.each(VIEW_NAMES, function() {                    view = that.getView(this);                    if (view && view.element().find($targetElement).length) {                        $targetCellElement = $targetElement.closest("td");                        $targetRowElement = $targetCellElement.closest(".dx-row");                        rowIndex = view.getRowIndex($targetRowElement);                        columnIndex = $targetCellElement[0] && $targetCellElement[0].cellIndex;                        options = {                            targetElement: $targetElement,                            target: viewName[this],                            rowIndex: rowIndex,                            row: view._getRows()[rowIndex],                            columnIndex: columnIndex,                            column: view.getColumns()[columnIndex],                            items: view.getContextMenuItems && view.getContextMenuItems($targetElement)                        };                        that.executeAction("onContextMenuPreparing", options);                        menuItems = options.items;                        if (menuItems)                            return false                    }                });                return menuItems            }        });        dataGrid.ContextMenuView = dataGrid.View.inherit({_renderCore: function() {                var that = this;                this._createComponent(that.element().addClass(DATAGRID_CONTEXT_MENU), "dxContextMenu", {                    onPositioning: function(actionArgs) {                        var event = actionArgs.jQueryEvent,                            $targetElement = $(event.target),                            contextMenuInstance = actionArgs.component,                            items = that.getController('contextMenu').getContextMenuItems($targetElement);                        if (items) {                            contextMenuInstance.option('items', items);                            event.stopPropagation()                        }                        else                            actionArgs.canceled = true                    },                    onItemClick: function(params) {                        params.itemData.onItemClick && params.itemData.onItemClick(params)                    },                    cssClass: DATAGRID_CLASS,                    target: that.component.element()                })            }});        dataGrid.registerModule("contextMenu", {            defaultOptions: function() {                return {onContextMenuPreparing: null}            },            controllers: {contextMenu: dataGrid.ContextMenuController},            views: {contextMenuView: dataGrid.ContextMenuView}        })    })(jQuery, DevExpress);    /*! Module widgets-web, file ui.dataGrid.keyboardNavigation.js */    (function($, DX) {        var ui = DX.ui,            utils = DX.utils,            events = ui.events,            dataGrid = ui.dxDataGrid;        var DATAGRID_ROW_CLASS = "dx-row",            DATAGRID_GROUP_ROW_CLASS = "dx-group-row",            DATAGRID_ROWS_VIEW_CLASS = "dx-datagrid-rowsview",            DATAGRID_MASTER_DETAIL_ROW_CLASS = "dx-master-detail-row",            DATAGRID_GROUP_FOOTER_CLASS = "dx-datagrid-group-footer",            DATAGRID_COMMAND_EXPAND_CLASS = "dx-command-expand",            DATAGRID_INTERACTIVE_ELEMENTS_SELECTOR = ".dx-checkbox, .dx-menu, input",            DATAGRID_VIEWS = ["rowsView", "columnHeadersView"],            DATAGRID_EDIT_MODE_ROW = "row";        dataGrid.KeyboardNavigationController = dataGrid.ViewController.inherit({            _focusView: function(view, viewIndex) {                this._focusedViews.viewIndex = viewIndex;                this._focusedView = view            },            _focusInteractiveElement: function($cell) {                var $focusedElement = $cell.find(DATAGRID_INTERACTIVE_ELEMENTS_SELECTOR).first();                this._testInteractiveElement = $focusedElement;                $focusedElement.focus()            },            _updateFocus: function() {                var that = this,                    $cell = that._getFocusedCell();                if ($cell) {                    if (that._hasSkipRow($cell.parent()))                        $cell = that._getNextCell("upArrow");                    if ($cell && $cell.length > 0)                        setTimeout(function() {                            if (that.getController('editorFactory').focus())                                that._focus($cell);                            that._editingController.isEditing() && $.proxy(that._focusInteractiveElement, that)($cell)                        })                }            },            _clickHandler: function(e) {                var event = e.jQueryEvent,                    $cell = $(event.currentTarget);                if (this._isCellValid($cell, true)) {                    this._focusView(event.data.view, event.data.viewIndex);                    this._updateFocusedCellPosition($cell);                    if (!this._editingController.isEditing()) {                        $cell.focus();                        this._testCellIsFocused = true                    }                }                else                    this._resetFocusedCell(this)            },            _initFocusedViews: function() {                var that = this,                    clickAction = that.createAction(that._clickHandler);                that._focusedViews = [];                $.each(DATAGRID_VIEWS, function(key, viewName) {                    var view = that.getView(viewName);                    if (view && view.isVisible())                        that._focusedViews.push(view)                });                $.each(that._focusedViews, function(index, view) {                    if (view)                        view.renderCompleted.add(function() {                            var $element = view.element();                            $element.off(events.addNamespace("dxpointerdown", "dxDataGridKeyboardNavigation"), clickAction);                            $element.on(events.addNamespace("dxpointerdown", "dxDataGridKeyboardNavigation"), "." + DATAGRID_ROW_CLASS + " td", {                                viewIndex: index,                                view: view                            }, clickAction);                            that._initKeyDownProcessor(that, $element, that._keyDownHandler);                            if (that._focusedView && that._focusedView.name === view.name && that._isNeedFocus)                                that._updateFocus()                        })                })            },            _initKeyDownProcessor: function(context, element, handler) {                if (this._keyDownProcessor) {                    this._keyDownProcessor.dispose();                    this._keyDownProcessor = null                }                this._keyDownProcessor = new ui.KeyboardProcessor({                    element: element,                    context: context,                    handler: handler                })            },            _getFocusedCell: function() {                if (this._focusedView && this._focusedCellPosition)                    return this._focusedView.getCell(this._focusedCellPosition)            },            _updateFocusedCellPosition: function($cell) {                var that = this,                    rowsView = that.getView("rowsView");                if ($cell.length > 0)                    this._focusedCellPosition = {                        columnIndex: rowsView.getCellIndex($cell),                        rowIndex: $cell.parent().length > 0 && that._focusedView ? that._focusedView.getRowIndex($cell.parent()) : null                    }            },            _isCellValid: function($cell, allCommandColumns) {                if (utils.isDefined($cell)) {                    var visibleColumns = this._columnsController.getVisibleColumns(),                        columnIndex = $cell[0].cellIndex,                        isExpandColumn = !allCommandColumns ? visibleColumns[columnIndex].command === "expand" : false,                        isValidGroupSpaceColumn = !utils.isDefined(visibleColumns[columnIndex].groupIndex) || parseInt($cell.attr("colspan")) > 1;                    if (visibleColumns.length > columnIndex && isValidGroupSpaceColumn)                        return !utils.isDefined(visibleColumns[columnIndex].command) || isExpandColumn                }            },            _isCellByPositionValid: function(cellPosition, allCommandColumns) {                var $cell = this._focusedView && this._focusedView.getCell(cellPosition);                return this._isCellValid($cell, allCommandColumns)            },            _isGroupRow: function($row) {                return $row && $row.hasClass(DATAGRID_GROUP_ROW_CLASS)            },            _focus: function($cell) {                var $row = $cell.parent(),                    $focusedCell = this._getFocusedCell(),                    $focusElement;                $focusedCell && $focusedCell.attr("tabindex", null);                if (this._isGroupRow($row)) {                    $focusElement = $row;                    this._focusedCellPosition.rowIndex = this._focusedView.getRowIndex($row)                }                else {                    $focusElement = $cell;                    this._updateFocusedCellPosition($cell)                }                $focusElement.attr("tabindex", 0);                $focusElement.focus();                this.getController('editorFactory').focus($focusElement)            },            _hasSkipRow: function($row) {                return $row && ($row.hasClass(DATAGRID_MASTER_DETAIL_ROW_CLASS) || $row.hasClass(DATAGRID_GROUP_FOOTER_CLASS))            },            _enterKeyHandler: function(eventArgs, isEditing) {                var $cell = this._getFocusedCell(),                    editingOptions = this.option("editing"),                    rowIndex = this._focusedCellPosition ? this._focusedCellPosition.rowIndex : null,                    $row = this._focusedView && this._focusedView.getRow(rowIndex);                if (this.option("grouping.allowCollapsing") && this._isGroupRow($row) || this.option("masterDetail.enabled") && $cell.hasClass(DATAGRID_COMMAND_EXPAND_CLASS)) {                    var key = this._dataController.getKeyByRowIndex(rowIndex),                        item = this._dataController.items()[rowIndex];                    if (key !== undefined && item && item.data && !item.data.isContinuation)                        this._dataController.changeRowExpand(key)                }                else {                    var isRowEditMode = this._editingController.getEditMode() === DATAGRID_EDIT_MODE_ROW;                    if (isEditing) {                        this._updateFocusedCellPosition($(eventArgs.originalEvent.target).closest('td'));                        if (isRowEditMode)                            setTimeout($.proxy(this._editingController.saveEditData, this._editingController));                        else                            this._editingController.closeEditCell()                    }                    else if (editingOptions.editEnabled)                        if (isRowEditMode)                            this._editingController.editRow(rowIndex);                        else                            this._focusedCellPosition && this._editingController.editCell(rowIndex, this._focusedCellPosition.columnIndex)                }            },            _leftRightKeysHandler: function(eventArgs, isEditing) {                var rowIndex = this._focusedCellPosition ? this._focusedCellPosition.rowIndex : null,                    $row = this._focusedView && this._focusedView.getRow(rowIndex),                    directionCode,                    $cell;                if (!isEditing && !this._isGroupRow($row)) {                    directionCode = this._getDirectionCodeByKey(eventArgs.key);                    $cell = this._getNextCell(directionCode);                    if ($cell && this._isCellValid($cell))                        this._focus($cell);                    eventArgs.originalEvent.preventDefault()                }            },            _getDirectionCodeByKey: function(key) {                var directionCode;                if (this.option("rtlEnabled"))                    directionCode = key === "leftArrow" ? "nextInRow" : "previousInRow";                else                    directionCode = key === "leftArrow" ? "previousInRow" : "nextInRow";                return directionCode            },            _upDownKeysHandler: function(eventArgs, isEditing) {                var rowIndex = this._focusedCellPosition ? this._focusedCellPosition.rowIndex : null,                    $cell;                if (!isEditing) {                    if (rowIndex === 0 || this._focusedView && rowIndex === this._focusedView.getRowsCount() - 1);                    $cell = this._getNextCell(eventArgs.key);                    if ($cell && this._isCellValid($cell))                        this._focus($cell);                    eventArgs.originalEvent.preventDefault()                }            },            _pageUpKeyHandler: function(eventArgs) {                var scrollingMode = this.option("scrolling.mode"),                    pageIndex = this._dataController.pageIndex(),                    isVirtualScrolling = scrollingMode === "virtual" || scrollingMode === "infinite";                if (pageIndex > 0 && !isVirtualScrolling) {                    this._dataController.pageIndex(pageIndex - 1);                    eventArgs.originalEvent.preventDefault()                }            },            _pageDownKeyHandler: function(eventArgs) {                var scrollingMode = this.option("scrolling.mode"),                    isVirtualScrolling = scrollingMode === "virtual" || scrollingMode === "infinite",                    pageIndex = this._dataController.pageIndex(),                    pageCount = this._dataController.pageCount();                if (pageIndex < pageCount - 1 && !isVirtualScrolling) {                    this._dataController.pageIndex(pageIndex + 1);                    eventArgs.originalEvent.preventDefault()                }            },            _spaceKeyHandler: function(eventArgs, isEditing) {                var rowIndex = this._focusedCellPosition ? this._focusedCellPosition.rowIndex : null;                if (this.option("selection") && this.option("selection").mode !== "none" && !isEditing) {                    this._selectionController.changeItemSelection(rowIndex, {                        shift: eventArgs.shift,                        control: eventArgs.ctrl                    });                    eventArgs.originalEvent.preventDefault()                }            },            _crtlAKeyHandler: function(eventArgs) {                if (eventArgs.ctrl && this.option("selection.mode") === "multiple" && this.option("selection.allowSelectAll")) {                    this._selectionController.selectAll();                    eventArgs.originalEvent.preventDefault()                }            },            _tabKeyHandler: function(eventArgs, isEditing) {                var editingOptions = this.option('editing'),                    direction = eventArgs.shift ? "previous" : "next",                    $cell;                if (editingOptions && eventArgs.originalEvent.target)                    if (isEditing) {                        if (!editingOptions.editEnabled)                            this._editingController.closeEditCell();                        this._updateFocusedCellPosition($(eventArgs.originalEvent.target).closest('td'));                        $cell = this._getNextCell(direction);                        if (this._focusCell($cell))                            if (this._editingController.getEditMode() !== DATAGRID_EDIT_MODE_ROW && editingOptions.editEnabled)                                this._editingController.editCell(this._focusedCellPosition.rowIndex, this._focusedCellPosition.columnIndex);                            else                                this._focusInteractiveElement($cell)                    }                    else {                        $cell = this._getNextCell(direction, this._getElementType(eventArgs.originalEvent.target));                        this._focusCell($cell)                    }                eventArgs.originalEvent.preventDefault()            },            _focusCell: function($cell) {                if (this._isCellValid($cell)) {                    this._focus($cell);                    return true                }            },            _getElementType: function(target) {                return $(target).is("tr") ? "row" : "cell"            },            _escapeKeyHandler: function(eventArgs, isEditing) {                if (isEditing) {                    this._updateFocusedCellPosition($(eventArgs.originalEvent.target).closest('td'));                    if (this._editingController.getEditMode() !== DATAGRID_EDIT_MODE_ROW)                        this._editingController.closeEditCell();                    else                        this._editingController.cancelEditData();                    eventArgs.originalEvent.preventDefault()                }            },            _ctrlFKeyHandler: function(eventArgs) {                if (eventArgs.ctrl && this.option("searchPanel") && this.option("searchPanel").visible) {                    this._testHeaderPanelFocused = true;                    this._headerPanel.focus();                    eventArgs.originalEvent.preventDefault()                }            },            _keyDownHandler: function(e) {                var isEditing = this._editingController.isEditing();                if (e.originalEvent.isDefaultPrevented())                    return;                this._isNeedFocus = true;                switch (e.key) {                    case"leftArrow":                    case"rightArrow":                        this._leftRightKeysHandler(e, isEditing);                        break;                    case"upArrow":                    case"downArrow":                        this._upDownKeysHandler(e, isEditing);                        break;                    case"pageUp":                        this._pageUpKeyHandler(e);                        break;                    case"pageDown":                        this._pageDownKeyHandler(e);                        break;                    case"space":                        this._spaceKeyHandler(e, isEditing);                        break;                    case"A":                        this._crtlAKeyHandler(e);                        break;                    case"tab":                        this._tabKeyHandler(e, isEditing);                        break;                    case"enter":                        this._enterKeyHandler(e, isEditing);                        break;                    case"escape":                        this._escapeKeyHandler(e, isEditing);                        break;                    case"F":                        this._ctrlFKeyHandler(e);                        break                }                e.originalEvent.stopPropagation()            },            _isLastRow: function(rowIndex) {                return rowIndex === this.getController("data").items().length - 1            },            _getNextCell: function(keyCode, elementType, cellPosition) {                var focusedCellPosition = cellPosition || this._focusedCellPosition,                    includeCommandCells = $.inArray(keyCode, ["next", "previous"]) > -1,                    rowIndex,                    newFocusedCellPosition,                    $cell,                    $row;                if (this._focusedView && focusedCellPosition) {                    newFocusedCellPosition = this._getNewPositionByCode({                        columnIndex: focusedCellPosition.columnIndex,                        rowIndex: focusedCellPosition.rowIndex                    }, elementType, keyCode);                    $cell = this._focusedView.getCell(newFocusedCellPosition);                    if (!this._isCellValid($cell) && this._isCellInRow(newFocusedCellPosition.columnIndex, includeCommandCells))                        $cell = this._getNextCell(keyCode, "cell", newFocusedCellPosition);                    $row = $cell && $cell.parent();                    if (this._hasSkipRow($row)) {                        rowIndex = this._focusedView.getRowIndex($row);                        if (!this._isLastRow(rowIndex))                            $cell = this._getNextCell(keyCode, "row", $.extend({}, focusedCellPosition, {rowIndex: rowIndex}));                        else                            return null                    }                    return $cell                }                return null            },            _getNewPositionByCode: function(cellPosition, elementType, code) {                var columnIndex = cellPosition.columnIndex,                    rowIndex = cellPosition.rowIndex,                    visibleColumnsCount = this.getController("columns").getVisibleColumns().length;                switch (code) {                    case"nextInRow":                    case"next":                        if (columnIndex < visibleColumnsCount - 1 && !this._isLastValidCell({                            columnIndex: columnIndex,                            rowIndex: rowIndex                        }) && elementType !== "row")                            columnIndex++;                        else if (!this._isLastRow(rowIndex) && code === "next") {                            columnIndex = 0;                            rowIndex++                        }                        break;                    case"previousInRow":                    case"previous":                        if (columnIndex > 0 && !this._isFirstValidCell({                            columnIndex: columnIndex,                            rowIndex: rowIndex                        }) && elementType !== "row")                            columnIndex--;                        else if (rowIndex > 0 && code === "previous") {                            columnIndex = visibleColumnsCount - 1;                            rowIndex--                        }                        break;                    case"upArrow":                        rowIndex = rowIndex > 0 ? rowIndex - 1 : rowIndex;                        break;                    case"downArrow":                        rowIndex = !this._isLastRow(rowIndex) ? rowIndex + 1 : rowIndex;                        break                }                return {                        columnIndex: columnIndex,                        rowIndex: rowIndex                    }            },            _isFirstValidCell: function(cellPosition) {                var isFirstValidCell = false;                if (cellPosition.rowIndex === 0 && cellPosition.columnIndex > 0)                    isFirstValidCell = isFirstValidCell || !this._haveValidCellBeforePosition(cellPosition);                return isFirstValidCell            },            _haveValidCellBeforePosition: function(cellPosition) {                var columnIndex = cellPosition.columnIndex,                    hasValidCells = false;                while (columnIndex > 0 && !hasValidCells) {                    var checkingPosition = {                            columnIndex: --columnIndex,                            rowIndex: cellPosition.rowIndex                        };                    hasValidCells = this._isCellByPositionValid(checkingPosition)                }                return hasValidCells            },            _isLastValidCell: function(cellPosition) {                var checkingPosition = {                        columnIndex: cellPosition.columnIndex + 1,                        rowIndex: cellPosition.rowIndex                    },                    visibleColumnsCount = this.getController("columns").getVisibleColumns().length,                    isCheckingCellValid = this._isCellByPositionValid(checkingPosition);                if (!this._isLastRow(cellPosition.rowIndex) || isCheckingCellValid)                    return false;                else if (cellPosition.columnIndex === visibleColumnsCount - 1)                    return true;                return this._isLastValidCell(checkingPosition)            },            _isCellInRow: function(columnIndex, includeCommandCells) {                var visibleColumnsCount = this.getController("columns").getVisibleColumns().length;                return includeCommandCells ? columnIndex >= 0 && columnIndex <= visibleColumnsCount - 1 : columnIndex > 0 && columnIndex < visibleColumnsCount - 1            },            _resetFocusedCell: function(that) {                var $cell = that._getFocusedCell();                $cell && $cell.attr("tabindex", null);                that._isNeedFocus = false            },            init: function() {                var that = this;                if (that.option("useKeyboard")) {                    that._dataController = that.getController("data");                    that._selectionController = that.getController("selection");                    that._editingController = that.getController("editing");                    that._headerPanel = that.getView("headerPanel");                    that._columnsController = that.getController("columns");                    that.getController("editorFactory").focused.add(function($element) {                        that.setupFocusedView();                        if (that._isNeedFocus)                            if (that._focusedView && that._focusedView.getScrollable) {                                that._focusedView.getScrollable().scrollToElement($element);                                that._isNeedFocus = false                            }                    });                    that._focusedCellPosition = {                        columnIndex: 0,                        rowIndex: 0                    };                    that._dataController.changed.add(function(change) {                        if (that._focusedCellPosition && change && change.changeType === 'prepend')                            that._focusedCellPosition.rowIndex += change.items.length                    });                    that._initFocusedViews();                    that._documentClickHandler = that.createAction(function(e) {                        if (!$(e.jQueryEvent.target).closest("." + DATAGRID_ROWS_VIEW_CLASS).length)                            that._resetFocusedCell(that)                    });                    $(document).on(events.addNamespace("dxpointerdown", "dxDataGridKeyboardNavigation"), that._documentClickHandler)                }            },            focus: function($element) {                var focusView = this._getFocusedViewByElement($element);                if (focusView) {                    this._focusView(focusView.view, focusView.viewIndex);                    this._isNeedFocus = true;                    this._focus($element);                    this._isHeaderView(focusView.view.name) && this._focusInteractiveElement($element)                }            },            _getFocusedViewByElement: function($element) {                var condition = function(view) {                        return $element.closest(view._$element).length                    };                return this._getFocusedViewByCondition(condition)            },            _getFocusedViewByCondition: function(conditionFunction) {                var focusView;                $.each(this._focusedViews, function(index, view) {                    if (conditionFunction(view)) {                        focusView = {                            viewIndex: index,                            view: view                        };                        return false                    }                });                return focusView            },            _isHeaderView: function(viewName) {                return viewName === "columnHeadersView"            },            focusViewByName: function(viewName) {                var view = this._getFocusedViewByName(viewName);                this._focusView(view.view, view.viewIndex)            },            setupFocusedView: function() {                if (!utils.isDefined(this._focusedView))                    this.focusViewByName("rowsView")            },            _getFocusedViewByName: function(viewName) {                var condition = function(view) {                        return view.name === viewName                    };                return this._getFocusedViewByCondition(condition)            },            optionChanged: function(args) {                var that = this;                switch (args.name) {                    case'useKeyboard':                        args.handled = true;                        break;                    default:                        that.callBase(args)                }            },            dispose: function() {                this.callBase();                this._focusedView = null;                this._focusedViews = null;                this._keyDownProcessor && this._keyDownProcessor.dispose();                $(document).off(events.addNamespace("dxpointerdown", "dxDataGridKeyboardNavigation"), this._documentClickHandler)            }        });        $.extend(dataGrid.__internals, {            DATAGRID_GROUP_ROW_CLASS: DATAGRID_GROUP_ROW_CLASS,            DATAGRID_ROW_CLASS: DATAGRID_ROW_CLASS        });        dataGrid.registerModule("keyboardNavigation", {            defaultOptions: function() {                return {useKeyboard: true}            },            controllers: {keyboardNavigation: dataGrid.KeyboardNavigationController},            extenders: {                views: {rowsView: {_renderCore: function(change) {                            this.callBase(change);                            this.element().attr("tabindex", this.option("useKeyboard") ? 0 : null)                        }}},                controllers: {editing: {editCell: function(rowIndex, columnIndex) {                            var isCellEditing = this.callBase(rowIndex, columnIndex),                                keyboardNavigationController = this.getController("keyboardNavigation");                            if (isCellEditing)                                keyboardNavigationController.setupFocusedView();                            return isCellEditing                        }}}            }        })    })(jQuery, DevExpress);    /*! Module widgets-web, file ui.dataGrid.errorHandling.js */    (function($, DX) {        var ui = DX.ui,            dataGrid = ui.dxDataGrid;        var DATAGRID_ERROR_ROW_CLASS = "dx-error-row",            DATAGRID_DATA_ROW_CLASS = "dx-data-row",            DATAGRID_ERROR_MESSAGE_CLASS = "dx-error-message",            DATAGRID_ERROR_CLOSEBUTTON_CLASS = "dx-closebutton",            DATAGRID_ACTION_CLASS = "dx-datagrid-action";        dataGrid.ErrorHandlingController = dataGrid.ViewController.inherit({            init: function() {                var that = this;                that._columnHeadersView = that.getView("columnHeadersView");                that._rowsView = that.getView("rowsView")            },            renderErrorRow: function(message, rowIndex) {                var that = this,                    viewElement = rowIndex >= 0 ? that._rowsView : that._columnHeadersView,                    $tableElement = viewElement._getTableElement(),                    $errorRow = $("<tr />").addClass(DATAGRID_ERROR_ROW_CLASS),                    $row = $tableElement.find("." + DATAGRID_DATA_ROW_CLASS).eq(rowIndex),                    $errorMessage = $("<div/>").addClass(DATAGRID_ERROR_MESSAGE_CLASS).text(message),                    $closeButton = $("<div/>").addClass(DATAGRID_ERROR_CLOSEBUTTON_CLASS).addClass(DATAGRID_ACTION_CLASS);                if (rowIndex >= 0) {                    that.removeErrorRow($tableElement.find("tr").eq($row.index() + 1));                    $errorRow.insertAfter($row)                }                else {                    that.removeErrorRow($tableElement.find("tr").last());                    $tableElement.append($errorRow)                }                $closeButton.on("dxclick", that.createAction(function(args) {                    var e = args.jQueryEvent,                        $currentErrorRow = $(e.currentTarget).closest("." + DATAGRID_ERROR_ROW_CLASS);                    e.stopPropagation();                    that.removeErrorRow($currentErrorRow)                }));                $("<td/>").attr({                    colspan: that._columnHeadersView.getColumnCount(),                    role: "presentation"                }).prepend($closeButton).append($errorMessage).appendTo($errorRow)            },            removeErrorRow: function($row) {                $row.hasClass(DATAGRID_ERROR_ROW_CLASS) && $row.remove()            },            optionChanged: function(args) {                var that = this;                switch (args.name) {                    case'errorRowEnabled':                        args.handled = true;                        break;                    default:                        that.callBase(args)                }            }        });        dataGrid.registerModule('errorHandling', {            defaultOptions: function() {                return {errorRowEnabled: true}            },            controllers: {errorHandling: dataGrid.ErrorHandlingController},            extenders: {controllers: {data: {init: function() {                            var that = this,                                errorHandlingController = that.getController('errorHandling');                            that.callBase();                            that.dataErrorOccurred.add(function(error) {                                var message = error && error.message || error;                                if (that.option("errorRowEnabled"))                                    errorHandlingController.renderErrorRow(message)                            })                        }}}}        })    })(jQuery, DevExpress);    /*! Module widgets-web, file ui.dataGrid.summaryModule.js */    (function($, DX) {        var ui = DX.ui,            utils = DX.utils,            dataGrid = ui.dxDataGrid,            normalizeSortingInfo = DX.data.utils.normalizeSortingInfo;        var DATAGRID_TOTAL_FOOTER_CLASS = "dx-datagrid-total-footer",            DATAGRID_SUMMARY_ITEM_CLASS = "dx-datagrid-summary-item",            DATAGRID_TEXT_CONTENT_CLASS = "dx-datagrid-text-content",            DATAGRID_GROUP_FOOTER_CLASS = "dx-datagrid-group-footer",            DATAGRID_GROUP_TEXT_CONTENT_CLASS = "dx-datagrid-group-text-content",            DATAGRID_GROUP_FOOTER_ROW_TYPE = "groupFooter";        var renderSummaryCell = function($cell, options) {                var i,                    column = options.column,                    summaryItems = options.summaryItems,                    summaryItem,                    $summaryItems = [];                if (!column.command && summaryItems) {                    for (i = 0; i < summaryItems.length; i++) {                        summaryItem = summaryItems[i];                        $summaryItems.push($("<div>").css('text-align', summaryItem.alignment || column.alignment).addClass(DATAGRID_SUMMARY_ITEM_CLASS).addClass(DATAGRID_TEXT_CONTENT_CLASS).addClass(summaryItem.cssClass).toggleClass(DATAGRID_GROUP_TEXT_CONTENT_CLASS, options.rowType === "group").text(dataGrid.getSummaryText(summaryItem, options.summaryTexts)))                    }                    $cell.append($summaryItems)                }            },            getSummaryCellOptions = function(that, options) {                var summaryTexts = that.option("summary.texts");                return {                        totalItem: options.row,                        summaryItems: options.row.summaryCells[options.columnIndex],                        summaryTexts: summaryTexts                    }            };        dataGrid.FooterView = dataGrid.ColumnsView.inherit(function() {            return {                    _getRows: function() {                        return this._dataController.footerItems()                    },                    _getCellOptions: function(options) {                        return $.extend(this.callBase(options), getSummaryCellOptions(this, options))                    },                    _renderCellContent: function($cell, options) {                        renderSummaryCell($cell, options);                        this.callBase($cell, options)                    },                    _renderCore: function() {                        var totalItem = this._dataController.footerItems()[0];                        this.element().empty().addClass(DATAGRID_TOTAL_FOOTER_CLASS);                        if (totalItem && totalItem.summaryCells && totalItem.summaryCells.length)                            this._setTableElement(this._renderTable())                    },                    _renderTable: function() {                        var $table = this.callBase.apply(this, arguments),                            $content = this.element();                        this.wrapTableInScrollContainer($table).appendTo($content);                        return $table                    },                    _columnOptionChanged: function(e) {                        var optionNames = e.optionNames;                        if (e.changeTypes.grouping)                            return;                        if (optionNames.width || optionNames.visibleWidth)                            this.callBase(e)                    },                    _handleDataChanged: function(e) {                        if (e.changeType === "refresh")                            this.render()                    },                    getHeight: function() {                        var $element = this.element();                        return $element ? $element.outerHeight() : 0                    },                    isVisible: function() {                        return !!this._dataController.footerItems().length                    }                }        }());        var SummaryDataSourceAdapterExtender = function() {                return {                        init: function() {                            this.callBase.apply(this, arguments);                            this._totalAggregates = []                        },                        summary: function(summary) {                            if (!arguments.length)                                return this._summary;                            this._summary = summary                        },                        totalAggregates: function() {                            return this._totalAggregates                        }                    }            }();        var SummaryDataSourceAdapterClientExtender = function() {                var calculateAggregates = function(that, summary, data, groupLevel) {                        var calculator;                        if (summary) {                            calculator = new DX.data.AggregateCalculator({                                totalAggregates: summary.totalAggregates,                                groupAggregates: summary.groupAggregates,                                data: data,                                groupLevel: groupLevel                            });                            calculator.calculate()                        }                        that._totalAggregates = calculator ? calculator.totalAggregates() : []                    };                var sortGroupsBySummaryCore = function(items, groups, sortByGroups) {                        if (!items || !groups.length)                            return items;                        var group = groups[0],                            sorts = sortByGroups[0],                            query;                        if (group && sorts && sorts.length) {                            query = DX.data.query(items);                            $.each(sorts, function(index) {                                if (index === 0)                                    query = query.sortBy(this.selector, this.desc);                                else                                    query = query.thenBy(this.selector, this.desc)                            });                            query.enumerate().done(function(sortedItems) {                                items = sortedItems                            })                        }                        groups = groups.slice(1);                        sortByGroups = sortByGroups.slice(1);                        if (groups.length && sortByGroups.length)                            $.each(items, function() {                                this.items = sortGroupsBySummaryCore(this.items, groups, sortByGroups)                            });                        return items                    };                var sortGroupsBySummary = function(data, group, summary) {                        var sortByGroups = summary && summary.sortByGroups && summary.sortByGroups();                        if (sortByGroups && sortByGroups.length)                            return sortGroupsBySummaryCore(data, group, sortByGroups);                        return data                    };                return {_handleDataLoadedCore: function(options) {                            var that = this,                                groups = normalizeSortingInfo(options.loadOptions.group || []),                                summary = that.summary();                            calculateAggregates(that, summary, options.data, groups.length);                            options.data = sortGroupsBySummary(options.data, groups, summary);                            options.totalAggregates = that._totalAggregates;                            that.callBase(options)                        }}            }();        dataGrid.DataSourceAdapterServer = dataGrid.DataSourceAdapterServer.inherit(SummaryDataSourceAdapterExtender);        dataGrid.DataSourceAdapterClient = dataGrid.DataSourceAdapterClient.inherit(SummaryDataSourceAdapterExtender).inherit(SummaryDataSourceAdapterClientExtender);        dataGrid.renderSummaryCell = renderSummaryCell;        $.extend(dataGrid.__internals, {            DATAGRID_TOTAL_FOOTER_CLASS: DATAGRID_TOTAL_FOOTER_CLASS,            DATAGRID_SUMMARY_ITEM_CLASS: DATAGRID_SUMMARY_ITEM_CLASS,            DATAGRID_GROUP_FOOTER_CLASS: DATAGRID_GROUP_FOOTER_CLASS        });        dataGrid.registerModule('summary', {            defaultOptions: function() {                return {                        summary: {                            groupItems: undefined,                            totalItems: undefined,                            calculateCustomSummary: undefined,                            texts: {                                sum: Globalize.localize("dxDataGrid-summarySum"),                                sumOtherColumn: Globalize.localize("dxDataGrid-summarySumOtherColumn"),                                min: Globalize.localize("dxDataGrid-summaryMin"),                                minOtherColumn: Globalize.localize("dxDataGrid-summaryMinOtherColumn"),                                max: Globalize.localize("dxDataGrid-summaryMax"),                                maxOtherColumn: Globalize.localize("dxDataGrid-summaryMaxOtherColumn"),                                avg: Globalize.localize("dxDataGrid-summaryAvg"),                                avgOtherColumn: Globalize.localize("dxDataGrid-summaryAvgOtherColumn"),                                count: Globalize.localize("dxDataGrid-summaryCount")                            }                        },                        sortByGroupSummaryInfo: undefined                    }            },            views: {footerView: dataGrid.FooterView},            extenders: {                controllers: {data: function() {                        return {                                _isDataColumn: function(column) {                                    return column && (!utils.isDefined(column.groupIndex) || column.showWhenGrouped)                                },                                _isGroupFooterVisible: function() {                                    var groupItems = this.option("summary.groupItems") || [],                                        groupItem,                                        column,                                        i;                                    for (i = 0; i < groupItems.length; i++) {                                        groupItem = groupItems[i];                                        column = this._columnsController.columnOption(groupItem.column);                                        if (groupItem.showInGroupFooter && this._isDataColumn(column))                                            return true                                    }                                    return false                                },                                _processGroupItems: function(items, groupCount, options) {                                    var result = this.callBase.apply(this, arguments);                                    if (options) {                                        if (options.isGroupFooterVisible === undefined)                                            options.isGroupFooterVisible = this._isGroupFooterVisible();                                        if (options.data && options.data.items && options.isGroupFooterVisible)                                            result.push({                                                rowType: DATAGRID_GROUP_FOOTER_ROW_TYPE,                                                data: options.data,                                                groupIndex: options.path.length - 1,                                                values: []                                            })                                    }                                    return result                                },                                _processGroupItem: function(groupItem, options) {                                    var that = this;                                    if (!options.summaryGroupItems)                                        options.summaryGroupItems = that.option("summary.groupItems") || [];                                    if (groupItem.rowType === "group") {                                        var groupColumnIndex = -1;                                        $.each(options.visibleColumns, function() {                                            if (groupItem.groupIndex === this.groupIndex) {                                                groupColumnIndex = this.index;                                                return false                                            }                                        });                                        groupItem.summaryCells = this._calculateSummaryCells(options.summaryGroupItems, groupItem.data.aggregates || [], options.visibleColumns, function(summaryItem, column) {                                            if (summaryItem.showInGroupFooter)                                                return -1;                                            if (summaryItem.alignByColumn && column && !utils.isDefined(column.groupIndex))                                                return column.index;                                            else                                                return groupColumnIndex                                        })                                    }                                    if (groupItem.rowType === DATAGRID_GROUP_FOOTER_ROW_TYPE)                                        groupItem.summaryCells = this._calculateSummaryCells(options.summaryGroupItems, groupItem.data.aggregates || [], options.visibleColumns, function(summaryItem, column) {                                            return summaryItem.showInGroupFooter && that._isDataColumn(column) ? column.index : -1                                        });                                    return groupItem                                },                                _calculateSummaryCells: function(summaryItems, aggregates, visibleColumns, calculateTargetColumnIndex) {                                    var that = this,                                        summaryCells = [],                                        summaryCellsByColumns = {};                                    $.each(summaryItems, function(summaryIndex, summaryItem) {                                        var column = that._columnsController.columnOption(summaryItem.column),                                            showInColumn = summaryItem.showInColumn && that._columnsController.columnOption(summaryItem.showInColumn) || column,                                            columnIndex = calculateTargetColumnIndex(summaryItem, showInColumn),                                            aggregate;                                        if (columnIndex >= 0) {                                            if (!summaryCellsByColumns[columnIndex])                                                summaryCellsByColumns[columnIndex] = [];                                            aggregate = aggregates[summaryIndex];                                            if (utils.isDefined(aggregate) && !isNaN(aggregate))                                                summaryCellsByColumns[columnIndex].push($.extend({}, summaryItem, {                                                    value: aggregate,                                                    columnCaption: column && column.index !== columnIndex ? column.caption : undefined                                                }))                                        }                                    });                                    if (!$.isEmptyObject(summaryCellsByColumns))                                        $.each(visibleColumns, function() {                                            summaryCells.push(summaryCellsByColumns[this.index] || [])                                        });                                    return summaryCells                                },                                _getSummaryCells: function(summaryTotalItems, totalAggregates) {                                    var that = this,                                        columnsController = that._columnsController;                                    return that._calculateSummaryCells(summaryTotalItems, totalAggregates, columnsController.getVisibleColumns(), function(summaryItem, column) {                                            return that._isDataColumn(column) ? column.index : -1                                        })                                },                                _updateItemsCore: function(change) {                                    var that = this,                                        summaryCells,                                        totalAggregates,                                        dataSource = that._dataSource,                                        summaryTotalItems = that.option("summary.totalItems");                                    that.callBase(change);                                    that._footerItems = [];                                    if (dataSource && summaryTotalItems && summaryTotalItems.length) {                                        totalAggregates = dataSource.totalAggregates();                                        summaryCells = this._getSummaryCells(summaryTotalItems, totalAggregates);                                        if (summaryCells.length)                                            that._footerItems.push({                                                rowType: 'totalFooter',                                                summaryCells: summaryCells                                            })                                    }                                },                                _getAggregates: function(summaryItems) {                                    var that = this,                                        columnsController = that.getController("columns"),                                        calculateCustomSummary = that.option("summary.calculateCustomSummary");                                    return $.map(summaryItems || [], function(summaryItem) {                                            var column = columnsController.columnOption(summaryItem.column),                                                calculateCellValue = column && column.calculateCellValue ? $.proxy(column, "calculateCellValue") : DX.data.utils.compileGetter(column ? column.dataField : summaryItem.column),                                                aggregator = summaryItem.summaryType || "count",                                                selector = calculateCellValue,                                                options;                                            if (aggregator === 'avg' || aggregator === 'sum')                                                selector = function(data) {                                                    return Number(calculateCellValue(data))                                                };                                            if (aggregator === "custom") {                                                if (!calculateCustomSummary) {                                                    DX.log("E1026");                                                    calculateCustomSummary = function(){}                                                }                                                options = {                                                    component: that.component,                                                    name: summaryItem.name,                                                    summaryProcess: "start",                                                    totalValue: undefined                                                };                                                calculateCustomSummary(options);                                                options.summaryProcess = "calculate";                                                aggregator = {                                                    seed: options.totalValue,                                                    step: function(totalValue, value) {                                                        options.summaryProcess = "calculate";                                                        options.totalValue = totalValue;                                                        options.value = value;                                                        calculateCustomSummary(options);                                                        return options.totalValue                                                    },                                                    finalize: function(totalValue) {                                                        options.summaryProcess = "finalize";                                                        options.totalValue = totalValue;                                                        delete options.value;                                                        calculateCustomSummary(options);                                                        return options.totalValue                                                    }                                                }                                            }                                            return {                                                    selector: selector,                                                    aggregator: aggregator                                                }                                        })                                },                                _addSortInfo: function(sortByGroups, groupColumn, selector, sortOrder) {                                    var groupIndex;                                    if (groupColumn) {                                        groupIndex = groupColumn.groupIndex;                                        sortOrder = sortOrder || groupColumn.sortOrder;                                        if (utils.isDefined(groupIndex)) {                                            sortByGroups[groupIndex] = sortByGroups[groupIndex] || [];                                            sortByGroups[groupIndex].push({                                                selector: selector,                                                desc: sortOrder === "desc"                                            })                                        }                                    }                                },                                _findSummaryItem: function(summaryItems, name) {                                    var summaryItemIndex = -1;                                    var getFullName = function(summaryItem) {                                            var summaryType = summaryItem.summaryType,                                                column = summaryItem.column;                                            return summaryType && column && summaryType + "_" + column                                        };                                    if (utils.isDefined(name))                                        $.each(summaryItems || [], function(index) {                                            if (this.name === name || index === name || this.summaryType === name || this.column === name || getFullName(this) === name) {                                                summaryItemIndex = index;                                                return false                                            }                                        });                                    return summaryItemIndex                                },                                _getSummarySortByGroups: function(sortByGroupSummaryInfo, groupSummaryItems) {                                    var that = this,                                        columnsController = that._columnsController,                                        groupColumns = columnsController.getGroupColumns(),                                        sortByGroups = [];                                    if (!groupSummaryItems || !groupSummaryItems.length)                                        return;                                    $.each(sortByGroupSummaryInfo || [], function() {                                        var sortOrder = this.sortOrder,                                            groupColumn = this.groupColumn,                                            summaryItemIndex = that._findSummaryItem(groupSummaryItems, this.summaryItem);                                        if (summaryItemIndex < 0)                                            return;                                        var selector = function(data) {                                                return data.aggregates[summaryItemIndex]                                            };                                        if (utils.isDefined(groupColumn)) {                                            groupColumn = columnsController.columnOption(groupColumn);                                            that._addSortInfo(sortByGroups, groupColumn, selector, sortOrder)                                        }                                        else                                            $.each(groupColumns, function(groupIndex, groupColumn) {                                                that._addSortInfo(sortByGroups, groupColumn, selector, sortOrder)                                            })                                    });                                    return sortByGroups                                },                                _createDataSourceAdapterCore: function(dataSource, remoteOperations) {                                    var summary = this._getSummaryOptions(),                                        dataSourceAdapter;                                    if (remoteOperations === 'auto' && summary)                                        remoteOperations = {                                            filtering: true,                                            sorting: true,                                            paging: false                                        };                                    dataSourceAdapter = this.callBase(dataSource, remoteOperations);                                    dataSourceAdapter.summary(summary);                                    return dataSourceAdapter                                },                                _getSummaryOptions: function() {                                    var that = this,                                        groupSummaryItems = that.option("summary.groupItems"),                                        totalSummaryItems = that.option("summary.totalItems"),                                        sortByGroupSummaryInfo = that.option("sortByGroupSummaryInfo"),                                        groupAggregates = that._getAggregates(groupSummaryItems),                                        totalAggregates = that._getAggregates(totalSummaryItems),                                        sortByGroups = function() {                                            return that._getSummarySortByGroups(sortByGroupSummaryInfo, groupSummaryItems)                                        };                                    if (groupAggregates.length || totalAggregates.length)                                        return {                                                groupAggregates: groupAggregates,                                                totalAggregates: totalAggregates,                                                sortByGroups: sortByGroups                                            }                                },                                publicMethods: function() {                                    var methods = this.callBase();                                    methods.push("getTotalSummaryValue");                                    return methods                                },                                getTotalSummaryValue: function(summaryItemName) {                                    var summaryItemIndex = this._findSummaryItem(this.option("summary.totalItems"), summaryItemName),                                        aggregates = this._dataSource.totalAggregates();                                    if (aggregates.length && summaryItemIndex > -1)                                        return aggregates[summaryItemIndex]                                },                                optionChanged: function(args) {                                    if (args.name === "summary" || args.name === "sortByGroupSummaryInfo")                                        args.name = "dataSource";                                    this.callBase(args)                                },                                init: function() {                                    this._footerItems = [];                                    this.callBase()                                },                                footerItems: function() {                                    return this._footerItems                                }                            }                    }()},                views: {rowsView: function() {                        return {                                _createRow: function(row) {                                    var $row = this.callBase(row);                                    row && $row.addClass(row.rowType === DATAGRID_GROUP_FOOTER_ROW_TYPE ? DATAGRID_GROUP_FOOTER_CLASS : "");                                    return $row                                },                                _renderCells: function($row, options) {                                    this.callBase.apply(this, arguments);                                    this._renderGroupSummaryCells($row, options)                                },                                _hasAlignByColumnSummaryItems: function(columnIndex, options) {                                    return options.row.summaryCells[options.row.summaryCells.length - columnIndex].length                                },                                _renderGroupSummaryCells: function($row, options) {                                    if (options.row.rowType === "group" && options.row.summaryCells && options.row.summaryCells.length) {                                        var $groupCell = $row.children().last(),                                            groupCellColSpan = Number($groupCell.attr("colspan")) || 1,                                            alignByColumnCellCount = 0;                                        for (var i = 1; i < groupCellColSpan; i++)                                            alignByColumnCellCount = this._hasAlignByColumnSummaryItems(i, options) ? i : alignByColumnCellCount;                                        if (alignByColumnCellCount > 0) {                                            $groupCell.attr("colspan", groupCellColSpan - alignByColumnCellCount);                                            for (i = 0; i < alignByColumnCellCount; i++) {                                                var columnIndex = options.columns.length - alignByColumnCellCount + i;                                                this._renderCell($row, $.extend({                                                    column: options.columns[columnIndex],                                                    columnIndex: columnIndex                                                }, options))                                            }                                        }                                    }                                },                                _getColumnTemplate: function(options) {                                    if (!options.column.command && !utils.isDefined(options.column.groupIndex) && options.summaryItems && options.summaryItems.length)                                        return renderSummaryCell;                                    else                                        return this.callBase(options)                                },                                _getCellOptions: function(options) {                                    var that = this,                                        parameters = that.callBase(options);                                    if (options.row.summaryCells)                                        return $.extend(parameters, getSummaryCellOptions(that, options));                                    else                                        return parameters                                }                            }                    }()}            }        })    })(jQuery, DevExpress);    /*! Module widgets-web, file ui.dataGrid.masterDetailModule.js */    (function($, DX) {        var ui = DX.ui,            utils = DX.utils,            dataGrid = ui.dxDataGrid,            DATAGRID_MASTER_DETAIL_CELL_CLASS = "dx-master-detail-cell",            DATAGRID_MASTER_DETAIL_ROW_CLASS = "dx-master-detail-row",            DATAGRID_ROW_LINES_CLASS = "dx-row-lines";        $.extend(dataGrid.__internals, {            DATAGRID_MASTER_DETAIL_CELL_CLASS: DATAGRID_MASTER_DETAIL_CELL_CLASS,            DATAGRID_MASTER_DETAIL_ROW_CLASS: DATAGRID_MASTER_DETAIL_ROW_CLASS,            DATAGRID_ROW_LINES_CLASS: DATAGRID_ROW_LINES_CLASS        });        dataGrid.registerModule('masterDetail', {            defaultOptions: function() {                return {masterDetail: {                            enabled: false,                            autoExpandAll: false,                            template: null                        }}            },            extenders: {                controllers: {                    editorFactory: {focus: function($element) {                            if ($element && $element.hasClass(DATAGRID_MASTER_DETAIL_CELL_CLASS))                                this.loseFocus();                            else                                return this.callBase($element)                        }},                    columns: {_getExpandColumnsCore: function() {                            var expandColumns = this.callBase();                            if (this.option('masterDetail.enabled'))                                expandColumns.push({});                            return expandColumns                        }},                    data: function() {                        var initMasterDetail = function(that) {                                that._expandedItems = [];                                that._isExpandAll = that.option('masterDetail.autoExpandAll')                            };                        return {                                init: function() {                                    var that = this;                                    initMasterDetail(that);                                    that.loadingChanged.add(function(isLoading) {                                        if (!isLoading)                                            that._expandedItems = $.grep(that._expandedItems, function(item) {                                                return item.visible                                            })                                    });                                    that.callBase()                                },                                expandAll: function(groupIndex) {                                    var that = this;                                    if (groupIndex < 0) {                                        that._isExpandAll = true;                                        that._expandedItems = [];                                        that.updateItems()                                    }                                    else                                        that.callBase.apply(that, arguments)                                },                                collapseAll: function(groupIndex) {                                    var that = this;                                    if (groupIndex < 0) {                                        that._isExpandAll = false;                                        that._expandedItems = [];                                        that.updateItems()                                    }                                    else                                        that.callBase.apply(that, arguments)                                },                                isRowExpanded: function(key) {                                    var that = this,                                        expandIndex = dataGrid.getIndexByKey(key, that._expandedItems);                                    if (utils.isArray(key))                                        return that.callBase.apply(that, arguments);                                    else                                        return !!(that._isExpandAll ^ (expandIndex >= 0 && that._expandedItems[expandIndex].visible))                                },                                _changeRowExpandCore: function(key) {                                    var that = this,                                        expandIndex,                                        rowIndex;                                    if (utils.isArray(key))                                        return that.callBase.apply(that, arguments);                                    else {                                        expandIndex = dataGrid.getIndexByKey(key, that._expandedItems);                                        if (expandIndex >= 0) {                                            var visible = that._expandedItems[expandIndex].visible;                                            that._expandedItems[expandIndex].visible = !visible                                        }                                        else                                            that._expandedItems.push({                                                key: key,                                                visible: true                                            });                                        rowIndex = that.getRowIndexByKey(key);                                        that.updateItems({                                            changeType: 'update',                                            rowIndices: [rowIndex, rowIndex + 1]                                        })                                    }                                },                                _processDataItem: function(data, options) {                                    var that = this,                                        dataItem = that.callBase.apply(that, arguments);                                    dataItem.isExpanded = that.isRowExpanded(dataItem.key);                                    if (options.detailColumnIndex === undefined) {                                        options.detailColumnIndex = -1;                                        $.each(options.visibleColumns, function(index, column) {                                            if (column.command === 'expand' && !utils.isDefined(column.groupIndex)) {                                                options.detailColumnIndex = index;                                                return false                                            }                                        })                                    }                                    if (options.detailColumnIndex >= 0)                                        dataItem.values[options.detailColumnIndex] = dataItem.isExpanded;                                    return dataItem                                },                                _processItems: function() {                                    var that = this,                                        items = that.callBase.apply(that, arguments),                                        expandIndex,                                        result = [];                                    if (this._isLoadingAll)                                        return items;                                    $.each(items, function(index, item) {                                        result.push(item);                                        expandIndex = dataGrid.getIndexByKey(item.key, that._expandedItems);                                        if (item.rowType === 'data' && (item.isExpanded || expandIndex >= 0) && !item.inserted)                                            result.push({                                                visible: item.isExpanded,                                                rowType: 'detail',                                                key: item.key,                                                data: item.data,                                                values: []                                            })                                    });                                    return result                                },                                optionChanged: function(args) {                                    var that = this,                                        value,                                        previousValue,                                        isEnabledChanged,                                        isAutoExpandAllChanged;                                    if (args.name === 'masterDetail') {                                        args.name = 'dataSource';                                        switch (args.fullName) {                                            case'masterDetail':                                                value = args.value || {};                                                previousValue = args.previousValue || {};                                                isEnabledChanged = value.enabled !== previousValue.enabled;                                                isAutoExpandAllChanged = value.autoExpandAll !== previousValue.autoExpandAll;                                                break;                                            case'masterDetail.enabled':                                                isEnabledChanged = true;                                                break;                                            case'masterDetail.autoExpandAll':                                                isAutoExpandAllChanged = true;                                                break                                        }                                        if (isEnabledChanged || isAutoExpandAllChanged)                                            initMasterDetail(that)                                    }                                    that.callBase(args)                                },                                refresh: function() {                                    var that = this;                                    initMasterDetail(that);                                    return that.callBase.apply(that, arguments)                                }                            }                    }()                },                views: {rowsView: function() {                        return {                                _getColumnTemplate: function(options) {                                    var that = this,                                        column = options.column,                                        template;                                    if (column.command === 'detail') {                                        template = that.option('masterDetail.template') || that._getDefaultTemplate(column);                                        options.denyRenderToDetachedContainer = true                                    }                                    else                                        template = that.callBase.apply(that, arguments);                                    return template                                },                                _createRow: function(row) {                                    var $row = this.callBase(row);                                    if (row && row.rowType === "detail") {                                        this.option('showRowLines') && $row.addClass(DATAGRID_ROW_LINES_CLASS);                                        $row.addClass(DATAGRID_MASTER_DETAIL_ROW_CLASS).toggle(row.visible)                                    }                                    return $row                                },                                _getGroupCellOptions: function(options) {                                    var row = options.row,                                        groupColumns = this._columnsController.getGroupColumns(),                                        columnIndex = groupColumns.length + options.columnsCountBeforeGroups,                                        emptyCellsCount = columnIndex + Number(this.option("masterDetail.enabled"));                                    if (row && row.rowType === "detail")                                        return {                                                columnIndex: columnIndex,                                                emptyCellsCount: emptyCellsCount,                                                colspan: options.columns.length - emptyCellsCount                                            };                                    return this.callBase(options)                                },                                _renderCells: function($row, options) {                                    var row = options.row,                                        $detailCell,                                        groupCellOptions = this._getGroupCellOptions(options),                                        i;                                    if (row.rowType === 'detail') {                                        for (i = 0; i < groupCellOptions.emptyCellsCount; i++)                                            this._renderCell($row, {                                                value: null,                                                row: row,                                                rowIndex: row.rowIndex,                                                column: options.columns[i]                                            });                                        $detailCell = this._renderCell($row, {                                            value: null,                                            row: row,                                            rowIndex: row.rowIndex,                                            column: {command: 'detail'},                                            columnIndex: groupCellOptions.columnIndex                                        });                                        $detailCell.addClass(DATAGRID_MASTER_DETAIL_CELL_CLASS).attr('colspan', groupCellOptions.colspan)                                    }                                    else                                        this.callBase.apply(this, arguments)                                }                            }                    }()}            }        })    })(jQuery, DevExpress);    /*! Module widgets-web, file ui.dataGrid.fixedColumns.js */    (function($, DX, undefined) {        var ui = DX.ui,            utils = DX.utils,            dataGrid = ui.dxDataGrid;        var DATAGRID_CONTENT_CLASS = "dx-datagrid-content",            DATAGRID_HOVER_STATE_CLASS = "dx-state-hover",            DATAGRID_HEADER_ROW_CLASS = "dx-header-row",            DATAGRID_CONTENT_FIXED_CLASS = "dx-datagrid-content-fixed",            DATAGRID_GROUP_TEXT_CONTENT_CLASS = "dx-datagrid-group-text-content",            DATAGRID_FIXED_COL_CLASS = "dx-col-fixed",            DATAGRID_POINTER_EVENTS_TARGET_CLASS = "dx-pointer-events-target",            DATAGRID_POINTER_EVENTS_NONE_CLASS = "dx-pointer-events-none";        var baseFixedColumns = {                init: function() {                    this.callBase();                    this._isFixedTableRendering = false;                    this._isFixedColumns = false                },                _createCol: function(column) {                    return this.callBase(column).toggleClass(DATAGRID_FIXED_COL_CLASS, this._isFixedTableRendering && (column.fixed || column.command && column.command !== "transparent"))                },                _createCell: function(column) {                    return this.callBase(column).attr("colspan", column.colspan).toggleClass(DATAGRID_POINTER_EVENTS_NONE_CLASS, column.command === "transparent")                },                _createTable: function(columns) {                    var that = this,                        $table = that.callBase(columns),                        hoverStateEnabled = that.option("hoverStateEnabled"),                        toggleHoverState = function(rowIndex, isHover) {                            that._fixedTableElement && that._getRowElements(that._fixedTableElement).eq(rowIndex).toggleClass(DATAGRID_HOVER_STATE_CLASS, isHover);                            that._tableElement && that._getRowElements(that._tableElement).eq(rowIndex).toggleClass(DATAGRID_HOVER_STATE_CLASS, isHover)                        };                    if (hoverStateEnabled && that._isFixedColumns)                        $table.on("mouseover mouseout", ".dx-data-row", that.createAction(function(args) {                            var event = args.jQueryEvent;                            toggleHoverState(that.getRowIndex($(event.target).closest(".dx-row")), event.type === "mouseover")                        }));                    return $table                },                _renderTable: function(options) {                    var that = this,                        $fixedTable,                        $table,                        fixedColumns = that._columnsController.getFixedColumns();                    that._isFixedColumns = !!fixedColumns.length;                    $table = that.callBase(options);                    if (that._isFixedColumns) {                        that._isFixedTableRendering = true;                        that._fixedTableElement = $fixedTable = that._createTable(fixedColumns);                        that._renderRows($fixedTable, $.extend({}, options, {columns: fixedColumns}));                        that.wrapTableInScrollContainer(that._fixedTableElement).appendTo(that.element()).addClass(DATAGRID_CONTENT_FIXED_CLASS + " " + DATAGRID_POINTER_EVENTS_TARGET_CLASS);                        that._isFixedTableRendering = false                    }                    else                        that._fixedTableElement && that._fixedTableElement.remove();                    return $table                },                _renderCellContent: function($cell, options) {                    var that = this,                        column = options.column;                    if (!that._isFixedTableRendering && that._isFixedColumns && (column.fixed || column.command || utils.isDefined(column.groupIndex)))                        $cell.html(" ").addClass(column.cssClass);                    else if (column.command !== "transparent")                        that.callBase($cell, options)                },                getCellElements: function(rowIndex) {                    var that = this,                        fixedColumns,                        fixedColumnIndex = 0,                        fixedCellElements,                        cellElements = that.callBase(rowIndex);                    if (that._fixedTableElement && cellElements) {                        fixedColumns = that._columnsController.getFixedColumns(),                        fixedCellElements = that._fixedTableElement.find(".dx-row").eq(rowIndex).children("td");                        $.each(fixedColumns, function(index, column) {                            if (column.command === "transparent")                                fixedColumnIndex += column.colspan;                            else {                                cellElements[fixedColumnIndex] = fixedCellElements.get(index);                                fixedColumnIndex++                            }                        })                    }                    return cellElements                },                getColumnWidths: function() {                    var that = this,                        i,                        fixedColumnIndex = 0,                        widths,                        result = that.callBase(),                        fixedColumns = that._columnsController.getFixedColumns();                    if (that._fixedTableElement && result.length) {                        widths = dataGrid.getWidths(that._fixedTableElement);                        for (i = 0; i < fixedColumns.length; i++)                            if (fixedColumns[i].command === "transparent")                                fixedColumnIndex += fixedColumns[i].colspan;                            else {                                if (result[fixedColumnIndex] < widths[i])                                    result[fixedColumnIndex] = widths[i];                                fixedColumnIndex++                            }                    }                    return result                },                _getTableElement: function() {                    var tableElement = this._isFixedTableRendering ? this._fixedTableElement : this.callBase();                    return tableElement                },                _setTableElement: function(tableElement) {                    if (this._isFixedTableRendering)                        this._fixedTableElement = tableElement;                    else                        this.callBase(tableElement)                },                getColumns: function($tableElement) {                    $tableElement = $tableElement || this._getTableElement();                    if (this._isFixedTableRendering || $tableElement && $tableElement.closest("table").parent("." + DATAGRID_CONTENT_FIXED_CLASS).length)                        return this._columnsController.getFixedColumns();                    return this.callBase($tableElement)                },                getRowIndex: function($row) {                    var $fixedTable = this._fixedTableElement;                    if ($fixedTable && $fixedTable.find($row).length)                        return this._getRowElements($fixedTable).index($row);                    return this.callBase($row)                },                _getTableElements: function() {                    var result = this.callBase.apply(this, arguments);                    if (this._fixedTableElement)                        result = result.add(this._fixedTableElement);                    return result                },                _resizeCore: function() {                    this.callBase();                    this._synchronizeRows()                },                setColumnWidths: function(widths) {                    this.callBase(widths);                    this._synchronizeRows()                },                _getClientHeight: function(element) {                    var boundingClientRectElement = element.getBoundingClientRect && element.getBoundingClientRect();                    return boundingClientRectElement && boundingClientRectElement.height ? boundingClientRectElement.height : element.clientHeight                },                _synchronizeRows: function() {                    var that = this,                        rowHeight,                        fixedRowHeight,                        rowIndex,                        heightTable,                        heightFixedTable,                        $rowElements,                        $fixedRowElements;                    if (that._isFixedColumns && that._tableElement && that._fixedTableElement) {                        heightTable = that._getClientHeight(that._tableElement.get(0));                        heightFixedTable = that._getClientHeight(that._fixedTableElement.get(0));                        $rowElements = that._getRowElements(that._tableElement);                        $fixedRowElements = that._getRowElements(that._fixedTableElement);                        if (heightTable !== heightFixedTable) {                            $rowElements.height("");                            $fixedRowElements.height("");                            for (rowIndex = 0; rowIndex < $rowElements.length; rowIndex++) {                                rowHeight = that._getClientHeight($rowElements.get(rowIndex));                                fixedRowHeight = that._getClientHeight($fixedRowElements.get(rowIndex));                                if (rowHeight > fixedRowHeight)                                    $fixedRowElements.eq(rowIndex).css("height", rowHeight);                                else if (rowHeight < fixedRowHeight)                                    $rowElements.eq(rowIndex).css("height", fixedRowHeight)                            }                        }                    }                }            };        var ColumnHeadersViewFixedColumnsExtender = $.extend({}, baseFixedColumns, {                getContextMenuItems: function($targetElement) {                    var that = this,                        $cell,                        column,                        onItemClick,                        columnFixingOptions = that.option("columnFixing"),                        items = that.callBase($targetElement);                    if ($targetElement.closest("." + DATAGRID_HEADER_ROW_CLASS).length) {                        $cell = $targetElement.closest("td");                        column = $cell.length && that.getColumns($targetElement)[$cell[0].cellIndex];                        if (column.allowFixing) {                            onItemClick = function(params) {                                switch (params.itemData.value) {                                    case"none":                                        that._columnsController.columnOption(column.index, "fixed", false);                                        break;                                    case"left":                                        that._columnsController.columnOption(column.index, "fixed", true);                                        that._columnsController.columnOption(column.index, "fixedPosition", "left");                                        break;                                    case"right":                                        that._columnsController.columnOption(column.index, "fixed", true);                                        that._columnsController.columnOption(column.index, "fixedPosition", "right");                                        break                                }                            };                            items.push({                                text: columnFixingOptions.texts.fix,                                beginGroup: true,                                items: [{                                        text: columnFixingOptions.texts.leftPosition,                                        value: "left",                                        disabled: column.fixed && (!column.fixedPosition || column.fixedPosition === "left"),                                        onItemClick: onItemClick                                    }, {                                        text: columnFixingOptions.texts.rightPosition,                                        value: "right",                                        disabled: column.fixed && column.fixedPosition === "right",                                        onItemClick: onItemClick                                    }]                            }, {                                text: columnFixingOptions.texts.unfix,                                value: "none",                                disabled: !column.fixed,                                onItemClick: onItemClick                            })                        }                    }                    return items                },                setScrollerSpacing: function(width) {                    var that = this,                        rtlEnabled = that.option("rtlEnabled");                    that.callBase(width);                    that.element().children("." + DATAGRID_CONTENT_FIXED_CLASS).css(rtlEnabled ? {paddingLeft: width} : {paddingRight: width})                }            });        var RowsViewFixedColumnsExtender = $.extend({}, baseFixedColumns, {                _renderTable: function(options) {                    var that = this,                        $content,                        $table,                        $fixedTable,                        fixedColumns = that._columnsController.getFixedColumns();                    that._isFixedColumns = !!fixedColumns.length;                    $table = that.callBase(options);                    if (that._isFixedColumns) {                        that._isFixedTableRendering = true;                        $fixedTable = that._createTable(fixedColumns);                        that._fixedTableElement = that._fixedTableElement || $fixedTable;                        that._renderRows($fixedTable, $.extend({}, options, {columns: fixedColumns}));                        $content = that._findContentElement();                        that._updateContent($content, options.change, $fixedTable);                        that._isFixedTableRendering = false                    }                    else                        that._fixedTableElement && that._fixedTableElement.remove();                    return $table                },                _findContentElement: function() {                    var that = this,                        $content,                        scrollable,                        scrollTop,                        element = that.element();                    if (element && that._isFixedTableRendering) {                        $content = element.children("." + DATAGRID_CONTENT_CLASS);                        if (!$content.length) {                            scrollable = that.getScrollable();                            $content = $("<div/>").addClass(DATAGRID_CONTENT_CLASS).on("dxmousewheel", function(e) {                                if (scrollable) {                                    scrollTop = scrollable.scrollTop();                                    scrollable.scrollTo({y: scrollTop - e.delta});                                    if (scrollable.scrollTop() > 0 && scrollable.scrollTop() + scrollable.clientHeight() < scrollable.scrollHeight() + that.getScrollbarWidth())                                        return false                                }                            }).appendTo(element)                        }                        return $content                    }                    return that.callBase()                },                _renderContent: function(contentElement, tableElement) {                    if (this._isFixedTableRendering)                        return contentElement.empty().addClass(DATAGRID_CONTENT_CLASS + " " + DATAGRID_CONTENT_FIXED_CLASS + " " + DATAGRID_POINTER_EVENTS_TARGET_CLASS).append(tableElement);                    return this.callBase(contentElement, tableElement)                },                _getGroupCellOptions: function(options) {                    if (this._isFixedTableRendering)                        return this.callBase($.extend({}, options, {columns: this._columnsController.getVisibleColumns()}));                    return this.callBase(options)                },                _renderGroupSummaryCells: function($row, options) {                    if (this._isFixedTableRendering)                        this.callBase($row, $.extend({}, options, {columns: this._columnsController.getVisibleColumns()}));                    else                        this.callBase($row, options)                },                _getColumnTemplate: function(options) {                    var that = this,                        column = options.column,                        template = this.callBase(options);                    if (that._isFixedTableRendering && options.rowType === 'group')                        if (column.groupIndex !== undefined)                            return function($container, params) {                                    var $groupContent = $("<div/>").addClass(DATAGRID_GROUP_TEXT_CONTENT_CLASS);                                    $container.append($groupContent);                                    template($groupContent, params)                                };                    return template                },                _hasAlignByColumnSummaryItems: function(columnIndex, options) {                    if (!this._isFixedTableRendering || options.columns[options.row.summaryCells.length - columnIndex].fixed)                        return this.callBase(columnIndex, options)                },                getCellIndex: function($cell) {                    var $fixedTable = this._fixedTableElement,                        columns,                        cellIndex = 0;                    if ($fixedTable && $fixedTable.find($cell).length) {                        columns = this._columnsController.getFixedColumns();                        $.each(columns, function(index, column) {                            if (index === $cell[0].cellIndex)                                return false;                            if (column.colspan) {                                cellIndex += column.colspan;                                return                            }                            cellIndex++                        });                        return cellIndex                    }                    return this.callBase($cell)                },                _updateFixedTablePosition: function(scrollTop) {                    if (this._fixedTableElement && this._tableElement)                        this._fixedTableElement.css("top", scrollTop + this._tableElement.position().top)                },                setScrollerSpacing: function() {                    var that = this,                        vWidth = that.getScrollbarWidth(),                        hWidth = that.getScrollbarWidth(true),                        styles = that.option("rtlEnabled") ? {marginLeft: vWidth} : {marginRight: vWidth};                    styles.marginBottom = hWidth;                    that.element().children("." + DATAGRID_CONTENT_FIXED_CLASS).css(styles)                },                _handleScroll: function(e) {                    this._updateFixedTablePosition(-e.scrollOffset.top);                    this.callBase(e)                },                _updateContentPosition: function() {                    var isUpdated = this.callBase();                    if (isUpdated)                        this._updateFixedTablePosition(-this._scrollTop);                    return isUpdated                },                getCell: function(cellPosition) {                    var that = this,                        columns = that.getColumns(),                        columnIndex = cellPosition.columnIndex,                        $rows;                    if (columns && columnIndex < columns.length && (columns[columnIndex].fixed || columns[columnIndex].command === "expand")) {                        var $colspanElement;                        $rows = that._getRowElements(that._fixedTableElement);                        $colspanElement = $rows.first().find("[colspan]");                        if ($colspanElement[0].cellIndex < columnIndex)                            cellPosition.columnIndex = columnIndex - $colspanElement.attr("colspan") + 1                    }                    return that.callBase(cellPosition, $rows)                },                optionChanged: function(args) {                    switch (args.name) {                        case'scrolling':                        case'rtlEnabled':                        case"disabled":                        case'loadPanel':                            this._fixedTableElement = null                    }                    this.callBase(args)                }            });        var FooterViewFixedColumnsExtender = baseFixedColumns;        dataGrid.registerModule('fixedColumns', {            defaultOptions: function() {                return {columnFixing: {                            enabled: false,                            texts: {                                fix: Globalize.localize("dxDataGrid-columnFixingFix"),                                unfix: Globalize.localize("dxDataGrid-columnFixingUnfix"),                                leftPosition: Globalize.localize("dxDataGrid-columnFixingLeftPosition"),                                rightPosition: Globalize.localize("dxDataGrid-columnFixingRightPosition")                            }                        }}            },            extenders: {views: {                    columnHeadersView: ColumnHeadersViewFixedColumnsExtender,                    rowsView: RowsViewFixedColumnsExtender,                    footerView: FooterViewFixedColumnsExtender,                    draggingHeaderView: {_pointCreated: function(point, columns, location, sourceColumn) {                            var result = this.callBase.apply(this, arguments),                                targetColumn = columns[point.columnIndex],                                prevColumn = columns[point.columnIndex - 1],                                getFixedPosition = function(column) {                                    return column.fixedPosition === "right" ? "right" : "left"                                };                            if (!result && location === "headers")                                if (sourceColumn && sourceColumn.fixed)                                    return !(targetColumn && targetColumn.fixed && getFixedPosition(targetColumn) === getFixedPosition(sourceColumn) || prevColumn && prevColumn.fixed && getFixedPosition(prevColumn) === getFixedPosition(sourceColumn));                                else                                    return targetColumn && targetColumn.fixed && getFixedPosition(targetColumn) !== "right" || prevColumn && prevColumn.fixed && getFixedPosition(prevColumn) === "right";                            return result                        }}                }}        })    })(jQuery, DevExpress);    /*! Module widgets-web, file ui.dataGrid.exportController.js */    (function($, DX) {        var ui = DX.ui,            utils = DX.utils,            dataGrid = ui.dxDataGrid,            DATAGRID_CHECKBOX_SIZE = "dx-datagrid-checkbox-size",            DATAGRID_EXPORT_MENU_CLASS = "dx-datagrid-export-menu",            DATAGRID_EXPORT_BUTTON_CLASS = "dx-datagrid-export-button",            DATAGRID_EXPORT_ICON = "export-to",            DATAGRID_EXPORT_EXCEL_ICON = "exportxlsx",            DATAGRID_EXPORT_EXCEL_BUTTON_ICON = "export-excel-button";        dataGrid.DataProvider = DX.Class.inherit({            _getGroupValue: function(item) {                var groupColumn = this._options.groupColumns[item.groupIndex],                    value = dataGrid.getDisplayValue(groupColumn, item.values[item.groupIndex]),                    result = groupColumn.caption + ": " + dataGrid.formatValue(value, groupColumn),                    visibleIndex;                visibleIndex = this._options.getVisibleIndex(groupColumn.index);                if (item.summaryCells && item.summaryCells.length && item.summaryCells[visibleIndex].length)                    result += " " + dataGrid.getGroupRowSummaryText(item.summaryCells[visibleIndex], this._options.summaryTexts);                return result            },            _correctCellIndex: function(cellIndex) {                var startIndex = this._options.startValueIndex,                    endIndex = this._options.endValueIndex;                return cellIndex <= endIndex ? startIndex + cellIndex : null            },            ctor: function(options) {                this._options = options            },            getColumns: function() {                return this._options.columns            },            getRowsCount: function() {                return this._options.items.length            },            isGroupRow: function(rowIndex) {                return rowIndex < this._options.items.length && this._options.items[rowIndex].rowType === "group"            },            getGroupLevel: function(rowIndex) {                var item = this._options.items[rowIndex],                    groupIndex = item.groupIndex;                if (item.isTotalSummary)                    return 0;                return utils.isDefined(groupIndex) ? groupIndex : this._options.groupColumns.length            },            getCellType: function(rowIndex, cellIndex) {                if (cellIndex < this._options.columns.length) {                    var item = this._options.items.length && this._options.items[rowIndex],                        column = this._options.columns[cellIndex];                    if (item && item.rowType === "data")                        if (isFinite(item.values[this._correctCellIndex(cellIndex)]) && !utils.isDefined(column.customizeText))                            return utils.isDefined(column.lookup) ? column.lookup.dataType : column.dataType;                    return "string"                }            },            ready: function() {                var options = this._options;                return $.when(options.items).done(function(items) {                        options.items = items                    })            },            getCellValue: function(rowIndex, cellIndex) {                var column,                    value,                    correctedCellIndex = this._correctCellIndex(cellIndex),                    itemValues,                    item = this._options.items.length && this._options.items[rowIndex];                if (item) {                    itemValues = item.values;                    switch (item.rowType) {                        case"summaryFooter":                            if (correctedCellIndex < itemValues.length) {                                value = itemValues[correctedCellIndex];                                if (utils.isDefined(value))                                    return dataGrid.getSummaryText(value, this._options.summaryTexts)                            }                            break;                        case"group":                            if (cellIndex < 1)                                return this._getGroupValue(item);                            break;                        default:                            column = this._options.columns[cellIndex];                            if (column) {                                value = dataGrid.getDisplayValue(column, itemValues[correctedCellIndex]);                                return !isFinite(value) || column.customizeText ? dataGrid.formatValue(value, column) : value                            }                    }                }            },            isHeadersVisible: function() {                return this._options.isHeadersVisible            },            isTotalRow: function(rowIndex) {                var items = this._options.items,                    item = items[rowIndex];                return item && item.rowType === "summaryFooter"            }        });        dataGrid.ExportController = dataGrid.ViewController.inherit({            _getColumns: function() {                var result = [],                    visibleColumns = this._columnsController.getVisibleColumns(),                    columnWidths = this._rowsView.getColumnWidths(),                    column,                    i;                for (i = 0; i < visibleColumns.length; i++) {                    column = visibleColumns[i];                    if (!utils.isDefined(column.command))                        result.push($.extend({}, column, {width: columnWidths[i]}))                }                return result            },            _getFooterSummaryItems: function(summaryCells, isTotal) {                var result = [],                    estimatedItemsCount = 1,                    values,                    itemslength,                    summaryCell,                    j,                    i = 0;                do {                    values = [];                    for (j = 0; j < summaryCells.length; j++) {                        summaryCell = summaryCells[j];                        itemslength = summaryCell.length;                        if (estimatedItemsCount < itemslength)                            estimatedItemsCount = itemslength;                        values.push(summaryCell[i])                    }                    result.push({                        values: values,                        rowType: "summaryFooter",                        isTotalSummary: isTotal                    })                } while (i++ < estimatedItemsCount - 1);                return result            },            _hasSummaryGroupFooters: function() {                var i,                    groupItems = this.option("summary.groupItems");                if (utils.isDefined(groupItems))                    for (i = 0; i < groupItems.length; i++)                        if (groupItems[i].showInGroupFooter)                            return true;                return false            },            _getItemsWithSummaryGroupFooters: function(sourceItems) {                var item,                    result = [],                    beforeGroupFooterItems = [],                    groupFooterItems = [],                    i;                for (i = 0; i < sourceItems.length; i++) {                    item = sourceItems[i];                    if (item.rowType === "groupFooter") {                        groupFooterItems = this._getFooterSummaryItems(item.summaryCells);                        result = result.concat(beforeGroupFooterItems, groupFooterItems);                        beforeGroupFooterItems = []                    }                    else                        beforeGroupFooterItems.push(item)                }                return result.length ? result : beforeGroupFooterItems            },            _getAllItems: function(data) {                var that = this,                    d = $.Deferred(),                    dataController = this.getController("data"),                    footerItems = dataController.footerItems(),                    totalItem = footerItems.length && footerItems[0],                    summaryTotalItems = that.option("summary.totalItems"),                    summaryCells,                    summaryItems;                dataController.loadAll(data).done(function(sourceItems, totalAggregates) {                    if (that._hasSummaryGroupFooters())                        sourceItems = that._getItemsWithSummaryGroupFooters(sourceItems);                    summaryCells = totalItem && totalItem.summaryCells;                    if (utils.isDefined(totalAggregates) && summaryTotalItems)                        summaryCells = dataController._getSummaryCells(summaryTotalItems, totalAggregates);                    summaryItems = totalItem && that._getFooterSummaryItems(summaryCells, true);                    if (summaryItems)                        sourceItems = sourceItems.concat(summaryItems);                    d.resolve(sourceItems)                }).fail(d.reject);                return d            },            _getSelectedItems: function() {                var selectionController = this.getController("selection"),                    selectedRowData = selectionController.getSelectedRowsData();                return this._getAllItems(selectedRowData)            },            _getStartEndValueIndexces: function(visibleColumns) {                var i,                    startIndex,                    endIndex,                    visibleColumnslength = visibleColumns.length;                for (i = 0; i < visibleColumnslength; i++)                    if (!utils.isDefined(visibleColumns[i].command)) {                        startIndex = i;                        break                    }                for (i = visibleColumnslength - 1; i >= 0; i--)                    if (!utils.isDefined(visibleColumns[i].command)) {                        endIndex = i;                        break                    }                return {                        startIndex: startIndex,                        endIndex: endIndex                    }            },            init: function() {                this._columnsController = this.getController("columns");                this._rowsView = this.getView("rowsView");                this.createAction("onExporting", {excludeValidators: ["disabled", "readOnly"]});                this.createAction("onExported", {excludeValidators: ["disabled", "readOnly"]});                this._clientExporter = new DX.dxClientExporter({                    exportingAction: this.getAction("onExporting"),                    exportedAction: this.getAction("onExported")                })            },            optionChanged: function(args) {                this.callBase(args);                if (args.name === "onExporting")                    this._clientExporter.option("exportingAction", this.getAction(args.name));                if (args.name === "onExported")                    this._clientExporter.option("exportedAction", this.getAction(args.name))            },            callbackNames: function() {                return ['selectionOnlyChanged']            },            getExportFormat: function() {                return ["EXCEL"]            },            getDataProvider: function() {                var groupColumns = this._columnsController.getGroupColumns(),                    startEndIndexces = this._getStartEndValueIndexces(this._columnsController.getVisibleColumns());                return new dataGrid.DataProvider({                        columns: this._getColumns(),                        groupColumns: groupColumns,                        items: !!this._selectionOnly ? this._getSelectedItems() : this._getAllItems(),                        getVisibleIndex: $.proxy(this._columnsController.getVisibleIndex, this._columnsController),                        startValueIndex: startEndIndexces.startIndex,                        endValueIndex: startEndIndexces.endIndex,                        isHeadersVisible: this.option("showColumnHeaders"),                        summaryTexts: this.option("summary.texts")                    })            },            exportToExcel: function(selectionOnly) {                this._selectionOnly = selectionOnly;                var excelWrapTextEnabled = this.option("export.excelWrapTextEnabled");                utils.isDefined(this._clientExporter) && this._clientExporter.exportTo({                    fileName: this.option("export.fileName"),                    proxyUrl: this.option("export.proxyUrl"),                    format: "EXCEL",                    wrapTextEnabled: utils.isDefined(excelWrapTextEnabled) ? excelWrapTextEnabled : !!this.option("wordWrapEnabled"),                    autoFilterEnabled: !!this.option("export.excelFilterEnabled"),                    component: this.component                })            },            publicMethods: function() {                return ["getDataProvider", "getExportFormat", "exportToExcel"]            },            selectionOnly: function(value) {                if (utils.isDefined(value)) {                    this._isSelectedRows = value;                    this.selectionOnlyChanged.fire()                }                else                    return this._isSelectedRows            }        });        dataGrid.registerModule("export", {            defaultOptions: function() {                return {"export": {                            enabled: false,                            fileName: "DataGrid",                            excelFilterEnabled: false,                            excelWrapTextEnabled: undefined,                            proxyUrl: undefined,                            allowExportSelectedData: false,                            texts: {                                exportTo: Globalize.localize("dxDataGrid-exportTo"),                                exportToExcel: Globalize.localize("dxDataGrid-exportToExcel"),                                excelFormat: Globalize.localize("dxDataGrid-excelFormat"),                                selectedRows: Globalize.localize("dxDataGrid-selectedRows")                            }                        }}            },            controllers: {"export": dataGrid.ExportController},            extenders: {views: {headerPanel: {                        _isExportButtonVisible: function() {                            return this.option("export.enabled")                        },                        _getButtonOptions: function() {                            var that = this,                                texts = that.option("export.texts");                            return that.option("export.allowExportSelectedData") ? {                                    hint: texts.exportTo,                                    icon: DATAGRID_EXPORT_ICON                                } : {                                    hint: texts.exportToExcel,                                    icon: DATAGRID_EXPORT_EXCEL_BUTTON_ICON,                                    onClick: function() {                                        that._exportController.exportToExcel()                                    }                                }                        },                        _renderExportButton: function() {                            var that = this;                            utils.isDefined(that._$exportButton) && that._$exportButton.remove();                            if (that.option("export.enabled")) {                                that._$exportButton = $("<div>").addClass(DATAGRID_EXPORT_BUTTON_CLASS).dxButton(that._getButtonOptions());                                that.element().append(that._$exportButton)                            }                        },                        _renderExportMenu: function() {                            var that = this,                                texts = that.option("export.texts"),                                menuItems = [{                                        text: texts.excelFormat,                                        icon: DATAGRID_EXPORT_EXCEL_ICON                                    }];                            utils.isDefined(that._exportContextMenu) && that._exportContextMenu.element().remove();                            if (that.option("export.enabled") && that.option("export.allowExportSelectedData")) {                                menuItems.push({                                    value: "selectionOnly",                                    template: function() {                                        var $selectionOnlyEditor = $("<div>").addClass(DATAGRID_CHECKBOX_SIZE).dxCheckBox({                                                text: texts.selectedRows,                                                value: !!that._exportController.selectionOnly(),                                                onValueChanged: function(e) {                                                    that._exportController.selectionOnly(e.value)                                                }                                            });                                        return $selectionOnlyEditor                                    },                                    beginGroup: true,                                    closeMenuOnClick: false                                });                                that._exportContextMenu = $("<div>").dxContextMenu({                                    alternativeInvocationMode: {                                        enabled: true,                                        invokingElement: that._$exportButton                                    },                                    items: menuItems,                                    cssClass: DATAGRID_EXPORT_MENU_CLASS,                                    onItemClick: function(e) {                                        if (e.itemData.text && e.itemData.text.indexOf("Excel") > -1)                                            that._exportController.exportToExcel(that._exportController.selectionOnly())                                    },                                    target: this._$exportButton,                                    position: {                                        at: "left bottom",                                        my: "left top",                                        offset: "0 3"                                    }                                }).appendTo(that.component.element()).dxContextMenu("instance")                            }                        },                        _renderCore: function() {                            this.callBase();                            this._renderExportButton();                            this._renderExportMenu()                        },                        optionChanged: function(args) {                            this.callBase(args);                            if (args.name === "export") {                                args.handled = true;                                this.render()                            }                        },                        init: function() {                            this.callBase();                            this._exportController = this.getController("export")                        },                        isVisible: function() {                            return this.callBase() || this._isExportButtonVisible()                        }                    }}}        });        $.extend(dataGrid.__internals, {            DATAGRID_EXPORT_MENU_CLASS: DATAGRID_EXPORT_MENU_CLASS,            DATAGRID_EXPORT_BUTTON_CLASS: DATAGRID_EXPORT_BUTTON_CLASS        })    })(jQuery, DevExpress);    /*! Module widgets-web, file ui.pivotGrid.js */    (function($, DX) {        var ui = DX.ui,            events = ui.events,            utils = DX.utils;        function mergeArraysByMaxValue(values1, values2) {            var result = [],                i;            for (i = 0; i < values1.length; i++)                result.push(Math.max(values1[i] || 0, values2[i] || 0));            return result        }        var getScrollBarInfo = function(rootElement, useNativeScrolling) {                var scrollBarWidth = 0,                    scrollBarUseNative,                    options = {};                var container = $('<div>').css({                        position: 'absolute',                        visibility: 'hidden',                        width: 100,                        height: 100                    }).appendTo(rootElement);                var content = $('<p>').css({                        width: '100%',                        height: 200                    }).appendTo(container);                if (useNativeScrolling !== 'auto') {                    options.useNative = !!useNativeScrolling;                    options.useSimulatedScrollbar = !useNativeScrolling                }                container.dxScrollable(options);                scrollBarUseNative = container.dxScrollable('instance').option('useNative');                scrollBarWidth = scrollBarUseNative ? container.width() - content.width() : 0;                container.remove();                return {                        scrollBarWidth: scrollBarWidth,                        scrollBarUseNative: scrollBarUseNative                    }            };        DX.registerComponent("dxPivotGrid", ui, ui.Widget.inherit({            _setDefaultOptions: function() {                this.callBase();                this.option({                    useNativeScrolling: "auto",                    encodeHtml: true,                    descriptions: null,                    dataSource: null,                    activeStateEnabled: false,                    fieldChooser: {                        enabled: true,                        layout: 0,                        title: Globalize.localize("dxPivotGrid-fieldChooserTitle"),                        width: 600,                        height: 600                    },                    onContextMenuPreparing: null,                    allowSorting: false,                    allowSortingBySummary: false,                    allowFiltering: false,                    allowExpandAll: false,                    showRowTotals: true,                    showRowGrandTotals: true,                    showColumnTotals: true,                    showColumnGrandTotals: true,                    loadPanel: {                        enabled: true,                        text: Globalize.localize("Loading"),                        width: 200,                        height: 70,                        showIndicator: true,                        indicatorSrc: "",                        showPane: true                    },                    texts: {                        grandTotal: Globalize.localize("dxPivotGrid-grandTotal"),                        total: Globalize.localize("dxPivotGrid-total"),                        noData: Globalize.localize("dxDataGrid-noDataText"),                        showFieldChooser: Globalize.localize("dxPivotGrid-showFieldChooser"),                        expandAll: Globalize.localize("dxPivotGrid-expandAll"),                        collapseAll: Globalize.localize("dxPivotGrid-collapseAll"),                        sortColumnBySummary: Globalize.localize("dxPivotGrid-sortColumnBySummary"),                        sortRowBySummary: Globalize.localize("dxPivotGrid-sortRowBySummary"),                        removeAllSorting: Globalize.localize("dxPivotGrid-removeAllSorting")                    },                    onCellClick: null,                    onCellPrepared: null,                    onExpandValueChanging: null,                    renderCellCountLimit: 20000                })            },            _initDataController: function() {                var that = this;                if (that._dataController)                    that._dataController.dispose();                that._dataController = new pivotGrid.DataController({                    descriptions: that.option('descriptions'),                    dataSource: that.option('dataSource'),                    texts: that.option('texts'),                    showRowTotals: that.option('showRowTotals'),                    showRowGrandTotals: that.option('showRowGrandTotals'),                    showColumnTotals: that.option('showColumnTotals'),                    showColumnGrandTotals: that.option('showColumnGrandTotals'),                    onFieldsPrepared: function(fields) {                        $.each(fields, function(index, field) {                            $.each(["allowSorting", "allowSortingBySummary", "allowFiltering", "allowExpandAll"], function(_, optionName) {                                if (field[optionName] === undefined)                                    field[optionName] = that.option(optionName)                            })                        })                    }                });                that._dataController.changed.add(function() {                    that._render()                });                that._dataController.loadingChanged.add(function() {                    that._updateLoading()                });                var expandValueChanging = that.option('onExpandValueChanging');                if (expandValueChanging)                    that._dataController.expandValueChanging.add(function(e) {                        expandValueChanging(e)                    })            },            _init: function() {                var that = this;                that.callBase();                that._initDataController();                that._scrollLeft = 0;                that._scrollTop = 0            },            _optionChanged: function(args) {                var that = this;                switch (args.name) {                    case"dataSource":                    case"descriptions":                    case"texts":                    case"showRowTotals":                    case"showRowGrandTotals":                    case"showColumnTotals":                    case"showColumnGrandTotals":                    case"showColumnGrandTotals":                    case"allowSorting":                    case"allowFiltering":                        that._initDataController();                        that._invalidate();                        break;                    case"useNativeScrolling":                    case"encodeHtml":                    case"renderCellCountLimit":                        that._invalidate();                        break;                    case"rtlEnabled":                        that.callBase(args);                        that._renderFieldChooser();                        that._renderContextMenu();                        that._renderLoadPanel(that._dataArea.groupElement());                        that._invalidate();                        break;                    case"onCellClick":                    case"onExpandValueChanging":                    case"onCellPrepared":                    case"onContextMenuPreparing":                    case"allowSortingBySummary":                    case"allowExpandAll":                        break;                    case"fieldChooser":                        that._renderFieldChooser();                        break;                    case"loadPanel":                        that._renderLoadPanel(that._dataArea.groupElement());                        that._invalidate();                        break;                    default:                        that.callBase(args)                }            },            _updateScrollPosition: function(columnsArea, rowsArea, dataArea) {                var that = this,                    setScrollPos = function(area, pos) {                        var scrollable;                        if (area) {                            scrollable = area.groupElement().data('dxScrollable');                            if (scrollable) {                                scrollable.scrollTo(pos);                                scrollable.update()                            }                        }                    };                if (rowsArea && !rowsArea.hasScroll())                    that._scrollTop = 0;                if (columnsArea && !columnsArea.hasScroll())                    that._scrollLeft = 0;                setScrollPos(dataArea, {                    x: that._scrollLeft,                    y: that._scrollTop                });                setScrollPos(columnsArea, that._scrollLeft);                setScrollPos(rowsArea, that._scrollTop)            },            _subscribeToEvents: function(columnsArea, rowsArea, dataArea) {                var that = this,                    subscribeToScrollEvent = function(area, handler) {                        var scrollable = area.groupElement().data('dxScrollable');                        if (scrollable) {                            scrollable.option('onScroll', handler);                            scrollable.option('onStop', handler)                        }                    };                subscribeToScrollEvent(dataArea, function(e) {                    var scrollOffset = e.scrollOffset;                    if (that._scrollLeft !== scrollOffset.left || that._scrollTop !== scrollOffset.top) {                        that._scrollLeft = Math.floor(e.scrollOffset.left);                        that._scrollTop = Math.floor(e.scrollOffset.top);                        that._updateScrollPosition(columnsArea, rowsArea, null)                    }                })            },            _clean: $.noop,            _needDelayResizing: function() {                var cells = this._dataController.getCellsInfo(),                    cellsCount = cells.length * (cells.length ? cells[0].length : 0);                return cellsCount > this.option("renderCellCountLimit")            },            _renderFieldChooser: function() {                var that = this,                    container = that._pivotGridContainer,                    fieldChooserOptions = that.option("fieldChooser") || {};                var popupOptions = {                        visible: false,                        shading: false,                        title: fieldChooserOptions.title,                        width: fieldChooserOptions.width,                        height: fieldChooserOptions.height,                        showCloseButton: true,                        rtlEnabled: that.option('rtlEnabled'),                        onShown: function(e) {                            var popup = e.component,                                $content = e.component.content();                            that._createComponent($content, "dxPivotGridFieldChooser", {                                layout: fieldChooserOptions.layout,                                texts: fieldChooserOptions.texts || {},                                dataSource: that.getDataSource(),                                width: undefined,                                height: undefined                            });                            that._createComponent($content.parent(), "dxResizable", {                                handles: that.option('rtlEnabled') ? "left bottom" : "right bottom",                                onResize: function(e) {                                    popup._setContentHeight();                                    $content.dxPivotGridFieldChooser("updateDimensions")                                }                            })                        }                    };                if (that._fieldChooserPopup)                    that._fieldChooserPopup.option(popupOptions);                else                    that._fieldChooserPopup = that._createComponent($('<div>').addClass('dx-fieldchooser-popup').appendTo(container), "dxPopup", popupOptions)            },            _renderContextMenu: function() {                var that = this,                    $container = that._pivotGridContainer;                if (that._contextMenu)                    that._contextMenu.element().remove();                that._contextMenu = that._createComponent($("<div>").appendTo($container), "dxContextMenu", {                    onPositioning: function(actionArgs) {                        var event = actionArgs.jQueryEvent,                            cellElement = event.target.cellIndex >= 0 ? event.target : $(event.target).closest('td').get(0),                            cellArgs = that._createCellArgs(cellElement),                            items = that._getContextMenuItems(cellArgs);                        if (items)                            actionArgs.component.option('items', items);                        else                            actionArgs.canceled = true                    },                    onItemClick: function(params) {                        params.itemData.onItemClick && params.itemData.onItemClick(params)                    },                    cssClass: pivotGrid.cssClassNames.pivotGrid,                    target: that.element()                })            },            _getContextMenuItems: function(e) {                var that = this,                    onContextMenuPreparing = that.option("onContextMenuPreparing"),                    items = [];                if (e.area === "row" || e.area === "column") {                    var areaFields = e[e.area + "Fields"],                        oppositeAreaFields = e[e.area === "column" ? "rowFields" : "columnFields"],                        field = e.cell.path && areaFields[e.cell.path.length - 1],                        dataSource = that.getDataSource();                    if (field && field.allowExpandAll && e.cell.path.length < e[e.area + "Fields"].length && e.cell.type === "D") {                        items.push({                            beginGroup: true,                            icon: "none",                            text: that.option("texts.expandAll"),                            onItemClick: function() {                                dataSource.expandAll(field.index)                            }                        });                        items.push({                            text: that.option("texts.collapseAll"),                            icon: "none",                            onItemClick: function() {                                dataSource.collapseAll(field.index)                            }                        })                    }                    if (e.cell.isLast) {                        var sortingBySummaryItemCount = 0;                        $.each(oppositeAreaFields, function(index, field) {                            if (field.allowSortingBySummary)                                $.each(e.dataFields, function(dataIndex, dataField) {                                    if (utils.isDefined(e.cell.dataIndex) && e.cell.dataIndex !== dataIndex)                                        return;                                    var showDataFieldCaption = !utils.isDefined(e.cell.dataIndex) && e.dataFields.length > 1,                                        textFormat = that.option(e.area === "column" ? "texts.sortColumnBySummary" : "texts.sortRowBySummary"),                                        checked = pivotGrid.findField(e.dataFields, field.sortBySummaryField) === dataIndex && (e.cell.path || []).join("/") === (field.sortBySummaryPath || []).join("/"),                                        text = utils.stringFormat(textFormat, showDataFieldCaption ? field.caption + " - " + dataField.caption : field.caption);                                    items.push({                                        beginGroup: sortingBySummaryItemCount === 0,                                        icon: checked ? field.sortOrder === "desc" ? "desc" : "asc" : "none",                                        text: text,                                        onItemClick: function() {                                            dataSource.field(field.index, {                                                sortBySummaryField: dataField.caption || dataField.dataField,                                                sortBySummaryPath: e.cell.path,                                                sortOrder: field.sortOrder === "desc" ? "asc" : "desc"                                            });                                            dataSource.load()                                        }                                    });                                    sortingBySummaryItemCount++                                })                        });                        $.each(oppositeAreaFields, function(index, field) {                            if (field.allowSortingBySummary && utils.isDefined(field.sortBySummaryField)) {                                items.push({                                    beginGroup: sortingBySummaryItemCount === 0,                                    icon: "none",                                    text: that.option("texts.removeAllSorting"),                                    onItemClick: function() {                                        $.each(oppositeAreaFields, function(index, field) {                                            dataSource.field(field.index, {                                                sortBySummaryField: undefined,                                                sortBySummaryPath: undefined,                                                sortOrder: undefined                                            })                                        });                                        dataSource.load()                                    }                                });                                return false                            }                        })                    }                }                if (that.option("fieldChooser.enabled"))                    items.push({                        beginGroup: true,                        icon: "field-chooser",                        text: that.option("texts.showFieldChooser"),                        onItemClick: function() {                            that._fieldChooserPopup.show()                        }                    });                if (onContextMenuPreparing) {                    e.items = items;                    onContextMenuPreparing(e);                    items = e.items                }                if (items && items.length)                    return items            },            _createCellArgs: function(cellElement) {                var that = this,                    $cellElement = $(cellElement),                    columnIndex = cellElement.cellIndex,                    rowIndex = cellElement.parentElement.rowIndex,                    $table = $cellElement.closest('table'),                    area = $table.data("area"),                    data = $table.data("data"),                    cell = data && data[rowIndex] && data[rowIndex][columnIndex],                    args = {                        area: area,                        rowFields: that.getDataSource().getAreaFields("row"),                        columnFields: that.getDataSource().getAreaFields("column"),                        dataFields: that.getDataSource().getAreaFields("data"),                        rowIndex: rowIndex,                        columnIndex: columnIndex,                        cellElement: $cellElement,                        cell: cell                    };                return args            },            _handleCellClick: function(e) {                var that = this,                    onCellClick = that.option('onCellClick'),                    args = that._createCellArgs(e.currentTarget);                if (!args.area && (args.rowIndex || args.columnIndex))                    return;                if (onCellClick)                    onCellClick(args);                if (!args.handled)                    if (!args.area && that.option("fieldChooser.enabled"))                        that._fieldChooserPopup.show()            },            _getNoDataText: function() {                return this.option("texts.noData")            },            _updateNoDataText: DX.ui.dxDataGrid.RowsView.prototype._updateNoDataText,            _renderLoadPanel: DX.ui.dxDataGrid.RowsView.prototype._renderLoadPanel,            _updateLoading: function() {                var that = this;                that._loadPanel && that._loadPanel.option("visible", that._dataController.isLoading())            },            _renderContentImpl: function() {                var that = this,                    columnsAreaElement = $('<td>'),                    rowsAreaElement = $('<td>'),                    dataAreaElement = $('<td>'),                    tableElement = $('<table>'),                    dataArea = that._dataArea || new pivotGrid.DataArea(that),                    rowsArea = (that._rowsArea || new pivotGrid.VerticalHeadersArea(that)).setDataController(that._dataController),                    columnsArea = (that._columnsArea || new pivotGrid.HorizontalHeadersArea(that)).setDataController(that._dataController),                    scrollBarInfo = getScrollBarInfo(that.element(), that.option("useNativeScrolling"));                that._scrollBarWidth = scrollBarInfo.scrollBarWidth;                that._scrollBarUseNative = scrollBarInfo.scrollBarUseNative;                if (!utils.isDefined(that._pivotGridContainer)) {                    that._pivotGridContainer = $('<div>');                    that._renderFieldChooser();                    that._renderContextMenu();                    $('<tr>').append($('<td>').addClass(pivotGrid.cssClassNames.areaDescription)).append(columnsAreaElement).appendTo(tableElement);                    $('<tr>').addClass(pivotGrid.cssClassNames.bottomAraesRow).append(rowsAreaElement).append(dataAreaElement).appendTo(tableElement);                    tableElement.appendTo(that._pivotGridContainer);                    tableElement.on(events.addNamespace("dxclick", "dxPivotGrid"), 'td', $.proxy(that, "_handleCellClick"))                }                else                    tableElement = that._pivotGridContainer.children().first();                that._rowsArea = rowsArea;                that._columnsArea = columnsArea;                that._dataArea = dataArea;                columnsArea.render(columnsAreaElement, that._dataController.getColumnsInfo());                rowsArea.render(rowsAreaElement, that._dataController.getRowsInfo());                dataArea.render(dataAreaElement, that._dataController.getCellsInfo());                dataArea.tableElement().prepend(columnsArea.headElement());                var updateHandler = function() {                        that.updateDimensions();                        that._subscribeToEvents(columnsArea, rowsArea, dataArea)                    };                if (!utils.isDefined(that._pivotGridContainer[0].parentElement)) {                    that._hasHeight = that.element().height() > 0;                    that._pivotGridContainer.appendTo(that.element());                    that.element().addClass(pivotGrid.cssClassNames.pivotGrid).addClass(pivotGrid.cssClassNames.rowLines);                    that._renderLoadPanel(dataArea.groupElement());                    rowsArea.processScroll();                    columnsArea.processScroll();                    if (that._needDelayResizing())                        setTimeout(updateHandler);                    else                        updateHandler()                }                else                    updateHandler()            },            _fireContentReadyAction: function() {                if (!this._dataController.isLoading())                    this.callBase()            },            getScrollPath: function(area) {                var that = this,                    i,                    currentScrollPosition = 0,                    scrollPosition,                    columnSizes;                if (area === 'column') {                    scrollPosition = that._scrollLeft;                    columnSizes = that._columnsArea.getColumnsWidth()                }                else {                    scrollPosition = that._scrollTop;                    columnSizes = that._rowsArea.getRowsHeight()                }                for (i = 0; i < columnSizes.length; i++) {                    if (scrollPosition < currentScrollPosition + columnSizes[i] / 2)                        return that._dataController.getHeaderItemPath(area, i);                    currentScrollPosition += columnSizes[i]                }            },            getDataSource: function() {                return this._dataController.getDataSource()            },            hasScroll: function(area) {                var that = this;                if (area === 'column')                    return that._columnsArea.hasScroll();                else                    return that._rowsArea.hasScroll()            },            _dimensionChanged: function() {                this.updateDimensions()            },            _visibilityChanged: function(visible) {                if (visible)                    this.updateDimensions()            },            _dispose: function() {                var that = this;                that.callBase.apply(that, arguments);                if (that._dataController)                    that._dataController.dispose()            },            resize: function() {                this.updateDimensions()            },            updateDimensions: function() {                var that = this,                    diff,                    groupWidth,                    groupHeight,                    tableElement = that.element().find('table').first(),                    bottomAraesRowElement,                    rowsArea = that._rowsArea,                    columnsArea = that._columnsArea,                    dataArea = that._dataArea,                    dataAreaHeights,                    rowsAreaHeights,                    resultHeights,                    resultWidths,                    rowsAreaColumnWidths,                    totalWidth = 0,                    totalHeight = 0,                    hasRowsScroll,                    hasColumnsScroll,                    dataFields = that.getDataSource().getAreaFields("data"),                    loadPanelOptions = that.option("loadPanel") || {},                    minHeight,                    scrollBarWidth = that._scrollBarWidth || 0;                if (!dataArea.headElement().length) {                    dataArea.tableElement().prepend(columnsArea.headElement());                    dataArea.resetColumnsWidth()                }                resultWidths = dataArea.getColumnsWidth();                rowsAreaHeights = rowsArea.getRowsHeight();                dataAreaHeights = dataArea.getRowsHeight();                resultHeights = mergeArraysByMaxValue(rowsAreaHeights, dataAreaHeights.slice(dataAreaHeights.length - rowsAreaHeights.length));                rowsAreaColumnWidths = rowsArea.getColumnsWidth();                diff = that.element().width() - tableElement.width();                groupWidth = Math.floor(dataArea.groupWidth() + diff);                if (that._hasHeight) {                    diff = that.element().height() - tableElement.height() - dataArea.headElement().height();                    bottomAraesRowElement = tableElement.find('.' + pivotGrid.cssClassNames.bottomAraesRow),                    groupHeight = Math.floor(bottomAraesRowElement.height() + diff)                }                totalWidth = dataArea.tableElement().width();                $.each(resultHeights, function(index, height) {                    totalHeight += height || 0                });                hasRowsScroll = groupHeight < totalHeight;                hasColumnsScroll = groupWidth < totalWidth;                if (!hasRowsScroll)                    groupHeight = totalHeight + (hasColumnsScroll ? scrollBarWidth : 0);                columnsArea.tableElement().append(dataArea.headElement());                if (resultHeights.length === 1 && loadPanelOptions.enabled && loadPanelOptions.height) {                    minHeight = loadPanelOptions.height + 50;                    if (resultHeights[0] < minHeight) {                        resultHeights[0] = minHeight;                        if (groupHeight < minHeight)                            groupHeight = minHeight                    }                }                columnsArea.groupWidth(groupWidth);                columnsArea.processScrollBarSpacing(hasRowsScroll ? scrollBarWidth : 0);                columnsArea.processStretch(resultWidths, hasColumnsScroll, dataFields);                columnsArea.setColumnsWidth(resultWidths);                rowsArea.groupHeight(groupHeight);                rowsArea.processScrollBarSpacing(hasColumnsScroll ? scrollBarWidth : 0);                rowsArea.setColumnsWidth(rowsAreaColumnWidths);                rowsArea.setRowsHeight(resultHeights);                dataArea.setColumnsWidth(resultWidths);                dataArea.setRowsHeight(resultHeights);                dataArea.groupWidth(groupWidth);                dataArea.groupHeight(groupHeight);                dataArea.groupElement().css('border-bottom-width', hasRowsScroll || scrollBarWidth ? '0px' : '');                rowsArea.groupElement().css('border-bottom-width', hasRowsScroll && !scrollBarWidth ? '0px' : '');                dataArea.processScroll(scrollBarWidth, hasRowsScroll, hasColumnsScroll, that._scrollBarUseNative);                that._updateNoDataText(dataArea.groupElement());                that._updateLoading();                that._updateScrollPosition(columnsArea, rowsArea, dataArea);                that._testResultWidths = resultWidths;                that._testResultHeights = resultHeights            },            applyPartialDataSource: function(area, path, dataSource) {                this._dataController.applyPartialDataSource(area, path, dataSource)            }        }));        var pivotGrid = $.extend(ui.dxPivotGrid, {                cssClassNames: {                    pivotGrid: 'dx-pivotgrid',                    rowLines: 'dx-row-lines',                    area: 'dx-pivotgrid-area',                    areaData: 'dx-pivotgrid-area-data',                    areaDescription: 'dx-pivotgrid-area-description',                    splitter: 'dx-pivotgrid-splitter',                    splitterButton: 'dx-button',                    splitterButtonDisable: 'dx-button-disable',                    splitterExpand: 'dx-expand',                    splitterCollapse: 'dx-collapse',                    bottomAraesRow: 'dx-bottom-row',                    verticalScroll: 'dx-vertical-scroll',                    headersVertical: 'dx-pivotgrid-vertical-headers',                    headersHorizontal: 'dx-pivotgrid-horizontal-headers',                    headersVerticalLastCell: 'dx-last-cell',                    headersVerticalExpandBorder: 'dx-expand-border',                    headersExpandCollapseImage: 'dx-expand',                    headersExpanded: 'dx-pivotgrid-expanded',                    headersCollapsed: 'dx-pivotgrid-collapsed',                    bottomBorder: 'dx-pivotgrid-bottom-border',                    total: 'dx-total',                    grandTotal: 'dx-grandtotal',                    rowTotal: 'dx-row-total'                },                mergeArraysByMaxValue: mergeArraysByMaxValue            })    })(jQuery, DevExpress);    /*! Module widgets-web, file ui.pivotGrid.dataSource.js */    (function($, DX) {        var pivotGrid = DX.ui.dxPivotGrid,            utils = DX.utils,            isDefined = utils.isDefined;        var DESCRIPTION_NAME_BY_AREA = {                row: "rows",                column: "columns",                data: "values",                filter: "filters"            };        function findField(fields, id) {            var i,                field;            if (fields && utils.isDefined(id))                for (i = 0; i < fields.length; i++) {                    field = fields[i];                    if (field.name === id || field.caption === id || field.dataField === id || field.index === id)                        return i                }            return -1        }        function foreachTreeItems(items, callback, path, parentAtFirst) {            var index,                item;            if (!items)                return;            for (index = 0; index < items.length; index++) {                item = items[index];                if (item) {                    if (path)                        path.push(item.value);                    if (parentAtFirst && callback(item, path, index, items) === false)                        return false;                    if (foreachTreeItems(item.children, callback, path, parentAtFirst) === false)                        return false;                    if (!parentAtFirst && callback(item, path, index, items) === false)                        return false;                    if (path)                        path.pop()                }            }        }        function formatValue(value, options) {            var formatObject = {                    value: value,                    valueText: DX.formatHelper.format(value, options.format, options.precision) || ''                };            return options.customizeText ? options.customizeText.call(options, formatObject) : formatObject.valueText        }        function foreachDataLevel(data, callback, index, childrenField) {            var item,                i;            index = index || 0;            childrenField = childrenField || "children";            if (data.length)                callback(data, index);            for (i = 0; i < data.length; i++) {                item = data[i];                if (item[childrenField] && item[childrenField].length)                    foreachDataLevel(item[childrenField], callback, index + 1, childrenField)            }        }        function getCompareFunction(valueSelector) {            return function(a, b) {                    var result = 0;                    if (valueSelector(a) > valueSelector(b))                        result = 1;                    else if (valueSelector(a) < valueSelector(b))                        result = -1;                    return result                }        }        DX.data.PivotGridDataSource = pivotGrid.DataSource = DX.Class.inherit(function() {            var isValuesEqual = function(value1, value2) {                    return DevExpress.data.utils.toComparable(value1) === DevExpress.data.utils.toComparable(value2)                };            var findHeaderItem = function(headerItems, path) {                    var pathIndex,                        foundHeaderItems,                        headerItem = null;                    var checkHeaderItem = function(item) {                            return isValuesEqual(item.value, path[pathIndex])                        };                    if ($.isArray(path))                        for (pathIndex = 0; pathIndex < path.length && headerItems; pathIndex++) {                            foundHeaderItems = $.grep(headerItems || [], checkHeaderItem);                            if (foundHeaderItems.length === 0) {                                headerItem = null;                                break                            }                            headerItem = foundHeaderItems[0];                            headerItems = headerItem.children                        }                    return headerItem                };            var getHeaderItemsLastIndex = function(headerItems, grandTotalIndex) {                    var i,                        lastIndex = -1,                        headerItem;                    if (headerItems)                        for (i = 0; i < headerItems.length; i++) {                            headerItem = headerItems[i];                            lastIndex = Math.max(lastIndex, headerItem.index);                            if (headerItem.children)                                lastIndex = Math.max(lastIndex, getHeaderItemsLastIndex(headerItem.children));                            else if (headerItem.collapsedChildren)                                lastIndex = Math.max(lastIndex, getHeaderItemsLastIndex(headerItem.collapsedChildren))                        }                    if (isDefined(grandTotalIndex))                        lastIndex = Math.max(lastIndex, grandTotalIndex);                    return lastIndex                };            var updateHeaderItemChildren = function(headerItems, headerItem, children, grandTotalIndex) {                    var applyingHeaderItemsCount = getHeaderItemsLastIndex(children) + 1,                        emptyIndex = getHeaderItemsLastIndex(headerItems, grandTotalIndex) + 1,                        index,                        applyingItemIndexesToCurrent = [];                    for (index = 0; index < applyingHeaderItemsCount; index++)                        applyingItemIndexesToCurrent[index] = emptyIndex++;                    headerItem.children = [];                    $.extend(true, headerItem.children, children);                    foreachTreeItems(headerItem.children, function(item) {                        item.index = applyingItemIndexesToCurrent[item.index]                    });                    return applyingItemIndexesToCurrent                };            var updateHeaderItems = function(headerItems, newHeaderItems) {                    var applyingItemIndexesToCurrent = [];                    foreachTreeItems(headerItems, function(headerItem) {                        delete headerItem.collapsedChildren                    });                    foreachTreeItems(newHeaderItems, function(newHeaderItem, path) {                        var headerItem = findHeaderItem(headerItems, path);                        if (headerItem)                            applyingItemIndexesToCurrent[newHeaderItem.index] = headerItem.index                    }, []);                    return applyingItemIndexesToCurrent                };            var updateDataSourceCells = function(dataSource, newDataSourceCells, newRowItemIndexesToCurrent, newColumnItemIndexesToCurrent) {                    var newRowIndex,                        newColumnIndex,                        newRowCells,                        newCell,                        rowIndex,                        columnIndex,                        dataSourceCells = dataSource.values;                    if (newDataSourceCells)                        for (newRowIndex = 0; newRowIndex <= newDataSourceCells.length; newRowIndex++) {                            newRowCells = newDataSourceCells[newRowIndex];                            rowIndex = newRowItemIndexesToCurrent[newRowIndex];                            if (!isDefined(rowIndex))                                rowIndex = dataSource.grandTotalRowIndex;                            if (newRowCells && isDefined(rowIndex)) {                                if (!dataSourceCells[rowIndex])                                    dataSourceCells[rowIndex] = [];                                for (newColumnIndex = 0; newColumnIndex <= newRowCells.length; newColumnIndex++) {                                    newCell = newRowCells[newColumnIndex];                                    columnIndex = newColumnItemIndexesToCurrent[newColumnIndex];                                    if (!isDefined(columnIndex))                                        columnIndex = dataSource.grandTotalColumnIndex;                                    if (isDefined(newCell) && isDefined(columnIndex))                                        dataSourceCells[rowIndex][columnIndex] = newCell                                }                            }                        }                };            function createStore(dataSourceOptions) {                var store,                    storeOptions;                if ($.isPlainObject(dataSourceOptions) && dataSourceOptions.load)                    store = new pivotGrid.LocalStore(dataSourceOptions);                else {                    if (dataSourceOptions && !dataSourceOptions.store)                        dataSourceOptions = {store: dataSourceOptions};                    storeOptions = dataSourceOptions.store;                    if (storeOptions.type === "xmla")                        store = new pivotGrid.XmlaStore(storeOptions);                    else if ($.isPlainObject(storeOptions) && storeOptions.type || storeOptions instanceof DX.data.Store || $.isArray(storeOptions))                        store = new pivotGrid.LocalStore(dataSourceOptions);                    else if (storeOptions instanceof DX.Class)                        store = storeOptions                }                return store            }            function getExpandedPaths(dataSource, loadOptions, dimentionName) {                var result = [],                    fields = loadOptions[dimentionName];                foreachTreeItems(dataSource[dimentionName], function(item, path) {                    if (item.children && fields[path.length - 1] && !fields[path.length - 1].expanded)                        path.length < fields.length && result.push(path.slice())                }, [], true);                if (result.length)                    return result            }            function getFieldsByGroup(fields, grouppingField) {                return $.map(fields, function(field) {                        if (field.groupName === grouppingField.groupName && utils.isNumber(field.groupIndex) && field.visible !== false)                            return $.extend(field, {                                    areaIndex: grouppingField.areaIndex,                                    area: grouppingField.area,                                    dataField: field.dataField || grouppingField.dataField,                                    dataType: field.dataType || grouppingField.dataType,                                    sortBy: field.sortBy || grouppingField.sortBy,                                    sortOrder: field.sortOrder || grouppingField.sortOrder,                                    sortBySummaryField: field.sortBySummaryField || grouppingField.sortBySummaryField,                                    sortBySummaryPath: field.sortBySummaryPath || grouppingField.sortBySummaryPath,                                    visible: field.visible || grouppingField.visible                                });                        return null                    }).sort(function(a, b) {                        return a.groupIndex - b.groupIndex                    })            }            function createDescriptions(fields, currentField) {                var descriptions = {                        rows: [],                        columns: [],                        values: [],                        filters: []                    };                $.each(fields || [], function(_, field) {                    var descriptionName = DESCRIPTION_NAME_BY_AREA[field.area],                        dimension = descriptions[descriptionName],                        groupName = field.groupName;                    if (groupName && !utils.isNumber(field.groupIndex)) {                        if (currentField && groupName === currentField.groupName)                            currentField = field;                        field.levels = getFieldsByGroup(fields, field)                    }                    if (!dimension || groupName && utils.isNumber(field.groupIndex) || field.visible === false)                        return;                    if (field.levels && dimension !== descriptions.filters) {                        dimension.push.apply(dimension, field.levels);                        if (field.filterValues && field.filterValues.length)                            descriptions.filters.push(field)                    }                    else                        dimension.push(field)                });                $.each(descriptions, function(_, fields) {                    utils.normalizeIndexes(fields, 'areaIndex', currentField);                    fields.sort(function(field1, field2) {                        return field1.areaIndex - field2.areaIndex                    })                });                return descriptions            }            function getFieldId(field) {                return (field.dataField || field.groupName || '') + (field.groupInterval ? field.groupName || '' : "NOGROUP") + (field.groupInterval || '') + (field.summaryType || '')            }            function mergeFields(fields, storeFields, retrieveFieldsOptionValue) {                var result = [],                    fieldsDictionary = {},                    removedFields = {},                    mergedGroups = [],                    dataTypes = getFieldsDataType(fields);                if (storeFields) {                    $.each(storeFields, function(_, field) {                        fieldsDictionary[getFieldId(field)] = field                    });                    $.each(fields, function(_, field) {                        var fieldKey = getFieldId(field),                            storeField = fieldsDictionary[fieldKey] || removedFields[fieldKey],                            mergedField;                        if (storeField)                            mergedField = $.extend({}, storeField, field);                        else                            fieldsDictionary[fieldKey] = mergedField = field;                        $.extend(mergedField, {dataType: dataTypes[field.dataField]});                        delete fieldsDictionary[fieldKey];                        removedFields[fieldKey] = storeField;                        result.push(mergedField)                    });                    if (retrieveFieldsOptionValue)                        $.each(fieldsDictionary, function(_, field) {                            result.push(field)                        })                }                else                    result = fields;                result.push.apply(result, mergedGroups);                return result            }            function createCaption(field) {                var caption = field.dataField || field.groupName || "",                    summaryType = (field.summaryType || "").toLowerCase();                if (utils.isString(field.groupInterval))                    caption += "_" + field.groupInterval;                if (summaryType && summaryType !== "custom") {                    summaryType = summaryType.replace(/^./, summaryType[0].toUpperCase());                    if (caption.length)                        summaryType = " (" + summaryType + ")"                }                else                    summaryType = "";                return DX.inflector.titleize(caption) + summaryType            }            function getFieldsDataType(fields) {                var result = {};                $.each(fields, function(_, field) {                    result[field.dataField] = result[field.dataField] || field.dataType                });                return result            }            function getFields(that) {                var result = $.Deferred(),                    store = that._store,                    storeFields = store && store.getFields(getFieldsDataType(that._fields)),                    mergedFields;                $.when(storeFields).done(function(storeFields) {                    that._storeFields = storeFields;                    mergedFields = mergeFields(that._fields, storeFields, that._retrieveFields);                    result.resolve(mergedFields)                }).fail(function() {                    result.resolve(that._fields)                });                return result            }            function getSliceIndex(items, path) {                var index = null,                    pathValue = (path || []).join(".");                if (pathValue.length)                    foreachTreeItems(items, function(item, itemPath) {                        if (pathValue === itemPath.join(".")) {                            index = item.index;                            return false                        }                    }, []);                return index            }            function getFieldSummaryValueSelector(field, dataSource, loadOptions, dimensionName) {                var values = dataSource.values,                    sortBySummaryFieldIndex = findField(loadOptions.values, field.sortBySummaryField),                    areRows = dimensionName === "rows",                    sortByDimension = areRows ? dataSource.columns : dataSource.rows,                    grandTotalIndex = areRows ? dataSource.grandTotalRowIndex : dataSource.grandTotalColumnIndex,                    sortBySummaryPath = field.sortBySummaryPath || [],                    sliceIndex = sortBySummaryPath.length ? getSliceIndex(sortByDimension, sortBySummaryPath) : grandTotalIndex;                if (values && values.length && sortBySummaryFieldIndex >= 0 && isDefined(sliceIndex))                    return function(field) {                            var rowIndex = areRows ? field.index : sliceIndex,                                columnIndex = areRows ? sliceIndex : field.index;                            return ((values[rowIndex] || [[]])[columnIndex] || [])[sortBySummaryFieldIndex] || null                        }            }            function getSortingMethod(field, dataSource, loadOptions, dimensionName) {                var sortOrder = field.sortOrder,                    defaultCompare = field.sortingMethod || getCompareFunction(function(item) {                        return item.value                    }),                    summaryValueSelector = getFieldSummaryValueSelector(field, dataSource, loadOptions, dimensionName),                    summaryCompare = summaryValueSelector && getCompareFunction(summaryValueSelector),                    sortingMethod = function(a, b) {                        var result = summaryCompare && summaryCompare(a, b) || 0;                        if (result === 0)                            result = defaultCompare(a, b);                        return sortOrder === "desc" ? -result : result                    };                return sortingMethod            }            function sortDimension(dataSource, loadOptions, dimensionName) {                var fields = loadOptions[dimensionName] || [],                    baseIndex = loadOptions.headerName === dimensionName ? loadOptions.path.length : 0,                    sortingMetodByLevel = [];                foreachDataLevel(dataSource[dimensionName], function(item, index) {                    var field = fields[index] || {},                        sortingMethod = sortingMetodByLevel[index] = sortingMetodByLevel[index] || getSortingMethod(field, dataSource, loadOptions, dimensionName);                    item.sort(sortingMethod)                }, baseIndex)            }            function sort(loadOptions, dataSource) {                sortDimension(dataSource, loadOptions, "rows");                sortDimension(dataSource, loadOptions, "columns")            }            function formatHeaderItems(data, loadOptions, headerName) {                foreachTreeItems(data[headerName], function(item, path) {                    item.text = item.text || formatValue(item.value, loadOptions[headerName][path.length - 1])                }, [])            }            function formatHeaders(loadOptions, data) {                formatHeaderItems(data, loadOptions, "columns");                formatHeaderItems(data, loadOptions, "rows")            }            pivotGrid.sort = sort;            return {                    ctor: function(options) {                        options = options || {};                        var that = this,                            store = createStore(options);                        that._store = store;                        that._loadedData = {                            rows: [],                            columns: [],                            values: []                        };                        that._data = $.extend(true, {}, that._loadedData);                        that._loadingCount = 0;                        $.each(["changed", "loadError", "loadingChanged", "fieldsPrepared", "expandValueChanging"], $.proxy(function(_, eventName) {                            var optionName = "on" + eventName[0].toUpperCase() + eventName.slice(1);                            if (options.hasOwnProperty(optionName))                                this.on(eventName, options[optionName])                        }, this));                        that._localSorting = !!options.localSorting;                        that._retrieveFields = isDefined(options.retrieveFields) ? options.retrieveFields : true;                        that._fields = options.fields || [];                        that._descriptions = options.descriptions ? $.extend(createDescriptions([]), options.descriptions) : undefined;                        if (!store) {                            $.extend(true, that._loadedData, options.store || options);                            that._data = $.extend(true, {}, that._loadedData)                        }                    },                    getData: function() {                        return this._data                    },                    getAreaFields: function(area, collectGroups) {                        var areaFields = [],                            descriptions;                        if (collectGroups || area === "data") {                            $.each(this._fields, function() {                                if (this.area === area && !isDefined(this.groupIndex) && this.visible !== false)                                    areaFields.push(this)                            });                            utils.normalizeIndexes(areaFields, 'areaIndex');                            areaFields.sort(function(field1, field2) {                                return field1.areaIndex - field2.areaIndex                            })                        }                        else {                            descriptions = this._descriptions || {};                            areaFields = descriptions[DESCRIPTION_NAME_BY_AREA[area]] || []                        }                        return areaFields                    },                    fields: function(fields) {                        var that = this;                        if (fields) {                            that._fields = mergeFields(fields, that._storeFields, that._retrieveFields);                            that._fieldsPrepared(that._fields)                        }                        return that._fields                    },                    field: function(id, options) {                        var that = this,                            field = this._fields && this._fields[utils.isNumber(id) ? id : findField(this._fields, id)],                            levels;                        if (field && options) {                            $.each(options, function(optionName, optionValue) {                                field[optionName] = optionValue;                                if (optionName === "sortOrder") {                                    levels = field.levels || [];                                    for (var i = 0; i < levels.length; i++)                                        levels[i][optionName] = optionValue                                }                            });                            that._descriptions = createDescriptions(this._fields, field)                        }                        return field                    },                    getFieldValues: function(index) {                        var that = this,                            field = this._fields && this._fields[index],                            store = this.store(),                            loadFields = [],                            loadOptions = {                                columns: loadFields,                                rows: [],                                values: this.getAreaFields("data"),                                filters: [],                                localSorting: this._localSorting                            },                            d = $.Deferred();                        if (field && store) {                            $.each(field.levels || [field], function() {                                loadFields.push($.extend({}, this, {                                    expanded: true,                                    filterValues: null,                                    sortOrder: 'asc',                                    sortBySummaryField: null                                }))                            });                            store.load(loadOptions).done(function(data) {                                formatHeaders(loadOptions, data);                                that._sort(loadOptions, data);                                d.resolve(data.columns)                            }).fail(d)                        }                        else                            d.reject();                        return d                    },                    load: function(options) {                        var that = this,                            d = $.Deferred();                        options = options || {};                        that._changeLoadingCount(1);                        d.fail(function(e) {                            that.fireEvent("loadError", [e])                        }).always(function() {                            that._changeLoadingCount(-1)                        });                        that._delayedLoadTask = DX.utils.executeAsync(function() {                            that._delayedLoadTask = undefined;                            if (!that._descriptions)                                $.when(getFields(that)).done(function(fields) {                                    that._fieldsPrepared(fields);                                    that._loadCore(options, d)                                }).fail(d.reject).fail(that._loadErrorHandler);                            else                                that._loadCore(options, d)                        });                        return d                    },                    _fieldsPrepared: function(fields) {                        var that = this;                        that._fields = fields;                        $.each(fields, function(index, field) {                            field.index = index;                            if (!isDefined(field.caption))                                field.caption = createCaption(field)                        });                        that.fireEvent("fieldsPrepared", [fields]);                        that._descriptions = createDescriptions(fields)                    },                    isLoading: function() {                        return this._loadingCount > 0                    },                    _changeLoadingCount: function(increment) {                        var oldLoading = this.isLoading(),                            newLoading;                        this._loadingCount += increment;                        newLoading = this.isLoading();                        if (oldLoading ^ newLoading)                            this.fireEvent("loadingChanged", [newLoading])                    },                    _loadCore: function(options, deferred) {                        var that = this,                            store = this._store,                            descriptions = this._descriptions,                            headerName = DESCRIPTION_NAME_BY_AREA[options.area];                        options = options || {};                        if (store) {                            $.extend(options, descriptions);                            options.columnExpandedPaths = getExpandedPaths(this._loadedData, options, "columns");                            options.rowExpandedPaths = getExpandedPaths(this._loadedData, options, "rows");                            if (that._localSorting)                                options.localSorting = true;                            if (headerName)                                options.headerName = headerName;                            $.when(store.load(options)).done(function(data) {                                if (options.path)                                    that.applyPartialDataSource(options.area, options.path, data, deferred);                                else {                                    $.extend(that._loadedData, data);                                    that._update(deferred)                                }                                deferred.resolve(that._data)                            }).fail(deferred.reject)                        }                        else {                            that._update(deferred);                            deferred.resolve(that._data)                        }                    },                    _sort: function(descriptions, data) {                        var store = this._store;                        if (store && store.supportSorting && (this._localSorting || !store.supportSorting()))                            sort(descriptions, data)                    },                    _update: function(deferred) {                        var that = this;                        formatHeaders(that._descriptions, that._loadedData);                        that._sort(that._descriptions, that._loadedData);                        that._data = $.extend(true, {}, that._loadedData);                        $.when(deferred).done(function() {                            that.fireEvent("changed");                            if (utils.isDefined(that._data.grandTotalRowIndex))                                that._loadedData.grandTotalRowIndex = that._data.grandTotalRowIndex;                            if (utils.isDefined(that._data.grandTotalColumnIndex))                                that._loadedData.grandTotalColumnIndex = that._data.grandTotalColumnIndex                        })                    },                    getHeaderItemPath: function(area, visibleIndex) {                        var that = this,                            index = 0,                            result,                            headerItems = area === 'column' ? that._data.columns : that._data.rows;                        if (area === 'column' && that._descriptions.values.length > 1)                            visibleIndex = Math.floor(visibleIndex / that._descriptions.values.length);                        foreachTreeItems(headerItems, function(item, path) {                            if (index === visibleIndex) {                                result = path;                                return false                            }                            index++                        }, []);                        return result                    },                    store: function() {                        return this._store                    },                    collapseHeaderItem: function(area, path) {                        var that = this,                            headerItems = area === 'column' ? that._loadedData.columns : that._loadedData.rows,                            headerItem = findHeaderItem(headerItems, path),                            field = that.getAreaFields(area === 'columns' ? "column" : "row")[path.length - 1];                        if (headerItem && headerItem.children) {                            that.fireEvent("expandValueChanging", [{                                    area: area,                                    path: path,                                    expanded: false                                }]);                            if (field)                                field.expanded = false;                            headerItem.collapsedChildren = headerItem.children;                            delete headerItem.children;                            that._update();                            return true                        }                        return false                    },                    collapseAll: function(fieldIndex) {                        var dataChanged = false,                            field = this.fields()[fieldIndex] || {};                        field.expanded = false;                        foreachTreeItems(this._loadedData[field.area + "s"], function(item, path) {                            if (item && item.children && field.areaIndex === path.length - 1) {                                item.collapsedChildren = item.children;                                delete item.children;                                dataChanged = true                            }                        }, [], true);                        dataChanged && this._update()                    },                    expandAll: function(fieldIndex) {                        var field = this.fields()[fieldIndex];                        if (field && field.area) {                            field.expanded = true;                            this.load()                        }                    },                    expandHeaderItem: function(area, path) {                        var that = this,                            hasCache,                            headerItems = area === 'column' ? that._loadedData.columns : that._loadedData.rows,                            headerItem = findHeaderItem(headerItems, path),                            options;                        if (headerItem && !headerItem.children) {                            hasCache = !!headerItem.collapsedChildren;                            options = {                                area: area,                                path: path,                                expanded: true,                                needExpandData: !hasCache                            };                            that.fireEvent("expandValueChanging", [options]);                            if (hasCache) {                                headerItem.children = headerItem.collapsedChildren;                                delete headerItem.collapsedChildren;                                that._update()                            }                            else                                that.load(options);                            return hasCache                        }                        return false                    },                    applyPartialDataSource: function(area, path, dataSource, deferred) {                        var that = this,                            loadedData = that._loadedData,                            headerItems = area === 'column' ? loadedData.columns : loadedData.rows,                            headerItem,                            newRowItemIndexesToCurrent,                            newColumnItemIndexesToCurrent;                        if (dataSource && dataSource.values) {                            dataSource.rows = dataSource.rows || [];                            dataSource.columns = dataSource.columns || [];                            headerItem = findHeaderItem(headerItems, path);                            if (headerItem) {                                if (area === 'column') {                                    newColumnItemIndexesToCurrent = updateHeaderItemChildren(headerItems, headerItem, dataSource.columns, loadedData.grandTotalColumnIndex);                                    newRowItemIndexesToCurrent = updateHeaderItems(loadedData.rows, dataSource.rows)                                }                                else {                                    newRowItemIndexesToCurrent = updateHeaderItemChildren(headerItems, headerItem, dataSource.rows, loadedData.grandTotalRowIndex);                                    newColumnItemIndexesToCurrent = updateHeaderItems(loadedData.columns, dataSource.columns)                                }                                updateDataSourceCells(loadedData, dataSource.values, newRowItemIndexesToCurrent, newColumnItemIndexesToCurrent);                                that._update(deferred)                            }                        }                    },                    dispose: function() {                        var that = this,                            delayedLoadTask = that._delayedLoadTask;                        this._disposeEvents();                        if (delayedLoadTask)                            delayedLoadTask.abort();                        this._isDisposed = true                    },                    isDisposed: function() {                        return !!this._isDisposed                    }                }        }()).include(DX.EventsMixin);        pivotGrid.foreachTreeItems = foreachTreeItems;        pivotGrid.foreachDataLevel = foreachDataLevel;        pivotGrid.getCompareFunction = getCompareFunction;        pivotGrid.findField = findField;        pivotGrid.formatValue = formatValue    })(jQuery, DevExpress);    /*! Module widgets-web, file ui.pivotGrid.dataController.js */    (function($, DX) {        var pivotGrid = DX.ui.dxPivotGrid,            utils = DX.utils;        var DESCRIPTION_NAME_BY_AREA = {                row: "rows",                column: "columns",                data: "values",                filter: "filters"            };        pivotGrid.proxyMethod = function(instance, methodName, defaultResult) {            if (!instance[methodName])                instance[methodName] = function() {                    var dataSource = this._dataSource;                    return dataSource ? dataSource[methodName].apply(dataSource, arguments) : defaultResult                }        };        pivotGrid.DataController = DX.Class.inherit(function() {            var foreachTreeItems = pivotGrid.foreachTreeItems,                formatValue = pivotGrid.formatValue;            function getHeaderItemText(item, description, options) {                var text = item.text;                if (utils.isDefined(item.displayText))                    text = item.displayText;                else if (utils.isDefined(item.caption))                    text = item.caption;                else if (item.type === 'GT')                    text = options.texts.grandTotal;                if (item.isAdditionalTotal)                    text = utils.stringFormat(options.texts.total || '', text);                return text            }            var createHeaderInfo = function() {                    var getHeaderItemsDepth = function(headerItems) {                            var depth = 0;                            foreachTreeItems(headerItems, function(item, path) {                                depth = Math.max(depth, path.length)                            }, []);                            return depth                        };                    var createInfoItem = function(headerItem, breadth, isHorizontal) {                            var infoItem = {                                    type: headerItem.type,                                    text: headerItem.text                                };                            if (headerItem.path)                                infoItem.path = headerItem.path;                            if (headerItem.width)                                infoItem.width = headerItem.width;                            if (headerItem.isLast)                                infoItem.isLast = true;                            if (headerItem.sorted)                                infoItem.sorted = true;                            if (headerItem.isMetric)                                infoItem.dataIndex = headerItem.dataIndex;                            if (utils.isDefined(headerItem.expanded))                                infoItem.expanded = headerItem.expanded;                            if (breadth > 1)                                infoItem[isHorizontal ? 'colspan' : 'rowspan'] = breadth;                            if (headerItem.depthSize && headerItem.depthSize > 1)                                infoItem[isHorizontal ? 'rowspan' : 'colspan'] = headerItem.depthSize;                            return infoItem                        };                    var addInfoItem = function(info, options) {                            var itemInfo,                                breadth = options.lastIndex - options.index || 1,                                addInfoItemCore = function(info, infoItem, itemIndex, depthIndex, isHorizontal) {                                    var index = isHorizontal ? depthIndex : itemIndex;                                    while (!info[index])                                        info.push([]);                                    if (isHorizontal)                                        info[index].push(infoItem);                                    else                                        info[index].unshift(infoItem)                                };                            itemInfo = createInfoItem(options.headerItem, breadth, options.isHorizontal);                            addInfoItemCore(info, itemInfo, options.index, options.depth, options.isHorizontal);                            if (!options.headerItem.children || options.headerItem.children.length === 0)                                return options.lastIndex + 1;                            return options.lastIndex                        };                    var getViewHeaderItems = function(headerItems, headerDescriptions, cellDescriptions, depthSize, options) {                            var cellDescriptionsCount = cellDescriptions.length,                                viewHeaderItems = $.extend(true, [], headerItems);                            setHeaderItemsParameters(viewHeaderItems, headerDescriptions);                            if (options.showTotals !== false)                                addAdditionalTotalHeaderItems(viewHeaderItems);                            if (options.showGrandTotals !== false)                                viewHeaderItems.push({type: 'GT'});                            foreachTreeItems(viewHeaderItems, function(item, path) {                                if (!item.children || item.children.length === 0)                                    item.depthSize = depthSize - path.length + 1                            }, []);                            if (cellDescriptionsCount > 1)                                addMetricHeaderItems(viewHeaderItems, cellDescriptions);                            foreachTreeItems(viewHeaderItems, function(item, path) {                                var field = headerDescriptions[path.length - 1] || {};                                item.text = getHeaderItemText(item, field, options);                                if (item.type === 'D')                                    item.width = field.width;                                item.isLast = !item.children || !item.children.length;                                if (item.isLast)                                    $.each(options.sortBySummaryPaths, function(index, sortBySummaryPath) {                                        var headerPath = path;                                        if (!utils.isDefined(item.dataIndex)) {                                            sortBySummaryPath = sortBySummaryPath.slice(0);                                            sortBySummaryPath.pop()                                        }                                        if (item.type === "GT")                                            headerPath = headerPath.slice(1);                                        if (headerPath.join("/") === sortBySummaryPath.join("/")) {                                            item.sorted = true;                                            return false                                        }                                    })                            }, []);                            if (!viewHeaderItems.length)                                viewHeaderItems.push({});                            return viewHeaderItems                        };                    var setHeaderItemsParameters = function(viewHeaderItems, headerDescriptions) {                            var headerDescriptionsCount = headerDescriptions && headerDescriptions.length || 0;                            foreachTreeItems(viewHeaderItems, function(item) {                                item.type = 'D'                            });                            foreachTreeItems(viewHeaderItems, function(item, path) {                                item.path = path.slice(0);                                if (path.length < headerDescriptionsCount && (!item.children || item.children.length !== 0))                                    item.expanded = !!item.children                            }, [])                        };                    var addMetricHeaderItems = function(headerItems, cellDescriptions) {                            foreachTreeItems(headerItems, function(item) {                                var i;                                if (!item.children || item.children.length === 0) {                                    item.children = [];                                    for (i = 0; i < cellDescriptions.length; i++)                                        item.children.push({                                            caption: cellDescriptions[i].caption,                                            path: item.path,                                            type: item.type,                                            value: i,                                            dataIndex: i,                                            isMetric: true                                        })                                }                            })                        };                    var addAdditionalTotalHeaderItems = function(headerItems) {                            foreachTreeItems(headerItems, function(item, path, index, items) {                                if (item.type === 'D' && item.expanded)                                    items.splice(index + 1, 0, $.extend(true, {}, item, {                                        children: null,                                        type: 'T',                                        expanded: null,                                        isAdditionalTotal: true                                    }))                            }, [])                        };                    var fillHeaderInfo = function(info, viewHeaderItems, depthSize, isHorizontal) {                            var lastIndex = 0,                                index,                                depth,                                indexesByDepth = [0];                            foreachTreeItems(viewHeaderItems, function(headerItem, path) {                                depth = headerItem.isMetric ? depthSize : path.length - 1;                                while (indexesByDepth.length - 1 < depth)                                    indexesByDepth.push(indexesByDepth[indexesByDepth.length - 1]);                                index = indexesByDepth[depth] || 0;                                lastIndex = addInfoItem(info, {                                    headerItem: headerItem,                                    index: index,                                    lastIndex: lastIndex,                                    depth: depth,                                    isHorizontal: isHorizontal                                });                                indexesByDepth.length = depth;                                indexesByDepth.push(lastIndex)                            }, [])                        };                    return function(headerItems, headerDescriptions, cellDescriptions, isHorizontal, options) {                            var info = [],                                viewHeaderItems,                                depthSize = getHeaderItemsDepth(headerItems) || 1;                            viewHeaderItems = getViewHeaderItems(headerItems, headerDescriptions, cellDescriptions, depthSize, options);                            fillHeaderInfo(info, viewHeaderItems, depthSize, isHorizontal);                            return info                        }                }();            var createCellsInfo = function(dataSource, cellDescriptions, rowIndexedItems, columnIndexedItems) {                    var rowIndex,                        columnIndex,                        valueIndex,                        cells,                        rowInfo,                        dataSourceCells = dataSource.values,                        cellDescriptionsCount = cellDescriptions ? cellDescriptions.length : 0,                        cellValues,                        cellInfo,                        columnItem,                        rowItem,                        getHeaderItemType = function(headerItem) {                            if (!headerItem)                                return 'GT';                            if (headerItem.children && headerItem.children.length > 0)                                return 'T';                            return 'D'                        },                        columnCount = 0,                        info = [];                    if (dataSourceCells && cellDescriptionsCount > 0) {                        for (rowIndex = 0; rowIndex < dataSourceCells.length; rowIndex++)                            columnCount = Math.max(columnCount, dataSourceCells[rowIndex].length);                        for (rowIndex = 0; rowIndex < dataSourceCells.length; rowIndex++) {                            rowItem = rowIndexedItems[rowIndex];                            if (!rowItem && rowIndex !== dataSource.grandTotalRowIndex)                                continue;                            cells = dataSourceCells[rowIndex];                            rowInfo = [];                            for (columnIndex = 0; columnIndex < columnCount; columnIndex++) {                                columnItem = columnIndexedItems[columnIndex];                                if (!columnItem && columnIndex !== dataSource.grandTotalColumnIndex)                                    continue;                                cellValues = cells[columnIndex];                                if (!$.isArray(cellValues))                                    cellValues = [cellValues];                                for (valueIndex = 0; valueIndex < cellDescriptionsCount; valueIndex++) {                                    cellInfo = {                                        text: formatValue(cellValues[valueIndex], cellDescriptions[valueIndex]),                                        columnType: getHeaderItemType(columnItem),                                        rowType: getHeaderItemType(rowItem),                                        rowPath: rowItem && rowItem.path,                                        columnPath: columnItem && columnItem.path,                                        dataIndex: valueIndex                                    };                                    if (cellDescriptions[valueIndex].width)                                        cellInfo.width = cellDescriptions[valueIndex].width;                                    if (columnItem)                                        rowInfo[columnItem.visibleIndex * cellDescriptionsCount + valueIndex] = cellInfo;                                    else if (columnIndexedItems.grandTotalVisibleIndex >= 0)                                        rowInfo[columnIndexedItems.grandTotalVisibleIndex * cellDescriptionsCount + valueIndex] = cellInfo                                }                            }                            if (rowItem)                                info[rowItem.visibleIndex] = rowInfo;                            else if (rowIndexedItems.grandTotalVisibleIndex >= 0)                                info[rowIndexedItems.grandTotalVisibleIndex] = rowInfo                        }                    }                    return info                };            var getHeaderIndexedItems = function(headerItems, maxDepth, options) {                    var visibleIndex = 0,                        indexedItems = [];                    foreachTreeItems(headerItems, function(headerItem, path) {                        if (headerItem.children && options.showTotals === false)                            return;                        var indexedItem = $.extend(true, {}, headerItem, {                                visibleIndex: visibleIndex++,                                path: path                            });                        if (utils.isDefined(indexedItem.index))                            indexedItems[indexedItem.index] = indexedItem;                        else                            indexedItems.push(indexedItem)                    }, []);                    if (options.showGrandTotals !== false)                        indexedItems.grandTotalVisibleIndex = visibleIndex;                    return indexedItems                };            var members = {                    ctor: function(options) {                        var that = this;                        that._options = options || {};                        that._dataSource = that._createDataSource(options);                        that._columnsInfo = [];                        that._rowsInfo = [];                        that._cellsInfo = [];                        that.expandValueChanging = $.Callbacks();                        that.loadingChanged = $.Callbacks();                        that._dataSource.load();                        that._update();                        that.changed = $.Callbacks()                    },                    _handleChanged: function() {                        this._update()                    },                    _handleExpandValueChanging: function(e) {                        this.expandValueChanging.fire(e)                    },                    _handleLoadingChanged: function(e) {                        this.loadingChanged.fire(e)                    },                    _handleFieldsPrepared: function(e) {                        this._options.onFieldsPrepared && this._options.onFieldsPrepared(e)                    },                    _createDataSource: function(options) {                        var that = this,                            dataSourceOptions = options.dataSource,                            dataSource,                            fields;                        that._isSharedDataSource = dataSourceOptions instanceof pivotGrid.DataSource;                        if (that._isSharedDataSource)                            dataSource = dataSourceOptions;                        else                            dataSource = new pivotGrid.DataSource(dataSourceOptions);                        that._changedHandler = $.proxy(that, "_handleChanged");                        that._expandValueChangingHandler = $.proxy(that, "_handleExpandValueChanging");                        that._loadingChangedHandler = $.proxy(that, "_handleLoadingChanged");                        that._fieldsPreparedHandler = $.proxy(that, "_handleFieldsPrepared");                        dataSource.on("changed", that._changedHandler);                        dataSource.on("expandValueChanging", that._expandValueChangingHandler);                        dataSource.on("loadingChanged", that._loadingChangedHandler);                        dataSource.on("fieldsPrepared", that._fieldsPreparedHandler);                        if (options.descriptions) {                            fields = [];                            $.each(DESCRIPTION_NAME_BY_AREA, function(areaName, descriptionName) {                                var areaFields = options.descriptions[descriptionName];                                if (areaFields)                                    $.each(areaFields, function(areaIndex, field) {                                        fields.push($.extend({                                            area: areaName,                                            areaIndex: areaIndex                                        }, field))                                    })                            })                        }                        if (fields)                            dataSource.fields(fields);                        return dataSource                    },                    getDataSource: function() {                        return this._dataSource                    },                    isLoading: function() {                        return this._dataSource.isLoading()                    },                    isEmpty: function() {                        var dataFields = this._dataSource.getAreaFields("data"),                            data = this._dataSource.getData();                        return !dataFields.length || !data.values.length                    },                    _update: function() {                        var columnFields = this._dataSource.getAreaFields("column"),                            rowFields = this._dataSource.getAreaFields("row"),                            dataFields = this._dataSource.getAreaFields("data"),                            dataSource = this._dataSource.getData();                        var createSortPaths = function(headerFields, dataFields) {                                var sortBySummaryPaths = [];                                $.each(headerFields, function(index, headerField) {                                    var fieldIndex = pivotGrid.findField(dataFields, headerField.sortBySummaryField);                                    if (fieldIndex >= 0)                                        sortBySummaryPaths.push((headerField.sortBySummaryPath || []).concat([fieldIndex]))                                });                                return sortBySummaryPaths                            };                        var rowOptions = {                                texts: this._options.texts || {},                                showTotals: this._options.showRowTotals,                                showGrandTotals: this._options.showRowGrandTotals,                                sortBySummaryPaths: createSortPaths(columnFields, dataFields)                            };                        var columnOptions = {                                texts: this._options.texts || {},                                showTotals: this._options.showColumnTotals,                                showGrandTotals: this._options.showColumnGrandTotals,                                sortBySummaryPaths: createSortPaths(rowFields, dataFields)                            };                        var rowIndexedItems = getHeaderIndexedItems(dataSource.rows, rowFields.length - 1, rowOptions),                            columnIndexedItems = getHeaderIndexedItems(dataSource.columns, columnFields.length - 1, columnOptions);                        if (!utils.isDefined(dataSource.grandTotalRowIndex))                            dataSource.grandTotalRowIndex = rowIndexedItems.length;                        if (!utils.isDefined(dataSource.grandTotalColumnIndex))                            dataSource.grandTotalColumnIndex = columnIndexedItems.length;                        this._columnsInfo = createHeaderInfo(dataSource.columns, columnFields, dataFields, true, columnOptions);                        this._rowsInfo = createHeaderInfo(dataSource.rows, rowFields, [], false, rowOptions);                        this._cellsInfo = createCellsInfo(dataSource, dataFields, rowIndexedItems, columnIndexedItems);                        this.changed && this.changed.fire()                    },                    getHeaderItemPath: function(area, visibleIndex) {                        var that = this,                            index = 0,                            result,                            data = that._dataSource.getData(),                            dataFields = that._dataSource.getAreaFields("data"),                            headerItems = area === 'column' ? data.columns : data.rows;                        if (area === 'column' && dataFields.length > 1)                            visibleIndex = Math.floor(visibleIndex / dataFields.length);                        foreachTreeItems(headerItems, function(item, path) {                            if (index === visibleIndex) {                                result = path;                                return false                            }                            index++                        }, []);                        return result                    },                    getRowsInfo: function() {                        return this._rowsInfo                    },                    getColumnsInfo: function() {                        return this._columnsInfo                    },                    getCellsInfo: function() {                        return this._cellsInfo                    },                    dispose: function() {                        var that = this;                        if (that._isSharedDataSource) {                            that._dataSource.off("changed", that._changedHandler);                            that._dataSource.off("expandValueChanging", that._expandValueChangingHandler);                            that._dataSource.off("loadingChanged", that._loadingChangedHandler)                        }                        else                            that._dataSource.dispose();                        that.expandValueChanging.empty();                        that.changed.empty();                        that.loadingChanged.empty()                    }                };            pivotGrid.proxyMethod(members, "load");            pivotGrid.proxyMethod(members, "applyPartialDataSource");            pivotGrid.proxyMethod(members, "collapseHeaderItem");            pivotGrid.proxyMethod(members, "expandHeaderItem");            pivotGrid.proxyMethod(members, "getData");            return members        }())    })(jQuery, DevExpress);    /*! Module widgets-web, file ui.pivotGrid.store.xmla.js */    (function($, DX) {        DX.data.XmlaStore = DX.ui.dxPivotGrid.XmlaStore = DX.Class.inherit(function() {            var discover = '<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/"><Body><Discover xmlns="urn:schemas-microsoft-com:xml-analysis"><RequestType>{2}</RequestType><Restrictions><RestrictionList><CATALOG_NAME>{0}</CATALOG_NAME><CUBE_NAME>{1}</CUBE_NAME></RestrictionList></Restrictions><Properties><PropertyList><Catalog>{0}</Catalog></PropertyList></Properties></Discover></Body></Envelope>',                execute = '<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/"><Body><Execute xmlns="urn:schemas-microsoft-com:xml-analysis"><Command><Statement>{0}</Statement></Command><Properties><PropertyList><Catalog>{1}</Catalog><ShowHiddenCubes>True</ShowHiddenCubes><SspropInitAppName>Microsoft SQL Server Management Studio</SspropInitAppName><Timeout>3600</Timeout></PropertyList></Properties></Execute></Body></Envelope>',                mdx = "SELECT {2} FROM {0} {1} CELL PROPERTIES VALUE, FORMAT_STRING, LANGUAGE, BACK_COLOR, FORE_COLOR, FONT_FLAGS",                mdxFilterSelect = "(SELECT {0} FROM {1})",                mdxWith = " set [{0}] as {1}",                orderMdx = "ORDER({0}, {1}, {2})",                mdxSlice = "WHERE ({0})",                mdxNonEmpty = "NonEmpty({0}, {1})",                mdxHierarchize = "Hierarchize({{0}})",                mdxAxis = "{0} DIMENSION PROPERTIES PARENT_UNIQUE_NAME,HIERARCHY_UNIQUE_NAME ON {1}",                mdxCrossJoin = "CrossJoin({0})",                mdxGenerate = "Generate({{0}}, ({1}, {2}))",                mdxSet = "{{0}}",                utils = DX.utils,                stringFormat = utils.stringFormat,                sortOrderDictionary = {                    asc: "asc",                    desc: "desc"                },                sortByDictionary = {                    displaytext: ".member_caption",                    value: ".member_value"                },                MEASURE_DEMENSION_KEY = "DX_MEASURES",                MD_DIMTYPE_MEASURE = "2";            DX.ui.dxPivotGrid.sendRequest = function(options) {                return $.ajax(options)            };            function execXMLA(requestOptions, data) {                var deferred = $.Deferred(),                    beforeSend = requestOptions.beforeSend,                    ajaxSettings = {                        url: requestOptions.url,                        dataType: "text",                        data: data,                        headers: {'Content-Type': 'text/xml'},                        xhrFields: {},                        method: "POST"                    };                if (utils.isFunction(beforeSend))                    beforeSend(ajaxSettings);                DX.ui.dxPivotGrid.sendRequest(ajaxSettings).fail(function() {                    deferred.reject(arguments)                }).done(function(text) {                    var xml;                    try {                        xml = $.parseXML(text)                    }                    catch(e) {                        deferred.reject({                            statusText: e.message,                            stack: e.stack,                            responseText: text                        })                    }                    deferred.resolve(xml)                });                return deferred            }            function mdxDescendants(level, levelMember, nextLevel) {                levelMember = levelMember ? ".[" + levelMember + "]" : "";                return "Descendants({" + level + levelMember + "}, " + nextLevel + ", SELF_AND_BEFORE)"            }            function getAllMember(dimention) {                return (dimention.hierarchyName || dimention.dataField) + ".[All]"            }            function getAllMembers(field) {                return field.dataField + ".allMembers"            }            function getCurrentMember(field) {                return (field.hierarchyName || field.dataField) + ".currentMember"            }            function crossJoinElements(elements) {                var elementsString = elements.join(",");                return elements.length > 1 ? stringFormat(mdxCrossJoin, elementsString) : elementsString            }            function orderField(field, orderArg, options, axisName, withArray) {                var sortOrder = sortOrderDictionary[field.sortOrder];                if (sortOrder || sortByDictionary[(field.sortBy + "").toLowerCase()])                    return stringFormat(orderMdx, orderArg, getOrderValue(field, options, axisName, orderArg, withArray), sortOrder || "asc");                else                    return orderArg            }            function generateCrossJoin(path, expandLevel, expandAllCount, expandIndex, slicePath, options, axisName, withArray) {                var crossJoinArgs = [],                    dimensions = options[axisName],                    dataField,                    allMember,                    fields = [],                    hierarchyName,                    arg,                    prevDimension,                    prevHierarchyName,                    isLastDimesionInGroup,                    isFirstDimesionInGroup,                    expandAllIndex,                    field,                    member,                    useGenerate,                    i;                for (i = expandIndex; i <= expandLevel; i++) {                    field = dimensions[i];                    dataField = field.dataField;                    prevHierarchyName = dimensions[i - 1] && dimensions[i - 1].hierarchyName;                    hierarchyName = field.hierarchyName;                    isLastDimesionInGroup = !hierarchyName || !dimensions[i + 1] || dimensions[i + 1].hierarchyName !== hierarchyName;                    expandAllIndex = path.length + expandAllCount + expandIndex;                    arg = null;                    useGenerate = false;                    fields.push(field);                    if (i < path.length) {                        if (isLastDimesionInGroup)                            arg = "(" + dataField + ".[" + path[i] + "])"                    }                    else if (i <= expandAllIndex)                        if (i === 0 && expandAllCount === 0) {                            allMember = getAllMember(dimensions[expandIndex]);                            if (!hierarchyName)                                arg = getAllMembers(dimensions[expandIndex]);                            else                                arg = allMember + "," + dimensions[expandIndex].dataField                        }                        else if (hierarchyName) {                            member = slicePath[slicePath.length - 1];                            if (isLastDimesionInGroup || i === expandAllIndex)                                if (prevHierarchyName === hierarchyName) {                                    if (slicePath.length)                                        prevDimension = dimensions[slicePath.length - 1];                                    if (!prevDimension || prevDimension.hierarchyName !== hierarchyName) {                                        prevDimension = dimensions[i - 1];                                        member = ""                                    }                                    arg = mdxDescendants(prevDimension.dataField, member, dataField)                                }                                else                                    arg = getAllMembers(field)                        }                        else {                            arg = getAllMembers(field);                            if (field.sortBySummaryField && crossJoinArgs.length && i === expandAllIndex)                                useGenerate = true                        }                    else {                        isFirstDimesionInGroup = !hierarchyName || prevHierarchyName !== hierarchyName;                        if (isFirstDimesionInGroup)                            arg = "(" + getAllMember(field) + ")"                    }                    if (arg) {                        arg = stringFormat(mdxSet, arg);                        arg = orderField(field, arg, options, axisName, withArray);                        if (useGenerate)                            arg = stringFormat(mdxGenerate, crossJoinArgs.pop(), getCurrentMember(dimensions[i - 1]), arg);                        crossJoinArgs.push(arg)                    }                }                return crossJoinElements(crossJoinArgs)            }            function fillCrossJoins(crossJoins, path, expandLevel, expandIndex, slicePath, options, axisName, withArray) {                var expandAllCount = -1,                    dimensions = options[axisName],                    dimestionIndex;                do {                    expandAllCount++;                    dimestionIndex = path.length + expandAllCount + expandIndex;                    crossJoins.push(generateCrossJoin(path, expandLevel, expandAllCount, expandIndex, slicePath, options, axisName, withArray))                } while (dimensions[dimestionIndex] && dimensions[dimestionIndex + 1] && dimensions[dimestionIndex].expanded)            }            function declareSet(set, withArray, name) {                name = name || "DX_Set_" + withArray.length;                withArray.push(stringFormat(mdxWith, name, set));                return "[" + name + "]"            }            function getRank(field, orderArg, withArray) {                var set;                if (field.hierarchyName)                    set = declareSet(stringFormat(mdxHierarchize, orderArg), withArray);                else                    set = getAllMembers(field);                return "rank(" + getCurrentMember(field) + "," + set + ")"            }            function getOrderValueForSummary(field, options, axisName) {                var sortByFields = (axisName === "columns" ? options.rows : options.columns) || [],                    dataFields = options.values || [],                    sortBySummaryFieldIndex = DX.ui.dxPivotGrid.findField(dataFields, field.sortBySummaryField),                    tupleElements = dataFields[sortBySummaryFieldIndex] ? [dataFields[sortBySummaryFieldIndex].dataField] : [],                    orderPath = field.sortBySummaryPath || [],                    prevElementHierarchyName;                $.each(orderPath, function(index, path) {                    var sortByField = sortByFields[index];                    if (sortByField)                        if (sortByField.hierarchyName && sortByField.hierarchyName === prevElementHierarchyName)                            tupleElements[tupleElements.length - 1] = (sortByField.hierarchyName || sortByField.dataField) + ".[" + path + "]";                        else {                            tupleElements.push((sortByField.hierarchyName || sortByField.dataField) + ".[" + path + "]");                            prevElementHierarchyName = sortByField.hierarchyName                        }                });                return tupleElements.join(",")            }            function getOrderValue(field, options, axisName, orderArg, withArray) {                var orderProperty = sortByDictionary[(field.sortBy + "").toLowerCase()];                if (field.sortBySummaryField)                    return "(" + getOrderValueForSummary(field, options, axisName) + ")";                else if (orderProperty)                    return getCurrentMember(field) + orderProperty;                else                    return getRank(field, orderArg, withArray)            }            function generateAxisMdx(options, axisName, cells, withArray, parseOptions) {                var dimensions = options[axisName],                    crossJoins = [],                    path = [],                    expandedPaths = [],                    expandIndex = 0,                    expandLevel = 0,                    result = [],                    cellsString = stringFormat(mdxSet, cells.join(","));                if (dimensions && dimensions.length) {                    if (options.headerName === axisName) {                        path = options.path;                        expandLevel = expandIndex = path.length                    }                    else {                        expandedPaths = (axisName === "columns" ? options.columnExpandedPaths : options.rowExpandedPaths) || expandedPaths;                        $.each(expandedPaths, function(_, path) {                            expandLevel = Math.max(expandLevel, path.length)                        })                    }                    while (dimensions[expandLevel + 1] && dimensions[expandLevel].expanded)                        expandLevel++;                    fillCrossJoins(crossJoins, [], expandLevel, expandIndex, path, options, axisName, withArray);                    $.each(expandedPaths, function(_, expandedPath) {                        fillCrossJoins(crossJoins, expandedPath, expandLevel, expandIndex, expandedPath, options, axisName, withArray)                    });                    for (var i = expandLevel; i >= path.length; i--)                        if (dimensions[i].hierarchyName) {                            parseOptions.visibleLevels[dimensions[i].hierarchyName] = parseOptions.visibleLevels[dimensions[i].hierarchyName] || [];                            parseOptions.visibleLevels[dimensions[i].hierarchyName].push(dimensions[i].dataField)                        }                }                crossJoins.length && result.push(stringFormat(mdxNonEmpty, declareSet(stringFormat(mdxSet, crossJoins.join(",")), withArray, axisName), cellsString));                if (axisName === "columns" && cells.length)                    result.push(cellsString);                return stringFormat(mdxAxis, crossJoinElements(result), axisName)            }            function generateAxisFieldsFilter(fields) {                var filterMembers = [];                $.each(fields, function(_, field) {                    var dataField = field.dataField,                        filterExpression = [],                        filterValues = field.filterValues || [],                        filterStringExpression;                    if (field.hierarchyName && utils.isNumber(field.groupIndex))                        return;                    $.each(filterValues, function(_, filterValue) {                        var filterMdx = dataField + ".[" + (utils.isArray(filterValue) ? filterValue[filterValue.length - 1] : filterValue) + "]";                        if (field.filterType === "exclude") {                            filterExpression.push(filterMdx + ".parent");                            filterMdx = "Descendants(" + filterMdx + ")"                        }                        filterExpression.push(filterMdx)                    });                    if (filterValues.length) {                        filterStringExpression = stringFormat(mdxSet, filterExpression.join(","));                        if (field.filterType === "exclude")                            filterStringExpression = "Except(" + getAllMembers(field) + "," + filterStringExpression + ")";                        filterMembers.push(filterStringExpression)                    }                });                return filterMembers.length ? crossJoinElements(filterMembers) : ""            }            function generateFrom(columnsFilter, rowsFilter, filter, cubeName) {                var from = "[" + cubeName + "]";                $.each([columnsFilter, rowsFilter, filter], function(_, filter) {                    if (filter)                        from = stringFormat(mdxFilterSelect, filter + "on 0", from)                });                return from            }            function generateMDX(options, cubeName, parseOptions) {                var columns = options.columns || [],                    rows = options.rows || [],                    values = options.values && options.values.length ? options.values : [{dataField: '[Measures]'}],                    slice = [],                    withArray = [],                    axisStrings = [],                    dataFields = $.map(values, function(cell) {                        return cell.dataField                    });                parseOptions.measureCount = values.length;                parseOptions.visibleLevels = {};                if (options.headerName && options.path)                    $.each(options.path, function(index, value) {                        var dimention = options[options.headerName][index];                        if (!dimention.hierarchyName || dimention.hierarchyName !== options[options.headerName][index + 1].hierarchyName)                            slice.push(dimention.dataField + ".[" + value + "]")                    });                if (columns.length || dataFields.length)                    axisStrings.push(generateAxisMdx(options, "columns", dataFields, withArray, parseOptions));                if (rows.length)                    axisStrings.push(generateAxisMdx(options, "rows", dataFields, withArray, parseOptions));                if (!axisStrings.length)                    return "";                var withString = (withArray.length ? "with" + withArray.join(" ") : "") + " ";                return withString + stringFormat(mdx, generateFrom(generateAxisFieldsFilter(columns), generateAxisFieldsFilter(rows), generateAxisFieldsFilter(options.filters || []), cubeName), slice.length ? stringFormat(mdxSlice, slice.join(",")) : "", axisStrings.join(","))            }            function getNumber(str) {                return parseInt(str, 10)            }            function parseAxes(xml) {                var axes = [];                $.each($(xml).find("Axis"), function(_, axisElement) {                    var $axis = $(axisElement),                        name = axisElement.getAttribute("name"),                        axis = [],                        index = 0;                    if (name.indexOf("Axis") === 0 && utils.isNumber(getNumber(name.substr(4)))) {                        axes.push(axis);                        $.each($axis.children("Tuples").children(), function(_, tupleElement) {                            var tupleMembers = $(tupleElement).children(),                                $tuple,                                levelSum = 0,                                members = [],                                level,                                membersCount = tupleMembers.length - 1,                                isAxisWithMeasure = axes.length === 1,                                i;                            if (isAxisWithMeasure)                                membersCount--;                            axis.push(members);                            for (i = membersCount; i >= 0; i--) {                                $tuple = $(tupleMembers[i]);                                level = getNumber($tuple.children("LNum").text());                                members[i] = {                                    caption: $tuple.children("Caption").text(),                                    level: level,                                    index: index++,                                    hasValue: !levelSum && (!!level || i === 0),                                    name: $tuple.children("UName").text(),                                    parentName: $tuple.children("PARENT_UNIQUE_NAME").text(),                                    levelName: $tuple.children("LName").text(),                                    hierarchyName: tupleMembers[i].getAttribute("Hierarchy")                                };                                levelSum += level                            }                        })                    }                });                while (axes.length < 2)                    axes.push([[{level: 0}]]);                return axes            }            function parseCells(xml, axes, measureCount) {                var cells = [],                    cell = [],                    index = 0,                    measureIndex,                    cellsOriginal = [],                    row;                $.each($(xml).find("CellData > Cell"), function(_, xmlCell) {                    var $cell = $(xmlCell),                        value = parseFloat($cell.children("Value").text());                    cellsOriginal[getNumber(xmlCell.getAttribute("CellOrdinal"))] = {value: isNaN(value) ? null : value}                });                $.each(axes[1], function() {                    row = [];                    cells.push(row);                    $.each(axes[0], function() {                        measureIndex = index % measureCount;                        if (measureIndex === 0) {                            cell = [];                            row.push(cell)                        }                        cell.push(cellsOriginal[index] ? cellsOriginal[index].value : null);                        index++                    })                });                return cells            }            function getItem(hash, name, member, index) {                var item = hash[name];                if (!item) {                    item = {};                    hash[name] = item                }                if (!item.value && member) {                    item.value = member.caption;                    item.levelName = member.levelName;                    item.hierarchyName = member.hierarchyName;                    item.parentName = member.parentName;                    item.index = index;                    item.level = member.level                }                return item            }            function getVisibleChildren(item, visibleLevels) {                var result = [],                    children = item.children && (item.children.length ? item.children : $.map(item.children.grandTotalHash || [], function(e) {                        return e.children                    })),                    firstChild = children && children[0];                if (firstChild && (visibleLevels[firstChild.hierarchyName] && $.inArray(firstChild.levelName, visibleLevels[firstChild.hierarchyName]) !== -1 || !visibleLevels[firstChild.hierarchyName] || firstChild.level === 0)) {                    var newChildren = $.map(children, function(child) {                            return child.hierarchyName === firstChild.hierarchyName ? child : null                        });                    newChildren.grandTotalHash = children.grandTotalHash;                    return newChildren                }                else if (firstChild)                    for (var i = 0; i < children.length; i++)                        if (children[i].hierarchyName === firstChild.hierarchyName)                            result.push.apply(result, getVisibleChildren(children[i], visibleLevels));                return result            }            function processMember(dataIndex, member, parentItem) {                var currentItem,                    children = parentItem.children = parentItem.children || [],                    hash = children.hash = children.hash || {},                    grandTotalHash = children.grandTotalHash = children.grandTotalHash || {};                if (member.parentName) {                    parentItem = getItem(hash, member.parentName);                    children = parentItem.children = parentItem.children || []                }                currentItem = getItem(hash, member.name, member, dataIndex);                if (member.hasValue && !currentItem.added) {                    currentItem.index = dataIndex;                    currentItem.added = true;                    children.push(currentItem)                }                if ((!parentItem.value || !parentItem.parentName) && member.parentName)                    grandTotalHash[member.parentName] = parentItem;                else if (grandTotalHash[parentItem.name])                    delete grandTotalHash[member.parentName];                return currentItem            }            function getGrandTotalIndex(parentItem, visibleLevels) {                var grandTotalIndex;                if (parentItem.children.length === 1 && parentItem.children[0].parentName === "") {                    grandTotalIndex = parentItem.children[0].index;                    var grandTotalHash = parentItem.children.grandTotalHash;                    parentItem.children = parentItem.children[0].children;                    parentItem.children.grandTotalHash = grandTotalHash;                    parentItem.children = getVisibleChildren(parentItem, visibleLevels)                }                else if (parentItem.children.length === 0)                    grandTotalIndex = 0;                return grandTotalIndex            }            function fillDataSourceAxes(dataSourceAxis, axisTuples, measureCount, visibleLevels) {                var grandTotalIndex,                    result = [];                $.each(axisTuples, function(tupleIndex, members) {                    var parentItem = {children: result},                        dataIndex = utils.isDefined(measureCount) ? Math.floor(tupleIndex / measureCount) : tupleIndex;                    $.each(members, function(_, member) {                        parentItem = processMember(dataIndex, member, parentItem)                    })                });                var parentItem = {children: result};                parentItem.children = getVisibleChildren(parentItem, visibleLevels);                grandTotalIndex = getGrandTotalIndex(parentItem, visibleLevels);                DX.ui.dxPivotGrid.foreachTreeItems(parentItem.children, function(item) {                    var children = getVisibleChildren(item, visibleLevels);                    if (children.length)                        item.children = children;                    else                        delete item.children;                    delete item.levelName;                    delete item.hierarchyName;                    delete item.added;                    delete item.parentName;                    delete item.level                }, undefined, true);                $.each(parentItem.children || [], function(_, e) {                    dataSourceAxis.push(e)                });                return grandTotalIndex            }            function parseResult(xml, parseOptions) {                var dataSource = {                        columns: [],                        rows: []                    },                    axes,                    error = $(xml).find("Error"),                    measureCount = parseOptions.measureCount;                if (error.length) {                    utils.logger.error(error.attr("Description"));                    return null                }                axes = parseAxes(xml);                dataSource.grandTotalColumnIndex = fillDataSourceAxes(dataSource.columns, axes[0], measureCount, parseOptions.visibleLevels);                dataSource.grandTotalRowIndex = fillDataSourceAxes(dataSource.rows, axes[1], undefined, parseOptions.visibleLevels);                dataSource.values = parseCells(xml, axes, measureCount);                return dataSource            }            function parseDiscoverRowSet(xml, schema, dimensions) {                var result = [],                    isMeasure = schema === "MEASURE",                    displayFolderField = isMeasure ? "MEASUREGROUP_NAME" : schema + "_DISPLAY_FOLDER";                $.each($(xml).find("row"), function(_, row) {                    var $row = $(row),                        hierarchyName = schema === "LEVEL" ? $row.children("HIERARCHY_UNIQUE_NAME").text() : undefined,                        levelNumber = $row.children("LEVEL_NUMBER").text();                    if ((levelNumber !== "0" || $row.children(schema + "_IS_VISIBLE").text() !== "true") && $row.children("DIMENSION_TYPE").text() !== MD_DIMTYPE_MEASURE) {                        var dimension = isMeasure ? MEASURE_DEMENSION_KEY : $row.children("DIMENSION_UNIQUE_NAME").text();                        result.push({                            dimension: dimensions[dimension] || dimension,                            groupIndex: levelNumber ? getNumber(levelNumber) - 1 : undefined,                            dataField: $row.children(schema + "_UNIQUE_NAME").text(),                            caption: $row.children(schema + "_CAPTION").text(),                            hierarchyName: hierarchyName,                            groupName: hierarchyName,                            displayFolder: $row.children(displayFolderField).text(),                            isMeasure: isMeasure                        })                    }                });                return result            }            function parseDimensionsDiscoverRowSet(xml) {                var result = {};                $.each($(xml).find("row"), function(_, row) {                    var $row = $(row),                        type = $row.children("DIMENSION_TYPE").text(),                        dimensionName = type === MD_DIMTYPE_MEASURE ? MEASURE_DEMENSION_KEY : $row.children("DIMENSION_UNIQUE_NAME").text();                    result[dimensionName] = $row.children("DIMENSION_CAPTION").text()                });                return result            }            return {                    ctor: function(options) {                        this._options = options                    },                    getFields: function() {                        var options = this._options,                            catalog = options.catalog,                            cube = options.cube,                            dimensionsRequest = execXMLA(options, stringFormat(discover, catalog, cube, "MDSCHEMA_DIMENSIONS")),                            measuresRequest = execXMLA(options, stringFormat(discover, catalog, cube, "MDSCHEMA_MEASURES")),                            hierarchiesRequest = execXMLA(options, stringFormat(discover, catalog, cube, "MDSCHEMA_HIERARCHIES")),                            levelsRequest = execXMLA(options, stringFormat(discover, catalog, cube, "MDSCHEMA_LEVELS")),                            result = $.Deferred();                        $.when(dimensionsRequest, measuresRequest, hierarchiesRequest, levelsRequest).done(function(dimensionsResponse, measuresResponse, hierarhiesResponse, levelsResponse) {                            var dimensions = parseDimensionsDiscoverRowSet(dimensionsResponse),                                hierarchies = parseDiscoverRowSet(hierarhiesResponse, "HIERARCHY", dimensions),                                levels = parseDiscoverRowSet(levelsResponse, "LEVEL", dimensions),                                fields = parseDiscoverRowSet(measuresResponse, "MEASURE", dimensions).concat(hierarchies),                                levelsByHierarchy = {};                            $.each(levels, function(_, level) {                                levelsByHierarchy[level.hierarchyName] = levelsByHierarchy[level.hierarchyName] || [];                                levelsByHierarchy[level.hierarchyName].push(level)                            });                            $.each(hierarchies, function(_, hierarchy) {                                if (levelsByHierarchy[hierarchy.dataField] && levelsByHierarchy[hierarchy.dataField].length > 1) {                                    hierarchy.groupName = hierarchy.hierarchyName = hierarchy.dataField;                                    fields.push.apply(fields, levelsByHierarchy[hierarchy.hierarchyName])                                }                            });                            result.resolve(fields)                        }).fail(result.reject);                        return result                    },                    load: function(options) {                        var result = $.Deferred(),                            storeOptions = this._options,                            data,                            executeQuery,                            parseOptions = {},                            mdxString = generateMDX(options, storeOptions.cube, parseOptions);                        if (mdxString) {                            executeQuery = stringFormat(execute, mdxString, storeOptions.catalog);                            $.when(execXMLA(storeOptions, executeQuery)).done(function(executeXml) {                                data = parseResult(executeXml, parseOptions);                                if (data)                                    result.resolve(data);                                else                                    result.reject()                            }).fail(result.reject)                        }                        else                            result.resolve({                                columns: [],                                rows: [],                                values: [],                                grandTotalColumnIndex: 0,                                grandTotalRowIndex: 0                            });                        return result                    },                    supportSorting: function() {                        return true                    }                }        }())    })(jQuery, DevExpress);    /*! Module widgets-web, file ui.pivotGrid.store.local.js */    (function($, DX) {        var dataUtils = DX.data.utils,            utils = DX.utils,            pivotGrid = DX.ui.dxPivotGrid;        pivotGrid.LocalStore = DevExpress.Class.inherit(function() {            var DATE_INTERVAL_SELECTORS = {                    year: function(date) {                        return date && date.getFullYear()                    },                    quarter: function(date) {                        return date && Math.floor(date.getMonth() / 3) + 1                    },                    month: function(date) {                        return date && date.getMonth() + 1                    },                    day: function(date) {                        return date && date.getDate()                    },                    dayOfWeek: function(date) {                        return date && date.getDay()                    }                };            var DATE_INTERVAL_FORMATS = {                    month: {                        format: 'month',                        dateType: 'full'                    },                    quarter: {                        format: 'quarter',                        dateType: 'full'                    },                    dayOfWeek: {                        format: 'dayOfWeek',                        dateType: 'full'                    }                };            function prepareFields(fields) {                $.each(fields || [], function() {                    var fieldSelector,                        intervalSelector,                        dataField = this.dataField,                        groupInteval,                        levels = this.levels;                    if (!this.selector) {                        if (!dataField)                            fieldSelector = function(data) {                                return data                            };                        else                            fieldSelector = dataField.indexOf(".") !== -1 ? dataUtils.compileGetter(dataField) : function(data) {                                return data[dataField]                            };                        if (levels) {                            prepareFields(levels);                            this.selector = function(data) {                                var value = [];                                $.each(levels, function(_, field) {                                    value.push(field.selector(data))                                });                                return value                            }                        }                        else if (this.dataType === 'date') {                            intervalSelector = DATE_INTERVAL_SELECTORS[this.groupInterval];                            this.selector = function(data) {                                var value = fieldSelector(data);                                if (value && !(value instanceof Date))                                    value = new Date(value);                                return intervalSelector ? intervalSelector(value) : value                            };                            this.format = this.format || DATE_INTERVAL_FORMATS[this.groupInterval]                        }                        else if (this.dataType === 'number') {                            groupInteval = utils.isNumber(this.groupInterval) && this.groupInterval > 0 && this.groupInterval;                            if (groupInteval)                                this.customizeText = this.customizeText || function(formatObject) {                                    var secondValue = formatObject.value + groupInteval,                                        secondValueText = DX.formatHelper.format(secondValue, this.format, this.precision);                                    return formatObject.valueText && secondValueText ? formatObject.valueText + " - " + secondValueText : ""                                };                            this.selector = function(data) {                                var value = fieldSelector(data);                                if (DX.utils.isString(value))                                    value = Number(value);                                return groupInteval ? Math.floor(value / groupInteval) * groupInteval : value                            }                        }                        else                            this.selector = fieldSelector                    }                })            }            var addHierarchyItem = function(value, hierarchyItems, pathHash, childrenHash) {                    var hierarchyItem = childrenHash[pathHash];                    if (!hierarchyItem) {                        hierarchyItem = {                            value: value,                            index: childrenHash.length++                        };                        childrenHash[pathHash] = hierarchyItem;                        hierarchyItems.push(hierarchyItem)                    }                    return hierarchyItem                };            function fillHierarchyItemIndexesCore(indexes, options, children, expandIndex, pathHash) {                var dimension = options.dimensions[expandIndex],                    expandedPathsHash = options.expandedPathsHash,                    dimensionValue,                    hierarchyItem;                if (dimension) {                    dimensionValue = dimension.selector(options.data);                    pathHash = pathHash ? pathHash + "." + dimensionValue : dimensionValue;                    hierarchyItem = addHierarchyItem(dimensionValue, children, pathHash, options.childrenHash);                    indexes.push(hierarchyItem.index);                    if (expandedPathsHash && expandedPathsHash[pathHash] || dimension.expanded) {                        if (!hierarchyItem.children)                            hierarchyItem.children = [];                        fillHierarchyItemIndexesCore(indexes, options, hierarchyItem.children, expandIndex + 1, pathHash)                    }                }            }            function generateHierarchyItems(data, loadOptions, headers, headerName) {                var result = [0],                    expandIndex = loadOptions.headerName === headerName ? loadOptions.path.length : 0,                    expandedPaths = headerName === "rows" ? loadOptions.rowExpandedPaths : loadOptions.columnExpandedPaths,                    options = {                        data: data,                        childrenHash: headers[headerName + "Hash"],                        dimensions: loadOptions[headerName],                        expandedPathsHash: loadOptions.headerName !== headerName && expandedPaths && expandedPaths.hash                    };                fillHierarchyItemIndexesCore(result, options, headers[headerName], expandIndex);                return result            }            function generateAggregationCells(data, cells, headers, options) {                var cellSet = [],                    x,                    y,                    rowIndex,                    columnIndex;                var rowIndexes = generateHierarchyItems(data, options, headers, "rows");                var columnIndexes = generateHierarchyItems(data, options, headers, "columns");                for (y = 0; y < rowIndexes.length; y++) {                    rowIndex = rowIndexes[y];                    cells[rowIndex] = cells[rowIndex] || [];                    for (x = 0; x < columnIndexes.length; x++) {                        columnIndex = columnIndexes[x];                        cellSet.push(cells[rowIndex][columnIndex] = cells[rowIndex][columnIndex] || [])                    }                }                return cellSet            }            function fillHashExpandedPath(expandedPaths) {                if (expandedPaths) {                    expandedPaths.hash = {};                    $.each(expandedPaths, function() {                        expandedPaths.hash[this.join(".")] = true                    })                }            }            function prepareLoadOption(options) {                options.rows = options.rows || [];                options.columns = options.columns || [];                options.filters = options.filters || [];                fillHashExpandedPath(options.columnExpandedPaths);                fillHashExpandedPath(options.rowExpandedPaths);                prepareFields(options.columns);                prepareFields(options.rows);                prepareFields(options.values);                prepareFields(options.filters)            }            function getAggregator(field) {                if (field.summaryType === "custom") {                    field.calculateCustomSummary = field.calculateCustomSummary || $.noop;                    return {                            seed: function() {                                var options = {                                        summaryProcess: "start",                                        totalValue: undefined                                    };                                field.calculateCustomSummary(options);                                return options                            },                            step: function(options, value) {                                options.summaryProcess = "calculate";                                options.value = value;                                field.calculateCustomSummary(options);                                return options                            },                            finalize: function(options) {                                options.summaryProcess = "finalize";                                delete options.value;                                field.calculateCustomSummary(options);                                return options.totalValue                            }                        }                }                return dataUtils.aggregators[field.summaryType] || dataUtils.aggregators.count            }            function aggregationStep(measures, aggregationCells, data) {                for (var aggregatorIndex = 0; aggregatorIndex < measures.length; aggregatorIndex++) {                    var cellField = measures[aggregatorIndex];                    var cellValue = cellField.selector(data);                    var aggregator = getAggregator(cellField);                    for (var cellSetIndex = 0; cellSetIndex < aggregationCells.length; cellSetIndex++) {                        var cell = aggregationCells[cellSetIndex];                        if (cell.length <= aggregatorIndex)                            cell[aggregatorIndex] = utils.isFunction(aggregator.seed) ? aggregator.seed() : aggregator.seed;                        if (cell[aggregatorIndex] === undefined)                            cell[aggregatorIndex] = cellValue;                        else if (utils.isDefined(cellValue))                            cell[aggregatorIndex] = aggregator.step(cell[aggregatorIndex], cellValue)                    }                }            }            function aggregationFinalize(measures, cells) {                $.each(measures, function(aggregatorIndex, cellField) {                    var aggregator = getAggregator(cellField);                    if (aggregator.finalize)                        $.each(cells, function(_, row) {                            $.each(row, function(_, cell) {                                if (cell)                                    cell[aggregatorIndex] = aggregator.finalize(cell[aggregatorIndex])                            })                        })                })            }            function areValuesEqual(filterValue, fieldValue) {                if (utils.isArray(filterValue)) {                    fieldValue = fieldValue || [];                    for (var i = 0; i < filterValue.length; i++)                        if (filterValue[i] !== fieldValue[i])                            return false;                    return true                }                else                    return filterValue === fieldValue            }            function createDimensionFilters(dimention) {                var filters = [];                $.each(dimention, function(_, field) {                    var filterValues = field.filterValues || [],                        groupName = field.groupName,                        filter;                    if (groupName && utils.isNumber(field.groupIndex))                        return;                    filter = function(dataItem) {                        var value = field.selector(dataItem),                            result = false;                        for (var i = 0; i < filterValues.length; i++)                            if (areValuesEqual(filterValues[i], value)) {                                result = true;                                break                            }                        return field.filterType === "exclude" ? !result : result                    };                    filterValues.length && filters.push(filter)                });                return filters            }            function createFilter(options) {                var filters = createDimensionFilters(options.rows).concat(createDimensionFilters(options.columns)).concat(createDimensionFilters(options.filters)),                    expandedDimensions = options[options.headerName],                    path = options.path;                if (expandedDimensions)                    filters.push(function(dataItem) {                        var expandValue;                        for (var i = 0; i < path.length; i++) {                            expandValue = expandedDimensions[i].selector(dataItem);                            if (expandValue !== path[i])                                return false                        }                        return true                    });                return function(dataItem) {                        for (var i = 0; i < filters.length; i++)                            if (!filters[i](dataItem))                                return false;                        return true                    }            }            function loadCore(items, options) {                var headers = {                        columns: [],                        rows: [],                        columnsHash: {length: 1},                        rowsHash: {length: 1}                    },                    values = [[[]]],                    aggregationCells,                    filter,                    data,                    i;                prepareLoadOption(options);                filter = createFilter(options);                for (i = 0; i < items.length; i++) {                    data = items[i];                    if (filter(data)) {                        aggregationCells = generateAggregationCells(data, values, headers, options);                        aggregationStep(options.values, aggregationCells, data)                    }                }                aggregationFinalize(options.values, values);                return {                        rows: headers.rows,                        columns: headers.columns,                        values: values,                        grandTotalRowIndex: 0,                        grandTotalColumnIndex: 0                    }            }            function createGroupFields(item) {                return $.map(["year", "quarter", "month"], function(value, index) {                        return $.extend({}, item, {                                groupInterval: value,                                groupIndex: index                            })                    })            }            function parseFields(dataSource, fieldsList, path, fieldsDataType) {                var result = [];                $.each(fieldsList || [], function(field, value) {                    var dataIndex = 1,                        currentPath = path.length ? path + "." + field : field,                        dataType = fieldsDataType[currentPath],                        getter = dataUtils.compileGetter(currentPath),                        items;                    while (!utils.isDefined(value) && dataSource[dataIndex]) {                        value = getter(dataSource[dataIndex]);                        dataIndex++                    }                    if (!dataType && utils.isDefined(value))                        dataType = $.type(value);                    items = [{                            dataField: currentPath,                            dataType: dataType,                            groupName: dataType === "date" ? field : undefined,                            groupInterval: undefined,                            displayFolder: path                        }];                    if (dataType === "date")                        items = items.concat(createGroupFields(items[0]));                    else if (dataType === "object")                        items = parseFields(dataSource, value, currentPath, fieldsDataType);                    result.push.apply(result, items)                });                return result            }            function discover(items, fieldsDataType) {                fieldsDataType = fieldsDataType || {};                return parseFields(items, items[0], "", fieldsDataType)            }            function loadDataSource(dataSource) {                var d = $.Deferred();                if (!dataSource.isLoaded())                    $.when(dataSource.load()).always(function() {                        loadDataSource(dataSource).done(d.resolve).fail(d.reject)                    });                else                    d.resolve(dataSource.items());                return d            }            return {                    ctor: function(options) {                        options = $.extend(dataUtils.normalizeDataSourceOptions(options), {                            paginate: false,                            onChanged: null                        });                        this._dataSource = new DX.data.DataSource(options)                    },                    getFields: function(fieldsDataType) {                        var that = this,                            dataSource = that._dataSource,                            d = $.Deferred();                        loadDataSource(dataSource).done(function(data) {                            d.resolve(discover(data, fieldsDataType))                        }).fail(d.reject);                        return d                    },                    load: function(options) {                        var that = this,                            dataSource = that._dataSource,                            d = $.Deferred();                        loadDataSource(dataSource).done(function(data) {                            var parsedData = loadCore(data, options);                            d.resolve(parsedData)                        }).fail(d.reject);                        return d                    },                    supportSorting: function() {                        return false                    }                }        }())    })(jQuery, DevExpress);    /*! Module widgets-web, file ui.pivotGrid.areaItem.js */    (function($, DX) {        var pivotGrid = DX.ui.dxPivotGrid,            utils = DX.utils,            Class = DX.Class;        var IE_WIDTH_CORRECTION = 1;        var getRealElementWidth = function(element, isFixed) {                return isFixed ? element.offsetWidth : element.offsetWidth + IE_WIDTH_CORRECTION            };        pivotGrid.getRealElementWidth = getRealElementWidth;        pivotGrid.AreaItem = Class.inherit({            _getRowElement: function(index) {                var that = this;                if (that._tableElement && that._tableElement.length > 0)                    return that._tableElement[0].rows[index];                return null            },            _createGroupElement: function() {                return $('<div>')            },            _createTableElement: function() {                return $('<table>')            },            _renderTableContent: function(tableElement, data) {                var that = this,                    rowElements = tableElement.find("tr"),                    areaName = that._getAreaName(),                    onCellPrepared = that.option("onCellPrepared"),                    rowElement,                    cellElement,                    row,                    cell,                    rowIndex,                    columnIndex;                tableElement.data("area", areaName);                tableElement.data("data", data);                if (onCellPrepared)                    for (rowIndex = 0; rowIndex < data.length; rowIndex++) {                        row = data[rowIndex];                        rowElement = rowElements.eq(rowIndex);                        for (columnIndex = 0; columnIndex < row.length; columnIndex++) {                            cell = row[columnIndex];                            cellElement = rowElement.children().eq(columnIndex);                            onCellPrepared({                                area: areaName,                                rowIndex: rowIndex,                                columnIndex: columnIndex,                                cellElement: cellElement,                                cell: cell                            })                        }                    }            },            _getRowHeight: function(index) {                var row = this._getRowElement(index);                if (row && row.lastChild)                    return row.lastChild.offsetHeight;                return 0            },            _setRowHeight: function(index, value) {                var row = this._getRowElement(index);                if (row)                    row.style.height = value + 'px'            },            ctor: function(component) {                this.component = component            },            option: function() {                return this.component.option.apply(this.component, arguments)            },            getRowsLength: function() {                var that = this;                if (that._tableElement && that._tableElement.length > 0)                    return that._tableElement[0].rows.length;                return 0            },            getRowsHeight: function() {                var that = this,                    result = [],                    rowsLength = that.getRowsLength(),                    i;                for (i = 0; i < rowsLength; i++)                    result.push(that._getRowHeight(i));                return result            },            setRowsHeight: function(values) {                var that = this,                    totalHeight = 0,                    valuesLength = values.length,                    i;                for (i = 0; i < valuesLength; i++) {                    totalHeight += values[i];                    that._setRowHeight(i, values[i])                }                this._tableHeight = totalHeight;                this._tableElement[0].style.height = totalHeight + 'px'            },            getColumnsWidth: function() {                var rowsLength = this.getRowsLength(),                    rowIndex,                    isFixed = this._tableElement[0].style.tableLayout === 'fixed',                    row,                    i,                    columnIndex,                    processedCells = [],                    result = [],                    fillCells = function(cells, rowIndex, columnIndex, rowSpan, colSpan) {                        var rowOffset,                            columnOffset;                        for (rowOffset = 0; rowOffset < rowSpan; rowOffset++)                            for (columnOffset = 0; columnOffset < colSpan; columnOffset++) {                                cells[rowIndex + rowOffset] = cells[rowIndex + rowOffset] || [];                                cells[rowIndex + rowOffset][columnIndex + columnOffset] = true                            }                    };                if (rowsLength)                    for (rowIndex = 0; rowIndex < rowsLength; rowIndex++) {                        processedCells[rowIndex] = processedCells[rowIndex] || [];                        row = this._getRowElement(rowIndex);                        for (i = 0; i < row.cells.length; i++) {                            for (columnIndex = 0; processedCells[rowIndex][columnIndex]; columnIndex++);;                            fillCells(processedCells, rowIndex, columnIndex, row.cells[i].rowSpan, row.cells[i].colSpan);                            if (row.cells[i].colSpan === 1)                                result[columnIndex] = getRealElementWidth(row.cells[i], isFixed)                        }                    }                return result            },            setColumnsWidth: function(values) {                var i,                    totalWidth = 0;                var colgroupElementHTML = '';                for (i = 0; i < values.length; i++) {                    totalWidth += values[i];                    colgroupElementHTML += '<col style="width: ' + values[i] + 'px"/>'                }                this._colgroupElement.html(colgroupElementHTML);                this._tableWidth = totalWidth;                this._tableElement[0].style.width = totalWidth + 'px';                this._tableElement[0].style.tableLayout = 'fixed'            },            resetColumnsWidth: function() {                this._colgroupElement.find('col').width('auto');                this._tableElement.css({                    width: '',                    tableLayout: ''                })            },            groupWidth: function(value) {                if (value === undefined)                    return this._groupElement.width();                else if (value >= 0) {                    this._groupWidth = value;                    return this._groupElement[0].style.width = value + 'px'                }            },            groupHeight: function(value) {                if (value === undefined)                    return this._groupElement.height();                else if (value >= 0) {                    this._groupHeight = value;                    this._groupElement[0].style.height = value + 'px'                }            },            groupElement: function() {                return this._groupElement            },            tableElement: function() {                return this._tableElement            },            element: function() {                return this._rootElement            },            headElement: function() {                return this._tableElement.find('thead')            },            render: function(rootElement, data) {                var that = this,                    tableElement = that._createTableElement();                if (utils.isDefined(that._tableElement)) {                    try {                        that._tableElement[0].innerHTML = ''                    }                    catch(e) {                        that._tableElement.empty()                    }                    that._tableElement.attr('style', '');                    that._colgroupElement = $('<colgroup>').appendTo(that._tableElement);                    that._renderTableContent(that._tableElement, data)                }                else {                    that._groupElement = that._createGroupElement();                    that._tableElement = tableElement;                    that._colgroupElement = $('<colgroup>').appendTo(that._tableElement);                    that._renderTableContent(that._tableElement, data);                    that._tableElement.appendTo(that._groupElement);                    that._groupElement.appendTo(rootElement);                    that._rootElement = rootElement                }            }        })    })(jQuery, DevExpress);    /*! Module widgets-web, file ui.pivotGrid.headersArea.js */    (function($, DX) {        var ui = DX.ui,            events = ui.events,            pivotGrid = ui.dxPivotGrid,            utils = DX.utils;        pivotGrid.HorizontalHeadersArea = pivotGrid.AreaItem.inherit({            _getAreaName: function() {                return "column"            },            _getAreaClassName: function() {                return pivotGrid.cssClassNames.headersHorizontal            },            _textCellRender: function(rootElement, value) {                var $span = $('<span>');                if (!value)                    $span.html(" ");                else                    this.option("encodeHtml") ? $span.text(value) : $span.html(value);                $span.appendTo(rootElement)            },            _createGroupElement: function() {                return $('<div>').addClass(this._getAreaClassName()).addClass(pivotGrid.cssClassNames.area)            },            _createTableElement: function() {                return $('<table>')            },            _createRow: function() {                return $('<tr>')            },            _createCell: function(cell) {                var that = this,                    cellElement = $('<td>').attr({                        colspan: cell.colspan,                        rowspan: cell.rowspan                    });                if (utils.isDefined(cell.expanded)) {                    cellElement.addClass(cell.expanded ? pivotGrid.cssClassNames.headersExpanded : pivotGrid.cssClassNames.headersCollapsed).on(events.addNamespace("dxclick", this._getEventsNamespace()), function(e) {                        setTimeout(function() {                            var area = that._getAreaName();                            if (cell.expanded)                                that._dataSource.collapseHeaderItem(area, cell.path);                            else                                that._dataSource.expandHeaderItem(area, cell.path)                        })                    });                    $('<span>').addClass(pivotGrid.cssClassNames.headersExpandCollapseImage).appendTo(cellElement)                }                return cellElement            },            _applyCustomStyles: function(options) {                if (options.cellIndex === options.cellsCount - 1)                    options.cellElement.css('border-right', '0px');                if (options.cell.rowspan === options.rowsCount - options.rowIndex || options.rowIndex + 1 === options.rowsCount)                    options.cellElement.css('border-bottom-width', '0px');                options.cellElement.toggleClass(pivotGrid.cssClassNames.rowTotal, options.cell.type === 'T' || options.cell.type === 'GT').toggleClass(pivotGrid.cssClassNames.total, options.cell.type === 'T').toggleClass(pivotGrid.cssClassNames.grandTotal, options.cell.type === 'GT');                if (options.cell.width)                    options.cellElement.css("min-width", options.cell.width);                if (options.cell.sorted)                    $('<span>').addClass("dx-icon-sorted").appendTo(options.cellElement)            },            _renderTableContent: function(tableElement, data) {                var that = this,                    rowsCount = data.length,                    row,                    cell,                    i,                    j,                    rowElement,                    cellElement,                    theadElement = $('<thead>').addClass(this._getAreaClassName());                tableElement.width('auto');                for (i = 0; i < rowsCount; i++) {                    row = data[i];                    rowElement = that._createRow();                    for (j = 0; j < row.length; j++) {                        cell = row[j];                        cellElement = that._createCell(cell);                        that._textCellRender(cellElement, cell.text);                        that._applyCustomStyles({                            cellElement: cellElement,                            cell: cell,                            cellsCount: row.length,                            cellIndex: j,                            rowElement: rowElement,                            rowIndex: i,                            rowsCount: rowsCount                        });                        rowElement.append(cellElement)                    }                    theadElement.append(rowElement)                }                tableElement.append(theadElement);                that.callBase.apply(that, arguments)            },            _getEventsNamespace: function() {                return 'dxHeadersArea'            },            hasScroll: function() {                if (this._groupWidth && this._tableWidth)                    return this._tableWidth > this._groupWidth;                return false            },            processScroll: function() {                if (!this._groupElement.data('dxScrollable')) {                    this._groupElement.dxScrollable({                        useNative: true,                        useSimulatedScrollbar: false,                        showScrollbar: false,                        bounceEnabled: false,                        direction: "horizontal"                    });                    this._groupElement.find('.dx-scrollable-container').css('overflow', 'hidden')                }            },            processScrollBarSpacing: function(scrollBarWidth) {                var that = this;                if (that._groupWidth)                    that.groupWidth(that._groupWidth - scrollBarWidth);                if (that._scrollBarWidth)                    that._groupElement.next().remove();                that._groupElement.toggleClass(pivotGrid.cssClassNames.verticalScroll, scrollBarWidth > 0);                that._groupElement.css('float', 'left').width(that._groupHeight);                that._scrollBarWidth = scrollBarWidth            },            processStretch: function(resultSizes, hasScroll, dataFields) {                var that = this,                    tableSize = 0,                    groupSize = that._groupWidth,                    diff,                    diffElement,                    onePixelElementsCount,                    fixedWidthCount = 0,                    i;                for (i = 0; i < resultSizes.length; i++) {                    if (dataFields.length && dataFields[i % dataFields.length].width) {                        if (dataFields.length > 1)                            fixedWidthCount++;                        resultSizes[i] = dataFields[i % dataFields.length].width                    }                    tableSize += resultSizes[i]                }                that._testOriginalTableSize = tableSize;                if (groupSize && !hasScroll) {                    diff = groupSize - tableSize;                    diffElement = Math.floor(diff / (resultSizes.length - fixedWidthCount));                    onePixelElementsCount = diff - diffElement * (resultSizes.length - fixedWidthCount);                    for (i = 0; i < resultSizes.length; i++) {                        if (dataFields.length > 1 && dataFields[i % dataFields.length].width)                            continue;                        resultSizes[i] += diffElement;                        if (onePixelElementsCount) {                            resultSizes[i]++;                            onePixelElementsCount--                        }                    }                }            },            ctor: function(component) {                this.callBase(component);                this._scrollBarWidth = 0            },            setDataController: function(dataController) {                this._dataSource = dataController;                return this            }        });        pivotGrid.VerticalHeadersArea = pivotGrid.HorizontalHeadersArea.inherit({            _getAreaClassName: function() {                return pivotGrid.cssClassNames.headersVertical            },            _applyCustomStyles: function(options) {                var cellElement = options.cellElement;                this.callBase(options);                cellElement.addClass(options.cellIndex === options.cellsCount - 1 ? pivotGrid.cssClassNames.headersVerticalLastCell : null);                if (options.rowIndex === options.rowsCount - 1)                    cellElement.css('border-bottom', '0px');                if (options.rowIndex !== 0 && options.cell.expanded)                    options.rowElement.addClass(pivotGrid.cssClassNames.headersVerticalExpandBorder)            },            _getAreaName: function() {                return "row"            },            _getEventsNamespace: function() {                return 'dxVerticalHeadersArea'            },            hasScroll: function() {                if (this._groupHeight && this._tableHeight)                    return this._tableHeight > this._groupHeight;                return false            },            processScroll: function() {                if (!this._groupElement.data('dxScrollable')) {                    this._groupElement.dxScrollable({                        useNative: true,                        useSimulatedScrollbar: false,                        showScrollbar: false,                        bounceEnabled: false,                        direction: "vertical"                    });                    this._groupElement.find('.dx-scrollable-container').css('overflow', 'hidden')                }            },            processScrollBarSpacing: function(scrollBarWidth) {                var that = this;                if (that._groupHeight)                    that.groupHeight(that._groupHeight - scrollBarWidth);                if (that._scrollBarWidth)                    that._groupElement.next().remove();                if (scrollBarWidth)                    that._groupElement.after($('<div>').width('100%').height(scrollBarWidth - 1));                that._scrollBarWidth = scrollBarWidth            }        })    })(jQuery, DevExpress);    /*! Module widgets-web, file ui.pivotGrid.dataArea.js */    (function($, DX) {        var pivotGrid = DX.ui.dxPivotGrid;        pivotGrid.DataArea = pivotGrid.AreaItem.inherit({            _getAreaName: function() {                return "data"            },            _createGroupElement: function() {                return $('<div />').addClass(pivotGrid.cssClassNames.area).addClass(pivotGrid.cssClassNames.areaData)            },            _renderTableContent: function(tableElement, data) {                var i,                    j,                    row,                    cell,                    cellText,                    tableContentHTML = '',                    style,                    classNames;                for (i = 0; i < data.length; i++) {                    tableContentHTML += '<tr>';                    row = data[i];                    for (j = 0; j < row.length; j++) {                        cell = row[j];                        classNames = [];                        style = '';                        if (i === data.length - 1)                            style = 'border-bottom: 0px';                        if (cell) {                            if (cell.rowType === 'T' || cell.columnType === 'T')                                classNames.push(pivotGrid.cssClassNames.total);                            if (cell.rowType === 'GT' || cell.columnType === 'GT')                                classNames.push(pivotGrid.cssClassNames.grandTotal);                            if (cell.rowType === 'T' || cell.rowType === 'GT')                                classNames.push(pivotGrid.cssClassNames.rowTotal);                            cellText = cell.text || '';                            if (this.option("encodeHtml") && (cellText.indexOf("<") !== -1 || cellText.indexOf(">") !== -1))                                cellText = $("<div>").text(cellText).html();                            if (cell.width) {                                if (style)                                    style += '; ';                                style += 'min-width: ' + cell.width + 'px'                            }                        }                        else                            cellText = '';                        tableContentHTML += '<td class="' + classNames.join(' ') + '" style="' + style + '">' + cellText + '</td>'                    }                    tableContentHTML += '</tr>'                }                tableElement.append(tableContentHTML);                this.callBase.apply(this, arguments)            },            _processScrollCore: function(hasRowsScroll, hasColumnsScroll, useNativeScrolling) {                var that = this,                    groupElement = that._groupElement,                    options = {                        useNative: !!useNativeScrolling,                        useSimulatedScrollbar: !useNativeScrolling,                        direction: "both",                        bounceEnabled: false                    };                if (hasColumnsScroll && !hasRowsScroll)                    options.direction = "horizontal";                else if (!hasColumnsScroll)                    options.direction = "vertical";                groupElement.dxScrollable(options)            },            processScroll: function(scrollBarWidth, hasRowsScroll, hasColumnsScroll, useNativeScrolling) {                var that = this,                    groupElement = that._groupElement;                that._rootElement.css({                    position: 'relative',                    display: 'block'                });                groupElement.css('border-top-width', 0);                that._processScrollCore(hasRowsScroll, hasColumnsScroll, useNativeScrolling)            }        })    })(jQuery, DevExpress);    /*! Module widgets-web, file ui.pivotGrid.fieldChooser.js */    (function($, DX) {        var ui = DX.ui,            utils = DX.utils,            pivotGrid = ui.dxPivotGrid,            dataGrid = ui.dxDataGrid,            DIV = "<div>";        var ColumnsView = dataGrid.ColumnsView.inherit(dataGrid.sortingMixin).inherit(dataGrid.headerFilterMixin);        var HeaderFilterView = dataGrid.HeaderFilterView;        var FIELDCHOOSER_CLASS = "dx-pivotgridfieldchooser",            FIELDCHOOSER_CONTAINER_CLASS = "dx-pivotgridfieldchooser-container";        var processItems = function(groupItems, field, filterValues, isTree, level, path) {                level = level || 0;                path = path || [];                var currentField = field.levels ? field.levels[level] : field,                    i;                for (i = 0; i < groupItems.length; i++) {                    groupItems[i].text = groupItems[i].text || DX.formatHelper.format(groupItems[i].value, currentField.format, currentField.precision);                    path.push(groupItems[i].value);                    groupItems[i].filterValue = isTree ? path.slice(0) : groupItems[i].value;                    if ($.inArray(isTree ? path.join("/") : groupItems[i].value, filterValues) > -1 ^ field.filterType === "exclude")                        groupItems[i].selected = true;                    if (groupItems[i].children) {                        groupItems[i].items = groupItems[i].children;                        groupItems[i].children = null;                        processItems(groupItems[i].items, field, filterValues, isTree, level + 1, path)                    }                    path.pop()                }            };        var compareOrder = [function(a, b) {                    var aValue = -!!a.isMeasure,                        bValue = +!!b.isMeasure;                    return aValue + bValue                }, function(a, b) {                    var aValue = -!!(a.items && a.items.length),                        bValue = +!!(b.items && b.items.length);                    return aValue + bValue                }, function(a, b) {                    var aValue = +!!(a.field && a.field.levels && a.field.levels.length),                        bValue = -!!(b.field && b.field.levels && b.field.levels.length);                    return aValue + bValue                }, pivotGrid.getCompareFunction(function(item) {                    return item.text                })];        function compareItems(a, b) {            var result = 0,                i = 0;            while (!result && compareOrder[i])                result = compareOrder[i++](a, b);            return result        }        function getScrollable(container) {            return container.find(".dx-scrollable").dxScrollable("instance")        }        DX.registerComponent("dxPivotGridFieldChooser", ui, ui.Widget.inherit({            _setDefaultOptions: function() {                this.callBase();                this.option({                    height: 400,                    layout: 0,                    dataSource: null,                    texts: {                        columnFields: Globalize.localize("dxPivotGrid-columnFields"),                        rowFields: Globalize.localize("dxPivotGrid-rowFields"),                        dataFields: Globalize.localize("dxPivotGrid-dataFields"),                        filterFields: Globalize.localize("dxPivotGrid-filterFields"),                        allFields: Globalize.localize("dxPivotGrid-allFields")                    },                    headerFilter: {                        width: 252,                        height: 300,                        texts: {                            emptyValue: Globalize.localize("dxDataGrid-headerFilterEmptyValue"),                            ok: Globalize.localize("dxDataGrid-headerFilterOK"),                            cancel: Globalize.localize("dxDataGrid-headerFilterCancel")                        }                    }                })            },            _refreshDataSource: function() {                var that = this;                that._expandedPaths = [];                that._changedHandler = that._changedHandler || function() {                    $.each(that._dataChangedHandlers, function(_, func) {                        func()                    });                    that._updateIndicatorsPosition()                };                if (that._dataSource) {                    that._dataSource.off("changed", that._changedHandler);                    that._dataSource = undefined                }                var dataSource = this.option("dataSource");                if (dataSource && dataSource.fields && dataSource.load)                    that._dataSource = dataSource;                that._dataSource && that._dataSource.on("changed", that._changedHandler)            },            _init: function() {                this.callBase();                this._columnsView = new ColumnsView(this);                this._headerFilterView = new HeaderFilterView(this);                this._subscribeToEvents();                this._refreshDataSource();                this._dataChangedHandlers = []            },            _subscribeToEvents: function() {                var that = this;                that.element().on("dxclick", ".dx-area-field.dx-area-box", function(e) {                    var field = $.extend(true, {}, $(e.currentTarget).data("field")),                        isHeaderFilter = $(e.target).hasClass("dx-header-filter");                    if (isHeaderFilter)                        that._headerFilterView.showHeaderFilterMenu($(e.currentTarget), {                            type: field.groupName ? 'tree' : 'list',                            dataSource: {                                load: function(options) {                                    var userData = options.userData;                                    if (userData.store)                                        return userData.store.load(options);                                    else {                                        var d = $.Deferred();                                        that._dataSource.getFieldValues(field.index).done(function(data) {                                            userData.store = new DX.data.ArrayStore(data);                                            userData.store.load(options).done(d.resolve).fail(d.reject)                                        }).fail(d.reject);                                        return d                                    }                                },                                postProcess: function(data) {                                    var filterValues = [];                                    if (field.filterValues)                                        $.each(field.filterValues, function(index, filterValue) {                                            filterValues.push(utils.isArray(filterValue) ? filterValue.join("/") : filterValue)                                        });                                    processItems(data, field, filterValues, !!field.groupName);                                    return data                                }                            },                            filterValues: field.filterValues,                            filterType: field.filterType,                            apply: function() {                                that._dataSource.field(field.index, {                                    filterValues: this.filterValues,                                    filterType: this.filterType                                });                                that._dataSource.load()                            }                        });                    else if (field.allowSorting && field.area !== "data") {                        that._dataSource.field(field.index, {sortOrder: field.sortOrder === "desc" ? "asc" : "desc"});                        that._dataSource.load()                    }                })            },            _setOptionsByReference: function() {                this.callBase();                $.extend(this._optionsByReference, {dataSource: true})            },            _optionChanged: function(args) {                var that = this;                switch (args.name) {                    case"dataSource":                        that._refreshDataSource();                        that._invalidate();                        break;                    case"layout":                    case"texts":                    case"headerFilter":                        that._invalidate();                        break;                    default:                        that.callBase(args)                }            },            _clean: function() {                this.element().children("." + FIELDCHOOSER_CONTAINER_CLASS).remove()            },            _renderContentImpl: function() {                var that = this,                    element = this.element(),                    $col1,                    $col2;                element.addClass(FIELDCHOOSER_CLASS);                that._dataChangedHandlers = [];                that._renderSortable(element);                that._headerFilterView.render(element);                var $container = $(DIV).addClass(FIELDCHOOSER_CONTAINER_CLASS).appendTo(element);                if (this.option("layout") === 0) {                    $col1 = $(DIV).addClass("dx-col").appendTo($container);                    $col2 = $(DIV).addClass("dx-col").appendTo($container);                    this._renderArea($col1, "all");                    this._renderArea($col1, "filter");                    this._renderArea($col2, "row");                    this._renderArea($col2, "column");                    this._renderArea($col2, "data")                }                else if (this.option("layout") === 1) {                    $col1 = $(DIV).addClass("dx-col").appendTo($container);                    $col2 = $(DIV).addClass("dx-col").appendTo($container);                    this._renderArea($col1, "all");                    this._renderArea($col2, "filter");                    this._renderArea($col2, "row");                    this._renderArea($col2, "column");                    this._renderArea($col2, "data")                }                else {                    this._renderArea($container, "all");                    $col1 = $(DIV).addClass("dx-col").appendTo($container);                    $col2 = $(DIV).addClass("dx-col").appendTo($container);                    this._renderArea($col1, "filter");                    this._renderArea($col1, "row");                    this._renderArea($col2, "column");                    this._renderArea($col2, "data")                }                this.updateDimensions()            },            _renderSortable: function(element) {                var that = this;                that._createComponent(element, "dxSortable", {                    itemSelector: ".dx-area-field",                    itemContainerSelector: ".dx-area-field-container",                    groupSelector: ".dx-area-fields",                    itemRender: function($sourceItem, target) {                        var $item;                        if ($sourceItem.hasClass("dx-area-box"))                            $item = $sourceItem.clone();                        else                            $item = $(DIV).addClass("dx-area-field").addClass("dx-area-box").text($sourceItem.text());                        if (target === "drag")                            $item.width(element.find(".dx-area-field-container").first().width());                        return $item                    },                    onDragging: function(e) {                        var field = e.sourceElement.data("field"),                            targetGroup = e.targetGroup;                        e.cancel = false;                        if (field.isMeasure === true) {                            if (targetGroup === "column" || targetGroup === "row" || targetGroup === "filter")                                e.cancel = true                        }                        else if (field.isMeasure === false && targetGroup === "data")                            e.cancel = true                    },                    onChanged: function(e) {                        var dataSource = that._dataSource,                            field = e.sourceElement.data("field");                        e.removeSourceElement = !!e.sourceGroup;                        if (field) {                            dataSource.field(field.index, {                                area: e.targetGroup,                                areaIndex: e.targetIndex                            });                            dataSource.load()                        }                    }                })            },            _createTreeItems: function(fields, groupFieldNames, path) {                var that = this,                    isMeasure,                    resultItems = [],                    groupedItems = [],                    groupFieldName = groupFieldNames[0],                    fieldsByGroup = {};                if (!groupFieldName)                    $.each(fields, function(index, field) {                        var icon;                        if (field.isMeasure === true)                            icon = "measure";                        if (field.isMeasure === false)                            icon = field.groupName ? "hierarchy" : "dimension";                        resultItems.push({                            index: field.index,                            field: field,                            key: field.dataField,                            selected: utils.isDefined(field.area),                            text: field.caption || field.dataField,                            icon: icon,                            isMeasure: field.isMeasure                        })                    });                else {                    $.each(fields, function(index, field) {                        var groupName = field[groupFieldName] || "";                        fieldsByGroup[groupName] = fieldsByGroup[groupName] || [];                        fieldsByGroup[groupName].push(field);                        if (isMeasure === undefined)                            isMeasure = true;                        isMeasure = isMeasure && field.isMeasure === true                    });                    $.each(fieldsByGroup, function(groupName, fields) {                        var currentPath = path ? path + '.' + groupName : groupName;                        var items = that._createTreeItems(fields, groupFieldNames.slice(1), currentPath);                        if (groupName)                            groupedItems.push({                                key: groupName,                                text: groupName,                                path: currentPath,                                isMeasure: items.isMeasure,                                expanded: $.inArray(currentPath, that._expandedPaths) >= 0,                                items: items                            });                        else                            resultItems = items                    });                    resultItems = groupedItems.concat(resultItems);                    resultItems.isMeasure = isMeasure                }                return resultItems            },            _createFieldsDataSource: function(dataSource) {                var fields = dataSource && dataSource.fields() || [],                    treeItems;                fields = $.map(fields, function(field) {                    return field.visible === false || utils.isDefined(field.groupIndex) ? null : field                });                treeItems = this._createTreeItems(fields, ["dimension", "displayFolder"]);                pivotGrid.foreachDataLevel(treeItems, function(items) {                    items.sort(compareItems)                }, 0, "items");                return treeItems            },            _renderFieldsTreeView: function(container) {                var that = this,                    dataSource = that._dataSource,                    treeView = that._createComponent(container, "dxTreeView", {                        dataSource: that._createFieldsDataSource(dataSource),                        showCheckBoxes: true,                        itemTemplate: function(itemData, itemIndex, itemElement) {                            if (itemData.icon)                                utils.getImageContainer(itemData.icon).appendTo(itemElement);                            $('<span>').toggleClass("dx-area-field", !itemData.items).data("field", itemData.field).text(itemData.text).appendTo(itemElement)                        },                        onItemCollapsed: function(e) {                            var index = $.inArray(e.itemData.path, that._expandedPaths);                            if (index >= 0)                                that._expandedPaths.splice(index, 1)                        },                        onItemExpanded: function(e) {                            var index = $.inArray(e.itemData.path, that._expandedPaths);                            if (index < 0)                                that._expandedPaths.push(e.itemData.path)                        },                        onItemSelected: function(e) {                            var data = e.itemData,                                field,                                area;                            if (data.items)                                dataChanged();                            else {                                if (data.selected)                                    field = dataSource.fields()[data.index],                                    area = field && field.isMeasure ? "data" : "column";                                dataSource.field(data.index, {                                    area: area,                                    areaIndex: undefined                                });                                dataSource.load()                            }                        }                    }),                    dataChanged = function() {                        var scrollable = getScrollable(container),                            scrollTop = scrollable ? scrollable.scrollTop() : 0;                        treeView.option({dataSource: that._createFieldsDataSource(dataSource)});                        scrollable = getScrollable(container);                        if (scrollable) {                            scrollable.scrollTo({y: scrollTop});                            scrollable.update()                        }                    };                that._dataChangedHandlers.push(dataChanged)            },            _renderField: function(field) {                var that = this,                    $fieldContent = $(DIV).addClass("dx-area-field-content").text(field.caption || field.dataField),                    $fieldElement = $(DIV).addClass("dx-area-field").addClass("dx-area-box").data("field", field).append($fieldContent);                if (field.area !== "data") {                    if (field.allowSorting)                        that._columnsView._applyColumnState({                            name: 'sort',                            rootElement: $fieldElement,                            column: {                                alignment: that.option("rtlEnabled") ? 'right' : 'left',                                sortOrder: field.sortOrder === 'desc' ? 'desc' : 'asc'                            },                            showColumnLines: true                        });                    if (field.allowFiltering)                        that._columnsView._applyColumnState({                            name: 'headerFilter',                            rootElement: $fieldElement,                            column: {                                alignment: that.option("rtlEnabled") ? 'right' : 'left',                                filterValues: field.filterValues                            },                            showColumnLines: true                        })                }                return $fieldElement            },            _renderAreaFields: function($container, area) {                var that = this,                    dataSource = that._dataSource,                    fields = dataSource ? dataSource.getAreaFields(area, true) : [];                $container.empty();                $.each(fields, function() {                    that._renderField(this).appendTo($container)                })            },            _renderArea: function(container, area, height) {                var that = this,                    $areaContainer = $(DIV).addClass("dx-area").appendTo(container),                    caption = that.option("texts." + area + "Fields"),                    $fieldsContainer,                    $fieldsContent,                    render;                $("<span>").addClass("dx-area-icon").addClass("dx-area-icon-" + area).appendTo($areaContainer);                $("<span>").html(" ").appendTo($areaContainer);                $("<span>").addClass("dx-area-caption").text(caption).appendTo($areaContainer);                $fieldsContainer = $(DIV).addClass("dx-area-fields").height(0).appendTo($areaContainer);                if (area !== "all") {                    $fieldsContent = $(DIV).addClass("dx-area-field-container").appendTo($fieldsContainer);                    render = function() {                        that._renderAreaFields($fieldsContent, area)                    };                    that._dataChangedHandlers.push(render);                    render();                    $fieldsContainer.attr("group", area).dxScrollable()                }                else {                    $fieldsContainer.addClass("dx-treeview-border-visible");                    that._renderFieldsTreeView($fieldsContainer)                }            },            _updateIndicatorsPosition: function() {                var columnsView = this._columnsView;                $.each(this.element().find(".dx-area-field.dx-area-box"), function() {                    columnsView._updateIndicatorHeight($(this), "sort");                    columnsView._updateIndicatorHeight($(this), "headerFilter")                })            },            updateDimensions: function() {                var that = this,                    $element = this.element(),                    $container = $element.children(".dx-pivotgridfieldchooser-container"),                    $cols = $element.find(".dx-col"),                    $areaElements = $element.find(".dx-area-fields"),                    $scrollableElements = $element.find(".dx-area .dx-scrollable"),                    areaHeight;                that._updateIndicatorsPosition();                $areaElements.height(0);                if (this.option("layout") === 0) {                    areaHeight = Math.floor(($element.height() - $container.height()) / 3);                    $areaElements.height(areaHeight);                    $areaElements.eq(0).height($cols.eq(1).height() - $cols.eq(0).height() + areaHeight)                }                else if (this.option("layout") === 1) {                    areaHeight = Math.floor(($element.height() - $container.height()) / 4);                    $areaElements.height(areaHeight);                    $areaElements.eq(0).height($cols.eq(1).height() - $cols.eq(0).height() + areaHeight)                }                else {                    areaHeight = Math.floor(($element.height() - $container.height()) / 4);                    $areaElements.height(areaHeight);                    $areaElements.eq(0).height(areaHeight * 2)                }                $scrollableElements.dxScrollable("update")            }        }))    })(jQuery, DevExpress);    /*! Module widgets-web, file ui.scheduler.js */    (function($, DX, undefined) {        var ui = DX.ui,            utils = DX.utils;        var WIDGET_CLASS = "dx-scheduler",            WIDGET_READONLY_CLASS = "dx-scheduler-readonly",            APPOINTMENT_POPUP_CLASS = "dx-sheduler-appointment-popup",            APPOINTMENT_TOOLTIP_CLASS = "dx-scheduler-appointment-tooltip",            APPOINTMENT_TOOLTIP_TITLE_CLASS = "dx-scheduler-appointment-tooltip-title",            APPOINTMENT_TOOLTIP_DATE_CLASS = "dx-scheduler-appointment-tooltip-date",            APPOINTMENT_TOOLTIP_BUTTONS_CLASS = "dx-scheduler-appointment-tooltip-buttons",            APPOINTEMENT_POPUP_WIDTH = 610;        var WORKSPACES = {                day: "dxSchedulerWorkSpaceDay",                week: "dxSchedulerWorkSpaceWeek",                workWeek: "dxSchedulerWorkSpaceWorkWeek",                month: "dxSchedulerWorkSpaceMonth"            };        DX.registerComponent("dxScheduler", ui, ui.Widget.inherit({            _stripDateTime: function(date) {                utils.correctDateWithUnitBeginning(date, "day");                return date            },            _setDefaultOptions: function() {                this.callBase();                this.option({                    views: ["day", "week"],                    currentView: "day",                    currentDate: this._stripDateTime(new Date),                    firstDayOfWeek: undefined,                    groups: [],                    resources: [],                    dataSource: null,                    appointmentTemplate: "item",                    startDayHour: 0,                    endDayHour: 24,                    editing: true,                    onAppointmentRendered: null,                    onAppointmentAdding: null,                    onAppointmentAdded: null,                    onAppointmentUpdating: null,                    onAppointmentUpdated: null,                    onAppointmentDeleting: null,                    onAppointmentDeleted: null                })            },            _defaultOptionsRules: function() {                return this.callBase().concat([{                            device: function(device) {                                return DX.devices.real().generic && !DX.devices.isSimulator()                            },                            options: {focusStateEnabled: true}                        }])            },            _optionChanged: function(args) {                var value = args.value;                switch (args.name) {                    case"firstDayOfWeek":                        this._workSpace.option("firstDayOfWeek", value);                        this._header.option("firstDayOfWeek", value);                        break;                    case"currentDate":                        value = utils.makeDate(value);                        value = this._stripDateTime(value);                        this._appointments.element().empty();                        this._workSpace.option("currentDate", value);                        this._header.option("currentDate", value);                        this._filterAppointmentsByDate();                        break;                    case"dataSource":                        this._refreshDataSource();                        this._appointmentModel.setDataSource(this._dataSource);                        this._filterAppointmentsByDateAndResources();                        this._appointments.option("dataSource", this._dataSource);                        break;                    case"views":                        this._header.option("views", value);                        break;                    case"currentView":                        this._header.option("currentView", value);                        this._refreshWorkSpace();                        this._appointments.option("renderingStrategy", value);                        this._filterAppointmentsByDateAndResources();                        break;                    case"appointmentTemplate":                        this._appointments.option("itemTemplate", value);                        break;                    case"groups":                        var dateRange = this._workSpace.getDateRange();                        this._resourcesManager.getResourcesValueByFields(value).done($.proxy(function(groups) {                            var resources = this._prepareResourcesForFilter(groups);                            this._workSpace.option("groups", groups);                            this._appointmentModel.filterByDateAndResources({                                min: dateRange[0],                                max: dateRange[1],                                resources: resources,                                startDayHour: this.option("startDayHour"),                                endDayHour: this.option("endDayHour")                            })                        }, this));                        break;                    case"resources":                        this._resourcesManager.setResources(value);                        this._filterAppointmentsByResources();                        break;                    case"startDayHour":                        this._filterAppointmentsByDate();                        this._workSpace.option("startDayHour", value);                        break;                    case"endDayHour":                        this._filterAppointmentsByDate();                        this._workSpace.option("endDayHour", value);                        break;                    case"onAppointmentAdding":                    case"onAppointmentAdded":                    case"onAppointmentUpdating":                    case"onAppointmentUpdated":                    case"onAppointmentDeleting":                    case"onAppointmentDeleted":                        this._actions[args.name] = this._createActionByOption(args.name);                        break;                    case"onAppointmentRendered":                        this._appointments.option("onItemRendered", value);                        break;                    case"tabIndex":                    case"focusStateEnabled":                        this._header.option(args.name, value);                        this._workSpace.option(args.name, value);                        this._appointments.option(args.name, value);                        this.callBase(args);                        break;                    case"width":                        this._header.option("width", value);                        this.callBase(args);                        break;                    case"editing":                        this.element().toggleClass(WIDGET_READONLY_CLASS, !value);                        this._appointments.option({                            allowDrag: value,                            allowResize: value                        });                        this._refreshPopup();                        this._hideTooltip();                        break;                    default:                        this.callBase(args)                }            },            _filterAppointmentsByDate: function() {                var dateRange = this._workSpace.getDateRange();                this._appointmentModel.filterByDate(dateRange[0], dateRange[1], this.option("startDayHour"), this.option("endDayHour"))            },            _filterAppointmentsByResources: function() {                if (!this.option("resources") || !this.option("resources").length)                    return;                var that = this;                this._resourcesManager.getResourcesValueByFields(this.option("groups")).done(function(data) {                    that._appointmentModel.filterByResources(that._prepareResourcesForFilter(data))                })            },            _filterAppointmentsByDateAndResources: function() {                var dateRange = this._workSpace.getDateRange(),                    that = this;                this._resourcesManager.getResourcesValueByFields(this.option("groups")).done(function(data) {                    var resources = that._prepareResourcesForFilter(data);                    that._appointmentModel.filterByDateAndResources({                        min: dateRange[0],                        max: dateRange[1],                        resources: resources,                        startDayHour: that.option("startDayHour"),                        endDayHour: that.option("endDayHour")                    })                })            },            _prepareResourcesForFilter: function(resources) {                return $.map(resources, function(resource) {                        var data = [];                        for (var i = 0, len = resource.items.length; i < len; i++)                            data.push(resource.items[i].id);                        return {                                field: resource.name,                                data: data                            }                    })            },            _dimensionChanged: function() {                this._appointments.repaint()            },            _visibilityChanged: function(visible) {                if (visible)                    this._dimensionChanged()            },            _init: function() {                this.callBase();                this._initDataSource();                this.element().addClass(WIDGET_CLASS);                this.element().toggleClass(WIDGET_READONLY_CLASS, !this.option("editing"));                this._appointmentModel = new ui.dxScheduler.dxSchedulerAppointmentModel(this._dataSource);                this._resourcesManager = new ui.dxScheduler.dxSchedulerResourceManager(this.option("resources"));                this._initActions()            },            _initActions: function() {                this._actions = {                    onAppointmentAdding: this._createActionByOption("onAppointmentAdding"),                    onAppointmentAdded: this._createActionByOption("onAppointmentAdded"),                    onAppointmentUpdating: this._createActionByOption("onAppointmentUpdating"),                    onAppointmentUpdated: this._createActionByOption("onAppointmentUpdated"),                    onAppointmentDeleting: this._createActionByOption("onAppointmentDeleting"),                    onAppointmentDeleted: this._createActionByOption("onAppointmentDeleted")                }            },            _initAppointmentRenderedAction: function() {                return this._createActionByOption("onAppointmentRendered", {excludeValidators: ["designMode", "disabled", "readOnly"]})            },            _defaultAppointmentViewEditors: function() {                var that = this;                return [{                            key: "text",                            type: "dxTextBox",                            label: "dxScheduler-editorLabelTitle",                            cssClass: APPOINTMENT_POPUP_CLASS + "-caption"                        }, {                            key: "allDay",                            type: "dxSwitch",                            label: "dxScheduler-allDay",                            cssClass: APPOINTMENT_POPUP_CLASS + "-allday",                            options: {onValueChanged: function(args) {                                    var value = args.value,                                        startDateEditor = that._appointmentView.getEditorInstance("startDate"),                                        endDateEditor = that._appointmentView.getEditorInstance("endDate"),                                        startDate;                                    if (startDateEditor && endDateEditor) {                                        startDateEditor.option("format", value ? "date" : "datetime");                                        endDateEditor.option("format", value ? "date" : "datetime");                                        startDate = new Date(startDateEditor.option("value"));                                        if (value) {                                            startDate.setHours(0);                                            startDate.setMinutes(0);                                            startDateEditor.option("value", startDate);                                            var endDate = new Date(startDate);                                            endDate.setDate(startDate.getDate() + 1);                                            endDateEditor.option("value", endDate)                                        }                                        else if (startDateEditor.option("value")) {                                            startDate.setHours(that.option("startDayHour"));                                            startDateEditor.option("value", startDate);                                            endDateEditor.option("value", that._workSpace._calculateEndDate(startDateEditor.option("value")))                                        }                                    }                                }}                        }, {                            key: "startDate",                            type: "dxDateBox",                            label: "dxScheduler-editorLabelStartDate",                            cssClass: APPOINTMENT_POPUP_CLASS + "-start-date",                            options: {                                format: "datetime",                                onValueChanged: function(args) {                                    var value = args.value,                                        previousValue = args.previousValue,                                        endDateEditor = that._appointmentView.getEditorInstance("endDate"),                                        endValue = endDateEditor.option("value");                                    if (endValue <= value) {                                        var duration = endValue.getTime() - previousValue.getTime();                                        endDateEditor.option("value", new Date(value.getTime() + duration))                                    }                                }                            }                        }, {                            key: "endDate",                            type: "dxDateBox",                            label: "dxScheduler-editorLabelEndDate",                            cssClass: APPOINTMENT_POPUP_CLASS + "-end-date",                            options: {                                format: "datetime",                                onValueChanged: function(args) {                                    var value = args.value,                                        previousValue = args.previousValue,                                        startDateEditor = that._appointmentView.getEditorInstance("startDate"),                                        startValue = startDateEditor.option("value");                                    if (startValue >= value) {                                        var duration = previousValue.getTime() - startValue.getTime();                                        startDateEditor.option("value", new Date(value.getTime() - duration))                                    }                                }                            }                        }, {                            key: "description",                            type: "dxTextArea",                            label: "dxScheduler-editorLabelDescription",                            cssClass: APPOINTMENT_POPUP_CLASS + "-description"                        }, {                            key: "recurrenceRule",                            type: "dxSchedulerRecurrenceEditor",                            label: "dxScheduler-editorLabelRecurrence",                            cssClass: APPOINTMENT_POPUP_CLASS + "-recurrence"                        }]            },            _renderFocusTarget: $.noop,            _render: function() {                this.callBase();                this._renderHeader();                this._appointments = this._createComponent("<div>", "dxSchedulerAppointments", this._appointmentsConfig());                this._resourcesManager.getResourcesValueByFields(this.option("groups")).done($.proxy(function(groups) {                    this._renderWorkSpace(groups);                    var allDayContainerClass = this._workSpace.getAllDayContainerClass();                    this._appointments.option({allDayContainer: this.element().find("." + allDayContainerClass)});                    this._filterAppointmentsByDateAndResources();                    this._appointments.option("dataSource", this._dataSource)                }, this))            },            _renderHeader: function() {                this._header = this._createComponent("<div>", "dxSchedulerHeader", this._headerConfig());                this.element().append(this._header.element())            },            _headerConfig: function() {                return {                        observer: this,                        views: this.option("views"),                        firstDayOfWeek: this.option("firstDayOfWeek"),                        currentView: this.option("currentView"),                        currentDate: this._stripDateTime(utils.makeDate(this.option("currentDate"))),                        tabIndex: this.option("tabIndex"),                        focusStateEnabled: this.option("focusStateEnabled"),                        width: this.option("width")                    }            },            _appointmentsConfig: function() {                return {                        observer: this,                        renderingStrategy: this.option("currentView"),                        itemTemplate: this._getTemplateByOption("appointmentTemplate"),                        onItemRendered: this.option("onAppointmentRendered"),                        tabIndex: this.option("tabIndex"),                        focusStateEnabled: this.option("focusStateEnabled"),                        allowDrag: this.option("editing"),                        allowResize: this.option("editing")                    }            },            _renderWorkSpace: function(groups) {                this._workSpace = this._createComponent("<div>", WORKSPACES[this.option("currentView")], this._workSpaceConfig(groups));                this._workSpace.getWorkArea().append(this._appointments.element());                this.element().append(this._workSpace.element())            },            _workSpaceConfig: function(groups) {                return {                        observer: this,                        currentDate: this._stripDateTime(utils.makeDate(this.option("currentDate"))),                        firstDayOfWeek: this.option("firstDayOfWeek"),                        groups: groups,                        startDayHour: this.option("startDayHour"),                        endDayHour: this.option("endDayHour"),                        tabIndex: this.option("tabIndex"),                        focusStateEnabled: this.option("focusStateEnabled")                    }            },            _refreshWorkSpace: function() {                var allDayContainerClass = this._workSpace.getAllDayContainerClass();                this._appointments.element().detach();                this._workSpace._dispose();                this._workSpace.element().remove();                delete this._workSpace;                this._resourcesManager.getResourcesValueByFields(this.option("groups")).done($.proxy(function(groups) {                    this._renderWorkSpace(groups);                    this._appointments.option({allDayContainer: this.element().find("." + allDayContainerClass)})                }, this))            },            _createPopup: function() {                if (this._$popup)                    return;                this._refreshPopup()            },            _refreshPopup: function() {                this._$popup = $("<div>").addClass(APPOINTMENT_POPUP_CLASS).appendTo(this.element());                this._popup = this._createComponent(this._$popup, "dxPopup", this._popupConfig());                var $popupContent = this._popup.content();                $popupContent.empty();                var editors = this._defaultAppointmentViewEditors(),                    resources = this.option("resources");                if (resources && resources.length) {                    this._resourcesManager.setResources(this.option("resources"));                    editors = editors.concat(this._resourcesManager.getEditors())                }                this._appointmentView = new ui.dxScheduler.dxSchedulerAppointmentDetailsView($popupContent, {                    editors: editors,                    rtlEnabled: this.option("rtlEnabled"),                    readOnly: !this.option("editing")                })            },            _popupConfig: function() {                var buttons = [];                if (this.option("editing"))                    buttons = [{                            shortcut: "done",                            location: "after",                            onClick: $.proxy(this._saveChanges, this)                        }, {                            shortcut: "cancel",                            location: "after"                        }];                return {                        width: APPOINTEMENT_POPUP_WIDTH,                        target: "body",                        buttons: buttons,                        onHiding: $.proxy(function() {                            this._workSpace.focus()                        }, this)                    }            },            _saveChanges: function() {                var appointmentData = this._appointmentView.option("values"),                    oldData = this._editAppointmentData;                if (oldData)                    this._checkRecurringAppointment(oldData.recurrenceRule, $.proxy(function() {                        this.updateAppointment(this._editAppointmentData, appointmentData)                    }, this));                else                    this.addAppointment(appointmentData)            },            _checkRecurringAppointment: function(isRecurrence, callback, isDeleted) {                if (isRecurrence)                    this._showRecurrenceChangeConfirm(isDeleted).done($.proxy(function(result) {                        if (result)                            callback();                        else                            this._appointments.repaint()                    }, this));                else                    callback()            },            _showRecurrenceChangeConfirm: function(isDeleted) {                var message;                if (isDeleted)                    message = "All occurrences of the recurring appointment will be deleted.<br> Are you sure you want to delete them?";                else                    message = "All occurrences of the recurring appointment will be edited.<br> Are you sure you want to edit them?";                return ui.dialog.confirm(message, null, false)            },            _getUpdatedData: function(options) {                var target = options.data,                    data = this.getTargetCellData(),                    date = data.date || target.startDate,                    groups = data.groups,                    duration = target.endDate.getTime() - target.startDate.getTime();                var updatedData = {};                updatedData.allDay = data.allDay;                updatedData.startDate = date;                updatedData.endDate = new Date(date.getTime() + duration);                for (var name in groups)                    if (groups.hasOwnProperty(name))                        updatedData[name] = groups[name];                return updatedData            },            _getCoordinates: function(dates, resources, allDay) {                var result = [];                for (var i = 0; i < dates.length; i++)                    result = result.concat(this._workSpace.getCoordinatesByDateInGroup(dates[i], resources, allDay));                return result            },            _subscribes: {                currentViewUpdated: function(currentView) {                    this.option("currentView", currentView)                },                needCoordinates: function(options) {                    var appointmentData = options.appointmentData,                        startDate = options.startDate,                        dateRange = this._workSpace.getDateRange(),                        dates = utils.getDatesByRecurrence(appointmentData.recurrenceRule, startDate, dateRange[0], dateRange[1]);                    if (!dates.length)                        dates.push(startDate);                    var itemResources = this._resourcesManager.getResourcesFromItem(appointmentData);                    options.callback(this._getCoordinates(dates, itemResources, appointmentData.allDay))                },                showEditAppointmentPopup: function(appointmentData) {                    this._editAppointmentData = appointmentData;                    this.showAppointmentPopup(appointmentData)                },                showAppointmentTooltip: function(options) {                    this._editAppointmentData = options.data;                    this.showAppointmentTooltip(options.data, options.target)                },                hideAppointmentTooltip: function() {                    this._hideTooltip()                },                showAddAppointmentPopup: function(appointmentData) {                    delete this._editAppointmentData;                    if (this.option("editing"))                        this.showAppointmentPopup(appointmentData)                },                updateAppointmentAfterResize: function(options) {                    this._checkRecurringAppointment(options.target.recurrenceRule, $.proxy(function() {                        this._updateAppointment(options.target, options.data, function() {                            DX.translator.move(options.$appointment, options.initialCoordinates);                            options.target.startDate = utils.makeDate(options.target.startDate);                            options.target.endDate = utils.makeDate(options.target.endDate);                            if (this.option("currentView") === "month" || options.target.allDay || this.appointmentTakesAllDay(options.target))                                options.$appointment.outerWidth(options.initialSize.width);                            else                                options.$appointment.outerHeight(options.initialSize.height)                        })                    }, this))                },                updateAppointmentAfterDrag: function(options) {                    var target = options.data,                        updatedData = this._getUpdatedData(options),                        allDayContainerClass = this._workSpace.getAllDayContainerClass();                    if (options.$appointment.parent().hasClass(allDayContainerClass) && !updatedData.allDay)                        updatedData.endDate = this._workSpace._calculateEndDate(updatedData.startDate);                    var appointment = $.extend({}, target, updatedData);                    var targetStartDate = new Date(target.startDate);                    if (this.option("currentView") === "month")                        targetStartDate = this._stripDateTime(targetStartDate);                    if (Math.abs(updatedData.startDate.getTime() - targetStartDate.getTime()) >= this._workSpace._getInterval())                        this._checkRecurringAppointment(target.recurrenceRule, $.proxy(function() {                            this._updateAppointment(target, appointment, function() {                                DX.translator.move(options.$appointment, options.initialCoordinates)                            })                        }, this));                    else                        DX.translator.move(options.$appointment, options.initialCoordinates)                },                updateCurrentDate: function(date) {                    this.option("currentDate", this._stripDateTime(utils.makeDate(date)))                },                getAppointmentColor: function(options) {                    var resourceForPainting = this._resourcesManager.getResourceForPainting(this.option("groups"));                    if (resourceForPainting) {                        var field = resourceForPainting.field;                        if (options.itemData[field]) {                            var resourceValues = DX.utils.wrapToArray(options.itemData[field]),                                resourceIndex = options.resourceIndex,                                groups = this.option("groups");                            if (!groups || !groups.length)                                resourceIndex = 0;                            var resourceValue = resourceValues[resourceIndex];                            options.callback(this._resourcesManager.getResourceColor(field, resourceValue))                        }                    }                },                getResourceForPainting: function(options) {                    options.callback(this._resourcesManager.getResourceForPainting(this.option("groups")))                },                getResourcesFromItem: function(options) {                    options.callback(this._resourcesManager.getResourcesFromItem(options.itemData))                },                getCellDimensions: function(options) {                    if (this._workSpace)                        options.callback(this._workSpace.getCellWidth(), this._workSpace.getCellHeight(), this._workSpace.getAllDayHeight())                },                initAppointmentRenderedAction: function(options) {                    options.callback(this._initAppointmentRenderedAction())                },                getMaxAllowedPosition: function(options) {                    if (this._workSpace)                        options.callback(this._workSpace.getMaxAllowedPosition())                },                getItemGroupIndexes: function(options) {                    var groups = this._resourcesManager.getResourcesFromItem(options.item),                        indexes = this._workSpace._getGroupIndexes(groups);                    options.callback(indexes)                },                appointmentTakesAllDay: function(options) {                    options.callback(this.appointmentTakesAllDay({                        startDate: options.startDate,                        endDate: options.endDate                    }))                },                checkContainerVisibility: function(options) {                    options.callback(this.element().is(":hidden"))                }            },            subsribe: function(subject, action) {                this._subscribes[subject] = action            },            fire: function(subject, args) {                var callback = this._subscribes[subject];                if (!$.isFunction(callback))                    throw DX.Error("E1031", subject);                callback.call(this, args)            },            getTargetCellData: function() {                return this._workSpace.getDataByDroppableCell()            },            showAppointmentTooltip: function(appointmentData, $appointment) {                var that = this;                ui.tooltip.show({                    target: $appointment,                    contentTemplate: function($content) {                        var $tooltip = that._tooltipContent(appointmentData);                        $tooltip.addClass($content.attr("class"));                        $content.replaceWith($tooltip)                    }                })            },            _tooltipContent: function(appointmentData) {                var that = this;                var $tooltip = $("<div>").addClass(APPOINTMENT_TOOLTIP_CLASS);                $("<div>").text(appointmentData.text).addClass(APPOINTMENT_TOOLTIP_TITLE_CLASS).appendTo($tooltip);                $("<div>").addClass(APPOINTMENT_TOOLTIP_DATE_CLASS).text(that._formatTooltipDate(appointmentData.startDate, appointmentData.endDate)).appendTo($tooltip);                var $buttons = $("<div>").addClass(APPOINTMENT_TOOLTIP_BUTTONS_CLASS).appendTo($tooltip);                if (this.option("editing"))                    $("<div>").appendTo($buttons).dxButton({                        icon: "trash",                        onClick: function() {                            that._checkRecurringAppointment(appointmentData.recurrenceRule, function() {                                that.deleteAppointment(appointmentData)                            }, true);                            that._hideTooltip()                        }                    });                $("<div>").appendTo($buttons).dxButton({                    icon: this.option("editing") ? "edit" : "",                    text: Globalize.localize("dxScheduler-openAppointment"),                    onClick: function() {                        that.showAppointmentPopup(appointmentData)                    }                });                return $tooltip            },            _hideTooltip: function() {                ui.tooltip.hide()            },            _formatTooltipDate: function(startDate, endDate) {                var dateTimeFormat = "MMMM d h:mm tt";                if (this.option("currentView") === "month") {                    var startDateString = Globalize.format(startDate, dateTimeFormat) + " - ",                        endDateString = startDate.getDate() === endDate.getDate() ? Globalize.format(endDate, "t") : Globalize.format(endDate, dateTimeFormat);                    return startDateString + endDateString                }                return Globalize.format(startDate, "t") + " - " + Globalize.format(endDate, "t")            },            _executeActionWhenOperationIsCompleted: function(action, appointment, e) {                var options = {appointment: appointment},                    isError = e && e.name === "Error";                if (isError)                    options.error = e;                action(options)            },            _updateAppointment: function(target, appointment, onUpdatePrevented) {                var updatingOptions = {                        newData: appointment,                        oldData: target,                        cancel: false                    };                this._actions["onAppointmentUpdating"](updatingOptions);                if (!updatingOptions.cancel)                    this._appointmentModel.update(target, appointment).always($.proxy(function(e) {                        this._executeActionWhenOperationIsCompleted(this._actions["onAppointmentUpdated"], appointment, e)                    }, this));                else if ($.isFunction(onUpdatePrevented))                    onUpdatePrevented.call(this)            },            showAppointmentPopup: function(appointmentData) {                this._createPopup();                this._popup.show();                this._appointmentView.option("values", appointmentData)            },            getAppointmentDetailsView: function() {                return this._appointmentView            },            getAppointmentResourceData: function(field, value) {                return this._resourcesManager.getResourceDataByValue(field, value)            },            getActions: function() {                return this._actions            },            appointmentTakesAllDay: function(appointment) {                var etalonDayDurationInHours = this.option("endDayHour") - this.option("startDayHour"),                    appointmentDurationInHours = (appointment.endDate.getTime() - appointment.startDate.getTime()) / 3600000;                return appointmentDurationInHours >= etalonDayDurationInHours            },            addAppointment: function(appointment) {                if (!appointment.text)                    appointment.text = "";                var addingOptions = {                        appointment: appointment,                        cancel: false                    };                this._actions["onAppointmentAdding"](addingOptions);                if (!addingOptions.cancel)                    this._appointmentModel.add(appointment).always($.proxy(function(e) {                        this._executeActionWhenOperationIsCompleted(this._actions["onAppointmentAdded"], appointment, e)                    }, this))            },            updateAppointment: function(target, appointment) {                this._updateAppointment(target, appointment)            },            deleteAppointment: function(appointment) {                var deletingOptions = {                        appointment: appointment,                        cancel: false                    };                this._actions["onAppointmentDeleting"](deletingOptions);                if (!deletingOptions.cancel)                    this._appointmentModel.remove(appointment).always($.proxy(function(e) {                        this._executeActionWhenOperationIsCompleted(this._actions["onAppointmentDeleted"], appointment, e)                    }, this))            }        }).include(ui.DataHelperMixin))    })(jQuery, DevExpress);    /*! Module widgets-web, file ui.scheduler.appointmentModel.js */    (function($, DX, undefined) {        var utils = DX.utils;        var AppointmentModel = DX.Class.inherit({                _resourceFilter: function(itemData, resources) {                    var result = true;                    for (var i = 0, len = resources.length; i < len; i++) {                        var resourceField = resources[i].field,                            resourceData = resources[i].data;                        if (itemData.hasOwnProperty(resourceField))                            if (!$.isArray(itemData[resourceField])) {                                if ($.inArray(itemData[resourceField], resourceData) === -1) {                                    result = false;                                    break                                }                            }                            else {                                result = false;                                for (var j = 0, itemDataCount = itemData[resourceField].length; j < itemDataCount; j++)                                    if ($.inArray(itemData[resourceField][j], resourceData) > -1) {                                        result = true;                                        break                                    }                            }                        else {                            result = false;                            break                        }                    }                    return result                },                ctor: function(dataSource) {                    this.setDataSource(dataSource)                },                setDataSource: function(dataSource) {                    this._dataSource = dataSource                },                filterByDate: function(min, max, startDayHour, endDayHour) {                    if (!this._dataSource)                        return;                    var filter = this._prepareDateFilter(min, max, startDayHour, endDayHour);                    this._dataSource.filter(filter);                    this._dataSource.load()                },                _prepareDateFilter: function(min, max, startDayHour, endDayHour) {                    var ds = this._dataSource;                    return function(itemData) {                            if ($.isFunction(ds._mapFunc))                                itemData = ds._mapFunc(itemData);                            var currentDate = utils.makeDate(itemData.startDate),                                rule = itemData.recurrenceRule,                                isAllDay = itemData.allDay;                            var stripDateTime = function(date) {                                    date = new Date(date);                                    utils.correctDateWithUnitBeginning(date, "day");                                    return date                                };                            var result = utils.dateInRange(currentDate, min, max) && !rule || utils.dateInRange(currentDate, stripDateTime(min), max) && isAllDay || utils.dateInRecurrenceRange(rule, currentDate, min, max);                            if (result && startDayHour)                                result = currentDate.getHours() >= startDayHour || isAllDay;                            if (result && endDayHour)                                result = currentDate.getHours() <= endDayHour || isAllDay;                            return result                        }                },                filterByResources: function(resources) {                    if (!this._dataSource)                        return;                    var filter = this._prepareResourcesFilter(resources);                    this._dataSource.filter(filter);                    this._dataSource.load()                },                _prepareResourcesFilter: function(resources) {                    return $.proxy(function(itemData) {                            return this._resourceFilter(itemData, resources)                        }, this)                },                filterByDateAndResources: function(options) {                    if (!this._dataSource)                        return;                    this._dataSource.filter($.proxy(function(itemData) {                        var dateFilter = this._prepareDateFilter(options.min, options.max, options.startDayHour, options.endDayHour),                            resourceFilter = this._prepareResourcesFilter(options.resources);                        return dateFilter(itemData) && resourceFilter(itemData)                    }, this));                    this._dataSource.load()                },                add: function(data) {                    return this._dataSource.store().insert(data).done($.proxy(function() {                            this._dataSource.load()                        }, this))                },                update: function(target, data) {                    return this._dataSource.store().update(target, data).done($.proxy(function() {                            this._dataSource.load()                        }, this))                },                remove: function(target) {                    return this._dataSource.store().remove(target).done($.proxy(function() {                            this._dataSource.load()                        }, this))                }            });        DX.ui.dxScheduler.dxSchedulerAppointmentModel = AppointmentModel    })(jQuery, DevExpress);    /*! Module widgets-web, file ui.scheduler.recurrenceEditor.js */    (function($, DX, undefined) {        var utils = DX.utils;        var RECURRENCE_EDITOR = "dx-recurrence-editor",            LABEL_PREFIX = "-label",            RECURRENCE_EDITOR_CONTAINER = "dx-recurrence-editor-container",            SWITCH_EDITOR = "dx-recurrence-switch",            SWITCH_REPEAT_END_EDITOR = "dx-recurrence-switch-repeat-end",            FREQUENCY_EDITOR = "dx-recurrence-radiogroup-freq",            INTERVAL_EDITOR = "dx-recurrence-numberbox-interval",            INTERVAL_EDITOR_FIELD = "dx-recurrence-interval-field",            REPEAT_END_EDITOR = "dx-recurrence-repeat-end",            REPEAT_END_EDITOR_FIELD = "dx-recurrence-repeat-end-field",            REPEAT_END_EDITOR_CONTAINER = "dx-recurrence-repeat-end-container",            REPEAT_TYPE_EDITOR = "dx-recurrence-radiogroup-repeat-type",            REPEAT_COUNT_EDITOR = "dx-recurrence-numberbox-repeat-count",            REPEAT_UNTIL_DATE_EDITOR = "dx-recurrence-datebox-until-date",            REPEAT_ON_EDITOR = "dx-recurrence-repeat-on",            REPEAT_ON_WEEK_EDITOR = "dx-recurrence-repeat-on-week",            DAY_OF_WEEK = "dx-recurrence-checkbox-day-of-week",            REPEAT_ON_MONTH_EDITOR = "dx-recurrence-repeat-on-month",            DAY_OF_MONTH = "dx-recurrence-numberbox-day-of-month",            REPEAT_ON_YEAR_EDITOR = "dx-recurrence-repeat-on-year",            MONTH_OF_YEAR = "dx-recurrence-selectbox-month-of-year",            FIELD_CLASS = "dx-field",            FIELD_LABEL_CLASS = "dx-field-label",            FIELD_VALUE_CLASS = "dx-field-value",            frequencies = [{                    text: function() {                        return Globalize.localize("dxScheduler-recurrenceDaily")                    },                    value: "DAILY"                }, {                    text: function() {                        return Globalize.localize("dxScheduler-recurrenceWeekly")                    },                    value: "WEEKLY"                }, {                    text: function() {                        return Globalize.localize("dxScheduler-recurrenceMonthly")                    },                    value: "MONTHLY"                }, {                    text: function() {                        return Globalize.localize("dxScheduler-recurrenceYearly")                    },                    value: "YEARLY"                }],            repeatEndTypes = [{                    text: function() {                        return Globalize.localize("dxScheduler-recurrenceRepeatCount")                    },                    value: "count"                }, {                    text: function() {                        return Globalize.localize("dxScheduler-recurrenceRepeatOnDate")                    },                    value: "until"                }];        var RecurrenceRule = DX.Class.inherit({                ctor: function(recurrence) {                    this._recurrenceRule = DX.utils.getRecurrenceRule(recurrence)                },                makeRules: function(string) {                    var that = this;                    that._recurrenceRule = utils.getRecurrenceRule(string)                },                makeRule: function(field, value) {                    if (!value) {                        delete this._recurrenceRule[field];                        return                    }                    if (utils.isDefined(field)) {                        if (field === "until")                            delete this._recurrenceRule.count;                        if (field === "count")                            delete this._recurrenceRule.until;                        this._recurrenceRule[field] = value                    }                },                repeatableRule: function() {                    var rules = this._recurrenceRule;                    if ("count" in rules)                        return "count";                    if ("until" in rules)                        return "until";                    return null                },                recurrenceString: function() {                    return utils.getRecurrenceString(this._recurrenceRule)                },                rules: function() {                    return this._recurrenceRule                },                daysFromByDayRule: function() {                    var result = [];                    if (this._recurrenceRule.byday)                        result = this._recurrenceRule.byday.split(",");                    return result                }            });        DX.registerComponent("dxSchedulerRecurrenceEditor", DX.ui.dxScheduler, DX.ui.Editor.inherit({            _setDefaultOptions: function() {                this.callBase();                this.option({                    value: null,                    onValueChanged: null,                    startDate: new Date                })            },            _init: function() {                this.callBase();                this._recurrenceRule = new RecurrenceRule(this.option("value"))            },            _render: function() {                this.callBase();                this.element().addClass(RECURRENCE_EDITOR);                this._renderSwitch();                this._$container = $("<div>").addClass(RECURRENCE_EDITOR_CONTAINER).appendTo(this.element());                this._renderEditors();                this._renderContainerVisibility()            },            _renderSwitch: function() {                var $switchEditor = $("<div>").addClass(SWITCH_EDITOR);                this._switchEditor = this._createComponent($switchEditor, "dxSwitch", {                    value: false,                    onValueChanged: $.proxy(this._switchValueChangeHandler, this)                });                this.element().append($switchEditor)            },            _switchValueChangeHandler: function(args) {                var value = args.value;                this._renderContainerVisibility(value);                if (!this.option("value") && value)                    this._handleDefaults();                else if (!value) {                    this._recurrenceRule.makeRules("");                    this.option("value", "")                }            },            _renderContainerVisibility: function(value) {                if (value) {                    this._$container.show();                    DX.utils.triggerShownEvent(this._$container)                }                else                    this._$container.hide()            },            _handleDefaults: function() {                this._recurrenceRule.makeRule("freq", "DAILY");                this.option("value", this._recurrenceRule.recurrenceString())            },            _renderEditors: function() {                this._renderFreqEditor();                this._renderIntervalEditor();                this._renderRepeatOnEditor();                this._renderRepeatEndSwitch();                this._renderRepeatEndEditor();                this._renderRepeatEndVisibility()            },            _renderFreqEditor: function() {                var freq = this._recurrenceRule.rules().freq || "DAILY";                var $freqEditor = $("<div>").addClass(FREQUENCY_EDITOR).addClass(FIELD_VALUE_CLASS);                this._freqEditor = this._createComponent($freqEditor, "dxRadioGroup", {                    field: "freq",                    items: frequencies,                    value: freq,                    valueExpr: "value",                    displayExpr: "text",                    layout: "horizontal",                    onValueChanged: $.proxy(this._valueChangedHandler, this)                });                var $field = $("<div>").addClass(FIELD_CLASS).append($freqEditor);                this._$container.append($field)            },            _renderIntervalEditor: function() {                var freq = this._recurrenceRule.rules().freq || "DAILY";                var $intervalEditor = $("<div>").addClass(INTERVAL_EDITOR).addClass(FIELD_VALUE_CLASS);                var $intervalEditorLabel = $("<div>").text(Globalize.localize("dxScheduler-recurrenceEvery") + ":").addClass(INTERVAL_EDITOR + LABEL_PREFIX).addClass(FIELD_LABEL_CLASS);                this._$intervalTypeLabel = $("<div>").text(Globalize.localize("dxScheduler-recurrenceRepeat" + freq.charAt(0).toUpperCase() + freq.substr(1).toLowerCase())).addClass(REPEAT_TYPE_EDITOR + LABEL_PREFIX);                var interval = this._recurrenceRule.rules().interval || 1;                this._intervalEditor = this._createComponent($intervalEditor, "dxNumberBox", {                    field: "interval",                    min: 1,                    value: interval,                    showSpinButtons: true,                    useTouchSpinButtons: false,                    onValueChanged: $.proxy(this._valueChangedHandler, this)                });                var $field = $("<div>").addClass(FIELD_CLASS).addClass(INTERVAL_EDITOR_FIELD).append($intervalEditorLabel, $intervalEditor, this._$intervalTypeLabel);                this._$container.append($field)            },            _renderRepeatOnEditor: function() {                var freq = this._recurrenceRule.rules().freq;                if (!utils.isDefined(this._$repeatOnEditor))                    this._$repeatOnEditor = $("<div>").addClass(REPEAT_ON_EDITOR).addClass(FIELD_CLASS).appendTo(this._$container);                if (!freq || freq === "DAILY") {                    this._clearRepeatOnEditor();                    this._clearRepeatOnLabel();                    return                }                if (!utils.isDefined(this._$repeatOnLabel))                    this._renderRepeatOnLabel(this._$repeatOnEditor);                if (freq === "WEEKLY" && !this._$repeatOnWeek) {                    this._renderRepeatOnWeekEditor();                    return                }                if (freq === "MONTHLY" && !this._$repeatOnMonth) {                    this._renderRepeatOnMonthEditor();                    return                }                if (freq === "YEARLY" && !this._$repeatOnYear) {                    this._renderRepeatOnYearEditor();                    return                }            },            _renderRepeatOnLabel: function($element) {                this._$repeatOnLabel = $("<div>").text(Globalize.localize("dxScheduler-recurrenceOn") + ":").addClass(REPEAT_ON_EDITOR + LABEL_PREFIX).addClass(FIELD_LABEL_CLASS);                $element.append(this._$repeatOnLabel)            },            _clearRepeatOnEditor: function() {                if (utils.isDefined(this._$repeatOnWeek)) {                    this._$repeatOnWeek.detach();                    this._$repeatOnWeek.remove();                    delete this._$repeatOnWeek                }                if (utils.isDefined(this._$repeatOnMonth)) {                    this._$repeatOnMonth.detach();                    this._$repeatOnMonth.remove();                    delete this._$repeatOnMonth                }                if (utils.isDefined(this._$repeatOnYear)) {                    this._$repeatOnYear.detach();                    this._$repeatOnYear.remove();                    delete this._$repeatOnYear                }            },            _clearRepeatOnEditorValues: function() {                this._recurrenceRule.makeRule("bymonth", "");                this._recurrenceRule.makeRule("bymonthday", "");                this._recurrenceRule.makeRule("byday", "")            },            _clearRepeatOnLabel: function() {                if (utils.isDefined(this._$repeatOnLabel)) {                    this._$repeatOnLabel.detach();                    this._$repeatOnLabel.remove();                    delete this._$repeatOnLabel                }            },            _renderRepeatOnWeekEditor: function() {                this._clearRepeatOnEditor();                this._$repeatOnWeek = $("<div>").addClass(REPEAT_ON_WEEK_EDITOR).addClass(FIELD_VALUE_CLASS).appendTo(this._$repeatOnEditor);                var days = Globalize.culture().calendar.days.namesShort,                    daysFromRules = this._daysOfWeekByRules();                this._daysOfWeek = [];                for (var i = 0; i < 7; i++) {                    var checkBoxText = days[i].toUpperCase();                    var $day = $("<div>").addClass(DAY_OF_WEEK),                        day = this._createComponent($day, "dxCheckBox", {                            text: checkBoxText,                            value: $.inArray(checkBoxText, daysFromRules) > -1 ? true : false,                            onValueChanged: $.proxy(this._repeatByDayValueChangeHandler, this)                        });                    this._daysOfWeek[i] = day;                    this._$repeatOnWeek.append($day)                }            },            _daysOfWeekByRules: function() {                var days = Globalize.culture().calendar.days.namesShort;                var daysByRule = this._recurrenceRule.daysFromByDayRule();                if (!daysByRule.length)                    daysByRule = [days[this.option("startDate").getDay()].toUpperCase()];                return daysByRule            },            _repeatByDayValueChangeHandler: function() {                var byDayRule = "";                $.each(this._daysOfWeek, function(index, day) {                    if (day.option("value")) {                        var dayName = day.option("text");                        if (!byDayRule)                            byDayRule = dayName;                        else                            byDayRule = byDayRule + "," + dayName                    }                });                this._recurrenceRule.makeRule("byday", byDayRule);                this.option("value", this._recurrenceRule.recurrenceString())            },            _renderRepeatOnMonthEditor: function() {                this._clearRepeatOnEditor();                this._$repeatOnMonth = $("<div>").addClass(REPEAT_ON_MONTH_EDITOR).addClass(FIELD_VALUE_CLASS).appendTo(this._$repeatOnEditor);                this._renderDayOfMonthEditor(this._$repeatOnMonth)            },            _renderRepeatOnYearEditor: function() {                this._clearRepeatOnEditor();                this._$repeatOnYear = $("<div>").addClass(REPEAT_ON_YEAR_EDITOR).addClass(FIELD_VALUE_CLASS).appendTo(this._$repeatOnEditor);                var months = [],                    monthsNames = Globalize.cultures["default"].calendar.months.names;                for (var i = 0; i < 12; i++)                    months[i] = {                        value: String(i + 1),                        text: monthsNames[i]                    };                var bymonth = this._monthOfYearByRules();                var $monthOfYear = $("<div>").addClass(MONTH_OF_YEAR).appendTo(this._$repeatOnYear);                var monthChanged = function(args) {                        this._valueChangedHandler.call(this, args);                        var monthValue = parseInt(args.component.option("value"));                        if (this._dayEditor && monthValue) {                            var maxAllowedDay = new Date((new Date).getFullYear(), parseInt(monthValue), 0).getDate();                            if (monthValue === 2)                                maxAllowedDay = 29;                            this._dayEditor.option("max", maxAllowedDay)                        }                    };                this._monthEditor = this._createComponent($monthOfYear, "dxSelectBox", {                    field: "bymonth",                    items: months,                    value: bymonth,                    displayExpr: "text",                    valueExpr: "value",                    onValueChanged: $.proxy(monthChanged, this)                });                this._renderDayOfMonthEditor(this._$repeatOnYear)            },            _monthOfYearByRules: function() {                var monthByRule = this._recurrenceRule.rules().bymonth;                if (!monthByRule)                    monthByRule = this.option("startDate").getMonth();                return monthByRule            },            _renderDayOfMonthEditor: function($element) {                var bymonthday = this._dayOfMonthByRules();                var $dayEditor = $("<div>").addClass(DAY_OF_MONTH);                this._dayEditor = this._createComponent($dayEditor, "dxNumberBox", {                    field: "bymonthday",                    min: 1,                    max: 31,                    showSpinButtons: true,                    useTouchSpinButtons: false,                    value: bymonthday,                    onValueChanged: $.proxy(this._valueChangedHandler, this)                });                $element.append($dayEditor)            },            _dayOfMonthByRules: function() {                var dayByRule = this._recurrenceRule.rules().bymonthday;                if (!dayByRule)                    dayByRule = this.option("startDate").getDate();                return dayByRule            },            _renderRepeatEndSwitch: function() {                var that = this;                var $switchEndEditor = $("<div>").addClass(SWITCH_REPEAT_END_EDITOR).addClass(FIELD_VALUE_CLASS),                    $switchEndLabel = $("<div>").text(Globalize.localize("dxScheduler-recurrenceEnd") + ":").addClass(INTERVAL_EDITOR + LABEL_PREFIX).addClass(FIELD_LABEL_CLASS);                this._switchEndEditor = this._createComponent($switchEndEditor, "dxSwitch", {                    value: that._recurrenceRule.repeatableRule() ? true : false,                    onValueChanged: $.proxy(this._repeatEndSwitchValueChangeHandler, this)                });                $("<div>").addClass(FIELD_CLASS).addClass(REPEAT_END_EDITOR_FIELD).append($switchEndLabel, $switchEndEditor).appendTo(this._$container)            },            _repeatEndSwitchValueChangeHandler: function(args) {                var value = args.value;                this._renderRepeatEndVisibility(value);                if (!this._recurrenceRule.rules().count && !this._recurrenceRule.rules().until && value)                    this._handleRepeatEndDefaults();                else if (!value) {                    this._recurrenceRule.makeRule("count", "");                    this._recurrenceRule.makeRule("until", "");                    this.option("value", this._recurrenceRule.recurrenceString())                }            },            _renderRepeatEndVisibility: function(value) {                if (!value)                    this._$repeatEndEditor.hide();                else                    this._$repeatEndEditor.show()            },            _handleRepeatEndDefaults: function() {                this._recurrenceRule.makeRule("count", 1);                this.option("value", this._recurrenceRule.recurrenceString())            },            _renderRepeatEndEditor: function(rule) {                rule = utils.isDefined(rule) ? rule : this._recurrenceRule.repeatableRule();                if (!rule)                    rule = "count";                if (!utils.isDefined(this._$repeatEndEditor)) {                    this._$repeatEndEditor = $("<div>").addClass(REPEAT_END_EDITOR_CONTAINER).addClass(FIELD_CLASS).appendTo(this._$container);                    this._renderRepeatEndTypeEditor()                }            },            _renderRepeatEndTypeEditor: function() {                var repeatType = this._recurrenceRule.repeatableRule() || "count",                    that = this;                this._$repeatTypeEditor = $("<div>").addClass(REPEAT_TYPE_EDITOR).addClass(FIELD_VALUE_CLASS).appendTo(this._$repeatEndEditor);                this._repeatTypeEditor = this._createComponent(this._$repeatTypeEditor, "dxRadioGroup", {                    items: repeatEndTypes,                    value: repeatType,                    displayExpr: "text",                    valueExpr: "value",                    itemTemplate: function(itemData) {                        if (itemData.value === "count")                            return that._renderRepeatCountEditor();                        else                            return that._renderRepeatUntilEditor()                    },                    layout: "vertical",                    onValueChanged: $.proxy(this._repeatTypeValueChangedHandler, this)                });                this._disableRepeatEndParts(repeatType)            },            _repeatTypeValueChangedHandler: function(args) {                var value = args.value;                this._disableRepeatEndParts(value);                if (value === "until")                    this._recurrenceRule.makeRule(value, utils.getAsciiStringByDate(this._repeatUntilDate.option("value")));                else if (value === "count")                    this._recurrenceRule.makeRule(value, this._repeatCountEditor.option("value"));                this.option("value", this._recurrenceRule.recurrenceString())            },            _disableRepeatEndParts: function(value) {                if (value === "until") {                    this._repeatCountEditor.option("disabled", true);                    this._repeatUntilDate.option("disabled", false)                }                else if (value === "count") {                    this._repeatCountEditor.option("disabled", false);                    this._repeatUntilDate.option("disabled", true)                }            },            _renderRepeatCountEditor: function() {                var repeatCount = this._recurrenceRule.rules().count || 1,                    $editorTemplate = $("<div>");                $("<div>").text(Globalize.localize("dxScheduler-recurrenceAfter") + ":").addClass(REPEAT_END_EDITOR + LABEL_PREFIX).appendTo($editorTemplate);                this._$repeatCountEditor = $("<div>").addClass(REPEAT_COUNT_EDITOR).addClass(FIELD_VALUE_CLASS).appendTo($editorTemplate);                $("<div>").text(Globalize.localize("dxScheduler-recurrenceRepeatCount")).addClass(REPEAT_END_EDITOR + LABEL_PREFIX).appendTo($editorTemplate);                this._repeatCountEditor = this._createComponent(this._$repeatCountEditor, "dxNumberBox", {                    field: "count",                    min: 1,                    showSpinButtons: true,                    useTouchSpinButtons: false,                    value: repeatCount,                    onValueChanged: $.proxy(this._repeatCountValueChangeHandler, this)                });                return $editorTemplate            },            _repeatCountValueChangeHandler: function(args) {                if (this._recurrenceRule.repeatableRule() !== "count")                    return;                var value = args.value;                this._recurrenceRule.makeRule("count", value);                this.option("value", this._recurrenceRule.recurrenceString())            },            _renderRepeatUntilEditor: function() {                var repeatUntil = this._recurrenceRule.rules().until || new Date,                    $editorTemplate = $("<div>");                $("<div>").text(Globalize.localize("dxScheduler-recurrenceOn") + ":").addClass(REPEAT_END_EDITOR + LABEL_PREFIX).appendTo($editorTemplate);                this._$repeatDateEditor = $("<div>").addClass(REPEAT_UNTIL_DATE_EDITOR).addClass(FIELD_VALUE_CLASS).appendTo($editorTemplate);                this._repeatUntilDate = this._createComponent(this._$repeatDateEditor, "dxDateBox", {                    field: "until",                    value: repeatUntil,                    format: "date",                    onValueChanged: $.proxy(this._repeatUntilValueChangeHandler, this)                });                return $editorTemplate            },            _repeatUntilValueChangeHandler: function(args) {                if (this._recurrenceRule.repeatableRule() !== "until")                    return;                var value = args.value;                if (typeof value !== "string")                    value = utils.getAsciiStringByDate(value);                this._recurrenceRule.makeRule("until", value);                this.option("value", this._recurrenceRule.recurrenceString())            },            _valueChangedHandler: function(args) {                var value = args.component.option("value"),                    field = args.component.option("field");                if (field === "freq")                    this._clearRepeatOnEditorValues();                this._recurrenceRule.makeRule(field, value);                this.option("value", this._recurrenceRule.recurrenceString() || "")            },            _optionChanged: function(args) {                switch (args.name) {                    case"value":                        this._recurrenceRule.makeRules(args.value);                        this._switchEditor.option("value", !!args.value);                        this._repeatTypeEditor.option("value", this._recurrenceRule.repeatableRule() || "count");                        this._renderRepeatEndEditor();                        this._renderRepeatOnEditor();                        this._changeEditorsValues(this._recurrenceRule.rules());                        this.callBase(args);                        break;                    case"startDate":                        this._clearRepeatOnEditor();                        this._renderRepeatOnEditor();                        break;                    default:                        this.callBase(args)                }            },            _changeEditorsValues: function(rules) {                this._freqEditor.option("value", rules.freq);                this._changeRepeatTypeLabel();                this._intervalEditor.option("value", rules.interval);                this._changeRepeatCountValue();                this._changeRepeatUntilValue();                this._changeCheckBoxesValue();                this._changeDayOfMonthValue();                this._changeMonthOfYearValue()            },            _changeRepeatTypeLabel: function() {                var $labels = this.element().find("." + REPEAT_TYPE_EDITOR + LABEL_PREFIX);                if (!$labels.length)                    return;                var freq = this._recurrenceRule.rules().freq || "DAILY";                $.each($labels, function(_, $label) {                    $($label).text(Globalize.localize("dxScheduler-recurrenceRepeat" + freq.charAt(0).toUpperCase() + freq.substr(1).toLowerCase()))                })            },            _changeRepeatCountValue: function() {                if (!this._$repeatCountEditor)                    return;                var count = this._recurrenceRule.rules().count || 1;                this._repeatCountEditor.option("value", count)            },            _changeRepeatUntilValue: function() {                if (!this._$repeatDateEditor)                    return;                var date = this._recurrenceRule.rules().until || new Date;                this._repeatUntilDate.option("value", date)            },            _changeCheckBoxesValue: function() {                if (!this._$repeatOnWeek)                    return;                var daysByRule = this._daysOfWeekByRules();                $.each(this._daysOfWeek, function(index, day) {                    day.option("value", $.inArray(day.option("text"), daysByRule) > -1)                })            },            _changeDayOfMonthValue: function() {                if (!this._$repeatOnMonth && !this._$repeatOnYear)                    return;                var day = this._dayOfMonthByRules() || 1;                this._dayEditor.option("value", day)            },            _changeMonthOfYearValue: function() {                if (!this._$repeatOnYear)                    return;                var month = this._monthOfYearByRules() || 1;                this._monthEditor.option("value", month)            }        }))    })(jQuery, DevExpress);    /*! Module widgets-web, file ui.scheduler.appointmentDetailsView.js */    (function($, DX, undefined) {        var EDITOR_LABEL_PREFIX = "dx-scheduler-editor-label-",            FIELD_CLASS = "dx-field",            FILED_POSTFIX = "-field",            FIELD_LABEL_CLASS = "dx-field-label",            FIELD_VALUE_CLASS = "dx-field-value",            FIELDSET_CLASS = "dx-fieldset";        var AppointmentDetailsView = DX.DOMComponent.inherit({                _setDefaultOptions: function() {                    this.callBase();                    this.option({                        values: {},                        editors: [],                        readOnly: false                    })                },                _optionChanged: function(args) {                    switch (args.name) {                        case"values":                            this._setEditorValues(args.value);                            break;                        case"editors":                            break;                        case"readOnly":                            break;                        default:                            this.callBase(args)                    }                },                _setEditorValues: function(values) {                    var editors = this.option("editors");                    for (var i = 0, length = editors.length; i < length; i++) {                        var editor = editors[i],                            type = editor.type,                            $editor = this.element().find("." + editor.cssClass),                            instance = $editor[type]("instance");                        if (editor.key === "recurrenceRule")                            instance.option("startDate", values.startDate);                        var value = values ? values[editor.key] : null;                        instance.option(this._getEditorValueOptions(type, value))                    }                },                _render: function() {                    var editors = this.option("editors");                    this._$fieldset = $("<div>").addClass(FIELDSET_CLASS);                    this._scrollable = this._createComponent("<div>", "dxScrollable", {useKeyboard: false});                    this._scrollable.content().append(this._$fieldset);                    for (var i = 0, length = editors.length; i < length; i++)                        this._renderEditor(editors[i]);                    this.element().append(this._scrollable.element())                },                _renderEditor: function(editor) {                    var scrollable = this._scrollable,                        values = this.option("values"),                        key = editor.key,                        type = editor.type,                        valueOptions = this._getEditorValueOptions(type, values[key]),                        options = $.extend(valueOptions, editor.options, {                            onValueChanged: function(arg) {                                if (editor.options && editor.options.onValueChanged)                                    editor.options.onValueChanged(arg);                                scrollable.update();                                values[key] = arg.values ? arg.values : arg.value;                                if (values[key] === undefined || DX.utils.isEmptyArray(values[key]))                                    delete values[key]                            },                            readOnly: this.option("readOnly")                        });                    var $field = $("<div>").addClass(FIELD_CLASS).addClass(editor.cssClass + FILED_POSTFIX);                    var labelText = Globalize.localize(editor.label) || editor.label,                        $label = $("<div>").text(labelText + ":").addClass(EDITOR_LABEL_PREFIX + key.toLowerCase()),                        $editor = $("<div>").addClass(editor.cssClass);                    var instance = this._createComponent($editor, type, options);                    instance.setAria("label", labelText);                    $label.addClass(FIELD_LABEL_CLASS);                    if (key !== "recurrenceRule")                        $editor.addClass(FIELD_VALUE_CLASS);                    $field.append($label, $editor);                    this._$fieldset.append($field)                },                _getEditorValueOptions: function(type, value) {                    var result = {value: value};                    if (type === "dxTagBox")                        result = {values: value ? DX.utils.wrapToArray(value) : []};                    return result                },                getEditorInstance: function(key) {                    var result = null,                        editors = this.option("editors");                    for (var i = 0, length = editors.length; i < length; i++) {                        var editor = editors[i];                        if (editor.key === key)                            result = this.element().find("." + editor.cssClass)[editor.type]("instance")                    }                    return result                }            });        DX.ui.dxScheduler.dxSchedulerAppointmentDetailsView = AppointmentDetailsView    })(jQuery, DevExpress);    /*! Module widgets-web, file ui.scheduler.resourceManager.js */    (function($, DX, undefined) {        var utils = DX.utils,            dataUtils = DX.data.utils;        var RESOURCE_CLASS_PREFIX = "dx-scheduler-resource-",            DEFAULT_VALUE_EXPR = "id",            DEFAULT_DISPLAY_EXPR = "text";        var ResourceManager = DX.Class.inherit({                _wrapDataSource: function(dataSource) {                    if (dataSource instanceof DX.data.DataSource)                        return dataSource;                    return new DX.data.DataSource({                            store: new DevExpress.data.ArrayStore(dataSource),                            pageSize: 0                        })                },                _mapResourceData: function(resource, data) {                    var valueGetter = dataUtils.compileGetter(resource.valueExpr || DEFAULT_VALUE_EXPR),                        displayGetter = dataUtils.compileGetter(resource.displayExpr || DEFAULT_DISPLAY_EXPR);                    return $.map(data, function(item) {                            return {                                    id: valueGetter(item),                                    text: displayGetter(item)                                }                        })                },                ctor: function(resources) {                    this.setResources(resources)                },                setResources: function(resources) {                    this._resources = resources;                    this._resourceFields = $.map(resources || [], function(resource) {                        return resource.field                    })                },                getResources: function() {                    return this._resources || []                },                getEditors: function() {                    var result = [];                    $.each(this.getResources(), function(i, resource) {                        result.push({                            options: {                                dataSource: resource.dataSource,                                displayExpr: resource.displayExpr || DEFAULT_DISPLAY_EXPR,                                valueExpr: resource.valueExpr || DEFAULT_VALUE_EXPR                            },                            key: resource.field,                            type: resource.allowMultiple ? "dxTagBox" : "dxSelectBox",                            label: resource.label || resource.field,                            cssClass: RESOURCE_CLASS_PREFIX + resource.field.toLowerCase()                        })                    });                    return result                },                getResourceDataByValue: function(field, value) {                    var result = $.Deferred(),                        that = this;                    $.each(this.getResources(), function(_, resource) {                        if (resource.field === field) {                            var dataSource = that._wrapDataSource(resource.dataSource);                            dataSource.filter(resource.valueExpr || DEFAULT_VALUE_EXPR, value);                            dataSource.load().done(function(data) {                                result.resolve(data[0])                            }).fail(function() {                                result.reject()                            });                            return false                        }                    });                    return result.promise()                },                getResourcesFromItem: function(itemData) {                    var that = this,                        result = null;                    $.each(itemData, function(name) {                        if ($.inArray(name, that._resourceFields) > -1) {                            if (!result)                                result = {};                            result[name] = utils.wrapToArray(itemData[name])                        }                    });                    return result                },                getResourcesValueByFields: function(groups) {                    var result = $.Deferred(),                        that = this,                        deferreds = [];                    $.each(this.getResourcesByFields(groups), function(i, resource) {                        var deferred = $.Deferred();                        that._wrapDataSource(resource.dataSource).load().done(function(data) {                            deferred.resolve({                                name: resource.field,                                items: that._mapResourceData(resource, data)                            });                            deferreds.push(deferred)                        }).fail(function() {                            deferred.reject()                        })                    });                    $.when.apply(null, deferreds).done(function() {                        result.resolve(Array.prototype.slice.call(arguments))                    }).fail(function() {                        result.reject()                    });                    return result.promise()                },                getResourceColor: function(field, value) {                    var result = $.Deferred(),                        color;                    this.getResourceDataByValue(field, value).done(function(data) {                        if (data)                            color = data.color;                        result.resolve(color)                    }).fail(function() {                        result.reject()                    });                    return result.promise()                },                getResourcesByFields: function(fields) {                    return $.grep(this.getResources(), function(resource) {                            return $.inArray(resource.field, fields) > -1                        })                },                getResourceForPainting: function(groups) {                    var resources = this.getResources(),                        result;                    $.each(resources, function(index, resource) {                        if (resource.mainColor) {                            result = resource;                            return false                        }                    });                    if (!result) {                        if ($.isArray(groups) && groups.length)                            resources = this.getResourcesByFields(groups);                        result = resources[resources.length - 1]                    }                    return result                }            });        DX.ui.dxScheduler.dxSchedulerResourceManager = ResourceManager    })(jQuery, DevExpress);    /*! Module widgets-web, file ui.scheduler.publisherMixin.js */    (function($, DX, undefined) {        var ui = DX.ui;        ui.dxScheduler.PublisherMixin = {notifyObserver: function(subject, args) {                var observer = this.option("observer");                if (observer)                    observer.fire(subject, args)            }}    })(jQuery, DevExpress);    /*! Module widgets-web, file ui.scheduler.navigator.js */    (function($, DX, undefined) {        var ui = DX.ui,            utils = DX.utils;        var ELEMENT_CLASS = "dx-scheduler-navigator",            NEXT_BUTTON_CLASS = "dx-scheduler-navigator-next",            CAPTION_BUTTON_CLASS = "dx-scheduler-navigator-caption",            PREVIOUS_BUTTON_CLASS = "dx-scheduler-navigator-previous";        var getWeekCaption = function(date, shift) {                var firstWeekDate = utils.getFirstWeekDate(date, shift ? this.option("firstDayOfWeek") || 1 : this.option("firstDayOfWeek")),                    lastWeekDate = new Date(firstWeekDate);                shift = shift || 6;                lastWeekDate = new Date(lastWeekDate.setDate(lastWeekDate.getDate() + shift));                return Globalize.format(firstWeekDate, " d") + "-" + Globalize.format(lastWeekDate, "d MMMM yyyy")            };        var CONFIG = {                day: {                    duration: 1,                    setter: "setDate",                    getter: "getDate",                    getCaption: function(date) {                        return Globalize.format(date, "d MMMM yyyy")                    }                },                week: {                    duration: 7,                    setter: "setDate",                    getter: "getDate",                    getCaption: getWeekCaption                },                workWeek: {                    duration: 7,                    setter: "setDate",                    getter: "getDate",                    getCaption: function(date) {                        return getWeekCaption.call(this, date, 4)                    }                },                month: {                    duration: 1,                    setter: "setMonth",                    getter: "getMonth",                    getCaption: function(date) {                        return Globalize.format(date, "MMMM yyyy")                    }                }            };        DX.registerComponent("dxSchedulerNavigator", ui.dxScheduler, ui.Widget.inherit({            _setDefaultOptions: function() {                this.callBase();                this.option({                    date: new Date,                    step: "day",                    firstDayOfWeek: undefined                })            },            _optionChanged: function(args) {                switch (args.name) {                    case"step":                    case"date":                        this._renderCaption();                        break;                    case"firstDayOfWeek":                        if (this._calendar)                            this._calendar.option(args.name, args.value);                        break;                    case"tabIndex":                    case"focusStateEnabled":                        this._next.option(args.name, args.value);                        this._caption.option(args.name, args.value);                        this._prev.option(args.name, args.value);                        this.callBase(args);                        break;                    default:                        this.callBase(args)                }            },            _init: function() {                this.callBase();                this.element().addClass(ELEMENT_CLASS);                this._initButtons()            },            _initButtons: function() {                var $next = $("<div>").addClass(NEXT_BUTTON_CLASS);                this._next = this._createComponent($next, "dxButton", {                    icon: "chevronnext",                    onClick: $.proxy(this._updateCurrentDate, this, 1),                    focusStateEnabled: this.option("focusStateEnabled"),                    tabIndex: this.option("tabIndex"),                    _templates: {}                });                var $caption = $("<div>").addClass(CAPTION_BUTTON_CLASS);                this._caption = this._createComponent($caption, "dxButton", {                    focusStateEnabled: this.option("focusStateEnabled"),                    tabIndex: this.option("tabIndex"),                    _templates: {}                });                var $prev = $("<div>").addClass(PREVIOUS_BUTTON_CLASS);                this._prev = this._createComponent($prev, "dxButton", {                    icon: "chevronprev",                    onClick: $.proxy(this._updateCurrentDate, this, -1),                    focusStateEnabled: this.option("focusStateEnabled"),                    tabIndex: this.option("tabIndex"),                    _templates: {}                });                this.setAria("label", "Next period", $next);                this.setAria("label", "Previous period", $prev);                this.element().append($prev, $caption, $next)            },            _updateCurrentDate: function(direction) {                var stepConfig = this._getConfig(),                    offset = stepConfig.duration * direction,                    date = new Date(this.option("date"));                date[stepConfig.setter](date[stepConfig.getter]() + offset);                this.notifyObserver("updateCurrentDate", date)            },            _renderFocusTarget: $.noop,            _render: function() {                this.callBase();                this._renderPopover();                this._renderCaption()            },            _renderPopover: function() {                this._popover = this._createComponent("<div>", "dxPopover", {                    target: this._caption.element(),                    onContentReady: $.proxy(this._popoverContentReadyHandler, this)                });                this._popover.element().appendTo(this.element())            },            _popoverContentReadyHandler: function() {                this._calendar = this._createComponent($("<div>"), "dxCalendar", this._calendarOptions());                this._popover.content().append(this._calendar.element())            },            _calendarOptions: function() {                return {                        firstDayOfWeek: this.option("firstDayOfWeek"),                        value: this.option("date"),                        onValueChanged: $.proxy(function(e) {                            this.notifyObserver("updateCurrentDate", e.value);                            this._popover.hide()                        }, this)                    }            },            _renderCaption: function() {                var date = this.option("date"),                    caption = this._getConfig().getCaption.call(this, date);                this._caption.option({                    text: caption,                    onClick: $.proxy(function() {                        this._popover.toggle()                    }, this)                })            },            _getConfig: function() {                var step = this.option("step"),                    config = CONFIG[step];                if (!config)                    throw DX.Error("E1033", step);                return config            }        }).include(ui.dxScheduler.PublisherMixin))    })(jQuery, DevExpress);    /*! Module widgets-web, file ui.scheduler.header.js */    (function($, DX, undefined) {        var ui = DX.ui;        var COMPONENT_CLASS = "dx-scheduler-header",            VIEW_SWITCHER_CLASS = "dx-scheduler-view-switcher";        DX.registerComponent("dxSchedulerHeader", ui.dxScheduler, ui.Widget.inherit({            _setDefaultOptions: function() {                this.callBase();                this.option({                    views: [],                    currentView: "day",                    firstDayOfWeek: undefined,                    currentDate: new Date                })            },            _optionChanged: function(args) {                var value = args.value;                switch (args.name) {                    case"views":                        this._viewSwitcher.option("items", value);                        break;                    case"currentView":                        this._viewSwitcher.option("selectedItem", value);                        this._navigator.option("step", value);                        break;                    case"currentDate":                        this._navigator.option("date", value);                        break;                    case"firstDayOfWeek":                        this._navigator.option("firstDayOfWeek", value);                        break;                    case"tabIndex":                    case"focusStateEnabled":                        this._viewSwitcher.option(args.name, value);                        this._navigator.option(args.name, value);                        this.callBase(args);                        break;                    default:                        this.callBase(args)                }            },            _init: function() {                this.callBase();                this.element().addClass(COMPONENT_CLASS);                this._navigator = this._createComponent("<div>", "dxSchedulerNavigator", {                    date: this.option("currentDate"),                    step: this.option("currentView"),                    firstDayOfWeek: this.option("firstDayOfWeek"),                    tabIndex: this.option("tabIndex"),                    focusStateEnabled: this.option("focusStateEnabled"),                    observer: this.option("observer")                });                this._navigator.element().appendTo(this.element());                var $viewSwitcher = $("<div>").addClass(VIEW_SWITCHER_CLASS).appendTo(this.element());                this._viewSwitcher = this._createComponent($viewSwitcher, "dxTabs", {                    selectionRequired: true,                    scrollingEnabled: false,                    onSelectionChanged: $.proxy(this._updateCurrentView, this),                    items: this.option("views"),                    itemTemplate: function(item) {                        return $("<span>").addClass("dx-tab-text").text(Globalize.localize("dxScheduler-switcher" + DX.inflector.camelize(item, true)))                    },                    selectedItem: this.option("currentView"),                    tabIndex: this.option("tabIndex"),                    focusStateEnabled: this.option("focusStateEnabled")                })            },            _updateCurrentView: function(e) {                var selectedItem = e.component.option("selectedItem");                this.notifyObserver("currentViewUpdated", selectedItem)            },            _renderFocusTarget: $.noop        }).include(ui.dxScheduler.PublisherMixin))    })(jQuery, DevExpress);    /*! Module widgets-web, file ui.scheduler.workSpace.js */    (function($, DX, undefined) {        var ui = DX.ui,            utils = DX.utils,            events = ui.events;        var COMPONENT_CLASS = "dx-scheduler-work-space",            GROUPED_WORKSPACE_CLASS = "dx-scheduler-work-space-grouped",            TIME_PANEL_CLASS = "dx-scheduler-time-panel",            TIME_PANEL_CELL_CLASS = "dx-scheduler-time-panel-cell",            TIME_PANEL_ROW_CLASS = "dx-scheduler-time-panel-row",            ALL_DAY_PANEL_CLASS = "dx-scheduler-all-day-panel",            ALL_DAY_TABLE_CLASS = "dx-scheduler-all-day-table",            ALL_DAY_CONTAINER_CLASS = "dx-scheduler-all-day-container",            ALL_DAY_TITLE_CLASS = "dx-scheduler-all-day-title",            ALL_DAY_TABLE_CELL_CLASS = "dx-scheduler-all-day-table-cell",            ALL_DAY_TABLE_ROW_CLASS = "dx-scheduler-all-day-table-row",            HEADER_PANEL_CLASS = "dx-scheduler-header-panel",            HEADER_PANEL_CELL_CLASS = "dx-scheduler-header-panel-cell",            HEADER_ROW_CLASS = "dx-scheduler-header-row",            GROUP_ROW_CLASS = "dx-scheduler-group-row",            GROUP_HEADER_CLASS = "dx-scheduler-group-header",            DATE_TABLE_CLASS = "dx-scheduler-date-table",            DATE_TABLE_CELL_CLASS = "dx-scheduler-date-table-cell",            DATE_TABLE_ROW_CLASS = "dx-scheduler-date-table-row",            DATE_TABLE_CURRENT_DATE_CLASS = "dx-scheduler-date-table-current-date",            DATE_TABLE_OTHER_MONTH_DATE_CLASS = "dx-scheduler-date-table-other-month",            DATE_TABLE_DROPPABLE_CELL_CLASS = "dx-scheduler-date-table-droppable-cell",            SCHEDULER_WORKSPACE_DXPOINTERDOWN_EVENT_NAME = events.addNamespace("dxpointerdown", "dxSchedulerWorkSpace"),            SCHEDULER_CELL_DXDRAGENTER_EVENT_NAME = events.addNamespace("dxdragenter", "dxSchedulerDateTable"),            SCHEDULER_CELL_DXDROP_EVENT_NAME = events.addNamespace("dxdrop", "dxSchedulerDateTable"),            FOCUSED_STATE_CLASS = "dx-state-focused",            CELL_DATA = "dxCellData";        DX.registerComponent("dxSchedulerWorkSpace", ui.dxScheduler, ui.Widget.inherit({            _supportedKeys: function() {                var isRTL = this.option("rtlEnabled");                var click = function(e) {                        e.preventDefault();                        e.stopPropagation();                        if (this._$focusedCell && this._$focusedCell.length)                            this._showAddAppointmentPopup(this._$focusedCell)                    };                return $.extend(this.callBase(), {                        enter: click,                        space: click,                        downArrow: function(e) {                            e.preventDefault();                            e.stopPropagation();                            var cellIndex = this._getFocusedCell().index(),                                $row = this._getFocusedCell().parent(),                                $cell = $row.next().children().eq(cellIndex);                            this._setFocusedCell($cell)                        },                        upArrow: function(e) {                            e.preventDefault();                            e.stopPropagation();                            var cellIndex = this._getFocusedCell().index(),                                $row = this._getFocusedCell().parent(),                                $cell = $row.prev().children().eq(cellIndex);                            this._setFocusedCell($cell)                        },                        rightArrow: function(e) {                            e.preventDefault();                            e.stopPropagation();                            var $cell = isRTL ? this._getFocusedCell().prev() : this._getFocusedCell().next();                            this._setFocusedCell($cell)                        },                        leftArrow: function(e) {                            e.preventDefault();                            e.stopPropagation();                            var $cell = isRTL ? this._getFocusedCell().next() : this._getFocusedCell().prev();                            this._setFocusedCell($cell)                        }                    })            },            _getFocusedCell: function() {                return this._$focusedCell || this._$dateTable.find("." + DATE_TABLE_CELL_CLASS).eq(0)            },            _setFocusedCell: function($cell) {                if (!$cell.length)                    return;                this._releaseFocusedCell();                $cell.addClass(FOCUSED_STATE_CLASS);                if (utils.isDefined(this._$focusedCell))                    this.setAria("label", undefined, this._$focusedCell);                this._$focusedCell = $cell;                this.setAria("label", "Add appointment", this._$focusedCell);                this._scrollable.scrollToElement($cell)            },            _releaseFocusedCell: function() {                if (utils.isDefined(this._$focusedCell))                    this._$focusedCell.removeClass(FOCUSED_STATE_CLASS)            },            _focusTarget: function() {                return this.element()            },            _focusInHandler: function(e) {                if ($(e.target).is(this._focusTarget()) && this._isCellClick !== false) {                    delete this._isCellClick;                    this.callBase.apply(this, arguments);                    var $cell = this._getFocusedCell();                    this._setFocusedCell($cell)                }            },            _focusOutHandler: function(e) {                this.callBase.apply(this, arguments);                this._releaseFocusedCell()            },            _activeStateUnit: "." + DATE_TABLE_CELL_CLASS + ", ." + ALL_DAY_TABLE_CELL_CLASS,            _setDefaultOptions: function() {                this.callBase();                this.option({                    currentDate: new Date,                    firstDayOfWeek: undefined,                    startDayHour: 0,                    endDayHour: 24,                    hoursInterval: 0.5,                    activeStateEnabled: true,                    hoverStateEnabled: true,                    groups: []                })            },            _optionChanged: function(args) {                var that = this;                function rerenderView() {                    that._cleanView();                    that._setFirstViewDate();                    that._renderView()                }                switch (args.name) {                    case"firstDayOfWeek":                    case"currentDate":                    case"groups":                        this._toggleGroupedClass();                        rerenderView();                        break;                    case"startDayHour":                    case"endDayHour":                        rerenderView();                        break;                    default:                        this.callBase(args)                }            },            _init: function() {                this.callBase();                this.element().addClass(COMPONENT_CLASS);                this._$headerPanel = $("<table>").addClass(HEADER_PANEL_CLASS);                this._$allDayTable = $("<table>").addClass(ALL_DAY_TABLE_CLASS);                this._$allDayPanel = $("<div>").append($("<div>").addClass(ALL_DAY_CONTAINER_CLASS)).append($("<div>").addClass(ALL_DAY_TITLE_CLASS).text(Globalize.localize("dxScheduler-allDay"))).append(this._$allDayTable).addClass(ALL_DAY_PANEL_CLASS);                this._$timePanel = $("<table>").addClass(TIME_PANEL_CLASS);                this._$dateTable = $("<table>").addClass(DATE_TABLE_CLASS);                this._scrollable = this._createComponent("<div>", "dxScrollable", {useKeyboard: false});                this._scrollable.content().append(this._$timePanel, this._$dateTable);                this.element().append(this._$headerPanel, this._$allDayPanel, this._scrollable.element());                this.element().addClass(this._getElementClass())            },            _getElementClass: $.noop,            _getRowCount: $.noop,            _getCellCount: $.noop,            _render: function() {                this.callBase();                this._setFirstViewDate();                this._renderView();                this._toggleGroupedClass();                this._attachEvents()            },            _setFirstViewDate: function() {                this._firstViewDate = utils.getFirstWeekDate(this.option("currentDate"), this._firstDayOfWeek());                if (this.option("startDayHour"))                    this._firstViewDate.setHours(this.option("startDayHour"))            },            _firstDayOfWeek: function() {                return this.option("firstDayOfWeek")            },            _renderView: function() {                this._renderHeaderPanel();                this._renderAllDayPanel();                this._renderTimePanel();                this._renderDateTable()            },            _toggleGroupedClass: function() {                this.element().toggleClass(GROUPED_WORKSPACE_CLASS, this.option("groups").length > 0)            },            _attachEvents: function() {                var pointerDownAction = this._createAction($.proxy(this._pointerDownHandler, this));                this.element().off(SCHEDULER_WORKSPACE_DXPOINTERDOWN_EVENT_NAME).on(SCHEDULER_WORKSPACE_DXPOINTERDOWN_EVENT_NAME, function(e) {                    pointerDownAction({jQueryEvent: e})                })            },            _pointerDownHandler: function(e) {                var $target = $(e.jQueryEvent.target);                if (!$target.hasClass(DATE_TABLE_CELL_CLASS) && !$target.hasClass(ALL_DAY_TABLE_CELL_CLASS)) {                    this._isCellClick = false;                    return                }                this._isCellClick = true;                if ($target.hasClass(FOCUSED_STATE_CLASS))                    this._showAddAppointmentPopup($target);                else                    this._setFocusedCell($target)            },            _showAddAppointmentPopup: function($cell) {                var cellData = $cell.data(CELL_DATA),                    args = $.extend(cellData, cellData.groups);                delete cellData.groups;                this.notifyObserver("showAddAppointmentPopup", args)            },            _renderHeaderPanel: function() {                var $head = $("<thead>");                this._renderGroupHeader($head);                this._renderDateHeader($head);                this._$headerPanel.append($head)            },            _renderDateHeader: function($element) {                var $headerRow = $("<tr>").addClass(HEADER_ROW_CLASS),                    count = this._getCellCount(),                    groupCount = this._getGroupCount() || 1;                for (var j = 0; j < groupCount; j++)                    for (var i = 0; i < count; i++) {                        var text = this._getHeaderText(i),                            $cell = $("<th>").text(text).addClass(HEADER_PANEL_CELL_CLASS).attr("title", text);                        $headerRow.append($cell)                    }                $element.append($headerRow)            },            _renderGroupHeader: function($element) {                var groupCount = this._getGroupCount();                if (groupCount) {                    var groupRows = this._makeGroupRows(this.option("groups"));                    this.element().attr("dx-group-row-count", groupRows.length);                    $element.append(groupRows)                }            },            _makeGroupRows: function(groups) {                var repeatCount = 1,                    groupCount = groups.length,                    cellCount = this._getCellCount() || 1,                    rows = [];                for (var i = 0; i < groupCount; i++) {                    if (i > 0)                        repeatCount = groups[i - 1].items.length * repeatCount;                    var cells = this._makeGroupRowCells(groups[i].items, repeatCount);                    rows.push($("<tr>").addClass(GROUP_ROW_CLASS).append(cells))                }                var maxCellCount = rows[groupCount - 1].find("th").length;                for (var j = 0; j < groupCount; j++) {                    var $cell = rows[j].find("th"),                        colspan = maxCellCount / $cell.length * cellCount;                    if (colspan > 1)                        $cell.attr("colspan", colspan)                }                return rows            },            _makeGroupRowCells: function(items, repeatCount) {                var cells = [],                    itemCount = items.length;                for (var i = 0; i < repeatCount; i++)                    for (var j = 0; j < itemCount; j++)                        cells.push($("<th>").addClass(GROUP_HEADER_CLASS).text(items[j].text));                return cells            },            _renderAllDayPanel: function() {                var cellCount = this._getCellCount() * (this._getGroupCount() || 1),                    that = this;                this._renderTableBody({                    container: this._$allDayTable,                    rowCount: 1,                    cellCount: cellCount,                    cellClass: ALL_DAY_TABLE_CELL_CLASS,                    rowClass: ALL_DAY_TABLE_ROW_CLASS,                    dataGenerator: function($cell, rowIndex, cellIndex) {                        var startDate = that._getDateByCellIndexes(rowIndex, cellIndex);                        utils.correctDateWithUnitBeginning(startDate, "day");                        var data = {                                startDate: startDate,                                endDate: new Date(startDate.getTime() + 24 * 60 * 60000),                                allDay: true                            };                        var groups = that._getCellGroups(cellIndex);                        if (groups.length)                            data.groups = {};                        for (var i = 0; i < groups.length; i++)                            data.groups[groups[i].name] = groups[i].id;                        $cell.data(CELL_DATA, data)                    }                })            },            _renderTimePanel: function() {                this._renderTableBody({                    container: this._$timePanel,                    rowCount: this._calculateDayDuration(),                    cellCount: 1,                    cellClass: TIME_PANEL_CELL_CLASS,                    rowClass: TIME_PANEL_ROW_CLASS                });                var startDayHour = this.option("startDayHour");                this._$timePanel.find("td").each(function(index) {                    $(this).text(Globalize.format(new Date(new Date(1970, 0).getTime() + 3600000 * (startDayHour + index)), "t"))                })            },            _calculateDayDuration: function() {                return this.option("endDayHour") - this.option("startDayHour")            },            _renderDateTable: function() {                var cellCount = this._getCellCount() * (this._getGroupCount() || 1),                    that = this;                this._renderTableBody({                    container: this._$dateTable,                    rowCount: this._getRowCount(),                    cellCount: cellCount,                    cellClass: DATE_TABLE_CELL_CLASS,                    rowClass: DATE_TABLE_ROW_CLASS,                    dataGenerator: function($cell, rowIndex, cellIndex) {                        var startDate = that._getDateByCellIndexes(rowIndex, cellIndex),                            data = {                                startDate: startDate,                                endDate: that._calculateEndDate(startDate),                                allDay: that._getTableAllDay()                            };                        $cell.toggleClass(DATE_TABLE_CURRENT_DATE_CLASS, that._isCurrentDateCell(startDate)).toggleClass(DATE_TABLE_OTHER_MONTH_DATE_CLASS, that._isOtherMonth(startDate));                        var groups = that._getCellGroups(cellIndex);                        if (groups.length)                            data.groups = {};                        for (var i = 0; i < groups.length; i++)                            data.groups[groups[i].name] = groups[i].id;                        $cell.data(CELL_DATA, data)                    }                });                this._attachTableEvents()            },            _getTableAllDay: function() {                return false            },            _isCurrentDateCell: function(cellDate) {                var today = new Date;                return utils.sameMonthAndYear(cellDate, today) && cellDate.getDate() === today.getDate()            },            _isOtherMonth: function(cellDate) {                return cellDate.getMonth() !== this.option("currentDate").getMonth()            },            _calculateEndDate: function(startDate) {                return new Date(startDate.getTime() + this._getInterval())            },            _getGroupCount: function() {                var groups = this.option("groups"),                    result = 0;                for (var i = 0, len = groups.length; i < len; i++)                    if (!i)                        result = groups[i].items.length;                    else                        result *= groups[i].items.length;                return result            },            _getPathToLeaf: function(leafIndex) {                var tree = this._createGroupTree(this.option("groups")[0], 0);                function findLeafByIndex(data, index) {                    for (var i = 0; i < data.length; i++)                        if (data[i].leafIndex === index)                            return data[i];                        else {                            var leaf = findLeafByIndex(data[i].children, index);                            if (leaf)                                return leaf                        }                }                function makeBranch(leaf, result) {                    result = result || [];                    result.push(leaf.value);                    if (leaf.parent)                        makeBranch(leaf.parent, result);                    return result                }                var leaf = findLeafByIndex(tree, leafIndex);                return makeBranch(leaf).reverse()            },            _getCellGroups: function(index) {                var result = [];                if (this._getGroupCount()) {                    var groupIndex = Math.floor(index / this._getCellCount()),                        groups = this.option("groups");                    if (groupIndex < 0)                        return;                    var path = this._getPathToLeaf(groupIndex);                    for (var i = 0; i < groups.length; i++)                        result.push({                            name: groups[i].name,                            id: path[i]                        })                }                return result            },            _attachTableEvents: function() {                var $currentTarget,                    cellHeight,                    cellWidth;                this._getDateTables().off(SCHEDULER_CELL_DXDRAGENTER_EVENT_NAME).off(SCHEDULER_CELL_DXDROP_EVENT_NAME).on(SCHEDULER_CELL_DXDRAGENTER_EVENT_NAME, "td", {itemSizeFunc: function($element) {                        if (!cellHeight)                            cellHeight = $element.height();                        if (!cellWidth)                            cellWidth = $element.width();                        return {                                width: cellWidth,                                height: cellHeight                            }                    }}, function(e) {                    if ($currentTarget)                        $currentTarget.removeClass(DATE_TABLE_DROPPABLE_CELL_CLASS);                    $currentTarget = $(e.target);                    $currentTarget.addClass(DATE_TABLE_DROPPABLE_CELL_CLASS)                }).on(SCHEDULER_CELL_DXDROP_EVENT_NAME, "td", function(e) {                    $(e.target).removeClass(DATE_TABLE_DROPPABLE_CELL_CLASS);                    cellHeight = 0;                    cellWidth = 0                })            },            _getDateTables: function() {                return this._$dateTable.add(this._$allDayTable)            },            _getInterval: function() {                return this.option("hoursInterval") * 3600000            },            _getHeaderText: function(headerIndex) {                return Globalize.format(this._getDateByIndex(headerIndex), this._getFormat()).toUpperCase()            },            _getDateByIndex: DX.abstract,            _getFormat: DX.abstract,            _getCellText: function(rowIndex, cellIndex) {                return ""            },            _calculateCellIndex: function(rowIndex, cellIndex) {                cellIndex = cellIndex % this._getCellCount();                var virtualRowCount = this._getVirtualRowCount();                return (this._getRowCount() + virtualRowCount) * cellIndex + rowIndex            },            _getVirtualRowCount: function() {                return this.option("startDayHour") / this.option("hoursInterval") + this._getEndDayHours() / this.option("hoursInterval")            },            _getEndDayHours: function() {                return 24 - this.option("endDayHour")            },            _getEndDayMilliseconds: function() {                return this._getEndDayHours() * 3600000            },            _renderTableBody: function(options) {                var rows = [];                for (var i = 0; i < options.rowCount; i++) {                    var $row = $("<tr>");                    if (options.rowClass)                        $row.addClass(options.rowClass);                    for (var j = 0; j < options.cellCount; j++) {                        var $td = $("<td>").text(this._getCellText(i, j));                        if (options.cellClass)                            $td.addClass(options.cellClass);                        if ($.isFunction(options.dataGenerator))                            options.dataGenerator($td, i, j);                        $row.append($td)                    }                    rows.push($row)                }                options.container.append($("<tbody>").append(rows))            },            _cleanView: function() {                this._$headerPanel.empty();                this._$dateTable.empty();                this._$timePanel.empty();                this._$allDayTable.empty()            },            getWorkArea: function() {                return this._scrollable.content()            },            _getCellCoordinatesByIndex: function(index) {                var cellIndex = Math.floor(index / this._getRowCount()),                    rowIndex = index - this._getRowCount() * cellIndex;                return {                        cellIndex: cellIndex,                        rowIndex: rowIndex                    }            },            _createGroupTree: function(group, groupIndex) {                var leafIndex = 0;                function make(group, groupIndex, result, parent) {                    result = result || [];                    for (var i = 0; i < group.items.length; i++) {                        var resultItem = {                                name: group.name,                                value: group.items[i].id,                                children: [],                                parent: parent ? parent : null                            };                        result.push(resultItem);                        var nextGroupIndex = groupIndex + 1;                        if (this.option("groups")[nextGroupIndex])                            make.call(this, this.option("groups")[nextGroupIndex], nextGroupIndex, resultItem.children, resultItem);                        if (!resultItem.children.length) {                            resultItem.leafIndex = leafIndex;                            leafIndex++                        }                    }                    return result                }                return make.call(this, group, groupIndex)            },            _hasGroupItem: function(groups, groupName, itemValue) {                var group = groups[groupName];                if (group)                    if ($.inArray(itemValue, group) > -1)                        return true;                return false            },            _grep: function(tree, groups, result) {                result = result || [];                for (var i = 0; i < tree.length; i++) {                    if (!this._hasGroupItem(groups, tree[i].name, tree[i].value))                        continue;                    if (utils.isDefined(tree[i].leafIndex))                        result.push(tree[i].leafIndex);                    if (tree[i].children)                        this._grep(tree[i].children, groups, result)                }                return result            },            _getDateByCellIndexes: function(rowIndex, cellIndex) {                var millisecondsOffset = this._getInterval() * this._calculateCellIndex(rowIndex, cellIndex);                return new Date(this._firstViewDate.getTime() + millisecondsOffset)            },            _getCellTimeOffset: function(dateTimeStamp) {                var timeInterval = this._getInterval(),                    timeOffset = dateTimeStamp % timeInterval;                return timeOffset ? timeOffset / timeInterval : 0            },            _calculateTimeDurationBetweenFirstViewDateAndCurrentDate: function(currentDate, allDay) {                var firstViewDate = this._firstViewDate.getTime();                if (allDay)                    firstViewDate = firstViewDate - this.option("startDayHour") * 60 * 60 * 1000;                var result = currentDate.getTime() - firstViewDate,                    days = Math.floor(result / (24 * 60 * 60 * 1000));                if (!allDay)                    result = result - days * this.option("startDayHour") * 3600000 - days * this._getEndDayMilliseconds();                return result            },            _getGroupIndexes: function(groups) {                var indexes = [];                if (groups && this.option("groups").length) {                    var tree = this._createGroupTree(this.option("groups")[0], 0);                    indexes = this._grep(tree, groups)                }                return indexes            },            _updateIndex: function(index) {                return index * this._getRowCount()            },            getCoordinatesByDate: function(date, groupIndex, allDay) {                var isRtl = this.option("rtlEnabled"),                    stepsCount = this._getCellCount() * this._getRowCount(),                    timeInterval = allDay ? 24 * 60 * 60 * 1000 : this._getInterval(),                    dateTimeStamp = this._calculateTimeDurationBetweenFirstViewDateAndCurrentDate(date, allDay);                groupIndex = groupIndex || 0;                var index = Math.floor(dateTimeStamp / timeInterval);                if (allDay)                    index = this._updateIndex(index);                Math.ceil(index / this._getRowCount()) * this.option("startDayHour") * 2;                if (index < 0 || index >= stepsCount)                    return {                            top: -1000,                            left: -1000                        };                var cellCoordinates = this._getCellCoordinatesByIndex(index),                    $cell = this._$dateTable.find("tr").eq(cellCoordinates.rowIndex).find("td").eq(cellCoordinates.cellIndex + groupIndex * this._getCellCount()),                    position = $cell.position();                position.top += $cell.height() * this._getCellTimeOffset(dateTimeStamp);                if (isRtl)                    position.left += $cell.outerWidth();                return position            },            getCoordinatesByDateInGroup: function(date, groups, allDay) {                var indexes = this._getGroupIndexes(groups),                    result = [];                if (indexes.length)                    for (var i = 0; i < indexes.length; i++)                        result.push(this.getCoordinatesByDate(date, indexes[i], allDay));                else                    result.push(this.getCoordinatesByDate(date, 0, allDay));                return result            },            getDataByDroppableCell: function() {                var cellData = this._getDateTables().find("." + DATE_TABLE_DROPPABLE_CELL_CLASS).data(CELL_DATA);                return {                        date: cellData.startDate,                        allDay: cellData.allDay,                        groups: cellData.groups                    }            },            _getLastViewDate: function() {                var dateOfLastViewCell = this._getDateByCellIndexes(this._getRowCount() - 1, this._getCellCount() - 1);                return new Date(dateOfLastViewCell.getTime() + this._getInterval() - 60000)            },            getDateRange: function() {                return [this._firstViewDate, this._getLastViewDate()]            },            getCellWidth: function() {                return this.element().find("." + DATE_TABLE_CELL_CLASS).first().outerWidth()            },            getCellHeight: function() {                return this.element().find("." + DATE_TABLE_CELL_CLASS).first().outerHeight()            },            getAllDayHeight: function() {                return this.element().find("." + ALL_DAY_PANEL_CLASS + " td").first().outerHeight()            },            getMaxAllowedPosition: function() {                var result = [],                    isRtl = this.option("rtlEnabled");                this._$dateTable.find("tr").first().find("td:nth-child(" + this._getCellCount() + "n)").each(function(_, cell) {                    var maxPosition = $(cell).position().left;                    if (!isRtl)                        maxPosition += $(cell).outerWidth();                    result.push(maxPosition)                });                return result            },            getAllDayContainerClass: function() {                return ALL_DAY_CONTAINER_CLASS            }        }).include(ui.dxScheduler.PublisherMixin))    })(jQuery, DevExpress);    /*! Module widgets-web, file ui.scheduler.workSpaceDay.js */    (function($, DX, undefined) {        var ui = DX.ui;        var DAY_CLASS = "dx-scheduler-work-space-day";        DX.registerComponent("dxSchedulerWorkSpaceDay", ui.dxScheduler, ui.dxScheduler.dxSchedulerWorkSpace.inherit({            _getElementClass: function() {                return DAY_CLASS            },            _getRowCount: function() {                var day = this._calculateDayDuration();                return day / this.option("hoursInterval")            },            _getCellCount: function() {                return 1            },            _setFirstViewDate: function() {                this._firstViewDate = this.option("currentDate");                if (this.option("startDayHour"))                    this._firstViewDate.setHours(this.option("startDayHour"))            },            _getDateByIndex: function() {                return this._firstViewDate            },            _getFormat: function() {                return "D"            },            _renderDateHeader: $.noop        }))    })(jQuery, DevExpress);    /*! Module widgets-web, file ui.scheduler.workSpaceWeek.js */    (function($, DX, undefined) {        var ui = DX.ui;        var WEEK_CLASS = "dx-scheduler-work-space-week";        DX.registerComponent("dxSchedulerWorkSpaceWeek", ui.dxScheduler, ui.dxScheduler.dxSchedulerWorkSpace.inherit({            _getElementClass: function() {                return WEEK_CLASS            },            _getRowCount: function() {                var day = this._calculateDayDuration();                return day / this.option("hoursInterval")            },            _getCellCount: function() {                return 7            },            _getDateByIndex: function(headerIndex) {                var resultDate = new Date(this._firstViewDate);                resultDate.setDate(this._firstViewDate.getDate() + headerIndex);                return resultDate            },            _getFormat: function() {                return "ddd d"            }        }))    })(jQuery, DevExpress);    /*! Module widgets-web, file ui.scheduler.workSpaceWorkWeek.js */    (function($, DX, undefined) {        var ui = DX.ui;        var WORK_WEEK_CLASS = "dx-scheduler-work-space-work-week";        var weekendCounter = 0;        DX.registerComponent("dxSchedulerWorkSpaceWorkWeek", ui.dxScheduler, ui.dxScheduler.dxSchedulerWorkSpaceWeek.inherit({            _getElementClass: function() {                return WORK_WEEK_CLASS            },            _getCellCount: function() {                return 5            },            _firstDayOfWeek: function() {                return this.option("firstDayOfWeek") || 1            },            _getDateByIndex: function(headerIndex) {                var resultDate = new Date(this._firstViewDate);                resultDate.setDate(this._firstViewDate.getDate() + headerIndex + weekendCounter);                var day = resultDate.getDay();                if (day % 6 === 0) {                    weekendCounter = Math.floor(day / 6 + 1);                    resultDate.setDate(resultDate.getDate() + weekendCounter)                }                return resultDate            },            _renderHeaderPanel: function() {                weekendCounter = 0;                this.callBase()            }        }))    })(jQuery, DevExpress);    /*! Module widgets-web, file ui.scheduler.workSpaceMonth.js */    (function($, DX, undefined) {        var ui = DX.ui,            utils = DX.utils;        var MONTH_CLASS = "dx-scheduler-work-space-month";        var DAYS_IN_WEEK = 7,            DAY_IN_MILLISECONDS = 86400000;        DX.registerComponent("dxSchedulerWorkSpaceMonth", ui.dxScheduler, ui.dxScheduler.dxSchedulerWorkSpace.inherit({            _getElementClass: function() {                return MONTH_CLASS            },            _getRowCount: function() {                return 6            },            _getCellCount: function() {                return DAYS_IN_WEEK            },            _getDateByIndex: function(headerIndex) {                var resultDate = new Date(this._firstViewDate);                resultDate.setDate(this._firstViewDate.getDate() + headerIndex);                return resultDate            },            _getFormat: function() {                return "ddd"            },            _calculateCellIndex: function(rowIndex, cellIndex) {                cellIndex = cellIndex % this._getCellCount();                return rowIndex * this._getCellCount() + cellIndex            },            _getInterval: function() {                return DAY_IN_MILLISECONDS            },            _calculateEndDate: function(startDate) {                var startDateCopy = new Date(startDate);                return new Date(startDateCopy.setHours(this.option("endDayHour")))            },            _calculateTimeDurationBetweenFirstViewDateAndCurrentDate: function(currentDate) {                return currentDate.getTime() - (this._firstViewDate.getTime() - this.option("startDayHour") * 3600000)            },            _getCellCoordinatesByIndex: function(index) {                var rowIndex = Math.floor(index / this._getCellCount()),                    cellIndex = index - this._getCellCount() * rowIndex;                return {                        rowIndex: rowIndex,                        cellIndex: cellIndex                    }            },            _renderTimePanel: $.noop,            _renderAllDayPanel: $.noop,            _getTableAllDay: $.noop,            _getCellTimeOffset: function() {                return 0            },            _setFirstViewDate: function() {                var firstMonthDate = DX.utils.getFirstMonthDate(this.option("currentDate"));                this._firstViewDate = utils.getFirstWeekDate(firstMonthDate, this.option("firstDayOfWeek"));                if (this.option("startDayHour"))                    this._firstViewDate.setHours(this.option("startDayHour"))            },            _getDate: function(week, day) {                var result = new Date(this._firstViewDate);                result.setDate(result.getDate() + week * DAYS_IN_WEEK + day);                return result            },            _getCellText: function(rowIndex, cellIndex) {                cellIndex = cellIndex % this._getCellCount();                var date = this._getDate(rowIndex, cellIndex);                return Globalize.format(date, "dd")            },            _updateIndex: function(index) {                return index            },            getCoordinatesByDates: function(startDate, endDate) {                var result = [],                    date = new Date(startDate);                while (date <= endDate) {                    result.push(this.getCoordinatesByDate(date));                    date.setDate(date.getDate() + 7);                    date = utils.getFirstWeekDate(date, this.option("firstDayOfWeek"))                }                return result            }        }))    })(jQuery, DevExpress);    /*! Module widgets-web, file ui.scheduler.appointments.js */    (function($, DX, undefined) {        var ui = DX.ui,            translator = DX.translator,            events = ui.events;        var COMPONENT_CLASS = "dx-scheduler-appointments",            APPOINTMENT_ITEM_CLASS = "dx-scheduler-appointment",            RECURRENCE_APPOINTMENT_CLASS = "dx-scheduler-appointment-recurrence",            EMPTY_APPOINTMENT_CLASS = "dx-scheduler-appointment-empty",            REDUCED_APPOINTMENT_CLASS = "dx-scheduler-appointment-reduced",            REDUCED_APPOINTMENT_ICON = "dx-appointment-reduced-icon";        var MONTH_APPOINTMENT_DEFAULT_SIZE = 15,            MONTH_APPOINTMENT_DEFAULT_OFFSET = 3,            MONTH_APPOINTMENT_HEIGHT_RATIO = 0.6,            APPOINTMENT_DEFAULT_SIZE = 20,            WEEK_APPOINTMENT_DEFAULT_OFFSET = 10,            EMPTY_APPOINTMENT_MAX_WIDTH = 45;        var REDUCED_APPOINTMENT_POINTERENTER_EVENT_NAME = events.addNamespace("dxpointerenter", "dxSchedulerAppointment"),            REDUCED_APPOINTMENT_POINTERLEAVE_EVENT_NAME = events.addNamespace("dxpointerleave", "dxSchedulerAppointment"),            DBLCLICK_EVENT_NAME = events.addNamespace("dxdblclick", "dxSchedulerAppointment");        var BaseRenderingStrategy = DX.Class.inherit({                ctor: function(instance) {                    this.instance = instance;                    this.isRtl = instance.option("rtlEnabled")                },                resizableConfig: DX.abstract,                handleResize: DX.abstract,                renderAppointmentGeometry: function($appointment, coordinates) {                    var geometry = this.getAppointmentGeometry(coordinates);                    translator.move($appointment, {                        top: geometry.top,                        left: geometry.left                    });                    $appointment.css({                        width: geometry.width,                        height: geometry.height                    });                    this._geometry = geometry                },                getAppointmentGeometry: function() {                    return {                            height: 0,                            width: 0,                            top: 0,                            left: 0                        }                },                createTaskPositionMap: function(items) {                    var length = items.length;                    if (!length)                        return;                    var map = [];                    for (var i = 0; i < length; i++)                        map.push(this._getItemPosition(items[i]));                    var positionArray = this._getSortedPositions(map),                        resultPositions = this._getResultPositions(positionArray);                    return this._getExtendedPositionMap(map, resultPositions)                },                _getItemPosition: function(item) {                    var height = this.calculateAppointmentHeight(item),                        width = this.calculateAppointmentWidth(item),                        position = this.instance._getAppointmentCoordinates(item),                        allDay = this.isAllDay(item),                        appointmentReduced = false;                    for (var j = 0; j < position.length; j++) {                        if (allDay)                            position[j].top = 0;                        if ((this._needVerifyItemSize() || allDay) && this.instance._maxAllowedPosition) {                            var currentMaxAllowedPosition = this._getCurrentMaxAllowedPosition(j, item);                            if (this.isAppointmentGreaterThan(currentMaxAllowedPosition, {                                left: position[j].left,                                width: width                            })) {                                appointmentReduced = true;                                if (this.isRtl)                                    width = Math.floor(position[j].left - currentMaxAllowedPosition);                                else                                    width = currentMaxAllowedPosition - Math.floor(position[j].left)                            }                        }                        $.extend(position[j], {                            height: height,                            width: width,                            allDay: allDay,                            appointmentReduced: appointmentReduced                        })                    }                    return position                },                _needVerifyItemSize: function() {                    return false                },                _getCurrentMaxAllowedPosition: function(index, item) {                    this.instance.notifyObserver("getItemGroupIndexes", {                        item: item,                        callback: function(indexes) {                            if (indexes.length)                                index = indexes[index]                        }                    });                    return Math.floor(this.instance._maxAllowedPosition[index])                },                calculateAppointmentHeight: function() {                    return 0                },                calculateAppointmentWidth: function() {                    return 0                },                isAppointmentGreaterThan: function(etalon, comparisonParameters) {                    if (this.isRtl)                        return comparisonParameters.left - comparisonParameters.width < etalon;                    return comparisonParameters.left + comparisonParameters.width > etalon                },                isAllDay: function() {                    return false                },                _getSortedPositions: function(arr) {                    var result = [];                    for (var i = 0, arrLength = arr.length; i < arrLength; i++)                        for (var j = 0, itemLength = arr[i].length; j < itemLength; j++) {                            var item = arr[i][j];                            result.push({                                i: i,                                j: j,                                top: item.top,                                left: item.left,                                isStart: true,                                allDay: item.allDay                            }, {                                i: i,                                j: j,                                top: item.top + item.height,                                left: item.left + item.width,                                isStart: false,                                allDay: item.allDay                            })                        }                    result.sort($.proxy(this._sortCondition, this));                    return result                },                _sortCondition: DX.abstract,                _rowCondition: function(a, b) {                    var columnCondition = a.left - b.left,                        rowCondition = a.top - b.top;                    return columnCondition ? columnCondition : rowCondition ? rowCondition : a.isStart - b.isStart                },                _columnCondition: function(a, b) {                    var columnCondition = a.left - b.left,                        rowCondition = a.top - b.top;                    return rowCondition ? rowCondition : columnCondition ? columnCondition : a.isStart - b.isStart                },                _getResultPositions: function(sortedArray) {                    var stack = [],                        indexes = [],                        result = [],                        position;                    for (var i = 0; i < sortedArray.length; i++) {                        var current = sortedArray[i],                            j;                        if (current.isStart) {                            position = undefined;                            for (j = 0; j < indexes.length; j++)                                if (!indexes[j]) {                                    position = j;                                    indexes[j] = true;                                    break                                }                            if (position === undefined) {                                position = indexes.length;                                indexes.push(true);                                for (j = 0; j < stack.length; j++)                                    stack[j].count++                            }                            stack.push({                                index: position,                                count: indexes.length,                                i: current.i,                                j: current.j                            })                        }                        else {                            var removeIndex = this._findIndexByKey(stack, "i", "j", current.i, current.j),                                resultItem = stack[removeIndex];                            stack.splice(removeIndex, 1);                            indexes[resultItem.index] = false;                            if (!stack.length)                                indexes = [];                            result.push(resultItem)                        }                    }                    return result.sort(function(a, b) {                            var columnCondition = a.j - b.j,                                rowCondition = a.i - b.i;                            return rowCondition ? rowCondition : columnCondition                        })                },                _findIndexByKey: function(arr, ikey, jkey, ivalue, jvalue) {                    var result = 0;                    for (var i = 0, len = arr.length; i < len; i++)                        if (arr[i][ikey] === ivalue && arr[i][jkey] === jvalue) {                            result = i;                            break                        }                    return result                },                _getExtendedPositionMap: function(map, positions) {                    var positionCounter = 0;                    for (var i = 0, mapLength = map.length; i < mapLength; i++)                        for (var j = 0, itemLength = map[i].length; j < itemLength; j++) {                            map[i][j].index = positions[positionCounter].index;                            map[i][j].count = positions[positionCounter++].count                        }                    return map                },                _startDate: function(item) {                    var startDate = this.instance._getStartDate(item);                    if (isNaN(startDate.getTime()))                        throw DX.Error("E1032", item.text);                    return startDate                },                _endDate: function(item) {                    var endDate = this.instance._getEndDate(item);                    if (!endDate)                        endDate = new Date(this._startDate(item).getTime() + this.instance.option("appointmentDurationInMinutes") * 60000);                    item.endDate = endDate;                    return endDate                }            });        var WeekRenderingStrategy = BaseRenderingStrategy.inherit({                resizableConfig: function(appointment) {                    if (this.isAllDay(appointment))                        return {                                minWidth: this.instance._defaultWidth,                                step: this.instance._defaultWidth,                                handles: "right left"                            };                    return {                            minHeight: this.instance._defaultHeight,                            step: this.instance._defaultHeight,                            handles: "top bottom"                        }                },                handleResize: function(args, start, end, appointment, initialSize) {                    var handle,                        deltaTime;                    if (this.isAllDay(appointment)) {                        var cellWidth = this.instance._defaultWidth || APPOINTMENT_DEFAULT_SIZE;                        handle = "dx-resizable-handle-left";                        deltaTime = 24 * 60 * 60000 * ((args.width - initialSize.width) / cellWidth) || 1                    }                    else {                        handle = "dx-resizable-handle-top";                        var deltaHeight = args.height - initialSize.height;                        deltaTime = 60000 * deltaHeight / this.instance._defaultHeight * this.instance.option("appointmentDurationInMinutes")                    }                    var cond = $(args.jQueryEvent.target).hasClass(handle),                        startTime = cond ? start.getTime() - deltaTime : start.getTime(),                        endTime = cond ? end.getTime() : end.getTime() + deltaTime;                    return [startTime, endTime]                },                renderAppointmentGeometry: function($appointment, coordinates) {                    this.callBase($appointment, coordinates);                    if (this._geometry.width < EMPTY_APPOINTMENT_MAX_WIDTH)                        $appointment.addClass(EMPTY_APPOINTMENT_CLASS)                },                getAppointmentGeometry: function(coordinates) {                    if (coordinates.allDay)                        return this._getAllDayAppointmentGeometry(coordinates);                    return this._getSimpleAppointmentGeometry(coordinates)                },                _getMinuteHeight: function() {                    return this.instance._defaultHeight / this.instance.option("appointmentDurationInMinutes")                },                _getAllDayAppointmentGeometry: function(coordinates) {                    var maxHeight = this.instance._allDayHeight || APPOINTMENT_DEFAULT_SIZE,                        index = coordinates.index,                        count = coordinates.count,                        height = maxHeight / (count > 3 ? 3 : count),                        width = coordinates.width,                        top = coordinates.top + index * height,                        left = coordinates.left;                    if (count > 3)                        if (index > 1) {                            top = coordinates.top;                            left = coordinates.left + (index - 2) * MONTH_APPOINTMENT_DEFAULT_SIZE;                            height = MONTH_APPOINTMENT_DEFAULT_SIZE,                            width = MONTH_APPOINTMENT_DEFAULT_SIZE;                            coordinates.skipResizing = true                        }                        else                            top += height;                    if (this.isRtl)                        left -= width;                    return {                            height: height,                            width: width,                            top: top,                            left: left                        }                },                _getSimpleAppointmentGeometry: function(coordinates) {                    var maxWidth = this.instance._defaultWidth - WEEK_APPOINTMENT_DEFAULT_OFFSET || APPOINTMENT_DEFAULT_SIZE,                        width = maxWidth / coordinates.count,                        height = coordinates.height,                        top = coordinates.top,                        left = coordinates.left + coordinates.index * width;                    if (this.isRtl)                        left -= maxWidth;                    return {                            height: height,                            width: width,                            top: top,                            left: left                        }                },                isAllDay: function(item) {                    var startDate = this._startDate(item),                        endDate = this._endDate(item),                        appointmentTakesAllDay = false;                    this.instance.notifyObserver("appointmentTakesAllDay", {                        startDate: startDate,                        endDate: endDate,                        callback: function(result) {                            appointmentTakesAllDay = result                        }                    });                    return item.allDay || appointmentTakesAllDay                },                calculateAppointmentWidth: function(appointment) {                    if (!this.isAllDay(appointment))                        return 0;                    var startDate = this._startDate(appointment),                        endDate = this._endDate(appointment),                        cellWidth = this.instance._defaultWidth || APPOINTMENT_DEFAULT_SIZE;                    var durationInHours = (endDate.getTime() - startDate.getTime()) / 3600000;                    var width = Math.ceil(durationInHours / 24) * cellWidth;                    return width                },                calculateAppointmentHeight: function(appointment) {                    if (this.isAllDay(appointment))                        return 0;                    var startDate = this._startDate(appointment),                        endDate = this._endDate(appointment);                    var durationInMinutes = (endDate.getTime() - startDate.getTime()) / 60000,                        minHeight = APPOINTMENT_DEFAULT_SIZE;                    var height = Math.round(durationInMinutes * this._getMinuteHeight());                    if (height < minHeight)                        height = minHeight;                    return height                },                _sortCondition: function(a, b) {                    var allDayCondition = a.allDay - b.allDay;                    return allDayCondition ? allDayCondition : this._rowCondition(a, b)                }            });        var MonthRenderingStrategy = BaseRenderingStrategy.inherit({                resizableConfig: function() {                    return {                            minWidth: this.instance._defaultWidth,                            minHeight: 0,                            step: this.instance._defaultWidth,                            handles: "right left"                        }                },                _needVerifyItemSize: function() {                    return true                },                handleResize: function(args, start, end, appointment, initialSize) {                    var isLeft = $(args.jQueryEvent.target).hasClass("dx-resizable-handle-left") && !this.isRtl || $(args.jQueryEvent.target).hasClass("dx-resizable-handle-right") && this.isRtl,                        cellWidth = this.instance._defaultWidth || APPOINTMENT_DEFAULT_SIZE,                        initialWidth = initialSize.width,                        deltaTime = 24 * 60 * 60000 * (Math.round(args.width / cellWidth) - Math.round(initialWidth / cellWidth) || 1),                        startTime = isLeft ? start.getTime() - deltaTime : start.getTime(),                        endTime = isLeft ? end.getTime() : end.getTime() + deltaTime;                    return [startTime, endTime]                },                calculateAppointmentWidth: function(appointment) {                    var startDate = this._startDate(appointment),                        endDate = this._endDate(appointment),                        cellWidth = this.instance._defaultWidth || APPOINTMENT_DEFAULT_SIZE;                    var durationInHours = (endDate.getTime() - startDate.getTime()) / 3600000;                    var width = Math.ceil(durationInHours / 24) * cellWidth;                    return width                },                renderAppointmentGeometry: function($appointment, coordinates) {                    this.callBase($appointment, coordinates);                    if (coordinates.index > 1)                        $appointment.addClass(EMPTY_APPOINTMENT_CLASS)                },                getAppointmentGeometry: function(coordinates) {                    var maxHeight = this.instance._defaultHeight || APPOINTMENT_DEFAULT_SIZE,                        index = coordinates.index,                        height = MONTH_APPOINTMENT_HEIGHT_RATIO * maxHeight / 2,                        width = coordinates.width,                        top = (1 - MONTH_APPOINTMENT_HEIGHT_RATIO) * maxHeight + coordinates.top + index * height,                        left = coordinates.left;                    if (index > 1) {                        top = coordinates.top + MONTH_APPOINTMENT_DEFAULT_OFFSET;                        left = coordinates.left + (index - 2) * (MONTH_APPOINTMENT_DEFAULT_SIZE + MONTH_APPOINTMENT_DEFAULT_OFFSET) + MONTH_APPOINTMENT_DEFAULT_OFFSET;                        height = MONTH_APPOINTMENT_DEFAULT_SIZE,                        width = MONTH_APPOINTMENT_DEFAULT_SIZE;                        coordinates.skipResizing = true                    }                    if (this.isRtl)                        left -= width;                    return {                            height: height,                            width: width,                            top: top,                            left: left                        }                },                _sortCondition: function(a, b) {                    return this._columnCondition(a, b)                }            });        DX.registerComponent("dxSchedulerAppointments", ui.dxScheduler, ui.CollectionWidget.inherit({            _supportedKeys: function(e) {                var that = this;                var moveAppointmentBack = function(e) {                        var itemData = that._getItemData(e.target);                        if (itemData.initialCoordinates)                            DX.translator.move($(e.target), itemData.initialCoordinates);                        if (itemData.initialSize) {                            $(e.target).outerWidth(itemData.initialSize.width);                            $(e.target).outerHeight(itemData.initialSize.height)                        }                        itemData._escPressed = true                    };                return $.extend(this.callBase(), {escape: $.proxy(moveAppointmentBack, this)})            },            _moveFocus: $.noop,            _focusTarget: function() {                return this._itemElements()            },            _focusInHandler: function(e) {                this.callBase.apply(this, arguments);                this.option("focusedElement", $(e.target))            },            _setDefaultOptions: function() {                this.callBase();                this.option({                    noDataText: null,                    activeStateEnabled: true,                    hoverStateEnabled: true,                    tabIndex: 0,                    appointmentDurationInMinutes: 30,                    allDayContainer: null,                    renderingStrategy: "day",                    allowDrag: true,                    allowResize: true                })            },            _optionChanged: function(args) {                switch (args.name) {                    case"appointmentDurationInMinutes":                        break;                    case"renderingStrategy":                        this._initRenderingStrategy();                        this.repaint();                        break;                    case"allDayContainer":                        break;                    case"allowDrag":                    case"allowResize":                        this.repaint();                        break;                    default:                        this.callBase(args)                }            },            _itemClass: function() {                return APPOINTMENT_ITEM_CLASS            },            _itemContainer: function() {                var $container = this.callBase(),                    $result = $container,                    $allDayContainer = this.option("allDayContainer");                if ($allDayContainer)                    $result = $container.add($allDayContainer);                return $result            },            _cleanItemContainer: function() {                this.callBase();                var $allDayContainer = this.option("allDayContainer");                if ($allDayContainer)                    $allDayContainer.empty()            },            _init: function() {                this.callBase();                this._initRenderingStrategy();                this.element().addClass(COMPONENT_CLASS);                this._appointmentClickTimeout;                this._preventSingleAppointmentClick = false            },            _initRenderingStrategy: function() {                this._renderingStrategy = this.option("renderingStrategy") === "month" ? new MonthRenderingStrategy(this) : new WeekRenderingStrategy(this)            },            _executeItemRenderAction: function(index, itemData, itemElement) {                var action = this._getItemRenderAction();                if (action)                    action({                        appointmentElement: itemElement,                        appointmentIndex: index,                        appointment: itemData                    })            },            _createItemRenderAction: function() {                this.notifyObserver("initAppointmentRenderedAction", {callback: $.proxy(function(action) {                        this._itemRenderAction = action                    }, this)});                return this._itemRenderAction            },            _getStartDate: function(obj) {                var result = obj.startDate;                return DX.utils.makeDate(result)            },            _getEndDate: function(obj) {                var result = obj.endDate;                if (result)                    return DX.utils.makeDate(result);                return result            },            _itemClickHandler: function(e) {                var target = e.currentTarget,                    data = this._getItemData(target);                this._normalizeAppointmentDates(data);                this._appointmentClickTimeout = setTimeout($.proxy(function() {                    if (!this._preventSingleAppointmentClick)                        this.notifyObserver("showAppointmentTooltip", {                            data: data,                            target: target                        });                    this._preventSingleAppointmentClick = false                }, this), 300);                this.callBase(e)            },            _normalizeAppointmentDates: function(appointmentData) {                var startDate = DX.utils.makeDate(appointmentData.startDate),                    endDate = DX.utils.makeDate(appointmentData.endDate);                appointmentData.startDate = startDate;                appointmentData.endDate = endDate            },            _renderItems: function(items) {                if (this._isContainerInvisible())                    return;                this.notifyObserver("getCellDimensions", {callback: $.proxy(function(width, height, allDayHeight) {                        this._defaultWidth = width;                        this._defaultHeight = height;                        this._allDayHeight = allDayHeight                    }, this)});                this.notifyObserver("getMaxAllowedPosition", {callback: $.proxy(function(result) {                        if (result)                            this._maxAllowedPosition = result                    }, this)});                this._positionMap = this._renderingStrategy.createTaskPositionMap(items);                this.callBase(items)            },            _renderItem: function(index, itemData) {                var $allDayContainer = this.option("allDayContainer"),                    $container = this.itemsContainer().not($allDayContainer);                if (this._renderingStrategy.isAllDay(itemData) && $allDayContainer)                    $container = $allDayContainer;                this.callBase(index, itemData, $container)            },            _postprocessRenderItem: function(args) {                var $appointment = args.itemElement,                    itemData = args.itemData,                    itemSettings = this._positionMap[args.itemIndex];                this._attachAppointmentDblclick($appointment, itemData);                this._paintAppointment($appointment, 0);                itemData.recurrenceRule && $appointment.addClass(RECURRENCE_APPOINTMENT_CLASS);                this._applyResourceDataAttr($appointment);                this._renderAppointmentClones($appointment, itemSettings);                this._renderingStrategy.renderAppointmentGeometry($appointment, itemSettings[0]);                this._renderDraggable($appointment);                if (!itemSettings[0].skipResizing)                    this._renderResizable($appointment);                if (itemSettings[0].appointmentReduced)                    this._renderAppointmentReducedIcon($appointment)            },            _isContainerInvisible: function() {                var isContainerInvisible = false;                this.notifyObserver("checkContainerVisibility", {callback: function(result) {                        isContainerInvisible = result                    }});                return isContainerInvisible            },            _attachAppointmentDblclick: function($appointment, appointmentData) {                $appointment.off(DBLCLICK_EVENT_NAME).on(DBLCLICK_EVENT_NAME, $.proxy(function(e) {                    clearTimeout(this._appointmentClickTimeout);                    this._preventSingleAppointmentClick = true;                    this.notifyObserver("showEditAppointmentPopup", appointmentData)                }, this))            },            _getAppointmentCoordinates: function(itemData) {                var startDate = this._getStartDate(itemData),                    coordinates = [{                            top: 0,                            left: 0                        }];                this.notifyObserver("needCoordinates", {                    startDate: startDate,                    appointmentData: itemData,                    callback: function(value) {                        coordinates = value                    }                });                return coordinates            },            _applyResourceDataAttr: function($appointment) {                this.notifyObserver("getResourcesFromItem", {                    itemData: this._getItemData($appointment),                    callback: function(resources) {                        if (resources)                            $.each(resources, function(name, values) {                                var attr = "data-" + name.toLowerCase() + "-";                                for (var i = 0; i < values.length; i++)                                    $appointment.attr(attr + values[i], true)                            })                    }                })            },            _renderDraggable: function($appointment) {                if (!this.option("allowDrag"))                    return;                var that = this,                    appointmentData = that._getItemData($appointment);                this._createComponent($appointment, "dxDraggable", {                    onDragStart: function(e) {                        that.notifyObserver("hideAppointmentTooltip");                        e.jQueryEvent.targetElements = $appointment.closest(".dx-scheduler");                        appointmentData.initialSize = {                            width: e.width,                            height: e.height                        };                        appointmentData.initialCoordinates = DX.translator.locate(e.element)                    },                    onDragEnd: function(e) {                        var itemData = that._getItemData($appointment);                        if (itemData._escPressed) {                            delete itemData._escPressed;                            e.jQueryEvent.cancel = true;                            return                        }                        that._dragEndHandler(e, appointmentData.initialCoordinates)                    },                    area: this.element().closest(".dx-scrollable-content")                })            },            _renderResizable: function($appointment) {                if (!this.option("allowResize"))                    return;                var appointmentData = this._getItemData($appointment),                    config = this._renderingStrategy.resizableConfig(appointmentData);                $.extend(config, {                    area: this.element().closest(".dx-scrollable-content"),                    onResizeStart: $.proxy(function(e) {                        appointmentData.initialSize = {                            width: e.width,                            height: e.height                        };                        appointmentData.initialCoordinates = DX.translator.locate(e.element)                    }, this),                    onResizeEnd: $.proxy(function(e) {                        if (appointmentData._escPressed) {                            delete appointmentData._escPressed;                            e.jQueryEvent.cancel = true;                            return                        }                        this._resizeEndHandler(e, appointmentData.initialSize, appointmentData.initialCoordinates)                    }, this)                });                this._createComponent($appointment, "dxResizable", config)            },            _paintAppointment: function($appointment, resourceIndex) {                this.notifyObserver("getAppointmentColor", {                    itemData: this._getItemData($appointment),                    resourceIndex: resourceIndex,                    callback: function(d) {                        d.done(function(color) {                            if (color)                                $appointment.css("background-color", color)                        })                    }                })            },            _renderAppointmentReducedIcon: function($appointment) {                $appointment.toggleClass(REDUCED_APPOINTMENT_CLASS, true);                var $icon = $("<div>").addClass(REDUCED_APPOINTMENT_ICON).appendTo($appointment),                    endDate = this._getEndDate(this._getItemData($appointment));                $icon.off(REDUCED_APPOINTMENT_POINTERENTER_EVENT_NAME).on(REDUCED_APPOINTMENT_POINTERENTER_EVENT_NAME, function() {                    ui.tooltip.show({                        target: $icon,                        content: Globalize.localize("dxScheduler-editorLabelEndDate") + ": " + Globalize.format(endDate, "d MMMM yyyy")                    })                }).off(REDUCED_APPOINTMENT_POINTERLEAVE_EVENT_NAME).on(REDUCED_APPOINTMENT_POINTERLEAVE_EVENT_NAME, function() {                    ui.tooltip.hide()                })            },            _renderAppointmentClones: function($appointment, coordinates) {                var coordinateCount = coordinates.length;                if (coordinateCount > 1) {                    var clones = [],                        itemData = this._getItemData($appointment),                        resourceForPainting = this._getResourceForPainting();                    for (var i = coordinateCount - 1; i > 0; i--) {                        var $clone = $appointment.clone(true);                        $appointment.after($clone);                        translator.clearCache($clone);                        this._renderingStrategy.renderAppointmentGeometry($clone, coordinates[i]);                        this._renderDraggable($clone);                        if (!coordinates[i].skipResizing)                            this._renderResizable($clone);                        if (coordinates[i].appointmentReduced)                            this._renderAppointmentReducedIcon($clone);                        clones.push($clone)                    }                    if (resourceForPainting) {                        var resourceValues = DX.utils.wrapToArray(itemData[resourceForPainting]);                        this._loop(resourceValues, coordinateCount - 1, function(elementIndex, iterationIndex) {                            this._paintAppointment(clones[iterationIndex], elementIndex)                        }, 1)                    }                }            },            _getResourceForPainting: function() {                var resourceForPainting;                this.notifyObserver("getResourceForPainting", {callback: function(resource) {                        if (resource)                            resourceForPainting = resource.field                    }});                return resourceForPainting            },            _loop: function(array, iterationCount, callback, startIndex) {                startIndex = startIndex || 0;                var arrayLength = array.length;                for (var i = 0; i < iterationCount; i++) {                    var elementIndex = startIndex + i;                    if (elementIndex >= arrayLength)                        elementIndex = elementIndex % arrayLength;                    callback.call(this, elementIndex, i)                }            },            _resizeEndHandler: function(e, initialSize, initialCoordinates) {                var itemData = this._getItemData(e.element),                    startDate = this._getStartDate(itemData),                    endDate = this._getEndDate(itemData);                var dateRange = this._renderingStrategy.handleResize(e, startDate, endDate, itemData, initialSize);                var updatedDates = {};                updatedDates.startDate = new Date(dateRange[0]);                updatedDates.endDate = new Date(dateRange[1]);                var data = $.extend({}, itemData, updatedDates);                this.notifyObserver("updateAppointmentAfterResize", {                    target: itemData,                    data: data,                    $appointment: e.element,                    initialSize: initialSize,                    initialCoordinates: initialCoordinates                })            },            _dragEndHandler: function(e, initialCoordinates) {                var itemData = this._getItemData(e.element);                this._normalizeAppointmentDates(itemData);                this.notifyObserver("updateAppointmentAfterDrag", {                    data: itemData,                    $appointment: e.element,                    initialCoordinates: initialCoordinates                })            }        }).include(ui.dxScheduler.PublisherMixin))    })(jQuery, DevExpress);    /*! Module widgets-web, file clientExporter.js */    (function(DX, $) {        var utils = DX.utils;        DX.registerComponent("dxClientExporter", DX, DX.Component.inherit({            NAME: "dxClientExporter",            _getDocumentCreator: function(exportableComponent, options) {                if (options.format === "EXCEL")                    return new DX.dxClientExporter.ExcelCreator(exportableComponent.getDataProvider(), $.extend({rtlEnabled: exportableComponent.option("rtlEnabled")}, options))            },            exportTo: function(options) {                var that = this,                    eventArgs,                    exportingAction = this.option("exportingAction"),                    exportedAction = this.option("exportedAction"),                    data,                    documentCreator,                    exportableComponent = options.component;                if (exportableComponent) {                    eventArgs = {                        fileName: options.fileName,                        format: options.format,                        cancel: false                    };                    utils.isDefined(exportingAction) && exportingAction(eventArgs);                    if (!eventArgs.cancel) {                        documentCreator = that._getDocumentCreator(exportableComponent, options);                        documentCreator.ready().done(function() {                            data = documentCreator.getData(utils.isFunction(window.Blob));                            utils.isDefined(exportedAction) && exportedAction();                            DX.dxClientExporter.fileSaver.saveAs(eventArgs.fileName, options.format, data, options.proxyUrl)                        })                    }                }            }        }))    })(DevExpress, jQuery);    /*! Module widgets-web, file excelCreator.js */    (function($, DX) {        var utils = DX.utils,            Class = DX.Class,            exporter = DX.dxClientExporter,            XML_TAG = "<?xml version=\"1.0\" encoding=\"utf-8\"?>",            GROUP_SHEET_PR_XML = "<sheetPr><outlinePr summaryBelow=\"0\"/></sheetPr>",            SINGLE_SHEET_PR_XML = "<sheetPr/>",            BASE_STYLE_XML = "<fonts count=\"2\"><font><sz val=\"11\"/><color theme=\"1\"/><name val=\"Calibri\"/><family val=\"2\"/><scheme val=\"minor\"/></font><font><b/><sz val=\"11\"/><color theme=\"1\"/><name val=\"Calibri\"/><family val=\"2\"/><scheme val=\"minor\"/></font></fonts><fills count=\"1\"><fill><patternFill patternType=\"none\"/></fill></fills><borders count=\"1\"><border><left style=\"thin\"><color rgb=\"FFD3D3D3\"/></left><right style=\"thin\"><color rgb=\"FFD3D3D3\"/></right><top style=\"thin\"><color rgb=\"FFD3D3D3\"/></top><bottom style=\"thin\"><color rgb=\"FFD3D3D3\"/></bottom></border></borders><cellStyleXfs count=\"1\"><xf numFmtId=\"0\" fontId=\"0\" fillId=\"0\" borderId=\"0\"/></cellStyleXfs>",            OPEN_XML_FORMAT_URL = "http://schemas.openxmlformats.org",            RELATIONSHIP_PART_NAME = "rels",            XL_FOLDER_NAME = "xl",            WORKBOOK_FILE_NAME = "workbook.xml",            CONTENTTYPES_FILE_NAME = "[Content_Types].xml",            SHAREDSTRING_FILE_NAME = "sharedStrings.xml",            STYLE_FILE_NAME = "styles.xml",            WORKSHEETS_FOLDER = "worksheets",            WORKSHEET_FILE_NAME = "sheet1.xml",            UNSUPPORTED_DEFINED_DATE_FORMATS = ["quarter", "quarterAndYear", "millisecond"],            DEFAULT_DATE_FORMAT = "shortDate",            DEFINED_NUMBER_FORMTATS = {                thousands: "#,##0{0},"K"",                millions: "#,##0{0},,"M"",                billions: "#,##0{0},,,"B"",                trillions: "#,##0{0},,,,"T"",                percent: "0{0}%",                decimal: "#{0}",                fixedPoint: "#,##0{0}",                exponential: "0{0}E+00",                currency: " "            },            EXCEL_START_TIME = new Date("12/30/1899").getTime(),            DAYS_COUNT_BEFORE_29_FEB_1900 = 60,            BOLD_STYLES_COUNT = 4,            MAX_DIGIT_WIDTH_IN_PIXELS = 7,            CUSTOM_FORMAT_START_INDEX = 165;        exporter.excelFormatConverter = {            _applyPrecision: function(format, precision) {                var result,                    i;                if (precision > 0) {                    result = format !== "decimal" ? "." : "";                    for (i = 0; i < precision; i++)                        result += "0";                    return result                }                return ""            },            _getCurrencyFormat: function() {                var currency = Globalize.cultures[Globalize.cultureSelector].numberFormat.currency,                    i,                    result,                    symbol,                    encodeSymbols;                if (utils.isArray(currency.pattern)) {                    encodeSymbols = {                        n: "#,##0{0}",                        "'": "\\'",                        "\\(": "\\(",                        "\\)": "\\)",                        " ": "\\ ",                        "\"": """,                        "\\$": currency.symbol                    };                    result = currency.pattern.slice();                    for (symbol in encodeSymbols)                        for (i = 0; i < result.length; i++)                            result[i] = result[i].replace(new RegExp(symbol, "g"), encodeSymbols[symbol]);                    return result.length === 2 ? result[1] + "_);" + result[0] : result[0]                }            },            _convertDateFormat: function(format) {                if (!DX.DateTimeFormat[format.toLowerCase()] || $.inArray(format, UNSUPPORTED_DEFINED_DATE_FORMATS) !== -1)                    format = DEFAULT_DATE_FORMAT;                var datePatterns = Globalize.cultures[Globalize.cultureSelector].calendar.patterns,                    pattern = DX.DateTimeFormat[format.toLowerCase()];                if (utils.isDefined(datePatterns[pattern]))                    pattern = datePatterns[pattern];                return pattern.replace(/\//g, "\\/").replace(/ /g, "\\ ").replace(/,/g, "\\,").replace(/:/g, "\\:").replace(/tt/g, "AM/PM").replace(/N/g, "#\\,###")            },            _convertNumberFormat: function(format, precision) {                var result,                    excelFormat = format === "currency" ? this._getCurrencyFormat() : DEFINED_NUMBER_FORMTATS[format];                if (excelFormat)                    result = utils.stringFormat(excelFormat, this._applyPrecision(format, precision));                return result            },            convertFormat: function(format, precision, type) {                if (utils.isDefined(format))                    if (type === "date")                        return exporter.excelFormatConverter._convertDateFormat(format);                    else if (DEFINED_NUMBER_FORMTATS[format])                        return exporter.excelFormatConverter._convertNumberFormat(format, precision)            }        };        exporter.ExcelCreator = Class.inherit({            _getXMLTag: function(tagName, attributes, content) {                var result = ["<"],                    key;                result.push(tagName);                for (key in attributes) {                    result.push(" ");                    result.push(key);                    result.push("=\"");                    result.push(attributes[key]);                    result.push("\"")                }                if (utils.isDefined(content)) {                    result.push(">");                    result.push(content);                    result.push("</");                    result.push(tagName);                    result.push(">")                }                else                    result.push(" />");                return result.join("")            },            _getDataProviderRowIndex: function(dpRowIndex) {                return dpRowIndex - !!this._dataProvider.isHeadersVisible()            },            _getExcelRowIndex: function(exRowIndex) {                return exRowIndex + !!this._dataProvider.isHeadersVisible()            },            _getCellIndex: function(rowIndex, cellIndex) {                var sheetIndex = '',                    max = 32,                    charCode;                if (this._maxIndex[0] < Number(rowIndex))                    this._maxIndex[0] = Number(rowIndex);                if (this._maxIndex[1] < Number(cellIndex))                    this._maxIndex[1] = Number(cellIndex);                do {                    charCode = 65 + (cellIndex > max ? cellIndex % max : Math.ceil(cellIndex));                    if (charCode <= 90)                    {                        sheetIndex = String.fromCharCode(charCode) + sheetIndex;                    } else {                        sheetIndex = String.fromCharCode(65) + String.fromCharCode(charCode-26) + sheetIndex;                    }                                      cellIndex = Math.floor(cellIndex / max)                } while (cellIndex);                sheetIndex += rowIndex;                return sheetIndex            },            _getDataType: function(dataType) {                var validTypes = {                        boolean: "b",                        date: "d",                        number: "n",                        string: "s"                    };                return utils.isDefined(validTypes[dataType]) ? validTypes[dataType] : "s"            },            _appendFormat: function(format, precision, dataType) {                format = exporter.excelFormatConverter.convertFormat(format, precision, dataType);                if (format) {                    if ($.inArray(format, this._styleFormat) === -1)                        this._styleFormat.push(format);                    return $.inArray(format, this._styleFormat) + 1                }            },            _appendString: function(value) {                if (utils.isDefined(value) && value.length) {                    if ($.inArray(value, this._stringArray) === -1) {                        if (value.indexOf("&") > 0)                            value = value.replace(new RegExp("&", "g"), "&");                        this._stringArray.push(value)                    }                    return $.inArray(value, this._stringArray)                }            },            _getExcelDateValue: function(date) {                var days,                    totalTime;                if (utils.isDefined(date)) {                    days = Math.floor((date.getTime() - EXCEL_START_TIME) / (1000 * 60 * 60 * 24));                    if (days < DAYS_COUNT_BEFORE_29_FEB_1900)                        days--;                    totalTime = (date.getHours() * 3600 + date.getMinutes() * 60 + date.getSeconds()) / (24 * 3600);                    return days + totalTime                }            },            _prepareValue: function(rowIndex, cellIndex) {                var value = this._dataProvider.getCellValue(rowIndex, cellIndex),                    type = this._getDataType(this._dataProvider.getCellType(rowIndex, cellIndex)),                    formatID = this._styleArray[cellIndex + BOLD_STYLES_COUNT].formatID,                    format = DX.utils.isNumber(formatID) ? this._styleFormat[formatID - 1] : null;                switch (type) {                    case"s":                        value = this._appendString(value);                        break;                    case"d":                        value = this._getExcelDateValue(value, format);                        type = "n";                        break                }                return {                        value: value,                        type: type                    }            },            _getHeadersArray: function() {                var i,                    columns = this._dataProvider.getColumns(),                    result = [],                    startIndex = !this._rtlEnabled ? 0 : columns.length - 1,                    endIndex = !this._rtlEnabled ? columns.length : -1,                    counter = !this._rtlEnabled ? 1 : -1;                for (i = startIndex; i !== endIndex; i += counter)                    result.push({                        style: 0,                        type: "s",                        value: this._appendString(columns[i].caption)                    });                return result            },            _getDataArray: function() {                var rowIndex,                    cellIndex,                    cellsArray,                    cellData,                    result = [],                    type,                    styleID,                    columns = this._dataProvider.getColumns(),                    startIndex = !this._rtlEnabled ? 0 : columns.length - 1,                    endIndex = !this._rtlEnabled ? columns.length : -1;                for (rowIndex = 0; rowIndex < this._dataProvider.getRowsCount(); rowIndex++) {                    cellsArray = [];                    for (cellIndex = startIndex; cellIndex !== endIndex; cellIndex += !this._rtlEnabled ? 1 : -1) {                        cellData = this._prepareValue(rowIndex, cellIndex);                        type = cellData.type;                        if (!this._dataProvider.isGroupRow(rowIndex) && utils.isDefined(this._styleArray[cellIndex + BOLD_STYLES_COUNT].formatID) && cellData.type !== "s")                            type = "n";                        styleID = cellIndex + BOLD_STYLES_COUNT;                        if (this._dataProvider.isGroupRow(rowIndex))                            styleID = BOLD_STYLES_COUNT - 1;                        if (this._dataProvider.isTotalRow(rowIndex))                            styleID = this._getBoldStyleID(columns[cellIndex].alignment);                        cellsArray.push({                            style: styleID,                            value: cellData.value,                            type: type                        })                    }                    if (rowIndex && !this._needSheetPr && this._dataProvider.getGroupLevel(this._getDataProviderRowIndex(rowIndex)) > 0)                        this._needSheetPr = true;                    result.push(cellsArray)                }                return result            },            _getBoldStyleID: function(alignment) {                for (var i = 0; i < BOLD_STYLES_COUNT - 1; i++)                    if (this._styleArray[i].alignment === alignment)                        return i            },            _culculateWidth: function(pixelsWidth) {                return Math.min(255, Math.floor((pixelsWidth - 5) / MAX_DIGIT_WIDTH_IN_PIXELS * 100 + 0.5) / 100)            },            _prepareStyleData: function() {                var i,                    column,                    wrapText = Number(!!this._options.wrapTextEnabled),                    alignments = ["center", "left", "right"],                    columns = this._dataProvider.getColumns();                for (i = 0; i < alignments.length; i++)                    this._styleArray.push({                        bold: true,                        alignment: alignments[i],                        wrapText: wrapText                    });                this._styleArray.push({                    bold: true,                    alignment: this._rtlEnabled ? "right" : "left",                    wrapText: 0                });                for (i = 0; i < columns.length; i++) {                    column = columns[i];                    this._styleArray.push({                        alignment: utils.isDefined(column.alignment) ? column.alignment : "left",                        formatID: this._appendFormat(column.format, column.precision, column.dataType),                        wrapText: wrapText                    });                    this._colsArray.push(this._culculateWidth(column.width))                }            },            _prepareCellData: function() {                if (this._dataProvider.isHeadersVisible())                    this._cellsArray.push(this._getHeadersArray());                this._cellsArray = this._cellsArray.concat(this._getDataArray())            },            _createXMLRelationships: function(xmlRelationships) {                return this._getXMLTag("Relationships", {xmlns: OPEN_XML_FORMAT_URL + "/package/2006/relationships"}, xmlRelationships)            },            _createXMLRelationship: function(id, type, target) {                return this._getXMLTag("Relationship", {                        Id: "rId" + id,                        Type: OPEN_XML_FORMAT_URL + "/officeDocument/2006/relationships/" + type,                        Target: target                    })            },            _getWorkbookContent: function() {                var content = "<bookViews><workbookView xWindow=\"0\" yWindow=\"0\" windowWidth=\"0\" windowHeight=\"0\"/></bookViews><sheets><sheet name=\"Sheet\" sheetId=\"1\" r:id=\"rId1\" /></sheets><definedNames><definedName name=\"_xlnm.Print_Titles\" localSheetId=\"0\">Sheet!$1:$1</definedName><definedName name=\"_xlnm._FilterDatabase\" hidden=\"0\" localSheetId=\"0\">Sheet!$A$1:$F$6332</definedName></definedNames>";                return XML_TAG + this._getXMLTag("workbook", {                        "xmlns:r": OPEN_XML_FORMAT_URL + "/officeDocument/2006/relationships",                        xmlns: OPEN_XML_FORMAT_URL + "/spreadsheetml/2006/main"                    }, content)            },            _getContentTypesContent: function() {                return XML_TAG + "<Types xmlns=\"" + OPEN_XML_FORMAT_URL + "/package/2006/content-types\"><Default Extension=\"rels\" ContentType=\"application/vnd.openxmlformats-package.relationships+xml\" /><Default Extension=\"xml\" ContentType=\"application/xml\" /><Override PartName=\"/xl/worksheets/sheet1.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml\" /><Override PartName=\"/xl/styles.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml\" /><Override PartName=\"/xl/sharedStrings.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml\" /><Override PartName=\"/xl/workbook.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml\" /></Types>"            },            _generateStylesXML: function() {                var xlFolder = this._zip.folder(XL_FOLDER_NAME),                    styleIndex,                    style,                    xmlStyles = [],                    formatIndex,                    XML = "";                for (formatIndex in this._styleFormat)                    this._styleFormat[formatIndex] = this._getXMLTag("numFmt", {                        numFmtId: Number(formatIndex) + CUSTOM_FORMAT_START_INDEX,                        formatCode: this._styleFormat[formatIndex]                    });                XML += this._getXMLTag("numFmts", {count: this._styleFormat.length}, this._styleFormat.join(""));                XML += BASE_STYLE_XML;                for (styleIndex in this._styleArray) {                    style = this._styleArray[styleIndex];                    xmlStyles.push(this._getXMLTag("xf", {                        xfId: 0,                        applyAlignment: 1,                        fontId: Number(!!style.bold),                        applyNumberFormat: utils.isDefined(style.formatID) ? 1 : 0,                        numFmtId: utils.isDefined(style.formatID) ? Number(style.formatID) + CUSTOM_FORMAT_START_INDEX - 1 : 0                    }, this._getXMLTag("alignment", {                        horizontal: style.alignment,                        wrapText: style.wrapText                    })))                }                XML += this._getXMLTag("cellXfs", {count: xmlStyles.length}, xmlStyles.join(""));                XML += this._getXMLTag("cellStyles", {count: 1}, this._getXMLTag("cellStyle", {                    name: "Normal",                    xfId: 0,                    builtinId: 0                }));                XML = XML_TAG + this._getXMLTag("styleSheet", {xmlns: OPEN_XML_FORMAT_URL + "/spreadsheetml/2006/main"}, XML);                xlFolder.file(STYLE_FILE_NAME, XML);                this._styleArray = []            },            _generateStringsXML: function() {                var xlFolder = this._zip.folder(XL_FOLDER_NAME),                    stringIndex,                    sharedStringXml = XML_TAG;                for (stringIndex in this._stringArray)                    this._stringArray[stringIndex] = this._getXMLTag("si", {}, this._getXMLTag("t", {}, this._stringArray[stringIndex]));                sharedStringXml += this._getXMLTag("sst", {                    xmlns: OPEN_XML_FORMAT_URL + "/spreadsheetml/2006/main",                    count: this._stringArray.length,                    uniqueCount: this._stringArray.length                }, this._stringArray.join(""));                xlFolder.file(SHAREDSTRING_FILE_NAME, sharedStringXml);                this._stringArray = []            },            _generateWorksheetXML: function() {                var colIndex,                    rowIndex,                    cellData,                    xmlCells,                    maxCellIndex,                    counter = 0,                    xmlRows = [],                    rSpans = "1:" + this._colsArray.length,                    xmlResult = [["<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><worksheet xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" mc:Ignorable=\"x14ac\" xmlns:x14ac=\"http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac\">", this._needSheetPr ? GROUP_SHEET_PR_XML : SINGLE_SHEET_PR_XML, "<dimension ref=\"A1:", this._getCellIndex(this._maxIndex[0], this._maxIndex[1]) + "\"/><sheetViews><sheetView tabSelected=\"1\" workbookViewId=\"0\"><pane ySplit=\"1\" topLeftCell=\"A2\" activePane=\"bottomLeft\" state=\"frozen\"/></sheetView></sheetViews><sheetFormatPr defaultRowHeight=\"15\" outlineLevelRow=\"", this._dataProvider.getRowsCount() > 0 ? this._dataProvider.getGroupLevel(0) : 0, "\" x14ac:dyDescent=\"0.25\"/>"].join("")];                for (colIndex in this._colsArray)                    this._colsArray[colIndex] = this._getXMLTag("col", {                        width: this._colsArray[colIndex],                        min: Number(colIndex) + 1,                        max: Number(colIndex) + 1                    });                xmlResult.push(this._getXMLTag("cols", [], this._colsArray.join("")) + "<sheetData>");                for (rowIndex in this._cellsArray) {                    xmlCells = [];                    for (colIndex in this._cellsArray[rowIndex]) {                        rowIndex = Number(rowIndex);                        cellData = this._cellsArray[rowIndex][colIndex];                        xmlCells.push(this._getXMLTag("c", {                            r: this._getCellIndex(rowIndex + 1, colIndex),                            s: cellData.style,                            t: cellData.type                        }, utils.isDefined(cellData.value) ? this._getXMLTag("v", {}, cellData.value) : null))                    }                    xmlRows.push(this._getXMLTag("row", {                        r: Number(rowIndex) + 1,                        spans: rSpans,                        outlineLevel: !Number(rowIndex) ? 0 : this._dataProvider.getGroupLevel(this._getDataProviderRowIndex(rowIndex)),                        "x14ac:dyDescent": "0.25"                    }, xmlCells.join("")));                    this._cellsArray[rowIndex] = null;                    if (counter++ > 10000) {                        xmlResult.push(xmlRows.join(""));                        xmlRows = [];                        counter = 0                    }                }                xmlResult.push(xmlRows.join(""));                xmlRows = [];                maxCellIndex = this._getCellIndex(this._maxIndex[0], this._maxIndex[1]);                xmlResult.push("</sheetData>" + (this._options.autoFilterEnabled ? "<autoFilter ref=\"A1:" + maxCellIndex + "\" />" : "") + "<ignoredErrors><ignoredError sqref=\"A1:" + maxCellIndex + "\" numberStoredAsText=\"1\" /></ignoredErrors></worksheet>");                this._zip.folder(XL_FOLDER_NAME).folder(WORKSHEETS_FOLDER).file(WORKSHEET_FILE_NAME, xmlResult.join(""));                this._colsArray = [];                this._cellsArray = [];                xmlResult = []            },            _generateCommonXML: function() {                var relsFileContent = XML_TAG + this._createXMLRelationships(this._createXMLRelationship(1, "officeDocument", "xl/" + WORKBOOK_FILE_NAME)),                    xmlRelationships,                    xlFolder = this._zip.folder(XL_FOLDER_NAME),                    relsXML = XML_TAG;                this._zip.folder("_" + RELATIONSHIP_PART_NAME).file("." + RELATIONSHIP_PART_NAME, relsFileContent);                xmlRelationships = this._createXMLRelationship(1, "worksheet", "worksheets/" + WORKSHEET_FILE_NAME) + this._createXMLRelationship(2, "styles", STYLE_FILE_NAME) + this._createXMLRelationship(3, "sharedStrings", SHAREDSTRING_FILE_NAME);                relsXML += this._createXMLRelationships(xmlRelationships);                xlFolder.folder("_" + RELATIONSHIP_PART_NAME).file(WORKBOOK_FILE_NAME + ".rels", relsXML);                xlFolder.file(WORKBOOK_FILE_NAME, this._getWorkbookContent());                this._zip.file(CONTENTTYPES_FILE_NAME, this._getContentTypesContent())            },            _generateContent: function() {                this._prepareStyleData();                this._prepareCellData();                this._generateWorkXML();                this._generateCommonXML()            },            _generateWorkXML: function() {                this._generateStylesXML();                this._generateStringsXML();                this._generateWorksheetXML()            },            ctor: function(dataProvider, options) {                this._rtlEnabled = options && !!options.rtlEnabled;                this._options = options;                this._maxIndex = [1, 2];                this._stringArray = [];                this._styleArray = [];                this._colsArray = [];                this._cellsArray = [];                this._styleFormat = [];                this._needSheetPr = false;                this._dataProvider = dataProvider;                this._zip = new JSZip            },            ready: function() {                return this._dataProvider.ready()            },            getData: function(isBlob) {                this._generateContent();                return this._zip.generate({                        type: isBlob ? "blob" : "base64",                        compression: "DEFLATE"                    })            }        });        exporter.__internals = {            CONTENTTYPES_FILE_NAME: CONTENTTYPES_FILE_NAME,            RELATIONSHIP_PART_NAME: RELATIONSHIP_PART_NAME,            XL_FOLDER_NAME: XL_FOLDER_NAME,            WORKBOOK_FILE_NAME: WORKBOOK_FILE_NAME,            STYLE_FILE_NAME: STYLE_FILE_NAME,            WORKSHEET_FILE_NAME: WORKSHEET_FILE_NAME,            WORKSHEETS_FOLDER: WORKSHEETS_FOLDER,            SHAREDSTRING_FILE_NAME: SHAREDSTRING_FILE_NAME,            GROUP_SHEET_PR_XML: GROUP_SHEET_PR_XML,            SINGLE_SHEET_PR_XML: SINGLE_SHEET_PR_XML        }    })(jQuery, DevExpress);    /*! Module widgets-web, file fileSaver.js */    (function(DX, $) {        var exporter = DX.dxClientExporter,            utils = DX.utils,            MIME_TYPES = {                CSS: "text/css",                EXCEL: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"            },            FILE_EXTESIONS = {                EXCEL: "xlsx",                CSS: "css"            };        exporter.fileSaver = {            _linkDownloader: function(fileName, href, callback) {                var exportLinkElement = document.createElement('a'),                    attributes = {                        download: fileName,                        href: href                    };                if (utils.isDefined(callback))                    attributes["onclick"] = callback;                document.body.appendChild(exportLinkElement);                $(exportLinkElement).css({display: "none"}).text("load").attr(attributes)[0].click();                return exportLinkElement            },            _formDownloader: function(proxyUrl, fileName, contentType, data, callback) {                var formAttributes = {                        method: "post",                        action: proxyUrl,                        enctype: "multipart/form-data"                    },                    exportForm = $("<form>").css({display: "none"}).attr(formAttributes);                if (utils.isDefined(callback))                    exportForm.submit(callback);                exportForm.append("<input type=\"hidden\" name=\"fileName\" value=\"" + fileName + "\" />");                exportForm.append("<input type=\"hidden\" name=\"contentType\" value=\"" + contentType + "\" />");                exportForm.append("<input type=\"hidden\" name=\"data\" value=\"" + data + "\" />");                exportForm.appendTo("body");                exportForm.submit();                if (exportForm.submit())                    exportForm.remove();                return exportForm            },            _saveByProxy: function(proxyUrl, fileName, format, data, callback) {                fileName += "." + FILE_EXTESIONS[format];                return this._formDownloader(proxyUrl, fileName, MIME_TYPES[format], data, callback)            },            _saveBase64As: function(fileName, format, data, linkClick) {                var href = "data:" + MIME_TYPES[format] + ";base64," + data;                fileName += "." + FILE_EXTESIONS[format];                return this._linkDownloader(fileName, href, linkClick)            },            _saveBlobAs: function(fileName, format, data, linkClick) {                this._blobSaved = false;                fileName += "." + FILE_EXTESIONS[format];                data = data.slice(0, data.size, MIME_TYPES[format]);                if (utils.isDefined(navigator.msSaveOrOpenBlob)) {                    navigator.msSaveOrOpenBlob(data, fileName);                    this._blobSaved = true                }                else {                    var URL = window.URL || window.webkitURL || window.mozURL || window.msURL || window.oURL;                    linkClick = utils.isDefined(linkClick) ? linkClick : function() {                        var link = $('#dxExportLink');                        URL.revokeObjectURL(link.attr('href'));                        link.remove();                        exporter.blobSaved = true                    };                    if (utils.isDefined(URL))                        return this._linkDownloader(fileName, URL.createObjectURL(data), linkClick)                }            },            saveAs: function(fileName, format, data, proxyURL) {                if (utils.isFunction(window.Blob))                    this._saveBlobAs(fileName, format, data);                else if (utils.isDefined(proxyURL) && !utils.isDefined(navigator.userAgent.match(/iPad/i)))                    this._saveByProxy(proxyURL, fileName, format, data);                else {                    if (!utils.isDefined(navigator.userAgent.match(/iPad/i)))                        DX.log("E1034");                    if (DX.browser.msie && parseInt(DX.browser.version) < 10)                        return;                    this._saveBase64As(fileName, format, data)                }            }        }    })(DevExpress, jQuery);    DevExpress.MOD_WIDGETS_WEB = true}if (!DevExpress.MOD_FRAMEWORK) {    if (!window.DevExpress)        throw Error('Required module is not referenced: core');    /*! Module framework, file framework.js */    (function($, DX, undefined) {        var mergeWithReplace = function(targetArray, arrayToMerge, needReplaceFn) {                var result = [];                for (var i = 0, length = targetArray.length; i < length; i++)                    if (!needReplaceFn(targetArray[i], arrayToMerge))                        result.push(targetArray[i]);                result.push.apply(result, arrayToMerge);                return result            };        var prepareCommandToReplace = function(targetCommand, commandsToMerge) {                var needToReplace = false;                $.each(commandsToMerge, function(_, commandToMerge) {                    var idEqual = targetCommand.option("id") === commandToMerge.option("id") && commandToMerge.option("id"),                        behaviorEqual = targetCommand.option("behavior") === commandToMerge.option("behavior") && targetCommand.option("behavior");                    needToReplace = idEqual || behaviorEqual;                    if (behaviorEqual && commandToMerge.option("onExecute") === null)                        commandToMerge.option("onExecute", targetCommand.option("onExecute"));                    if (needToReplace) {                        targetCommand.element().remove();                        return false                    }                });                return needToReplace            };        var mergeCommands = function(targetCommands, commandsToMerge) {                return mergeWithReplace(targetCommands, commandsToMerge, prepareCommandToReplace)            };        var resolvePropertyValue = function(command, containerOptions, propertyName, defaultValue) {                var containerOption = containerOptions ? containerOptions[propertyName] : undefined,                    defaultOption = containerOption === undefined ? defaultValue : containerOption,                    commandOption = command.option(propertyName);                return commandOption === undefined || commandOption === defaultValue ? defaultOption : commandOption            };        var resolveTextValue = function(command, containerOptions) {                var showText = resolvePropertyValue(command, containerOptions, "showText"),                    hasIcon = !!command.option("icon"),                    titleValue = resolvePropertyValue(command, containerOptions, "title", "");                return showText || !hasIcon ? titleValue : ""            };        var resolveIconValue = function(command, containerOptions, propertyName) {                var showIcon = resolvePropertyValue(command, containerOptions, "showIcon"),                    hasText = !!command.option("title"),                    iconValue = resolvePropertyValue(command, containerOptions, propertyName, "");                return showIcon || !hasText ? iconValue : ""            };        var resolveTypeValue = function(command, containerOptions) {                return resolvePropertyValue(command, containerOptions, "type")            };        DX.framework = {            utils: {                mergeCommands: mergeCommands,                commandToContainer: {                    resolveTypeValue: resolveTypeValue,                    resolveIconValue: resolveIconValue,                    resolveTextValue: resolveTextValue,                    resolvePropertyValue: resolvePropertyValue                }            },            templateProvider: DX.ui.KoTemplateProvider        }    })(jQuery, DevExpress);    /*! Module framework, file framework.errors.js */    (function($, DX) {        $.extend(DX.ERROR_MESSAGES, {            E3001: "Routing rule is not found for the '{0}' URI.",            E3002: "The passed object cannot be formatted into a URI string by the application's router. An appropriate route should be registered.",            E3003: "Unable to navigate. Application is being initialized.",            E3004: "Cannot execute the command: {0}.",            E3005: "The '{0}' command {1} is not registered in the application's command mapping. Go to http://dxpr.es/1bTjfj1 for more details.",            E3006: "Unknown navigation target: '{0}'. Use the 'current', 'back' or 'blank' values.",            E3007: "Error while restoring the application state. The state has been cleared. Refresh the page.",            E3008: "Unable to go back.",            E3009: "Unable to go forward.",            E3010: "The command's 'id' option should be specified.\r\nProcessed markup: {0}\n",            E3011: "Layout controller cannot be resolved. There are no appropriate layout controllers for the current context. Check browser console for details.",            E3012: "Layout controller cannot be resolved. Two or more layout controllers suit the current context. Check browser console for details.",            E3013: "The '{0}' template with the '{1}' name is not found. Make sure the case is correct in the specified view name and the template fits the current context.",            E3014: "All the children of the dxView element should be either of the dxCommand or dxContent type.\r\nProcessed markup: {0}",            E3015: "The 'exec' method should be called before the 'finalize' method.",            E3016: "Unknown transition type '{0}'.",            E3018: "Unable to parse options.\nMessage: {0};\nOptions value: {1}.",            E3019: "View templates should be updated according to the 13.1 changes. Go to http://dxpr.es/15ikrJA for more details.",            E3020: "Concurrent templates are found:\r\n{0}Target device:\r\n{1}.",            E3021: "Remote template cannot be loaded.\r\nUrl:{0}\r\nError:{1}.",            E3022: "Cannot initialize the HtmlApplication component.",            E3023: "Navigation item is not found",            W3001: "A view with the '{0}' key doesn't exist.",            W3002: "A view with the '{0}' key has already been released.",            W3003: "Layout resolving context:\n{0}\nAvailable layout controller registrations:\n{1}\n",            W3004: "Layout resolving context:\n{0}\nConcurent layout controller registrations for the context:\n{1}\n",            W3005: "Direct hash-based navigation is detected. Use data-bind=\"dxAction: url\" instead of href=\"#url\".\nFound markup:\n{0}\n"        })    })(jQuery, DevExpress);    /*! Module framework, file framework.routing.js */    (function($, DX) {        var JSON_URI_PREFIX = encodeURIComponent("json:");        var Class = DX.Class;        DX.framework.Route = Class.inherit({            _trimSeparators: function(str) {                return str.replace(/^[\/.]+|\/+$/g, "")            },            _escapeRe: function(str) {                return str.replace(/\W/g, "\\$1")            },            _checkConstraint: function(param, constraint) {                param = String(param);                if (typeof constraint === "string")                    constraint = new RegExp(constraint);                var match = constraint.exec(param);                if (!match || match[0] !== param)                    return false;                return true            },            _ensureReady: function() {                var that = this;                if (this._patternRe)                    return false;                this._pattern = this._trimSeparators(this._pattern);                this._patternRe = "";                this._params = [];                this._segments = [];                this._separators = [];                this._pattern.replace(/[^\/]+/g, function(segment, index) {                    that._segments.push(segment);                    if (index)                        that._separators.push(that._pattern.substr(index - 1, 1))                });                $.each(this._segments, function(index) {                    var isStatic = true,                        segment = this,                        separator = index ? that._separators[index - 1] : "";                    if (segment.charAt(0) === ":") {                        isStatic = false;                        segment = segment.substr(1);                        that._params.push(segment);                        that._patternRe += "(?:" + separator + "([^/]*))";                        if (segment in that._defaults)                            that._patternRe += "?"                    }                    else                        that._patternRe += separator + that._escapeRe(segment)                });                this._patternRe = new RegExp("^" + this._patternRe + "$")            },            ctor: function(pattern, defaults, constraints) {                this._pattern = pattern || "";                this._defaults = defaults || {};                this._constraints = constraints || {}            },            parse: function(uri) {                var that = this;                this._ensureReady();                var matches = this._patternRe.exec(uri);                if (!matches)                    return false;                var result = $.extend({}, this._defaults);                $.each(this._params, function(i) {                    var index = i + 1;                    if (matches.length >= index && matches[index])                        result[this] = that.parseSegment(matches[index])                });                $.each(this._constraints, function(key) {                    if (!that._checkConstraint(result[key], that._constraints[key])) {                        result = false;                        return false                    }                });                return result            },            format: function(routeValues) {                var that = this,                    query = "";                this._ensureReady();                var mergeValues = $.extend({}, this._defaults),                    useStatic = 0,                    ret = [],                    dels = [],                    unusedRouteValues = {};                $.each(routeValues, function(paramName, paramValue) {                    routeValues[paramName] = that.formatSegment(paramValue);                    if (!(paramName in mergeValues))                        unusedRouteValues[paramName] = true                });                $.each(this._segments, function(index, segment) {                    ret[index] = index ? that._separators[index - 1] : '';                    if (segment.charAt(0) === ':') {                        var paramName = segment.substr(1);                        if (!(paramName in routeValues) && !(paramName in that._defaults)) {                            ret = null;                            return false                        }                        if (paramName in that._constraints && !that._checkConstraint(routeValues[paramName], that._constraints[paramName])) {                            ret = null;                            return false                        }                        if (paramName in routeValues) {                            if (routeValues[paramName] !== undefined) {                                mergeValues[paramName] = routeValues[paramName];                                ret[index] += routeValues[paramName];                                useStatic = index                            }                            delete unusedRouteValues[paramName]                        }                        else if (paramName in mergeValues) {                            ret[index] += mergeValues[paramName];                            dels.push(index)                        }                    }                    else {                        ret[index] += segment;                        useStatic = index                    }                });                $.each(mergeValues, function(key, value) {                    if (!!value && $.inArray(":" + key, that._segments) === -1 && routeValues[key] !== value) {                        ret = null;                        return false                    }                });                var unusedCount = 0;                if (!$.isEmptyObject(unusedRouteValues)) {                    query = "?";                    $.each(unusedRouteValues, function(key) {                        query += key + "=" + routeValues[key] + "&";                        unusedCount++                    });                    query = query.substr(0, query.length - 1)                }                if (ret === null)                    return false;                if (dels.length)                    $.map(dels, function(i) {                        if (i >= useStatic)                            ret[i] = ''                    });                var path = ret.join('');                path = path.replace(/\/+$/, "");                return {                        uri: path + query,                        unusedCount: unusedCount                    }            },            formatSegment: function(value) {                if ($.isArray(value) || $.isPlainObject(value))                    return JSON_URI_PREFIX + encodeURIComponent(JSON.stringify(value));                return encodeURIComponent(value)            },            parseSegment: function(value) {                if (value.substr(0, JSON_URI_PREFIX.length) === JSON_URI_PREFIX)                    try {                        return $.parseJSON(decodeURIComponent(value.substr(JSON_URI_PREFIX.length)))                    }                    catch(x) {}                return decodeURIComponent(value)            }        });        DX.framework.Router = DX.Class.inherit({            ctor: function() {                this._registry = []            },            _trimSeparators: function(str) {                return str.replace(/^[\/.]+|\/+$/g, "")            },            _createRoute: function(pattern, defaults, constraints) {                return new DX.framework.Route(pattern, defaults, constraints)            },            register: function(pattern, defaults, constraints) {                this._registry.push(this._createRoute(pattern, defaults, constraints))            },            _parseQuery: function(query) {                var result = {},                    values = query.split("&");                $.each(values, function(index, value) {                    var keyValuePair = value.split("=");                    result[keyValuePair[0]] = decodeURIComponent(keyValuePair[1])                });                return result            },            parse: function(uri) {                var that = this,                    ret;                uri = this._trimSeparators(uri);                var parts = uri.split("?", 2),                    path = parts[0],                    query = parts[1];                $.each(this._registry, function() {                    var result = this.parse(path);                    if (result !== false) {                        ret = result;                        if (query)                            ret = $.extend(ret, that._parseQuery(query));                        return false                    }                });                return ret ? ret : false            },            format: function(obj) {                var ret = false,                    minUnusedCount = 99999;                obj = obj || {};                $.each(this._registry, function() {                    var toFormat = $.extend(true, {}, obj);                    var result = this.format(toFormat);                    if (result !== false)                        if (minUnusedCount > result.unusedCount) {                            minUnusedCount = result.unusedCount;                            ret = result.uri                        }                });                return ret            }        });        DX.framework.Route.__internals = {JSON_URI_PREFIX: JSON_URI_PREFIX}    })(jQuery, DevExpress);    /*! Module framework, file framework.command.js */    (function($, DX) {        var Command = DX.DOMComponent.inherit({                ctor: function(element, options) {                    if ($.isPlainObject(element)) {                        options = element;                        element = $("<div />")                    }                    this.beforeExecute = $.Callbacks();                    this.afterExecute = $.Callbacks();                    this._callbacksToEvents("Command", ["beforeExecute", "afterExecute"]);                    this.callBase(element, options)                },                _setDeprecatedOptions: function() {                    this.callBase();                    $.extend(this._deprecatedOptions, {                        action: {                            since: "14.2",                            alias: "onExecute"                        },                        iconSrc: {                            since: "15.1",                            alias: "icon"                        }                    })                },                _setDefaultOptions: function() {                    this.callBase();                    this.option({                        onExecute: null,                        id: null,                        title: "",                        icon: "",                        visible: true,                        disabled: false                    })                },                execute: function() {                    var isDisabled = this._options.disabled;                    if ($.isFunction(isDisabled))                        isDisabled = !!isDisabled.apply(this, arguments);                    if (isDisabled)                        throw DX.Error("E3004", this._options.id);                    this.fireEvent("beforeExecute", arguments);                    this._createActionByOption("onExecute").apply(this, arguments);                    this.fireEvent("afterExecute", arguments)                },                _render: function() {                    this.callBase();                    this.element().addClass("dx-command")                },                _renderDisabledState: $.noop,                _dispose: function() {                    this.callBase();                    this.element().removeData(this.NAME);                    this.beforeExecute.empty();                    this.afterExecute.empty()                }            });        DX.registerComponent("dxCommand", DX.framework, Command)    })(jQuery, DevExpress);    /*! Module framework, file framework.commandMapping.js */    (function($, DX) {        DX.framework.CommandMapping = DX.Class.inherit({            ctor: function() {                this._commandMappings = {};                this._containerDefaults = {}            },            setDefaults: function(containerId, defaults) {                this._containerDefaults[containerId] = defaults;                return this            },            mapCommands: function(containerId, commandMappings) {                var that = this;                $.each(commandMappings, function(index, commandMapping) {                    if (typeof commandMapping === "string")                        commandMapping = {id: commandMapping};                    var commandId = commandMapping.id;                    var mappings = that._commandMappings[containerId] || {};                    mappings[commandId] = $.extend({                        showIcon: true,                        showText: true                    }, that._containerDefaults[containerId] || {}, commandMapping);                    that._commandMappings[containerId] = mappings                });                this._initExistingCommands();                return this            },            unmapCommands: function(containerId, commandIds) {                var that = this;                $.each(commandIds, function(index, commandId) {                    var mappings = that._commandMappings[containerId] || {};                    if (mappings)                        delete mappings[commandId]                });                this._initExistingCommands()            },            getCommandMappingForContainer: function(commandId, containerId) {                return (this._commandMappings[containerId] || {})[commandId]            },            checkCommandsExist: function(commands) {                var that = this,                    result = $.grep(commands, function(commandName, index) {                        return $.inArray(commandName, that._existingCommands) < 0 && $.inArray(commandName, commands) === index                    });                if (result.length !== 0)                    throw DX.Error("E3005", result.join("', '"), result.length === 1 ? " is" : "s are");            },            load: function(config) {                if (!config)                    return;                var that = this;                $.each(config, function(name, container) {                    that.setDefaults(name, container.defaults);                    that.mapCommands(name, container.commands)                });                return this            },            _initExistingCommands: function() {                var that = this;                this._existingCommands = [];                $.each(that._commandMappings, function(name, _commands) {                    $.each(_commands, function(index, command) {                        if ($.inArray(command.id, that._existingCommands) < 0)                            that._existingCommands.push(command.id)                    })                })            }        });        DX.framework.CommandMapping.defaultMapping = {            "global-navigation": {                defaults: {                    showIcon: true,                    showText: true                },                commands: []            },            "ios-header-toolbar": {                defaults: {                    showIcon: false,                    showText: true,                    location: "after"                },                commands: ["edit", "save", {                        id: "back",                        location: "before"                    }, {                        id: "cancel",                        location: "before"                    }, {                        id: "create",                        showIcon: true,                        showText: false                    }]            },            "ios-action-sheet": {                defaults: {                    showIcon: false,                    showText: true                },                commands: []            },            "ios-view-footer": {                defaults: {                    showIcon: false,                    showText: true                },                commands: [{                        id: "delete",                        type: "danger"                    }]            },            "android-header-toolbar": {                defaults: {                    showIcon: true,                    showText: false,                    location: "after"                },                commands: [{                        id: "back",                        showIcon: false,                        location: "before"                    }, "create", {                        id: "save",                        showText: true,                        showIcon: false,                        location: "after"                    }, {                        id: "edit",                        showText: false,                        location: "after"                    }, {                        id: "cancel",                        showText: false,                        location: "before"                    }, {                        id: "delete",                        showText: false,                        location: "after"                    }]            },            "android-simple-toolbar": {                defaults: {                    showIcon: true,                    showText: false,                    location: "after"                },                commands: [{                        id: "back",                        showIcon: false,                        location: "before"                    }, {id: "create"}, {                        id: "save",                        showText: true,                        showIcon: false,                        location: "after"                    }, {                        id: "edit",                        showText: false,                        location: "after"                    }, {                        id: "cancel",                        showText: false,                        location: "before"                    }, {                        id: "delete",                        showText: false,                        location: "after"                    }]            },            "android-footer-toolbar": {                defaults: {location: "after"},                commands: [{                        id: "create",                        showText: false,                        location: "center"                    }, {                        id: "edit",                        showText: false,                        location: "before"                    }, {                        id: "delete",                        location: "menu"                    }, {                        id: "save",                        showIcon: false,                        location: "before"                    }]            },            "generic-header-toolbar": {                defaults: {                    showIcon: false,                    showText: true,                    location: "after"                },                commands: ["edit", "save", {                        id: "back",                        location: "before"                    }, {                        id: "cancel",                        location: "before"                    }, {                        id: "create",                        showIcon: true,                        showText: false                    }]            },            "generic-view-footer": {                defaults: {                    showIcon: false,                    showText: true                },                commands: [{                        id: "delete",                        type: "danger"                    }]            },            "win8-appbar": {                defaults: {location: "after"},                commands: ["edit", "cancel", "save", "delete", {                        id: "create",                        location: "before"                    }, {                        id: "refresh",                        location: "before"                    }]            },            "win8-toolbar": {                defaults: {                    showText: false,                    location: "before"                },                commands: [{id: "previousPage"}]            },            "win8-phone-appbar": {                defaults: {location: "center"},                commands: ["create", "edit", "cancel", "save", "refresh", {                        id: "delete",                        location: "menu"                    }]            },            "win8-split-toolbar": {                defaults: {                    showIcon: true,                    showText: false,                    location: "after"                },                commands: [{                        id: "back",                        showIcon: false,                        location: "before"                    }, {id: "create"}, {                        id: "save",                        showText: true,                        location: "before"                    }, {                        id: "edit",                        showText: true,                        location: "menu"                    }, {                        id: "cancel",                        showText: true,                        location: "menu"                    }, {                        id: "delete",                        showText: true,                        location: "menu"                    }]            },            "win8-master-detail-toolbar": {                defaults: {                    showText: false,                    location: "before"                },                commands: ["back"]            },            "desktop-toolbar": {                defaults: {                    showIcon: false,                    showText: true,                    location: "after"                },                commands: ["cancel", "create", "edit", "save", {                        id: "delete",                        type: "danger"                    }]            }        }    })(jQuery, DevExpress);    /*! Module framework, file framework.viewCache.js */    (function($, DX, undefined) {        var Class = DX.Class;        DX.framework.ViewCache = Class.inherit({            ctor: function() {                this._cache = {};                this.viewRemoved = $.Callbacks();                this._callbacksToEvents("ViewCache", ["viewRemoved"])            },            setView: function(key, viewInfo) {                this._cache[key] = viewInfo            },            getView: function(key) {                return this._cache[key]            },            removeView: function(key) {                var result = this._cache[key];                if (result) {                    delete this._cache[key];                    this.fireEvent("viewRemoved", [{viewInfo: result}])                }                return result            },            clear: function() {                var that = this;                $.each(this._cache, function(key) {                    that.removeView(key)                })            },            hasView: function(key) {                return key in this._cache            }        }).include(DX.EventsMixin);        DX.framework.NullViewCache = DX.framework.ViewCache.inherit({setView: function(key, viewInfo) {                this.callBase(key, viewInfo);                this.removeView(key)            }});        DX.framework.ConditionalViewCacheDecorator = Class.inherit({            ctor: function(options) {                this._filter = options.filter;                this._viewCache = options.viewCache;                this.viewRemoved = this._viewCache.viewRemoved;                this._events = this._viewCache._events            },            setView: function(key, viewInfo) {                this._viewCache.setView(key, viewInfo);                if (!this._filter(key, viewInfo))                    this._viewCache.removeView(key)            },            getView: function(key) {                return this._viewCache.getView(key)            },            removeView: function(key) {                return this._viewCache.removeView(key)            },            clear: function() {                return this._viewCache.clear()            },            hasView: function(key) {                return this._viewCache.hasView(key)            }        }).include(DX.EventsMixin);        var DEFAULT_VIEW_CACHE_CAPACITY = 10;        DX.framework.CapacityViewCacheDecorator = Class.inherit({            ctor: function(options) {                this._keys = [];                this._size = options.size || DEFAULT_VIEW_CACHE_CAPACITY;                this._viewCache = options.viewCache;                this.viewRemoved = this._viewCache.viewRemoved;                this._events = this._viewCache._events            },            setView: function(key, viewInfo) {                if (!this.hasView(key)) {                    if (this._keys.length === this._size)                        this.removeView(this._keys[0]);                    this._keys.push(key)                }                this._viewCache.setView(key, viewInfo)            },            getView: function(key) {                var index = $.inArray(key, this._keys);                if (index < 0)                    return null;                this._keys.push(key);                this._keys.splice(index, 1);                return this._viewCache.getView(key)            },            removeView: function(key) {                var index = $.inArray(key, this._keys);                if (index > -1)                    this._keys.splice(index, 1);                return this._viewCache.removeView(key)            },            clear: function() {                this._keys = [];                return this._viewCache.clear()            },            hasView: function(key) {                return this._viewCache.hasView(key)            }        }).include(DX.EventsMixin);        DX.framework.HistoryDependentViewCacheDecorator = Class.inherit({            ctor: function(options) {                this._viewCache = options.viewCache || new DX.framework.ViewCache;                this._navigationManager = options.navigationManager;                this._navigationManager.on("itemRemoved", $.proxy(this._onNavigationItemRemoved, this));                this.viewRemoved = this._viewCache.viewRemoved;                this._events = this._viewCache._events            },            _onNavigationItemRemoved: function(item) {                this.removeView(item.key)            },            setView: function(key, viewInfo) {                this._viewCache.setView(key, viewInfo)            },            getView: function(key) {                return this._viewCache.getView(key)            },            removeView: function(key) {                return this._viewCache.removeView(key)            },            clear: function() {                return this._viewCache.clear()            },            hasView: function(key) {                return this._viewCache.hasView(key)            }        }).include(DX.EventsMixin)    })(jQuery, DevExpress);    /*! Module framework, file framework.stateManager.js */    (function($, DX, undefined) {        var Class = DX.Class;        DX.framework.MemoryKeyValueStorage = Class.inherit({            ctor: function() {                this.storage = {}            },            getItem: function(key) {                return this.storage[key]            },            setItem: function(key, value) {                this.storage[key] = value            },            removeItem: function(key) {                delete this.storage[key]            }        });        DX.framework.StateManager = Class.inherit({            ctor: function(options) {                options = options || {};                this.storage = options.storage || new DX.framework.MemoryKeyValueStorage;                this.stateSources = options.stateSources || []            },            addStateSource: function(stateSource) {                this.stateSources.push(stateSource)            },            removeStateSource: function(stateSource) {                var index = $.inArray(stateSource, this.stateSources);                if (index > -1) {                    this.stateSources.splice(index, 1);                    stateSource.removeState(this.storage)                }            },            saveState: function() {                var that = this;                $.each(this.stateSources, function(index, stateSource) {                    stateSource.saveState(that.storage)                })            },            restoreState: function() {                var that = this;                $.each(this.stateSources, function(index, stateSource) {                    stateSource.restoreState(that.storage)                })            },            clearState: function() {                var that = this;                $.each(this.stateSources, function(index, stateSource) {                    stateSource.removeState(that.storage)                })            }        })    })(jQuery, DevExpress);    /*! Module framework, file framework.browserAdapters.js */    (function($, DX, undefined) {        var Class = DX.Class;        var ROOT_PAGE_URL = "__root__",            BUGGY_ANDROID_BUFFER_PAGE_URL = "__buffer__";        DX.framework.DefaultBrowserAdapter = Class.inherit({            ctor: function(options) {                options = options || {};                this._window = options.window || window;                this.popState = $.Callbacks();                $(this._window).on("hashchange", $.proxy(this._onHashChange, this));                this._tasks = DX.createQueue();                this.canWorkInPureBrowser = true            },            replaceState: function(uri) {                var that = this;                return this._addTask(function() {                        uri = that._normalizeUri(uri);                        that._window.history.replaceState(null, null, "#" + uri);                        that._currentTask.resolve()                    })            },            pushState: function(uri) {                var that = this;                return this._addTask(function() {                        uri = that._normalizeUri(uri);                        that._window.history.pushState(null, null, "#" + uri);                        that._currentTask.resolve()                    })            },            createRootPage: function() {                return this.replaceState(ROOT_PAGE_URL)            },            _onHashChange: function() {                if (this._currentTask)                    this._currentTask.resolve();                this.popState.fire()            },            back: function() {                var that = this;                return this._addTask(function() {                        that._window.history.back()                    })            },            getHash: function() {                return this._normalizeUri(this._window.location.hash)            },            isRootPage: function() {                return this.getHash() === ROOT_PAGE_URL            },            _normalizeUri: function(uri) {                return (uri || "").replace(/^#+/, "")            },            _addTask: function(task) {                var that = this,                    d = $.Deferred();                this._tasks.add(function() {                    that._currentTask = d;                    task();                    return d                });                return d.promise()            }        });        DX.framework.OldBrowserAdapter = DX.framework.DefaultBrowserAdapter.inherit({            ctor: function() {                this._innerEventCount = 0;                this.callBase.apply(this, arguments);                this._skipNextEvent = false            },            replaceState: function(uri) {                var that = this;                uri = that._normalizeUri(uri);                if (that.getHash() !== uri) {                    that._addTask(function() {                        that._skipNextEvent = true;                        that._window.history.back()                    });                    return that._addTask(function() {                            that._skipNextEvent = true;                            that._window.location.hash = uri                        })                }                return $.Deferred().resolve().promise()            },            pushState: function(uri) {                var that = this;                uri = this._normalizeUri(uri);                if (this.getHash() !== uri)                    return that._addTask(function() {                            that._skipNextEvent = true;                            that._window.location.hash = uri                        });                return $.Deferred().resolve().promise()            },            createRootPage: function() {                return this.pushState(ROOT_PAGE_URL)            },            _onHashChange: function() {                var currentTask = this._currentTask;                this._currentTask = null;                if (this._skipNextEvent)                    this._skipNextEvent = false;                else                    this.popState.fire();                if (currentTask)                    currentTask.resolve()            }        });        DX.framework.BuggyAndroidBrowserAdapter = DX.framework.OldBrowserAdapter.inherit({createRootPage: function() {                this.pushState(BUGGY_ANDROID_BUFFER_PAGE_URL);                return this.callBase()            }});        DX.framework.HistorylessBrowserAdapter = DX.framework.DefaultBrowserAdapter.inherit({            ctor: function(options) {                options = options || {};                this._window = options.window || window;                this.popState = $.Callbacks();                $(this._window).on("dxback", $.proxy(this._onHashChange, this));                this._currentHash = this._window.location.hash            },            replaceState: function(uri) {                this._currentHash = this._normalizeUri(uri);                return $.Deferred().resolve().promise()            },            pushState: function(uri) {                return this.replaceState(uri)            },            createRootPage: function() {                return this.replaceState(ROOT_PAGE_URL)            },            getHash: function() {                return this._normalizeUri(this._currentHash)            },            back: function() {                return this.replaceState(ROOT_PAGE_URL)            },            _onHashChange: function() {                var promise = this.back();                this.popState.fire();                return promise            }        });        DX.framework.BuggyCordovaWP81BrowserAdapter = DX.framework.DefaultBrowserAdapter.inherit({ctor: function(options) {                this.callBase(options);                this.canWorkInPureBrowser = false            }})    })(jQuery, DevExpress);    /*! Module framework, file framework.navigationDevices.js */    (function($, DX, undefined) {        var Class = DX.Class;        var SESSION_KEY = "dxPhoneJSApplication";        DX.framework.HistoryBasedNavigationDevice = Class.inherit({            ctor: function(options) {                options = options || {};                this._browserAdapter = options.browserAdapter || this._createBrowserAdapter(options);                this.uriChanged = $.Callbacks();                this._browserAdapter.popState.add($.proxy(this._onPopState, this))            },            init: $.noop,            getUri: function() {                return this._browserAdapter.getHash()            },            setUri: function(uri, replaceCurrent) {                if (replaceCurrent)                    return this._browserAdapter.replaceState(uri);                else if (uri !== this.getUri())                    return this._browserAdapter.pushState(uri);                else                    return $.Deferred().resolve().promise()            },            back: function() {                return this._browserAdapter.back()            },            _onPopState: function() {                this.uriChanged.fire(this.getUri())            },            _isBuggyAndroid2: function() {                var realDevice = DX.devices.real();                var version = realDevice.version;                return realDevice.platform === "android" && version.length > 1 && (version[0] === 2 && version[1] < 4 || version[0] < 2)            },            _isBuggyAndroid4: function() {                var realDevice = DX.devices.real();                var version = realDevice.version;                return realDevice.platform === "android" && version.length > 1 && version[0] === 4 && version[1] === 0            },            _isWindowsPhone8: function() {                var realDevice = DX.devices.real();                return realDevice.platform === "win8" && realDevice.phone            },            _createBrowserAdapter: function(options) {                var sourceWindow = options.window || window,                    supportPushReplace = sourceWindow.history.replaceState && sourceWindow.history.pushState,                    result;                if (this._isWindowsPhone8())                    result = new DX.framework.BuggyCordovaWP81BrowserAdapter(options);                else if (sourceWindow !== sourceWindow.top)                    result = new DX.framework.HistorylessBrowserAdapter(options);                else if (this._isBuggyAndroid4())                    result = new DX.framework.BuggyAndroidBrowserAdapter(options);                else if (this._isBuggyAndroid2() || !supportPushReplace)                    result = new DX.framework.OldBrowserAdapter(options);                else                    result = new DX.framework.DefaultBrowserAdapter(options);                return result            }        });        DX.framework.StackBasedNavigationDevice = DX.framework.HistoryBasedNavigationDevice.inherit({            ctor: function(options) {                this.callBase(options);                this.backInitiated = $.Callbacks();                this._rootStateHandler = null;                $(window).on("unload", this._saveBrowserState)            },            init: function() {                var that = this;                if (that._browserAdapter.canWorkInPureBrowser)                    return that._initRootPage().done(function() {                            if (that._browserAdapter.isRootPage())                                that._browserAdapter.pushState("")                        });                else                    return $.Deferred().resolve().promise()            },            setUri: function(uri) {                return this.callBase(uri, !this._browserAdapter.isRootPage())            },            _saveBrowserState: function() {                if (window.sessionStorage)                    sessionStorage.setItem(SESSION_KEY, true)            },            _initRootPage: function() {                var hash = this.getUri();                if (!window.sessionStorage || sessionStorage.getItem(SESSION_KEY))                    return $.Deferred().resolve().promise();                sessionStorage.removeItem(SESSION_KEY);                this._browserAdapter.createRootPage();                return this._browserAdapter.pushState(hash)            },            _onPopState: function() {                if (this._browserAdapter.isRootPage())                    if (this._rootStateHandler)                        this._rootStateHandler();                    else                        this.backInitiated.fire();                else {                    if (!this._rootStateHandler)                        this._createRootStateHndler();                    this.back()                }            },            _createRootStateHndler: function() {                var uri = this.getUri();                this._rootStateHandler = function() {                    this.uriChanged.fire(uri);                    this._rootStateHandler = null                }            }        })    })(jQuery, DevExpress);    /*! Module framework, file framework.navigationManager.js */    (function($, DX, undefined) {        var Class = DX.Class;        var NAVIGATION_TARGETS = {                current: "current",                blank: "blank",                back: "back"            },            STORAGE_HISTORY_KEY = "__history";        DX.framework.HistoryBasedNavigationManager = Class.inherit({            ctor: function(options) {                options = options || {};                this._currentItem = undefined;                this._previousItem = undefined;                this.navigating = $.Callbacks();                this.navigated = $.Callbacks();                this.navigationCanceled = $.Callbacks();                this.navigatingBack = $.Callbacks();                this.itemRemoved = $.Callbacks();                this._callbacksToEvents("DefaultLayoutController", ["navigating", "navigated", "navigationCanceled", "navigatingBack", "itemRemoved"]);                this._createNavigationDevice(options)            },            _createNavigationDevice: function(options) {                this._navigationDevice = options.navigationDevice || new DX.framework.HistoryBasedNavigationDevice;                this._navigationDevice.uriChanged.add($.proxy(this._uriChangedHandler, this))            },            _uriChangedHandler: function(uri) {                while (DX.hideTopOverlayCallback.fire());                this._forceNavigate = true;                this.navigate(uri)            },            _syncUriWithCurrentNavigationItem: function() {                var currentUri = this._currentItem && this._currentItem.uri;                this._navigationDevice.setUri(currentUri, true)            },            _cancelNavigation: function(args) {                this._syncUriWithCurrentNavigationItem();                this.fireEvent("navigationCanceled", [args])            },            _getDefaultOptions: function() {                return {                        direction: "none",                        target: NAVIGATION_TARGETS.blank                    }            },            _updateHistory: function(uri, options) {                this._previousItem = this._currentItem;                this._currentItem = {                    uri: uri,                    key: uri                };                this._navigationDevice.setUri(uri, options.target === NAVIGATION_TARGETS.current)            },            _setCurrentItem: function(item) {                this._currentItem = item            },            navigate: function(uri, options) {                options = options || {};                var that = this,                    isFirstNavigate = !that._currentItem,                    currentItem = that._currentItem || {},                    targetItem = options.item || {},                    currentUri = currentItem.uri,                    currentKey = currentItem.key,                    targetKey = targetItem.key,                    args;                if (uri === undefined)                    uri = that._navigationDevice.getUri();                if (/^_back$/.test(uri)) {                    that.back();                    return                }                options = $.extend(that._getDefaultOptions(), options || {});                if (isFirstNavigate)                    options.target = NAVIGATION_TARGETS.current;                args = {                    currentUri: currentUri,                    uri: uri,                    cancel: false,                    navigateWhen: [],                    options: options                };                that.fireEvent("navigating", [args]);                uri = args.uri;                if (args.cancel || currentUri === uri && (targetKey === undefined || targetKey === currentKey) && !that._forceNavigate)                    that._cancelNavigation(args);                else {                    that._forceNavigate = false;                    $.when.apply($, args.navigateWhen).done(function() {                        DX.utils.executeAsync(function() {                            that._updateHistory(uri, options);                            that.fireEvent("navigated", [{                                    uri: uri,                                    previousUri: currentUri,                                    options: options,                                    item: that._currentItem                                }])                        })                    })                }            },            back: function() {                return this._navigationDevice.back()            },            previousItem: function() {                return this._previousItem            },            currentItem: function(item) {                if (arguments.length > 0) {                    if (!item)                        throw DX.Error("E3023");                    this._setCurrentItem(item)                }                else                    return this._currentItem            },            rootUri: function() {                return this._currentItem && this._currentItem.uri            },            canBack: function() {                return true            },            saveState: $.noop,            restoreState: $.noop,            removeState: $.noop        }).include(DX.EventsMixin);        DX.framework.StackBasedNavigationManager = DX.framework.HistoryBasedNavigationManager.inherit({            ctor: function(options) {                options = options || {};                this.callBase(options);                this._createNavigationStacks(options);                DX.hardwareBackButton.add($.proxy(this._deviceBackInitiated, this));                this._stateStorageKey = options.stateStorageKey || STORAGE_HISTORY_KEY            },            init: function() {                return this._navigationDevice.init()            },            _createNavigationDevice: function(options) {                if (!options.navigationDevice)                    options.navigationDevice = new DX.framework.StackBasedNavigationDevice;                this.callBase(options);                this._navigationDevice.backInitiated.add($.proxy(this._deviceBackInitiated, this))            },            _uriChangedHandler: function(uri) {                this.navigate(uri)            },            _createNavigationStacks: function(options) {                this.navigationStacks = {};                this._keepPositionInStack = options.keepPositionInStack;                this.currentStack = new DX.framework.NavigationStack            },            _deviceBackInitiated: function() {                if (!DX.hideTopOverlayCallback.fire())                    this.back({isHardwareButton: true});                else                    this._syncUriWithCurrentNavigationItem()            },            _getDefaultOptions: function() {                return {target: NAVIGATION_TARGETS.blank}            },            _createNavigationStack: function() {                var result = new DX.framework.NavigationStack;                result.itemsRemoved.add($.proxy(this._removeItems, this));                return result            },            _setCurrentItem: function(item) {                this._setCurrentStack(item.stack);                this.currentStack.currentItem(item);                this.callBase(item);                this._syncUriWithCurrentNavigationItem()            },            _setCurrentStack: function(stackOrStackKey) {                var stack,                    stackKey;                if (typeof stackOrStackKey === "string") {                    stackKey = stackOrStackKey;                    if (!(stackKey in this.navigationStacks))                        this.navigationStacks[stackKey] = this._createNavigationStack();                    stack = this.navigationStacks[stackKey]                }                else {                    stack = stackOrStackKey;                    stackKey = $.map(this.navigationStacks, function(stack, key) {                        if (stack === stackOrStackKey)                            return key;                        return null                    })[0]                }                this.currentStack = stack;                this.currentStackKey = stackKey            },            _getViewTargetStackKey: function(uri, isRoot) {                var result;                if (isRoot)                    if (this.navigationStacks[uri] !== undefined)                        result = uri;                    else {                        for (var stackKey in this.navigationStacks)                            if (this.navigationStacks[stackKey].items[0].uri === uri) {                                result = stackKey;                                break                            }                        result = result || uri                    }                else                    result = this.currentStackKey || uri;                return result            },            _updateHistory: function(uri, options) {                var isRoot = options.root,                    forceIsRoot = isRoot,                    forceToRoot = false,                    stackKey = options.stack || this._getViewTargetStackKey(uri, isRoot),                    previousStack = this.currentStack,                    keepPositionInStack = options.keepPositionInStack !== undefined ? options.keepPositionInStack : this._keepPositionInStack;                this._setCurrentStack(stackKey);                if (isRoot || !this.currentStack.items.length) {                    forceToRoot = this.currentStack === previousStack;                    forceIsRoot = true                }                if (isRoot && this.currentStack.items.length) {                    if (!keepPositionInStack || forceToRoot) {                        this.currentStack.currentIndex = 0;                        if (this.currentItem().uri !== uri)                            this.currentStack.navigate(uri, true)                    }                    options.direction = options.direction || "none"                }                else {                    var prevIndex = this.currentStack.currentIndex,                        prevItem = this.currentItem() || {};                    switch (options.target) {                        case NAVIGATION_TARGETS.blank:                            this.currentStack.navigate(uri);                            break;                        case NAVIGATION_TARGETS.current:                            this.currentStack.navigate(uri, true);                            break;                        case NAVIGATION_TARGETS.back:                            if (this.currentStack.currentIndex > 0)                                this.currentStack.back(uri);                            else                                this.currentStack.navigate(uri, true);                            break;                        default:                            throw DX.Error("E3006", options.target);                    }                    if (options.direction === undefined) {                        var indexDelta = this.currentStack.currentIndex - prevIndex;                        if (indexDelta < 0)                            options.direction = this.currentStack.currentItem().backDirection || "backward";                        else if (indexDelta > 0 && this.currentStack.currentIndex > 0)                            options.direction = "forward";                        else                            options.direction = "none"                    }                    prevItem.backDirection = options.direction === "forward" ? "backward" : "none"                }                options.root = forceIsRoot;                this._currentItem = this.currentStack.currentItem();                this._syncUriWithCurrentNavigationItem()            },            _removeItems: function(items) {                var that = this;                $.each(items, function(index, item) {                    that.fireEvent("itemRemoved", [item])                })            },            back: function(options) {                options = options || {};                var navigatingBackArgs = $.extend({cancel: false}, options);                this.fireEvent("navigatingBack", [navigatingBackArgs]);                if (navigatingBackArgs.cancel) {                    this._syncUriWithCurrentNavigationItem();                    return                }                var item = this.previousItem(navigatingBackArgs.stack);                if (item)                    this.navigate(item.uri, {                        stack: navigatingBackArgs.stack,                        target: NAVIGATION_TARGETS.back,                        item: item                    });                else                    this.callBase()            },            rootUri: function() {                return this.currentStack.items.length ? this.currentStack.items[0].uri : this.callBase()            },            canBack: function(stackKey) {                var stack = stackKey ? this.navigationStacks[stackKey] : this.currentStack;                return stack.canBack()            },            saveState: function(storage) {                if (this.currentStack.items.length) {                    var state = {                            navigationStacks: {},                            currentStackKey: this.currentStackKey                        };                    $.each(this.navigationStacks, function(stackKey, stack) {                        var stackState = {};                        state.navigationStacks[stackKey] = stackState;                        stackState.currentIndex = stack.currentIndex;                        stackState.items = $.map(stack.items, function(item) {                            return {                                    key: item.key,                                    uri: item.uri                                }                        })                    });                    var json = JSON.stringify(state);                    storage.setItem(this._stateStorageKey, json)                }                else                    this.removeState(storage)            },            restoreState: function(storage) {                if (this.disableRestoreState)                    return;                var json = storage.getItem(this._stateStorageKey);                if (json)                    try {                        var that = this,                            state = JSON.parse(json);                        $.each(state.navigationStacks, function(stackKey, stackState) {                            var stack = that._createNavigationStack();                            that.navigationStacks[stackKey] = stack;                            stack.currentIndex = stackState.currentIndex;                            stack.items = $.map(stackState.items, function(item) {                                item.stack = stack;                                return item                            })                        });                        this.currentStackKey = state.currentStackKey;                        this.currentStack = this.navigationStacks[this.currentStackKey];                        this._currentItem = this.currentStack.currentItem();                        this._navigationDevice.setUri(this.currentItem().uri);                        this._forceNavigate = true                    }                    catch(e) {                        this.removeState(storage);                        throw DX.Error("E3007");                    }            },            removeState: function(storage) {                storage.removeItem(this._stateStorageKey)            },            currentIndex: function() {                return this.currentStack.currentIndex            },            previousItem: function(stackKey) {                var stack = this.navigationStacks[stackKey] || this.currentStack;                return stack.previousItem()            },            getItemByIndex: function(index) {                return this.currentStack.items[index]            },            clearHistory: function() {                this.currentStack.clear()            },            itemByKey: function(itemKey) {                var result;                $.each(this.navigationStacks, function(stackKey, stack) {                    var item = stack.itemByKey(itemKey);                    if (item) {                        result = item;                        return false                    }                });                return result            },            currentItem: function(itemOrItemKey) {                var item;                if (arguments.length > 0) {                    if (typeof itemOrItemKey === "string")                        item = this.itemByKey(itemOrItemKey);                    else if ($.isPlainObject(itemOrItemKey))                        item = itemOrItemKey;                    this.callBase(item)                }                else                    return this.callBase()            }        });        DX.framework.NavigationStack = Class.inherit({            ctor: function(options) {                options = options || {};                this.itemsRemoved = $.Callbacks();                this.clear()            },            currentItem: function(item) {                if (item) {                    for (var i = 0; i < this.items.length; i++)                        if (item === this.items[i]) {                            this.currentIndex = i;                            break                        }                }                else                    return this.items[this.currentIndex]            },            previousItem: function() {                return this.items.length > 1 ? this.items[this.currentIndex - 1] : undefined            },            canBack: function() {                return this.currentIndex > 0            },            clear: function() {                this._deleteItems(this.items);                this.items = [];                this.currentIndex = -1            },            back: function(uri) {                this.currentIndex--;                if (this.currentIndex < 0)                    throw DX.Error("E3008");                var currentItem = this.currentItem();                if (currentItem.uri !== uri)                    this._updateItem(this.currentIndex, uri)            },            forward: function() {                this.currentIndex++;                if (this.currentIndex >= this.items.length)                    throw DX.Error("E3009");            },            navigate: function(uri, replaceCurrent) {                if (this.currentIndex < this.items.length && this.currentIndex > -1 && this.items[this.currentIndex].uri === uri)                    return;                if (replaceCurrent && this.currentIndex > -1)                    this.currentIndex--;                if (this.currentIndex + 1 < this.items.length && this.items[this.currentIndex + 1].uri === uri)                    this.currentIndex++;                else {                    var toDelete = this.items.splice(this.currentIndex + 1, this.items.length - this.currentIndex - 1);                    this.items.push({stack: this});                    this.currentIndex++;                    this._updateItem(this.currentIndex, uri);                    this._deleteItems(toDelete)                }                return this.currentItem()            },            itemByKey: function(key) {                for (var i = 0; i < this.items.length; i++) {                    var item = this.items[i];                    if (item.key === key)                        return item                }            },            _updateItem: function(index, uri) {                var item = this.items[index];                item.uri = uri;                item.key = this.items[0].uri + "_" + index + "_" + uri            },            _deleteItems: function(items) {                if (items)                    this.itemsRemoved.fire(items)            }        });        DX.framework.HistoryBasedNavigationManager.NAVIGATION_TARGETS = NAVIGATION_TARGETS    })(jQuery, DevExpress);    /*! Module framework, file framework.actionExecutors.js */    (function($, DX, undefined) {        function prepareNavigateOptions(options, actionArguments) {            if (actionArguments.args) {                var sourceEventArguments = actionArguments.args[0];                options.jQueryEvent = sourceEventArguments.jQueryEvent            }            if ((actionArguments.component || {}).NAME === "dxCommand")                $.extend(options, actionArguments.component.option())        }        DX.framework.createActionExecutors = function(app) {            return {                    routing: {execute: function(e) {                            var action = e.action,                                options = {},                                routeValues,                                uri;                            if ($.isPlainObject(action)) {                                routeValues = action.routeValues;                                if (routeValues && $.isPlainObject(routeValues))                                    options = action.options;                                else                                    routeValues = action;                                uri = app.router.format(routeValues);                                prepareNavigateOptions(options, e);                                app.navigate(uri, options);                                e.handled = true                            }                        }},                    hash: {execute: function(e) {                            if (typeof e.action !== "string" || e.action.charAt(0) !== "#")                                return;                            var uriTemplate = e.action.substr(1),                                args = e.args[0],                                uri = uriTemplate;                            var defaultEvaluate = function(expr) {                                    var getter = DX.data.utils.compileGetter(expr),                                        model = e.args[0].model;                                    return getter(model)                                };                            var evaluate = args.evaluate || defaultEvaluate;                            uri = uriTemplate.replace(/\{([^}]+)\}/g, function(entry, expr) {                                expr = $.trim(expr);                                if (expr.indexOf(",") > -1)                                    expr = $.map(expr.split(","), $.trim);                                var value = evaluate(expr);                                if (value === undefined)                                    value = "";                                value = DX.framework.Route.prototype.formatSegment(value);                                return value                            });                            var options = {};                            prepareNavigateOptions(options, e);                            app.navigate(uri, options);                            e.handled = true                        }}                }        }    })(jQuery, DevExpress);    /*! Module framework, file framework.application.js */    (function($, DX) {        var Class = DX.Class,            BACK_COMMAND_TITLE,            INIT_IN_PROGRESS = "InProgress",            INIT_COMPLETE = "Inited",            frameworkNS = DX.framework;        DX.framework.Application = Class.inherit({            ctor: function(options) {                options = options || {};                this._options = options;                this.namespace = options.namespace || window;                this._applicationMode = options.mode ? options.mode : "mobileApp";                this.components = [];                BACK_COMMAND_TITLE = DX.localization.localizeString("@Back");                this.router = options.router || new DX.framework.Router;                var navigationManagers = {                        mobileApp: DX.framework.StackBasedNavigationManager,                        webSite: DX.framework.HistoryBasedNavigationManager                    };                this.navigationManager = options.navigationManager || new navigationManagers[this._applicationMode]({keepPositionInStack: options.navigateToRootViewMode === "keepHistory"});                this.navigationManager.on("navigating", $.proxy(this._onNavigating, this));                this.navigationManager.on("navigatingBack", $.proxy(this._onNavigatingBack, this));                this.navigationManager.on("navigated", $.proxy(this._onNavigated, this));                this.navigationManager.on("navigationCanceled", $.proxy(this._onNavigationCanceled, this));                this.stateManager = options.stateManager || new DX.framework.StateManager({storage: options.stateStorage || sessionStorage});                this.stateManager.addStateSource(this.navigationManager);                this.viewCache = this._createViewCache(options);                this.commandMapping = this._createCommandMapping(options.commandMapping);                this.createNavigation(options.navigation);                this.beforeViewSetup = $.Callbacks();                this.afterViewSetup = $.Callbacks();                this.viewShowing = $.Callbacks();                this.viewShown = $.Callbacks();                this.viewHidden = $.Callbacks();                this.viewDisposing = $.Callbacks();                this.viewDisposed = $.Callbacks();                this.navigating = $.Callbacks();                this.navigatingBack = $.Callbacks();                this.initialized = $.Callbacks();                this._callbacksToEvents("HtmlApplication", ["beforeViewSetup", "afterViewSetup", "viewShowing", "viewShown", "viewHidden", "viewDisposing", "viewDisposed", "navigating", "navigatingBack", "initialized"]);                this._isNavigating = false;                this._viewLinksHash = {};                DX.registerActionExecutor(DX.framework.createActionExecutors(this));                this.components.push(this.router);                this.components.push(this.navigationManager)            },            _createViewCache: function(options) {                var result;                if (options.viewCache)                    result = options.viewCache;                else if (options.disableViewCache)                    result = new DX.framework.NullViewCache;                else                    result = new DX.framework.CapacityViewCacheDecorator({                        size: options.viewCacheSize,                        viewCache: new DX.framework.ViewCache                    });                result.on("viewRemoved", $.proxy(function(e) {                    this._releaseViewLink(e.viewInfo)                }, this));                return result            },            _createCommandMapping: function(commandMapping) {                var result = commandMapping;                if (!(commandMapping instanceof DX.framework.CommandMapping)) {                    result = new DX.framework.CommandMapping;                    result.load(DX.framework.CommandMapping.defaultMapping || {}).load(commandMapping || {})                }                return result            },            createNavigation: function(navigationConfig) {                this.navigation = this._createNavigationCommands(navigationConfig);                this._mapNavigationCommands(this.navigation, this.commandMapping)            },            _createNavigationCommands: function(commandConfig) {                if (!commandConfig)                    return [];                var generatedIdCount = 0;                return $.map(commandConfig, function(item) {                        var command;                        if (item instanceof frameworkNS.dxCommand)                            command = item;                        else                            command = new frameworkNS.dxCommand($.extend({root: true}, item));                        if (!command.option("id"))                            command.option("id", "navigation_" + generatedIdCount++);                        return command                    })            },            _mapNavigationCommands: function(navigationCommands, commandMapping) {                var navigationCommandIds = $.map(navigationCommands, function(command) {                        return command.option("id")                    });                commandMapping.mapCommands("global-navigation", navigationCommandIds)            },            _callComponentMethod: function(methodName, args) {                var tasks = [];                $.each(this.components, function(index, component) {                    if (component[methodName] && $.isFunction(component[methodName])) {                        var result = component[methodName](args);                        if (result && result.done)                            tasks.push(result)                    }                });                return $.when.apply($, tasks)            },            init: function() {                var that = this;                that._initState = INIT_IN_PROGRESS;                return that._callComponentMethod("init").done(function() {                        that._initState = INIT_COMPLETE;                        that._processEvent("initialized")                    }).fail(function(error) {                        throw error || DX.Error("E3022");                    })            },            _onNavigatingBack: function(args) {                this._processEvent("navigatingBack", args)            },            _onNavigating: function(args) {                var that = this;                if (that._isNavigating) {                    that._pendingNavigationArgs = args;                    args.cancel = true;                    return                }                else {                    that._isNavigating = true;                    delete that._pendingNavigationArgs                }                var routeData = this.router.parse(args.uri);                if (!routeData)                    throw DX.Error("E3001", args.uri);                var uri = this.router.format(routeData);                if (args.uri !== uri && uri) {                    args.cancel = true;                    DX.utils.executeAsync(function() {                        that.navigate(uri, args.options)                    })                }                else                    that._processEvent("navigating", args)            },            _onNavigated: function(args) {                var that = this,                    direction = args.options.direction,                    resultDeferred,                    viewInfo = that._acquireViewInfo(args.item, args.options);                if (!viewInfo.model) {                    this._processEvent("beforeViewSetup", {viewInfo: viewInfo});                    that._createViewModel(viewInfo);                    that._createViewCommands(viewInfo);                    this._processEvent("afterViewSetup", {viewInfo: viewInfo})                }                that._highlightCurrentNavigationCommand(viewInfo);                resultDeferred = that._showView(viewInfo, direction).always(function() {                    that._isNavigating = false;                    var pendingArgs = that._pendingNavigationArgs;                    if (pendingArgs)                        DX.utils.executeAsync(function() {                            that.navigate(pendingArgs.uri, pendingArgs.options)                        })                });                return resultDeferred            },            _isViewReadyToShow: function(viewInfo) {                return !!viewInfo.model            },            _onNavigationCanceled: function(args) {                var that = this;                if (!that._pendingNavigationArgs || that._pendingNavigationArgs.uri !== args.uri) {                    var currentItem = that.navigationManager.currentItem();                    if (currentItem)                        DX.utils.executeAsync(function() {                            var viewInfo = that._acquireViewInfo(currentItem, args.options);                            that._highlightCurrentNavigationCommand(viewInfo, true)                        });                    that._isNavigating = false                }            },            _disposeRemovedViews: function() {                var that = this,                    args;                $.each(that._viewLinksHash, function(key, link) {                    if (!link.linkCount) {                        args = {viewInfo: link.viewInfo};                        that._processEvent("viewDisposing", args, args.viewInfo.model);                        that._disposeView(link.viewInfo);                        that._processEvent("viewDisposed", args, args.viewInfo.model);                        delete that._viewLinksHash[key]                    }                })            },            _onViewHidden: function(viewInfo) {                var args = {viewInfo: viewInfo};                this._processEvent("viewHidden", args, args.viewInfo.model)            },            _disposeView: function(viewInfo) {                var commands = viewInfo.commands || [];                $.each(commands, function(index, command) {                    command._dispose()                })            },            _acquireViewInfo: function(navigationItem, navigateOptions) {                var viewInfo = this.viewCache.getView(navigationItem.key);                if (!viewInfo) {                    viewInfo = this._createViewInfo(navigationItem, navigateOptions);                    this._obtainViewLink(viewInfo);                    this.viewCache.setView(navigationItem.key, viewInfo)                }                return viewInfo            },            _processEvent: function(eventName, args, model) {                this._callComponentMethod(eventName, args);                this.fireEvent(eventName, [args]);                var modelMethod = (model || {})[eventName];                if (modelMethod)                    modelMethod.call(model, args)            },            _createViewInfo: function(navigationItem, navigateOptions) {                var uri = navigationItem.uri,                    routeData = this.router.parse(uri);                var viewInfo = {                        viewName: routeData.view,                        routeData: routeData,                        uri: uri,                        key: navigationItem.key,                        canBack: this.canBack(),                        navigateOptions: navigateOptions,                        previousViewInfo: this._getPreviousViewInfo(navigateOptions)                    };                return viewInfo            },            _createViewModel: function(viewInfo) {                viewInfo.model = viewInfo.model || this._callViewCodeBehind(viewInfo)            },            _createViewCommands: function(viewInfo) {                viewInfo.commands = viewInfo.model.commands || [];                if (viewInfo.canBack && this._applicationMode !== "webSite")                    this._appendBackCommand(viewInfo)            },            _callViewCodeBehind: function(viewInfo) {                var setupFunc = $.noop,                    routeData = viewInfo.routeData;                if (routeData.view in this.namespace)                    setupFunc = this.namespace[routeData.view];                return setupFunc.call(this.namespace, routeData, viewInfo) || {}            },            _appendBackCommand: function(viewInfo) {                var commands = viewInfo.commands,                    that = this,                    stackKey = this.navigationManager.currentStackKey,                    backTitle = BACK_COMMAND_TITLE;                if (that._options.useViewTitleAsBackText)                    backTitle = ((viewInfo.previousViewInfo || {}).model || {}).title || backTitle;                var toMergeTo = [new DX.framework.dxCommand({                            id: "back",                            title: backTitle,                            behavior: "back",                            onExecute: function() {                                that.back({stack: stackKey})                            },                            icon: "arrowleft",                            type: "back",                            renderStage: that._options.useViewTitleAsBackText ? "onViewRendering" : "onViewShown"                        })];                var result = DX.framework.utils.mergeCommands(toMergeTo, commands);                commands.length = 0;                commands.push.apply(commands, result)            },            _showView: function(viewInfo, direction) {                var that = this;                var eventArgs = {                        viewInfo: viewInfo,                        direction: direction                    };                return that._showViewImpl(eventArgs.viewInfo, eventArgs.direction).done(function() {                        DX.utils.executeAsync(function() {                            that._processEvent("viewShown", eventArgs, viewInfo.model);                            that._disposeRemovedViews()                        })                    })            },            _highlightCurrentNavigationCommand: function(viewInfo, forceUpdate) {                var that = this,                    selectedCommand,                    currentNavigationItemId = viewInfo.model && viewInfo.model.currentNavigationItemId;                if (currentNavigationItemId !== undefined)                    $.each(this.navigation, function(index, command) {                        if (command.option("id") === currentNavigationItemId) {                            selectedCommand = command;                            return false                        }                    });                if (!selectedCommand)                    $.each(this.navigation, function(index, command) {                        var commandUri = command.option("onExecute");                        if (DX.utils.isString(commandUri)) {                            commandUri = commandUri.replace(/^#+/, "");                            if (commandUri === that.navigationManager.rootUri()) {                                selectedCommand = command;                                return false                            }                        }                    });                $.each(this.navigation, function(index, command) {                    if (forceUpdate && command === selectedCommand && command.option("highlighted"))                        command.fireEvent("optionChanged", [{                                name: "highlighted",                                value: true,                                previousValue: true                            }]);                    command.option("highlighted", command === selectedCommand)                })            },            _showViewImpl: DX.abstract,            _obtainViewLink: function(viewInfo) {                var key = viewInfo.key;                if (!this._viewLinksHash[key])                    this._viewLinksHash[key] = {                        viewInfo: viewInfo,                        linkCount: 1                    };                else                    this._viewLinksHash[key].linkCount++            },            _releaseViewLink: function(viewInfo) {                if (this._viewLinksHash[viewInfo.key] === undefined)                    DX.log("W3001", viewInfo.key);                if (this._viewLinksHash[viewInfo.key].linkCount === 0)                    DX.log("W3002", viewInfo.key);                this._viewLinksHash[viewInfo.key].linkCount--            },            navigate: function(uri, options) {                var that = this;                if ($.isPlainObject(uri)) {                    uri = that.router.format(uri);                    if (uri === false)                        throw DX.Error("E3002");                }                if (!that._initState)                    that.init().done(function() {                        that.restoreState();                        that.navigate(uri, options)                    });                else if (that._initState === INIT_COMPLETE) {                    if (!that._isNavigating || uri)                        that.navigationManager.navigate(uri, options)                }                else                    throw DX.Error("E3003");            },            canBack: function(stackKey) {                return this.navigationManager.canBack(stackKey)            },            _getPreviousViewInfo: function(navigateOptions) {                var previousNavigationItem = this.navigationManager.previousItem(navigateOptions.stack),                    result;                if (previousNavigationItem)                    result = this.viewCache.getView(previousNavigationItem.key);                return result            },            back: function(options) {                this.navigationManager.back(options)            },            saveState: function() {                this.stateManager.saveState()            },            restoreState: function() {                this.stateManager.restoreState()            },            clearState: function() {                this.stateManager.clearState()            }        }).include(DX.EventsMixin)    })(jQuery, DevExpress);    /*! Module framework, file framework.html.js */    (function($, DX, undefined) {        DX.framework.html = {            layoutSets: {},            animationSets: {                "native": {                    "view-content-change": [{animation: "slide"}, {                            animation: "ios7-slide",                            device: {platform: "ios"}                        }, {                            animation: "none",                            device: {                                deviceType: "desktop",                                platform: "generic"                            }                        }, {                            animation: "none",                            device: {grade: "C"}                        }],                    "view-header-toolbar": [{animation: "ios7-toolbar"}, {                            animation: "slide",                            device: {grade: "B"}                        }, {                            animation: "none",                            device: {grade: "C"}                        }]                },                "default": {                    "view-content-change": [{animation: "slide"}, {                            animation: "ios7-slide",                            device: {platform: "ios"}                        }, {                            animation: "fade",                            device: {                                deviceType: "desktop",                                platform: "generic"                            }                        }, {                            animation: "none",                            device: {grade: "C"}                        }],                    "view-content-rendered": [{animation: "fade"}, {                            animation: "none",                            device: {grade: "C"}                        }],                    "view-header-toolbar": [{animation: "ios7-toolbar"}, {                            animation: "slide",                            device: {grade: "B"}                        }, {                            animation: "none",                            device: {grade: "C"}                        }],                    "command-rendered": [{animation: "stagger-fade-drop"}, {                            animation: "fade",                            device: {grade: "B"}                        }, {                            animation: "fade",                            device: {deviceType: "desktop"}                        }, {                            animation: "none",                            device: {grade: "C"}                        }],                    "list-item-rendered": [{                            animation: "stagger-3d-drop",                            device: {grade: "A"}                        }, {                            animation: "fade",                            device: {deviceType: "desktop"}                        }, {                            animation: "none",                            device: {grade: "C"}                        }],                    "detail-item-rendered": [{                            animation: "stagger-3d-drop",                            device: {grade: "A"}                        }, {                            animation: "fade",                            device: {deviceType: "desktop"}                        }, {                            animation: "none",                            device: {grade: "C"}                        }],                    "edit-item-rendered": [{                            animation: "stagger-3d-drop",                            device: {grade: "A"}                        }, {                            animation: "fade",                            device: {deviceType: "desktop"}                        }, {                            animation: "none",                            device: {grade: "C"}                        }]                },                slide: {                    "view-content-change": [{animation: "slide"}, {                            animation: "ios7-slide",                            device: {platform: "ios"}                        }, {                            animation: "fade",                            device: {                                deviceType: "desktop",                                platform: "generic"                            }                        }, {                            animation: "none",                            device: {grade: "C"}                        }],                    "view-content-rendered": [{animation: "fade"}, {                            animation: "none",                            device: {grade: "C"}                        }],                    "view-header-toolbar": [{animation: "ios7-toolbar"}, {                            animation: "slide",                            device: {grade: "B"}                        }, {                            animation: "none",                            device: {grade: "C"}                        }],                    "command-rendered": [{animation: "stagger-fade-drop"}, {                            animation: "fade",                            device: {grade: "B"}                        }, {                            animation: "fade",                            device: {deviceType: "desktop"}                        }, {                            animation: "none",                            device: {grade: "C"}                        }],                    "list-item-rendered": [{                            animation: "stagger-fade-slide",                            device: {grade: "A"}                        }, {                            animation: "fade",                            device: {deviceType: "desktop"}                        }, {                            animation: "none",                            device: {grade: "C"}                        }],                    "detail-item-rendered": [{                            animation: "stagger-fade-slide",                            device: {grade: "A"}                        }, {                            animation: "fade",                            device: {deviceType: "desktop"}                        }, {                            animation: "none",                            device: {grade: "C"}                        }],                    "edit-item-rendered": [{                            animation: "stagger-fade-slide",                            device: {grade: "A"}                        }, {                            animation: "fade",                            device: {deviceType: "desktop"}                        }, {                            animation: "none",                            device: {grade: "C"}                        }]                },                zoom: {                    "view-content-change": [{animation: "slide"}, {                            animation: "ios7-slide",                            device: {platform: "ios"}                        }, {                            animation: "fade",                            device: {                                deviceType: "desktop",                                platform: "generic"                            }                        }, {                            animation: "none",                            device: {grade: "C"}                        }],                    "view-content-rendered": [{animation: "fade"}, {                            animation: "none",                            device: {grade: "C"}                        }],                    "view-header-toolbar": [{animation: "ios7-toolbar"}, {                            animation: "slide",                            device: {grade: "B"}                        }, {                            animation: "fade",                            device: {deviceType: "desktop"}                        }, {                            animation: "none",                            device: {grade: "C"}                        }],                    "command-rendered": [{animation: "stagger-fade-zoom"}, {                            animation: "fade",                            device: {grade: "B"}                        }, {                            animation: "fade",                            device: {deviceType: "desktop"}                        }, {                            animation: "none",                            device: {grade: "C"}                        }],                    "list-item-rendered": [{                            animation: "stagger-fade-zoom",                            device: {grade: "A"}                        }, {                            animation: "fade",                            device: {deviceType: "desktop"}                        }, {                            animation: "none",                            device: {grade: "C"}                        }],                    "detail-item-rendered": [{                            animation: "stagger-fade-zoom",                            device: {grade: "A"}                        }, {                            animation: "fade",                            device: {deviceType: "desktop"}                        }, {                            animation: "none",                            device: {grade: "C"}                        }],                    "edit-item-rendered": [{                            animation: "stagger-fade-zoom",                            device: {grade: "A"}                        }, {                            animation: "fade",                            device: {deviceType: "desktop"}                        }, {                            animation: "none",                            device: {grade: "C"}                        }]                }            }        }    })(jQuery, DevExpress);    /*! Module framework, file framework.widgetCommandAdapters.js */    (function($, DX) {        var commandToContainer = DX.framework.utils.commandToContainer,            DX_COMMAND_TO_WIDGET_ADAPTER = "dxCommandToWidgetAdapter";        var WidgetItemWrapperBase = DX.Class.inherit({                ctor: function(command, containerOptions) {                    this.command = command;                    this.containerOptions = containerOptions;                    this._createWidgetItem(command, containerOptions);                    this._commandChangedHandler = $.proxy(this._onCommandChanged, this);                    command.on("optionChanged", this._commandChangedHandler)                },                _createWidgetItem: function(command, containerOptions) {                    this.widgetItem = $.extend({                        command: command,                        containerOptions: containerOptions                    }, containerOptions, command.option());                    this._updateItem()                },                _onCommandChanged: function(args) {                    var optionName = args.name,                        newValue = args.value,                        oldValue = args.previousValue;                    this.widgetItem[optionName] = newValue;                    this._updateItem(optionName, newValue, oldValue)                },                _updateItem: function(optionName, newValue, oldValue){},                dispose: function() {                    if (this.command)                        this.command.off("optionChanged", this._commandChangedHandler);                    delete this.command;                    delete this.containerOptions;                    delete this.widgetItem;                    delete this.updateItemHandler                }            });        var WidgetAdapterBase = DX.Class.inherit({                ctor: function($widgetElement) {                    this.$widgetElement = $widgetElement;                    this.$widgetElement.data(DX_COMMAND_TO_WIDGET_ADAPTER, this);                    this.widget = this._getWidgetByElement($widgetElement);                    this._widgetWidgetContentReadyHandler = $.proxy(this._onWidgetContentReady, this);                    this._widgetWidgetItemRenderedHandler = $.proxy(this._onWidgetItemRendered, this);                    this._widgetDisposingHandler = $.proxy(this._onWidgetDisposing, this);                    this.widget.on("itemRendered", this._widgetWidgetItemRenderedHandler);                    this.widget.on("contentReady", this._widgetWidgetContentReadyHandler);                    this.widget.on("disposing", this._widgetDisposingHandler);                    this.itemWrappers = [];                    this._transitionExecutor = new DX.TransitionExecutor                },                addCommand: function(command, containerOptions) {                    var itemWrapper = this._createItemWrapper(command, containerOptions);                    this.itemWrappers.push(itemWrapper);                    this._addItemToWidget(itemWrapper);                    this.refresh();                    this._commandChangedHandler = $.proxy(this._onCommandChanged, this);                    itemWrapper.command.on("optionChanged", this._commandChangedHandler)                },                beginUpdate: function() {                    this.widget.beginUpdate()                },                endUpdate: function() {                    this.widget.endUpdate();                    return this.animationDeferred                },                _onWidgetItemRendered: function(e) {                    if (e.itemData.isJustAdded && e.itemElement.is(":visible")) {                        this._transitionExecutor.enter(e.itemElement, "command-rendered");                        delete e.itemData.isJustAdded                    }                },                _onWidgetContentReady: function(e) {                    this.animationDeferred = this._transitionExecutor.start()                },                _onWidgetDisposing: function() {                    this.dispose(true)                },                _onCommandChanged: function(args) {                    if (args.name !== "highlighted")                        this.refresh()                },                _addItemToWidget: function(itemWrapper) {                    var items = this.widget.option("items");                    items.push(itemWrapper.widgetItem);                    if (this.widget.element().is(":visible"))                        itemWrapper.widgetItem.isJustAdded = true                },                refresh: function() {                    var items = this.widget.option("items");                    this.widget.option("items", items)                },                clear: function(widgetDisposing) {                    var that = this;                    $.each(that.itemWrappers, function(index, itemWrapper) {                        itemWrapper.command.off("optionChanged", that._commandChangedHandler);                        itemWrapper.dispose()                    });                    this.itemWrappers.length = 0;                    if (!widgetDisposing)                        this._clearWidgetItems()                },                _clearWidgetItems: function() {                    this.widget.option("items", [])                },                dispose: function(widgetDisposing) {                    this.clear(widgetDisposing);                    if (this.widget) {                        this.widget.off("itemRendered", this._widgetWidgetItemRenderedHandler);                        this.widget.off("contentReady", this._widgetContentReadyHandler);                        this.widget.off("disposing", this._widgetDisposingHandler);                        this.$widgetElement.removeData(DX_COMMAND_TO_WIDGET_ADAPTER);                        delete this.widget;                        delete this.$widgetElement                    }                }            });        var CommandToWidgetAdapter = DX.Class.inherit({                ctor: function(createAdapter) {                    this.createAdapter = createAdapter                },                _getWidgetAdapter: function($container) {                    var widgetAdapter = $container.data(DX_COMMAND_TO_WIDGET_ADAPTER);                    if (!widgetAdapter)                        widgetAdapter = this.createAdapter($container);                    return widgetAdapter                },                addCommand: function($container, command, containerOptions) {                    var widgetAdapter = this._getWidgetAdapter($container);                    widgetAdapter.addCommand(command, containerOptions)                },                clearContainer: function($container) {                    var widgetAdapter = this._getWidgetAdapter($container);                    widgetAdapter.clear()                },                beginUpdate: function($container) {                    var widgetAdapter = this._getWidgetAdapter($container);                    widgetAdapter.beginUpdate()                },                endUpdate: function($container) {                    var widgetAdapter = this._getWidgetAdapter($container);                    return widgetAdapter.endUpdate()                }            });        var dxToolbarItemWrapper = WidgetItemWrapperBase.inherit({_updateItem: function() {                    var widgetItem = this.widgetItem,                        command = this.command,                        containerOptions = this.containerOptions,                        location = commandToContainer.resolvePropertyValue(command, containerOptions, "location"),                        optionsTarget;                    widgetItem.location = location;                    if (location === "menu")                        optionsTarget = widgetItem;                    else {                        optionsTarget = $.extend({}, widgetItem);                        widgetItem.options = optionsTarget;                        widgetItem.widget = "button"                    }                    optionsTarget.onClick = function(e) {                        command.execute(e)                    };                    optionsTarget.text = commandToContainer.resolveTextValue(command, containerOptions);                    optionsTarget.disabled = command.option("disabled");                    optionsTarget.icon = commandToContainer.resolveIconValue(command, containerOptions, "icon");                    optionsTarget.type = commandToContainer.resolveTypeValue(command, containerOptions)                }});        var dxToolbarAdapter = WidgetAdapterBase.inherit({                ctor: function($widgetElement) {                    this.callBase($widgetElement)                },                _getWidgetByElement: function($element) {                    return $element.dxToolbar("instance")                },                _createItemWrapper: function(command, containerOptions) {                    return new dxToolbarItemWrapper(command, containerOptions)                },                addCommand: function(command, containerOptions) {                    this.callBase(command, containerOptions);                    this.widget.option("visible", true)                }            });        var dxActionSheetItemWrapper = WidgetItemWrapperBase.inherit({_updateItem: function() {                    var widgetItem = this.widgetItem,                        command = this.command,                        containerOptions = this.containerOptions;                    widgetItem.text = commandToContainer.resolveTextValue(command, containerOptions);                    widgetItem.icon = commandToContainer.resolveIconValue(command, containerOptions, "icon")                }});        var dxActionSheetAdapter = WidgetAdapterBase.inherit({                _createItemWrapper: function(command, containerOptions) {                    return new dxActionSheetItemWrapper(command, containerOptions)                },                _getWidgetByElement: function($element) {                    return $element.dxActionSheet("instance")                }            });        var dxListItemWrapper = WidgetItemWrapperBase.inherit({                _createWidgetItem: function(command, containerOptions) {                    this.callBase(command, containerOptions);                    this.widgetItem.onClick = $.proxy(this._itemClick, this)                },                _updateItem: function() {                    var widgetItem = this.widgetItem,                        command = this.command,                        containerOptions = this.containerOptions;                    widgetItem.title = commandToContainer.resolveTextValue(command, containerOptions);                    widgetItem.icon = commandToContainer.resolveIconValue(command, containerOptions, "icon")                },                _itemClick: function(e) {                    this.command.execute(e)                }            });        var dxListAdapter = WidgetAdapterBase.inherit({                _createItemWrapper: function(command, containerOptions) {                    return new dxListItemWrapper(command, containerOptions)                },                _getWidgetByElement: function($element) {                    return $element.dxList("instance")                }            });        var dxNavBarItemWrapper = WidgetItemWrapperBase.inherit({_updateItem: function(optionName, newValue, oldValue) {                    var command = this.command,                        containerOptions = this.containerOptions;                    if (optionName !== "highlighted") {                        this.widgetItem.text = commandToContainer.resolveTextValue(command, containerOptions);                        this.widgetItem.icon = commandToContainer.resolveIconValue(command, containerOptions, "icon")                    }                }});        var dxNavBarAdapter = WidgetAdapterBase.inherit({                ctor: function($widgetElement) {                    this.callBase($widgetElement);                    this.widget.option("onItemClick", $.proxy(this._onNavBarItemClick, this))                },                _onNavBarItemClick: function(e) {                    var items = this.widget.option("items");                    for (var i = items.length; --i; )                        items[i].command.option("highlighted", false);                    e.itemData.command.execute(e)                },                _getWidgetByElement: function($element) {                    return $element.dxNavBar("instance")                },                _createItemWrapper: function(command, containerOptions) {                    return new dxNavBarItemWrapper(command, containerOptions)                },                addCommand: function(command, containerOptions) {                    this.callBase(command, containerOptions);                    this._updateSelectedIndex()                },                _onCommandChanged: function(args) {                    var optionName = args.name,                        newValue = args.value;                    if (optionName !== "highlighted" || newValue)                        this._updateSelectedIndex();                    this.callBase(args)                },                _updateSelectedIndex: function() {                    var items = this.widget.option("items");                    for (var i = 0, itemsCount = items.length; i < itemsCount; i++)                        if (items[i].highlighted) {                            this.widget.option("selectedIndex", i);                            break                        }                }            });        var dxPivotAdapter = WidgetAdapterBase.inherit({                ctor: function($widgetElement) {                    this.callBase($widgetElement);                    this.widget.option("onSelectionChanged", $.proxy(this._onPivotSelectionChange, this))                },                _onPivotSelectionChange: function(e) {                    if (e.addedItems.length && e.removedItems.length && e.addedItems[0] && e.addedItems[0].command)                        e.addedItems[0].command.execute(e)                },                _getWidgetByElement: function($element) {                    return $element.dxPivot("instance")                },                _createItemWrapper: function(command, containerOptions) {                    return new dxToolbarItemWrapper(command, containerOptions)                },                addCommand: function(command, containerOptions) {                    this.callBase(command, containerOptions);                    this._updateSelectedIndex()                },                _onCommandChanged: function(args) {                    var optionName = args.name,                        newValue = args.value;                    if (optionName === "visible")                        this._rerenderPivot();                    else if (optionName !== "highlighted" || newValue)                        this._updateSelectedIndex()                },                _addItemToWidget: function(itemWrapper) {                    if (itemWrapper.command.option("visible"))                        this.callBase(itemWrapper)                },                _updateSelectedIndex: function() {                    var pivot = this.widget,                        items = pivot.option("items") || [];                    DX.fx.off = true;                    for (var i = 0, itemsCount = items.length; i < itemsCount; i++)                        if (items[i].highlighted) {                            pivot.option("selectedIndex", i);                            break                        }                    DX.fx.off = false                },                _rerenderPivot: function() {                    var that = this;                    that.widget.option("items", []);                    $.each(that.itemWrappers, function(index, itemWrapper) {                        if (itemWrapper.command.option("visible"))                            that._addItemToWidget(itemWrapper)                    });                    that.refresh();                    that._updateSelectedIndex()                }            });        var dxSlideOutItemWrapper = WidgetItemWrapperBase.inherit({_updateItem: function(optionName, newValue, oldValue) {                    var widgetItem = this.widgetItem,                        command = this.command,                        containerOptions = this.containerOptions;                    if (name !== "highlighted") {                        widgetItem.title = commandToContainer.resolveTextValue(command, containerOptions);                        widgetItem.icon = commandToContainer.resolveIconValue(command, containerOptions, "icon")                    }                }});        var dxSlideOutAdapter = WidgetAdapterBase.inherit({                ctor: function($widgetElement) {                    this.callBase($widgetElement);                    this.widget.option("onItemClick", $.proxy(this._onSlideOutItemClick, this))                },                _onSlideOutItemClick: function(e) {                    e.itemData.command.execute(e)                },                _getWidgetByElement: function($element) {                    return $element.dxSlideOut("instance")                },                _createItemWrapper: function(command, containerOptions) {                    return new dxSlideOutItemWrapper(command, containerOptions)                },                _updateSelectedIndex: function() {                    var items = this.widget.option("items") || [];                    for (var i = 0, itemsCount = items.length; i < itemsCount; i++)                        if (items[i].highlighted) {                            this.widget.option("selectedIndex", i);                            break                        }                },                addCommand: function(command, containerOptions) {                    this.callBase(command, containerOptions);                    this._updateSelectedIndex()                },                _onCommandChanged: function(args) {                    var optionName = args.name,                        newValue = args.value;                    if (optionName !== "highlighted" || newValue)                        this._updateSelectedIndex();                    this.callBase(args)                }            });        var adapters = DX.framework.html.commandToDXWidgetAdapters = {};        adapters.dxToolbar = new CommandToWidgetAdapter(function($widgetElement) {            return new dxToolbarAdapter($widgetElement)        });        adapters.dxActionSheet = new CommandToWidgetAdapter(function($widgetElement) {            return new dxActionSheetAdapter($widgetElement)        });        adapters.dxList = new CommandToWidgetAdapter(function($widgetElement) {            return new dxListAdapter($widgetElement)        });        adapters.dxNavBar = new CommandToWidgetAdapter(function($widgetElement) {            return new dxNavBarAdapter($widgetElement)        });        adapters.dxPivot = new CommandToWidgetAdapter(function($widgetElement) {            return new dxPivotAdapter($widgetElement)        });        adapters.dxSlideOut = new CommandToWidgetAdapter(function($widgetElement) {            return new dxSlideOutAdapter($widgetElement)        });        DX.framework.html.WidgetItemWrapperBase = WidgetItemWrapperBase;        DX.framework.html.WidgetAdapterBase = WidgetAdapterBase    })(jQuery, DevExpress);    /*! Module framework, file framework.commandManager.js */    (function($, DX, undefined) {        var Class = DX.Class;        var CommandContainer = DX.DOMComponent.inherit({                ctor: function(element, options) {                    if ($.isPlainObject(element)) {                        options = element;                        element = $("<div />")                    }                    this.callBase(element, options)                },                _setDefaultOptions: function() {                    this.callBase();                    this.option({id: null})                },                _render: function() {                    this.callBase();                    this.element().addClass("dx-command-container")                }            });        DX.registerComponent("dxCommandContainer", DX.framework, CommandContainer);        DX.framework.html.CommandManager = Class.inherit({            ctor: function(options) {                options = options || {};                this.defaultWidgetAdapter = options.defaultWidgetAdapter || this._getDefaultWidgetAdapter();                this.commandMapping = options.commandMapping || new DX.framework.CommandMapping            },            _getDefaultWidgetAdapter: function() {                return {                        addCommand: $.noop,                        clearContainer: $.noop                    }            },            _getContainerAdapter: function($container) {                var componentNames = $container.data("dxComponents"),                    adapters = DX.framework.html.commandToDXWidgetAdapters;                if (componentNames)                    for (var index in componentNames) {                        var widgetName = componentNames[index];                        if (widgetName in adapters)                            return adapters[widgetName]                    }                return this.defaultWidgetAdapter            },            findCommands: function($view) {                var result = $.map($view.addBack().find(".dx-command"), function(element) {                        return $(element).dxCommand("instance")                    });                return result            },            findCommandContainers: function($markup) {                var result = $.map($markup.find(".dx-command-container"), function(element) {                        return $(element).dxCommandContainer("instance")                    });                return result            },            _checkCommandId: function(id, command) {                if (id === null)                    throw DX.Error("E3010", command.element().get(0).outerHTML);            },            renderCommandsToContainers: function(commands, containers) {                var that = this,                    commandHash = {},                    commandIds = [],                    deferreds = [];                $.each(commands, function(i, command) {                    var id = command.option("id");                    that._checkCommandId(id, command);                    commandIds.push(id);                    commandHash[id] = command                });                that.commandMapping.checkCommandsExist(commandIds);                $.each(containers, function(k, container) {                    var commandInfos = [];                    $.each(commandHash, function(id, command) {                        var commandId = id;                        var commandOptions = that.commandMapping.getCommandMappingForContainer(commandId, container.option("id"));                        if (commandOptions)                            commandInfos.push({                                command: command,                                options: commandOptions                            })                    });                    if (commandInfos.length) {                        var deferred = that._attachCommandsToContainer(container.element(), commandInfos);                        if (deferred)                            deferreds.push(deferred)                    }                });                return $.when.apply($, deferreds)            },            clearContainer: function(container) {                var $container = container.element(),                    adapter = this._getContainerAdapter($container);                adapter.clearContainer($container)            },            _arrangeCommandsToContainers: function(commands, containers) {                DX.log("W0002", "CommandManager", "_arrangeCommandsToContainers", "14.1", "Use the 'renderCommandsToContainers' method instead.");                this.renderCommandsToContainers(commands, containers)            },            _attachCommandsToContainer: function($container, commandInfos) {                var adapter = this._getContainerAdapter($container),                    result;                if (adapter.beginUpdate)                    adapter.beginUpdate($container);                $.each(commandInfos, function(index, commandInfo) {                    adapter.addCommand($container, commandInfo.command, commandInfo.options)                });                if (adapter.endUpdate)                    result = adapter.endUpdate($container);                return result            }        })    })(jQuery, DevExpress);    /*! Module framework, file framework.layoutController.js */    (function($, DX, undefined) {        var Class = DX.Class,            HIDDEN_BAG_ID = "__hidden-bag",            TRANSITION_SELECTOR = ".dx-transition:not(.dx-transition .dx-transition)",            CONTENT_SELECTOR = ".dx-content",            DEFAULT_COMMAND_RENDER_STAGE = "onViewShown";        var transitionSelector = function(transitionName) {                return ".dx-transition-" + transitionName            };        DX.framework.html.DefaultLayoutController = Class.inherit({            ctor: function(options) {                options = options || {};                this.name = options.name || "";                this._layoutModel = options.layoutModel || {};                this._defaultPaneName = options.defaultPaneName || "content";                this._transitionDuration = options.transitionDuration === undefined ? 400 : options.transitionDuration;                this.viewReleased = $.Callbacks();                this.viewRendered = $.Callbacks();                this._callbacksToEvents("DefaultLayoutController", ["viewReleased", "viewRendered"])            },            init: function(options) {                options = options || {};                this._visibleViews = {};                this._$viewPort = options.$viewPort || $("body");                this._commandManager = options.commandManager;                this._viewEngine = options.viewEngine;                this.transitionExecutor = new DX.TransitionExecutor;                this._prepareTemplates();                this._$viewPort.append(this._getRootElement());                this._hideElements(this._getRootElement());                if (options.templateContext) {                    this._templateContext = options.templateContext;                    this._proxiedTemplateContextChangedHandler = $.proxy(this._templateContextChangedHandler, this)                }            },            activate: function() {                var $rootElement = this._getRootElement();                this._showElements($rootElement);                this._attachRefreshViewRequiredHandler();                return $.Deferred().resolve().promise()            },            deactivate: function() {                this._releaseVisibleViews();                this._hideElements(this._getRootElement());                this._detachRefreshViewRequiredHandler();                return $.Deferred().resolve().promise()            },            activeViewInfo: function() {                return this._visibleViews[this._defaultPaneName]            },            _applyTemplate: function($elements, model) {                $elements.each(function(i, element) {                    DX.framework.templateProvider.applyTemplate(element, model)                })            },            _releaseVisibleViews: function() {                var that = this;                $.each(this._visibleViews, function(index, viewInfo) {                    that._hideView(viewInfo);                    that._releaseView(viewInfo)                });                this._visibleViews = {}            },            _templateContextChangedHandler: function() {                $.each(this._visibleViews, $.proxy(function(index, viewInfo) {                    this.showView(viewInfo)                }, this))            },            _attachRefreshViewRequiredHandler: function() {                if (this._templateContext)                    this._templateContext.on("optionChanged", this._proxiedTemplateContextChangedHandler)            },            _detachRefreshViewRequiredHandler: function() {                if (this._templateContextChanged)                    this._templateContext.off("optionChanged", this._proxiedTemplateContextChangedHandler)            },            _getPreviousViewInfo: function(viewInfo) {                return this._visibleViews[this._getViewPaneName(viewInfo.viewTemplateInfo)]            },            _prepareTemplates: function() {                var that = this;                var $layoutTemplate = that._viewEngine.getLayoutTemplate(this._getLayoutTemplateName());                that._$layoutTemplate = $layoutTemplate;                that._$mainLayout = that._createEmptyLayout();                that._showElements(that._$mainLayout);                that._applyTemplate(that._$mainLayout, that._layoutModel);                that._$navigationWidget = that._createNavigationWidget()            },            renderNavigation: function(navigationCommands) {                this._clearNavigationWidget();                this._renderNavigationImpl(navigationCommands)            },            _renderNavigationImpl: function(navigationCommands) {                this._renderCommands(this._$mainLayout, navigationCommands)            },            _createNavigationWidget: function() {                var containers = this._findCommandContainers(this._$mainLayout),                    result;                $.each(containers, function(k, container) {                    if (container.option("id") === "global-navigation") {                        result = container.element();                        return false                    }                });                return result            },            _clearNavigationWidget: function() {                if (this._$navigationWidget)                    this._commandManager.clearContainer(this._$navigationWidget.dxCommandContainer("instance"))            },            _getRootElement: function() {                return this._$mainLayout            },            _getViewFrame: function(viewInfo) {                return this._$mainLayout            },            _getLayoutTemplateName: function() {                return this.name            },            _applyModelToTransitionElements: function($markup, model) {                var that = this;                this._getTransitionElements($markup).each(function(i, item) {                    that._applyTemplate($(item).children(), model)                })            },            _createViewLayoutTemplate: function() {                var that = this;                var $viewLayoutTemplate = that._$layoutTemplate.clone();                this._hideElements($viewLayoutTemplate);                return $viewLayoutTemplate            },            _createEmptyLayout: function() {                var that = this;                var $result = that._$layoutTemplate.clone();                this._hideElements($result);                this._getTransitionElements($result).empty();                $result.children(CONTENT_SELECTOR).remove();                return $result            },            _getTransitionElements: function($markup) {                return $markup.find(TRANSITION_SELECTOR).addBack(TRANSITION_SELECTOR)            },            showView: function(viewInfo, direction) {                direction = direction || "forward";                var that = this,                    previousViewInfo = that._getPreviousViewInfo(viewInfo),                    previousViewTemplateId = previousViewInfo === viewInfo ? previousViewInfo.currentViewTemplateId : undefined;                this._defineCurrentViewTemplateId(viewInfo);                if (previousViewTemplateId && previousViewTemplateId === viewInfo.currentViewTemplateId && viewInfo === previousViewInfo)                    return $.Deferred().resolve().promise();                that._ensureViewRendered(viewInfo);                this.fireEvent("viewShowing", [viewInfo]);                return this._showViewImpl(viewInfo, direction, previousViewTemplateId).done(function() {                        that._onViewShown(viewInfo)                    })            },            disposeView: function(viewInfo) {                this._clearRenderResult(viewInfo)            },            _clearRenderResult: function(viewInfo) {                if (viewInfo.renderResult) {                    viewInfo.renderResult.$markup.remove();                    viewInfo.renderResult.$viewItems.remove();                    delete viewInfo.renderResult                }            },            _prepareViewTemplate: function($viewTemplate, viewInfo){},            _renderViewImpl: function($viewTemplate, viewInfo) {                var that = this,                    allowedChildrenSelector = ".dx-command,.dx-content,script",                    $layout = this._createViewLayoutTemplate(),                    $viewItems,                    isSimplifiedMarkup = true,                    outOfContentItems = $();                if ($viewTemplate.children(allowedChildrenSelector).length === 0)                    this._viewEngine._wrapViewDefaultContent($viewTemplate);                $viewItems = $viewTemplate.children();                this._applyModelToTransitionElements($layout, viewInfo.model);                this._viewEngine.applyLayout($viewTemplate, $layout);                $viewItems.each(function(i, item) {                    var $item = $(item);                    that._applyTemplate($item, viewInfo.model);                    if ($item.is(allowedChildrenSelector))                        isSimplifiedMarkup = false;                    else                        outOfContentItems = outOfContentItems.add($item)                });                if (outOfContentItems.length && !isSimplifiedMarkup)                    throw DX.Error("E3014", outOfContentItems[0].outerHTML);                viewInfo.renderResult = viewInfo.renderResult || {};                viewInfo.renderResult.$viewItems = $viewItems;                viewInfo.renderResult.$markup = $layout            },            _renderCommands: function($markup, commands) {                var commandContainers = this._findCommandContainers($markup);                this._commandManager.renderCommandsToContainers(commands, commandContainers)            },            _prepareViewCommands: function(viewInfo) {                var $viewItems = viewInfo.renderResult.$viewItems,                    viewCommands = this._commandManager.findCommands($viewItems),                    commandsToRenderMap = {};                viewInfo.commands = DX.framework.utils.mergeCommands(viewInfo.commands || [], viewCommands);                viewInfo.commandsToRenderMap = commandsToRenderMap;                $.each(viewInfo.commands, function(index, command) {                    var renderStage = command.option("renderStage") || DEFAULT_COMMAND_RENDER_STAGE,                        targetArray = commandsToRenderMap[renderStage] = commandsToRenderMap[renderStage] || [];                    targetArray.push(command)                })            },            _applyViewCommands: function(viewInfo, renderStage) {                renderStage = renderStage || DEFAULT_COMMAND_RENDER_STAGE;                var commandsToRender = viewInfo.commandsToRenderMap[renderStage],                    $markup = viewInfo.renderResult.$markup;                if (commandsToRender) {                    this._renderCommands($markup, commandsToRender);                    delete viewInfo.commandsToRenderMap[renderStage]                }            },            _findCommandContainers: function($markup) {                return DX.utils.createComponents($markup, ["dxCommandContainer"])            },            _defineCurrentViewTemplateId: function(viewInfo) {                var viewTemplateInstance = viewInfo.$viewTemplate ? viewInfo.$viewTemplate.dxView("instance") : this._viewEngine.getViewTemplateInfo(viewInfo.viewName),                    currentViewTemplateId = viewTemplateInstance.getId();                viewInfo.currentViewTemplateId = currentViewTemplateId            },            _ensureViewRendered: function(viewInfo) {                var $cachedMarkup = viewInfo.renderResult && viewInfo.renderResult.markupCache[viewInfo.currentViewTemplateId];                if ($cachedMarkup)                    viewInfo.renderResult.$markup = $cachedMarkup;                else {                    this._renderView(viewInfo);                    viewInfo.renderResult.markupCache = viewInfo.renderResult.markupCache || {};                    viewInfo.renderResult.markupCache[viewInfo.currentViewTemplateId] = viewInfo.renderResult.$markup                }            },            _renderView: function(viewInfo) {                var $viewTemplate = viewInfo.$viewTemplate || this._viewEngine.getViewTemplate(viewInfo.viewName);                this._prepareViewTemplate($viewTemplate, viewInfo);                this._renderViewImpl($viewTemplate, viewInfo);                this._prepareViewCommands(viewInfo);                this._applyViewCommands(viewInfo, "onViewRendering");                this._appendViewToLayout(viewInfo);                $viewTemplate.remove();                this._onRenderComplete(viewInfo);                this.fireEvent("viewRendered", [viewInfo])            },            _appendViewToLayout: function(viewInfo) {                var that = this,                    $viewFrame = that._getViewFrame(viewInfo),                    $markup = viewInfo.renderResult.$markup,                    $transitionContentElements = $(),                    animationItems = [];                $.each($markup.find(".dx-content-placeholder"), function(index, el) {                    DX.framework.prepareTransition($(el), $(el).attr("data-dx-content-placeholder-name"))                });                $.each(that._getTransitionElements($viewFrame), function(index, transitionElement) {                    var $transition = $(transitionElement),                        $viewElement = $markup.find(transitionSelector($transition.attr("data-dx-transition-name"))).children(),                        animationItem = {                            $element: $viewElement,                            animation: $transition.attr("data-dx-transition-type")                        };                    animationItems.push(animationItem);                    that._hideViewElements($viewElement);                    $transition.append($viewElement);                    $transitionContentElements = $transitionContentElements.add($viewElement)                });                that._$mainLayout.append(viewInfo.renderResult.$viewItems.filter(".dx-command"));                $markup.remove();                viewInfo.renderResult.$markup = $transitionContentElements;                viewInfo.renderResult.animationItems = animationItems            },            _onRenderComplete: function(viewInfo){},            _onViewShown: function(viewInfo) {                $(document).trigger("dx.viewchanged")            },            _enter: function(animationItems) {                var transitionExecutor = this.transitionExecutor;                $.each(animationItems, function(index, item) {                    transitionExecutor.enter(item.$element, item.animation)                })            },            _leave: function(animationItems) {                var transitionExecutor = this.transitionExecutor;                $.each(animationItems, function(index, item) {                    transitionExecutor.leave(item.$element, item.animation)                })            },            _doTransition: function(oldViewInfo, newViewInfo, direction) {                if (oldViewInfo)                    this._leave(oldViewInfo.renderResult.animationItems);                this._enter(newViewInfo.renderResult.animationItems);                return this.transitionExecutor.start({direction: direction})            },            _showViewImpl: function(viewInfo, direction, previousViewTemplateId) {                var that = this,                    result,                    previousViewInfo = this._getPreviousViewInfo(viewInfo);                this._showView(viewInfo);                if (!previousViewInfo || previousViewInfo === viewInfo) {                    that._changeView(viewInfo, previousViewTemplateId);                    result = $.Deferred().resolve().promise()                }                else                    result = that._doTransition(previousViewInfo, viewInfo, direction).done(function() {                        that._changeView(viewInfo)                    });                return result            },            _releaseView: function(viewInfo) {                this.viewReleased.fireWith(this, [viewInfo])            },            _changeView: function(viewInfo, previousViewTemplateId) {                var that = this;                if (previousViewTemplateId)                    that._hideView(viewInfo, previousViewTemplateId);                else {                    var previousViewInfo = that._getPreviousViewInfo(viewInfo);                    if (previousViewInfo && previousViewInfo !== viewInfo) {                        that._hideView(previousViewInfo);                        that._releaseView(previousViewInfo)                    }                    this._visibleViews[this._getViewPaneName(viewInfo.viewTemplateInfo)] = viewInfo                }                this._applyViewCommands(viewInfo);                this._subscribeToDeferredItems(viewInfo);                this._renderDeferredItems(viewInfo.renderResult.$markup)            },            _subscribeToDeferredItems: function(viewInfo) {                var that = this,                    $markup = viewInfo.renderResult.$markup;                $markup.find(".dx-pending-rendering").add($markup.filter(".dx-pending-rendering")).each(function() {                    var $element = $(this),                        promise = $element.data("dx-rendered-promise");                    if (promise)                        promise.done(function() {                            that._renderCommands($element, viewInfo.commands)                        })                })            },            _renderDeferredItems: function($items) {                var that = this,                    $pendingItem = $items.find(".dx-pending-rendering-manual").add($items.filter(".dx-pending-rendering-manual")).first();                if ($pendingItem.length) {                    var render = $pendingItem.data("dx-render-delegate");                    setTimeout(function() {                        render().done(function() {                            that._renderDeferredItems($items)                        })                    })                }            },            _getViewPaneName: function(viewTemplateInfo) {                return this._defaultPaneName            },            _hideElements: function($elements) {                $elements.addClass("dx-hidden")            },            _showElements: function($elements) {                $elements.removeClass("dx-hidden");                DX.utils.triggerShownEvent($elements)            },            _hideViewElements: function($elements) {                DX.utils.triggerHidingEvent($elements);                this._patchIDs($elements);                this._disableInputs($elements);                $elements.removeClass("dx-active-view").addClass("dx-inactive-view")            },            _hideView: function(viewInfo, templateId) {                if (viewInfo.renderResult) {                    var $markupToHide = templateId === undefined ? viewInfo.renderResult.$markup : viewInfo.renderResult.markupCache[templateId];                    this._hideViewElements($markupToHide)                }            },            _showViewElements: function($elements) {                this._unpatchIDs($elements);                this._enableInputs($elements);                $elements.removeClass("dx-inactive-view").addClass("dx-active-view");                DX.utils.triggerShownEvent($elements)            },            _showView: function(viewInfo) {                if (viewInfo.renderResult)                    this._showViewElements(viewInfo.renderResult.$markup)            },            _patchIDs: function($markup) {                this._processIDs($markup, function(id) {                    var result = id;                    if (id.indexOf(HIDDEN_BAG_ID) === -1)                        result = HIDDEN_BAG_ID + "-" + id;                    return result                })            },            _unpatchIDs: function($markup) {                this._processIDs($markup, function(id) {                    var result = id;                    if (id.indexOf(HIDDEN_BAG_ID) === 0)                        result = id.substr(HIDDEN_BAG_ID.length + 1);                    return result                })            },            _processIDs: function($markup, process) {                var elementsWithIds = $markup.find("[id]");                $.each(elementsWithIds, function(index, element) {                    var $el = $(element),                        id = $el.attr("id");                    $el.attr("id", process(id))                })            },            _enableInputs: function($markup) {                var $inputs = $markup.find(":input[data-disabled=true]");                $.each($inputs, function(index, input) {                    $(input).removeAttr("disabled").removeAttr("data-disabled")                })            },            _disableInputs: function($markup) {                var $inputs = $markup.find(":input:not([disabled], [disabled=true])");                $.each($inputs, function(index, input) {                    $(input).attr({                        disabled: true,                        "data-disabled": true                    })                })            }        }).include(DX.EventsMixin);        var layoutSets = DX.framework.html.layoutSets;        layoutSets["default"] = layoutSets["default"] || [];        layoutSets["default"].push({controller: new DX.framework.html.DefaultLayoutController})    })(jQuery, DevExpress);    /*! Module framework, file framework.viewEngine.js */    (function($, DX, undefined) {        var Class = DX.Class,            framework = DX.framework,            _VIEW_ROLE = "dxView",            _LAYOUT_ROLE = "dxLayout";        DX.registerComponent(_VIEW_ROLE, framework, DX.DOMComponent.inherit({            _setDefaultOptions: function() {                this.callBase();                this.option({                    name: null,                    title: null                })            },            ctor: function() {                this.callBase.apply(this, arguments);                this._id = DX.utils.uniqueId()            },            _render: function() {                this.callBase();                this.element().addClass("dx-view");                this.element().attr("dx-data-template-id", this._id)            },            getId: function() {                return this._id            }        }), framework);        DX.registerComponent(_LAYOUT_ROLE, framework, DX.DOMComponent.inherit({            _setDefaultOptions: function() {                this.callBase();                this.option({name: null})            },            _render: function() {                this.callBase();                this.element().addClass("dx-layout")            }        }));        DX.registerComponent("dxViewPlaceholder", framework, DX.DOMComponent.inherit({            _setDefaultOptions: function() {                this.callBase();                this.option({viewName: null})            },            _render: function() {                this.callBase();                this.element().addClass("dx-view-placeholder")            }        }));        var setupTransitionElement = function($element, transitionType, transitionName, contentCssPosition) {                if (contentCssPosition === "absolute")                    $element.addClass("dx-transition-absolute");                else                    $element.addClass("dx-transition-static");                $element.addClass("dx-transition").addClass("dx-transition-" + transitionName).addClass("dx-transition-" + transitionType).attr("data-dx-transition-type", transitionType).attr("data-dx-transition-name", transitionName)            };        var setupTransitionInnerElement = function($element) {                $element.addClass("dx-transition-inner-wrapper")            };        DX.registerComponent("dxTransition", framework, DX.DOMComponent.inherit({            _setDefaultOptions: function() {                this.callBase();                this.option({                    name: null,                    type: undefined,                    animation: "slide"                })            },            _render: function() {                this.callBase();                var element = this.element();                setupTransitionElement(element, this.option("type") || this.option("animation"), this.option("name"), "absolute");                element.wrapInner("<div/>");                setupTransitionInnerElement(element.children());                if (this.option("type"))                    DX.log("W0003", "dxTransition", "type", "15.1", "Use the 'animation' property instead")            },            _clean: function() {                this.callBase();                this.element().empty()            }        }));        DX.framework.prepareTransition = function($element, targetPlaceholderName) {            if ($element.children(".dx-content").length === 0) {                $element.wrapInner("<div>");                $element.children().dxContent({targetPlaceholder: targetPlaceholderName})            }        };        DX.registerComponent("dxContentPlaceholder", framework, DX.DOMComponent.inherit({            _setDefaultOptions: function() {                this.callBase();                this.option({                    name: null,                    transition: undefined,                    animation: "none",                    contentCssPosition: "absolute"                })            },            _render: function() {                this.callBase();                var $element = this.element();                $element.addClass("dx-content-placeholder").addClass("dx-content-placeholder-" + this.option("name"));                $element.attr("data-dx-content-placeholder-name", this.option("name"));                setupTransitionElement($element, this.option("transition") || this.option("animation"), this.option("name"), this.option("contentCssPosition"));                if (this.option("transition"))                    DX.log("W0003", "dxContentPlaceholder", "transition", "15.1", "Use the 'animation' property instead")            },            prepareTransition: function() {                DX.framework.prepareTransition(this.element(), this.option("name"))            }        }));        DX.registerComponent("dxContent", framework, DX.DOMComponent.inherit({            _setDefaultOptions: function() {                this.callBase();                this.option({targetPlaceholder: null})            },            _optionChanged: function() {                this._refresh()            },            _clean: function() {                this.callBase();                this.element().removeClass(this._currentClass)            },            _render: function() {                this.callBase();                var element = this.element();                element.addClass("dx-content");                this._currentClass = "dx-content-" + this.option("targetPlaceholder");                element.attr("data-dx-target-placeholder-id", this.option("targetPlaceholder"));                element.addClass(this._currentClass);                setupTransitionInnerElement(element)            }        }));        framework.html.ViewEngine = Class.inherit({            ctor: function(options) {                options = options || {};                this.$root = options.$root;                this.device = options.device || {};                this.dataOptionsAttributeName = options.dataOptionsAttributeName || "data-options";                this._templateMap = {};                this._pendingViewContainer = null;                this.markupLoaded = $.Callbacks();                this._templateContext = options.templateContext            },            _enumerateTemplates: function(processFn) {                var that = this;                $.each(that._templateMap, function(name, templatesByRoleMap) {                    $.each(templatesByRoleMap, function(role, templates) {                        $.each(templates, function(index, template) {                            processFn(template)                        })                    })                })            },            _findComponent: function(name, role) {                var components = (this._templateMap[name] || {})[role] || [],                    filter = this._templateContext && this._templateContext.option() || {};                components = this._filterTemplates(filter, components);                this._checkMatchedTemplates(components);                return components[0]            },            _findTemplate: function(name, role) {                var component = this._findComponent(name, role);                if (!component)                    throw DX.Error("E3013", role, name);                var $template = component.element(),                    $result = $template.clone().removeClass("dx-hidden");                return $result            },            _extendModelFromViewData: function($view, model) {                DX.utils.extendFromObject(model, $view.data(_VIEW_ROLE).option())            },            _loadTemplatesFromMarkupCore: function($markup) {                var that = this;                if ($markup.find("[data-dx-role]").length)                    throw DX.Error("E3019");                that.markupLoaded.fire({markup: $markup});                $markup.appendTo(that.$root);                var components = DX.utils.createComponents($markup, [_VIEW_ROLE, _LAYOUT_ROLE]);                $.each(components, function(index, component) {                    var $element = component.element();                    $element.addClass("dx-hidden");                    DX.utils.createComponents($markup, ["dxContent", "dxContentPlaceholder", "dxTransition"]);                    that._registerTemplateComponent(component);                    component.element().detach()                })            },            _registerTemplateComponent: function(component) {                var role = component.NAME,                    options = component.option(),                    templateName = options.name,                    componentsByRoleMap = this._templateMap[templateName] || {};                componentsByRoleMap[role] = componentsByRoleMap[role] || [];                componentsByRoleMap[role].push(component);                this._templateMap[templateName] = componentsByRoleMap            },            _applyPartialViews: function($render) {                var that = this;                DX.utils.createComponents($render, ["dxViewPlaceholder"]);                $.each($render.find(".dx-view-placeholder"), function() {                    var $partialPlaceholder = $(this);                    if ($partialPlaceholder.children().length)                        return;                    var viewName = $partialPlaceholder.data("dxViewPlaceholder").option("viewName"),                        $view = that._findTemplate(viewName, _VIEW_ROLE);                    that._applyPartialViews($view);                    $partialPlaceholder.append($view);                    $view.removeClass("dx-hidden")                })            },            _ajaxImpl: function() {                return $.ajax.apply($, arguments)            },            _loadTemplatesFromURL: function(url) {                var that = this,                    options = this._getLoadOptions(),                    deferred = $.Deferred();                url = options.winPhonePrefix + url;                this._ajaxImpl({                    url: url,                    isLocal: options.isLocal,                    dataType: "html"                }).done(function(data) {                    that._loadTemplatesFromMarkupCore(DX.utils.createMarkupFromString(data));                    deferred.resolve()                }).fail(function(jqXHR, textStatus, errorThrown) {                    var error = DX.Error("E3021", url, errorThrown);                    deferred.reject(error)                });                return deferred.promise()            },            _getLoadOptions: function() {                if (location.protocol.indexOf("wmapp") >= 0)                    return {                            winPhonePrefix: location.protocol + "www/",                            isLocal: true                        };                return {                        winPhonePrefix: "",                        isLocal: undefined                    }            },            _loadExternalTemplates: function() {                var tasks = [],                    that = this;                $("head").find("link[rel='dx-template']").each(function(index, link) {                    var task = that._loadTemplatesFromURL($(link).attr("href"));                    tasks.push(task)                });                return $.when.apply($, tasks)            },            _processTemplates: function() {                var that = this;                $.each(that._templateMap, function(name, templatesByRoleMap) {                    $.each(templatesByRoleMap, function(role, templates) {                        that._filterTemplatesByDevice(templates)                    })                });                that._enumerateTemplates(function(template) {                    that._applyPartialViews(template.element())                })            },            _filterTemplatesByDevice: function(components) {                var filteredComponents = this._filterTemplates(this.device, components);                $.each(components, function(index, component) {                    if ($.inArray(component, filteredComponents) < 0) {                        component._dispose();                        component.element().remove()                    }                });                components.length = 0;                components.push.apply(components, filteredComponents)            },            _filterTemplates: function(filter, components) {                return DX.utils.findBestMatches(filter, components, function(component) {                        return component.option()                    })            },            _checkMatchedTemplates: function(bestMatches) {                if (bestMatches.length > 1) {                    var message = "";                    $.each(bestMatches, function(index, match) {                        message += match.element().attr("data-options") + "\r\n"                    });                    throw DX.Error("E3020", message, JSON.stringify(this.device));                }            },            _extendModelFormViewTemplate: function($viewTemplate, model) {                this._extendModelFromViewData($viewTemplate, model)            },            _wrapViewDefaultContent: function($viewTemplate) {                $viewTemplate.wrapInner("<div class=\"dx-full-height\"></div>");                $viewTemplate.children().eq(0).dxContent({targetPlaceholder: 'content'})            },            _initDefaultLayout: function() {                this._$defaultLayoutTemplate = $("<div class=\"dx-full-height\" data-options=\"dxLayout : { name: 'default' } \"> \n" + "    <div class=\"dx-full-height\" data-options=\"dxContentPlaceholder : { name: 'content' } \" ></div> \n" + "</div>");                DX.utils.createComponents(this._$defaultLayoutTemplate)            },            _getDefaultLayoutTemplate: function() {                var $result = this._$defaultLayoutTemplate.clone();                return $result            },            applyLayout: function($view, $layout) {                if ($layout === undefined || $layout.length === 0)                    $layout = this._getDefaultLayoutTemplate();                if ($view.children(".dx-content").length === 0)                    this._wrapViewDefaultContent($view);                var $toMerge = $().add($layout).add($view);                var $placeholderContents = $toMerge.find(".dx-content");                $.each($placeholderContents, function() {                    var $placeholderContent = $(this);                    var placeholderId = $placeholderContent.attr("data-dx-target-placeholder-id");                    var $placeholder = $toMerge.find(".dx-content-placeholder-" + placeholderId);                    $placeholder.empty();                    $placeholder.append($placeholderContent)                });                $placeholderContents.filter(":not(.dx-content-placeholder .dx-content)").remove();                return $layout            },            init: function() {                var that = this;                this._initDefaultLayout();                return this._loadExternalTemplates().done(function() {                        that._loadTemplatesFromMarkupCore(that.$root.children());                        that._processTemplates()                    })            },            getViewTemplate: function(viewName) {                return this._findTemplate(viewName, _VIEW_ROLE)            },            getViewTemplateInfo: function(name) {                return this._findComponent(name, _VIEW_ROLE)            },            getLayoutTemplate: function(layoutName) {                if (!layoutName)                    return this._getDefaultLayoutTemplate();                return this._findTemplate(layoutName, _LAYOUT_ROLE)            },            getLayoutTemplateInfo: function(name) {                return this._findComponent(name, _LAYOUT_ROLE)            },            loadTemplates: function(source) {                var result;                if (typeof source === "string")                    result = this._loadTemplatesFromURL(source);                else {                    this._loadTemplatesFromMarkupCore(source);                    result = $.Deferred().resolve().promise()                }                return result.done($.proxy(this._processTemplates, this))            }        })    })(jQuery, DevExpress);    /*! Module framework, file framework.htmlApplication.js */    (function($, DX, undefined) {        var frameworkNS = DX.framework,            htmlNS = frameworkNS.html;        var VIEW_PORT_CLASSNAME = "dx-viewport";        htmlNS.HtmlApplication = frameworkNS.Application.inherit({            ctor: function(options) {                options = options || {};                this.callBase(options);                this._$root = $(options.rootNode || document.body);                this._initViewport(options.viewPort);                if (this._applicationMode === "mobileApp")                    DX.utils.initMobileViewport(options.viewPort);                this.device = options.device || DX.devices.current();                this.commandManager = options.commandManager || new DX.framework.html.CommandManager({commandMapping: this.commandMapping});                this._initTemplateContext();                this.viewEngine = options.viewEngine || new htmlNS.ViewEngine({                    $root: this._$root,                    device: this.device,                    templateContext: this._templateContext                });                this.components.push(this.viewEngine);                this._initMarkupFilters(this.viewEngine);                this.viewRendered = $.Callbacks();                this._layoutSet = options.layoutSet || DX.framework.html.layoutSets["default"];                this._animationSet = options.animationSet || DX.framework.html.animationSets["default"];                this._availableLayoutControllers = [];                this._activeLayoutControllersStack = [];                this.resolveLayoutController = $.Callbacks();                this._callbacksToEvents("HtmlApplication", ["viewRendered", "resolveLayoutController"]);                this._initAnimations(this._animationSet)            },            _initAnimations: function(animationSet) {                if (!animationSet)                    return;                $.each(animationSet, function(name, configs) {                    $.each(configs, function(index, config) {                        DX.animationPresets.registerPreset(name, config)                    })                });                DX.animationPresets.applyChanges()            },            _localizeMarkup: function($markup) {                DX.localization.localizeNode($markup)            },            _notifyIfBadMarkup: function($markup) {                $markup.each(function() {                    var html = $(this).html();                    if (/href="#/.test(html))                        DX.log("W3005", html)                })            },            _initMarkupFilters: function(viewEngine) {                var filters = [];                filters.push(this._localizeMarkup);                filters.push(this._notifyIfBadMarkup);                if (viewEngine.markupLoaded)                    viewEngine.markupLoaded.add(function(args) {                        $.each(filters, function(_, filter) {                            filter(args.markup)                        })                    })            },            _createViewCache: function(options) {                var result = this.callBase(options);                if (!options.viewCache)                    result = new DX.framework.ConditionalViewCacheDecorator({                        filter: function(key, viewInfo) {                            return !viewInfo.viewTemplateInfo.disableCache                        },                        viewCache: result                    });                return result            },            _initViewport: function() {                this._$viewPort = this._getViewPort();                DX.viewPort(this._$viewPort)            },            _getViewPort: function() {                var $viewPort = $("." + VIEW_PORT_CLASSNAME);                if (!$viewPort.length)                    $viewPort = $("<div>").addClass(VIEW_PORT_CLASSNAME).appendTo(this._$root);                return $viewPort            },            _initTemplateContext: function() {                this._templateContext = new DX.Component({orientation: DX.devices.orientation()});                DX.devices.on("orientationChanged", $.proxy(function(args) {                    this._templateContext.option("orientation", args.orientation)                }, this))            },            _showViewImpl: function(viewInfo, direction) {                var that = this,                    deferred = $.Deferred(),                    result = deferred.promise(),                    layoutController = viewInfo.layoutController;                that._obtainViewLink(viewInfo);                layoutController.showView(viewInfo, direction).done(function() {                    that._activateLayoutController(layoutController, that._getTargetNode(viewInfo)).done(function() {                        deferred.resolve()                    })                });                DX.ui.events.lockFeedback(result);                return result            },            _resolveLayoutController: function(viewInfo) {                var args = {                        viewInfo: viewInfo,                        layoutController: null,                        availableLayoutControllers: this._availableLayoutControllers                    };                this._processEvent("resolveLayoutController", args, viewInfo.model);                return args.layoutController || this._resolveLayoutControllerImpl(viewInfo)            },            _ensureOneLayoutControllerFound: function(target, matches) {                var toJSONInterceptor = function(key, value) {                        if (key === "controller")                            return "[controller]: { name:" + value.name + " }";                        return value                    };                if (!matches.length) {                    DX.log("W3003", JSON.stringify(target, null, 4), JSON.stringify(this._availableLayoutControllers, toJSONInterceptor, 4));                    throw DX.Error("E3011");                }                if (matches.length > 1) {                    DX.log("W3004", JSON.stringify(target, null, 4), JSON.stringify(matches, toJSONInterceptor, 4));                    throw DX.Error("E3012");                }            },            _resolveLayoutControllerImpl: function(viewInfo) {                var templateInfo = viewInfo.viewTemplateInfo || {},                    navigateOptions = viewInfo.navigateOptions || {},                    target = $.extend({                        root: !viewInfo.canBack,                        customResolveRequired: false,                        pane: templateInfo.pane,                        modal: navigateOptions.modal !== undefined ? navigateOptions.modal : templateInfo.modal || false                    }, DX.devices.current());                var matches = DX.utils.findBestMatches(target, this._availableLayoutControllers);                this._ensureOneLayoutControllerFound(target, matches);                return matches[0].controller            },            _onNavigatingBack: function(args) {                this.callBase.apply(this, arguments);                if (!args.cancel && !this.canBack() && this._activeLayoutControllersStack.length > 1) {                    var previousActiveLayoutController = this._activeLayoutControllersStack[this._activeLayoutControllersStack.length - 2],                        previousViewInfo = previousActiveLayoutController.activeViewInfo();                    args.cancel = true;                    this._activateLayoutController(previousActiveLayoutController);                    this.navigationManager.currentItem(previousViewInfo.key)                }            },            _activeLayoutController: function() {                return this._activeLayoutControllersStack.length ? this._activeLayoutControllersStack[this._activeLayoutControllersStack.length - 1] : undefined            },            _getTargetNode: function(viewInfo) {                var jQueryEvent = (viewInfo.navigateOptions || {}).jQueryEvent;                return jQueryEvent ? $(jQueryEvent.target) : undefined            },            _activateLayoutController: function(layoutController, targetNode) {                var that = this,                    result = $.Deferred(),                    previousLayoutController = that._activeLayoutController();                if (previousLayoutController !== layoutController)                    layoutController.activate(targetNode).done(function() {                        var tasks = [];                        if (!layoutController.isOverlay) {                            var controllerToDeactivate;                            while (that._activeLayoutControllersStack.length && controllerToDeactivate !== layoutController) {                                controllerToDeactivate = that._activeLayoutController();                                if (controllerToDeactivate !== layoutController) {                                    that._activeLayoutControllersStack.pop();                                    tasks.push(controllerToDeactivate.deactivate())                                }                            }                        }                        $.when.apply($, tasks).done(function() {                            that._activeLayoutControllersStack.push(layoutController);                            result.resolve()                        })                    });                else                    result.resolve();                return result.promise()            },            init: function() {                var that = this,                    result = this.callBase();                result.done(function() {                    that._initLayoutControllers();                    that.renderNavigation()                });                return result            },            _disposeView: function(viewInfo) {                if (viewInfo.layoutController.disposeView)                    viewInfo.layoutController.disposeView(viewInfo);                this.callBase(viewInfo)            },            viewPort: function() {                return this._$viewPort            },            _createViewInfo: function(navigationItem, navigateOptions) {                var viewInfo = this.callBase.apply(this, arguments),                    templateInfo = this.getViewTemplateInfo(viewInfo.viewName);                if (!templateInfo)                    throw DX.Error("E3013", "dxView", viewInfo.viewName);                viewInfo.viewTemplateInfo = templateInfo;                viewInfo.layoutController = this._resolveLayoutController(viewInfo);                return viewInfo            },            _createViewModel: function(viewInfo) {                this.callBase(viewInfo);                var templateInfo = viewInfo.viewTemplateInfo,                    model = viewInfo.model;                for (var name in templateInfo)                    if (!(name in model))                        model[name] = templateInfo[name]            },            _initLayoutControllers: function() {                var that = this;                $.each(that._layoutSet, function(index, controllerInfo) {                    var controller = controllerInfo.controller,                        target = DX.devices.current();                    if (DX.utils.findBestMatches(target, [controllerInfo]).length) {                        that._availableLayoutControllers.push(controllerInfo);                        if (controller.init)                            controller.init({                                app: that,                                $viewPort: that._$viewPort,                                navigationManager: that.navigationManager,                                viewEngine: that.viewEngine,                                templateContext: that._templateContext,                                commandManager: that.commandManager                            });                        if (controller.on) {                            controller.on("viewReleased", function(viewInfo) {                                that._onViewReleased(viewInfo)                            });                            controller.on("viewRendered", function(viewInfo) {                                that._processEvent("viewRendered", {viewInfo: viewInfo}, viewInfo.model)                            });                            controller.on("viewShowing", function(viewInfo) {                                that._processEvent("viewShowing", {viewInfo: viewInfo}, viewInfo.model)                            })                        }                    }                })            },            _onViewReleased: function(viewInfo) {                this._onViewHidden(viewInfo);                this._releaseViewLink(viewInfo)            },            renderNavigation: function() {                var that = this;                $.each(that._availableLayoutControllers, function(index, controllerInfo) {                    var controller = controllerInfo.controller;                    if (controller.renderNavigation)                        controller.renderNavigation(that.navigation)                })            },            getViewTemplate: function(viewName) {                return this.viewEngine.getViewTemplate(viewName)            },            getViewTemplateInfo: function(viewName) {                var viewComponent = this.viewEngine.getViewTemplateInfo(viewName);                return viewComponent && viewComponent.option()            },            loadTemplates: function(source) {                return this.viewEngine.loadTemplates(source)            },            templateContext: function() {                return this._templateContext            }        })    })(jQuery, DevExpress);    DevExpress.MOD_FRAMEWORK = true}if (!DevExpress.MOD_VIZ_CORE) {    if (!window.DevExpress)        throw Error('Required module is not referenced: core');    /*! Module viz-core, file namespaces.js */    (function(DevExpress) {        DevExpress.viz = {}    })(DevExpress);    /*! Module viz-core, file namespaces.js */    (function(DevExpress) {        DevExpress.viz.core = {}    })(DevExpress);    /*! Module viz-core, file errorsWarnings.js */    (function($, DX) {        $.extend(DX.ERROR_MESSAGES, {            E2001: "Invalid data source",            E2002: "Axis type and data type are incompatible",            E2003: "\"{0}\" data source field contains data of unsupported type",            E2004: "\"{0}\" data source field is inconsistent",            E2101: "Unknown series type was specified: {0}",            E2102: "Ambiguity occurred between two value axes with the same name",            E2103: "\"{0}\" option must be a function",            E2104: "Invalid logarithm base",            E2105: "Invalid value of a \"{0}\"",            E2106: "Invalid visible range",            E2202: "Invalid scale {0} value",            E2203: "The \"{0}\" field of the \"selectedRange\" configuration object is not valid",            W2001: "{0} cannot be drawn because its container is invisible",            W2002: "The {0} data field is absent",            W2003: "Tick interval is too small",            W2101: "\"{0}\" pane does not exist; \"{1}\" pane is used instead",            W2102: "Value axis with the \"{0}\" name was created automatically",            W2103: "Chart title was hidden due to container size",            W2104: "Legend was hidden due to container size",            W2105: "Title of \"{0}\" axis was hidden due to container size",            W2106: "Labels of \"{0}\" axis were hidden due to container size",            W2301: "Invalid value range"        })    })(jQuery, DevExpress);    /*! Module viz-core, file numericTickManager.js */    (function($, DX, undefined) {        var core = DX.viz.core,            utils = DX.utils,            _isDefined = utils.isDefined,            _adjustValue = utils.adjustValue,            _math = Math,            _abs = _math.abs,            _ceil = _math.ceil,            _floor = _math.floor,            _noop = $.noop,            MINOR_TICKS_COUNT_LIMIT = 200,            DEFAULT_MINOR_NUMBER_MULTIPLIERS = [2, 4, 5, 8, 10];        core.outOfScreen = {            x: -1000,            y: -1000        };        core.tickManager = {};        core.tickManager.continuous = {            _hasUnitBeginningTickCorrection: _noop,            _removeBoundedOverlappingDates: _noop,            _correctInterval: function(step) {                this._tickInterval *= step            },            _correctMax: function(tickInterval) {                this._max = this._adjustNumericTickValue(_ceil(this._max / tickInterval) * tickInterval, tickInterval, this._min)            },            _correctMin: function(tickInterval) {                this._min = this._adjustNumericTickValue(_floor(this._min / tickInterval) * tickInterval, tickInterval, this._min)            },            _findBusinessDelta: function(min, max) {                return _adjustValue(_abs(min - max))            },            _findTickIntervalForCustomTicks: function() {                return _abs(this._customTicks[1] - this._customTicks[0])            },            _getBoundInterval: function() {                var that = this,                    boundCoef = that._options.boundCoef;                return _isDefined(boundCoef) && isFinite(boundCoef) ? that._tickInterval * _abs(boundCoef) : that._tickInterval / 2            },            _getInterval: function(deltaCoef, numberMultipliers) {                var interval = deltaCoef || this._getDeltaCoef(this._screenDelta, this._businessDelta, this._options.gridSpacingFactor),                    multipliers = numberMultipliers || this._options.numberMultipliers,                    factor,                    result = 0,                    newResult,                    hasResult = false,                    i;                if (interval > 1.0)                    for (factor = 1; !hasResult; factor *= 10)                        for (i = 0; i < multipliers.length; i++) {                            result = multipliers[i] * factor;                            if (interval <= result) {                                hasResult = true;                                break                            }                        }                else if (interval > 0) {                    result = 1;                    for (factor = 0.1; !hasResult; factor /= 10)                        for (i = multipliers.length - 1; i >= 0; i--) {                            newResult = multipliers[i] * factor;                            if (interval > newResult) {                                hasResult = true;                                break                            }                            result = newResult                        }                }                return _adjustValue(result)            },            _getMarginValue: function(min, max, margin) {                return utils.applyPrecisionByMinDelta(min, margin, _abs(max - min) * margin)            },            _getDefaultMinorInterval: function(screenDelta, businessDelta) {                var deltaCoef = this._getDeltaCoef(screenDelta, businessDelta, this._options.minorGridSpacingFactor),                    multipliers = DEFAULT_MINOR_NUMBER_MULTIPLIERS,                    i = multipliers.length - 1,                    result;                for (i; i >= 0; i--) {                    result = businessDelta / multipliers[i];                    if (deltaCoef <= result)                        return _adjustValue(result)                }                return 0            },            _getMinorInterval: function(screenDelta, businessDelta) {                var that = this,                    options = that._options,                    minorTickInterval = options.minorTickInterval,                    minorTickCount = options.minorTickCount,                    interval,                    intervalsCount,                    count;                if (isFinite(minorTickInterval) && that._isTickIntervalCorrect(minorTickInterval, MINOR_TICKS_COUNT_LIMIT, businessDelta)) {                    interval = minorTickInterval;                    count = interval < businessDelta ? _ceil(businessDelta / interval) - 1 : 0                }                else if (_isDefined(minorTickCount)) {                    intervalsCount = _isDefined(minorTickCount) ? minorTickCount + 1 : _floor(screenDelta / options.minorGridSpacingFactor);                    count = intervalsCount - 1;                    interval = count > 0 ? businessDelta / intervalsCount : 0                }                else {                    interval = that._getDefaultMinorInterval(screenDelta, businessDelta);                    count = interval < businessDelta ? _floor(businessDelta / interval) - 1 : 0                }                that._minorTickInterval = interval;                that._minorTickCount = count            },            _getNextTickValue: function(value, tickInterval, isTickIntervalNegative) {                tickInterval = _isDefined(isTickIntervalNegative) && isTickIntervalNegative ? -tickInterval : tickInterval;                value += tickInterval;                return this._adjustNumericTickValue(value, tickInterval, this._min)            },            _isTickIntervalValid: function(tickInterval) {                return _isDefined(tickInterval) && isFinite(tickInterval) && tickInterval !== 0            }        }    })(jQuery, DevExpress);    /*! Module viz-core, file datetimeTickManager.js */    (function($, DX, undefined) {        var core = DX.viz.core,            utils = DX.utils,            _isDefined = utils.isDefined,            _convertDateUnitToMilliseconds = utils.convertDateUnitToMilliseconds,            _correctDateWithUnitBeginning = utils.correctDateWithUnitBeginning,            _dateToMilliseconds = utils.dateToMilliseconds,            _convertMillisecondsToDateUnits = utils.convertMillisecondsToDateUnits,            _math = Math,            _abs = _math.abs,            _ceil = _math.ceil,            _floor = _math.floor,            _round = _math.round,            MINOR_TICKS_COUNT_LIMIT = 50,            DEFAULT_DATETIME_MULTIPLIERS = {                millisecond: [1, 2, 5, 10, 25, 100, 250, 300, 500],                second: [1, 2, 3, 5, 10, 15, 20, 30],                minute: [1, 2, 3, 5, 10, 15, 20, 30],                hour: [1, 2, 3, 4, 6, 8, 12],                day: [1, 2, 3, 5, 7, 10, 14],                month: [1, 2, 3, 6]            };        core.tickManager.datetime = $.extend({}, core.tickManager.continuous, {            _correctInterval: function(step) {                var tickIntervalInMs = _dateToMilliseconds(this._tickInterval);                this._tickInterval = _convertMillisecondsToDateUnits(tickIntervalInMs * step)            },            _correctMax: function(tickInterval) {                var interval = _dateToMilliseconds(tickInterval);                this._max = new Date(_ceil(this._max / interval) * interval)            },            _correctMin: function(tickInterval) {                var interval = _dateToMilliseconds(tickInterval);                this._min = new Date(_floor(this._min / interval) * interval);                if (this._options.setTicksAtUnitBeginning)                    _correctDateWithUnitBeginning(this._min, tickInterval)            },            _findTickIntervalForCustomTicks: function() {                return _convertMillisecondsToDateUnits(_abs(this._customTicks[1] - this._customTicks[0]))            },            _getBoundInterval: function() {                var that = this,                    interval = that._tickInterval,                    intervalInMs = _dateToMilliseconds(interval),                    boundCoef = that._options.boundCoef,                    boundIntervalInMs = _isDefined(boundCoef) && isFinite(boundCoef) ? intervalInMs * _abs(boundCoef) : intervalInMs / 2;                return _convertMillisecondsToDateUnits(boundIntervalInMs)            },            _getInterval: function(deltaCoef) {                var interval = deltaCoef || this._getDeltaCoef(this._screenDelta, this._businessDelta, this._options.gridSpacingFactor),                    multipliers = this._options.numberMultipliers,                    result = {},                    factor,                    i,                    key,                    specificMultipliers,                    yearsCount;                if (interval > 0 && interval < 1.0)                    return {milliseconds: 1};                if (interval === 0)                    return 0;                for (key in DEFAULT_DATETIME_MULTIPLIERS)                    if (DEFAULT_DATETIME_MULTIPLIERS.hasOwnProperty(key)) {                        specificMultipliers = DEFAULT_DATETIME_MULTIPLIERS[key];                        for (i = 0; i < specificMultipliers.length; i++)                            if (interval <= _convertDateUnitToMilliseconds(key, specificMultipliers[i])) {                                result[key + 's'] = specificMultipliers[i];                                return result                            }                    }                for (factor = 1; ; factor *= 10)                    for (i = 0; i < multipliers.length; i++) {                        yearsCount = factor * multipliers[i];                        if (interval <= _convertDateUnitToMilliseconds('year', yearsCount))                            return {years: yearsCount}                    }                return 0            },            _getMarginValue: function(min, max, margin) {                return _convertMillisecondsToDateUnits(_round(_abs(max - min) * margin))            },            _getMinorInterval: function(screenDelta, businessDelta) {                var that = this,                    options = that._options,                    interval,                    intervalInMs,                    intervalsCount,                    count;                if (_isDefined(options.minorTickInterval) && that._isTickIntervalCorrect(options.minorTickInterval, MINOR_TICKS_COUNT_LIMIT, businessDelta)) {                    interval = options.minorTickInterval;                    intervalInMs = _dateToMilliseconds(interval);                    count = intervalInMs < businessDelta ? _ceil(businessDelta / intervalInMs) - 1 : 0                }                else {                    intervalsCount = _isDefined(options.minorTickCount) ? options.minorTickCount + 1 : _floor(screenDelta / options.minorGridSpacingFactor);                    count = intervalsCount - 1;                    interval = count > 0 ? _convertMillisecondsToDateUnits(businessDelta / intervalsCount) : 0                }                that._minorTickInterval = interval;                that._minorTickCount = count            },            _getNextTickValue: function(value, tickInterval, isTickIntervalNegative, isTickIntervalWithPow, withCorrection) {                var newValue = utils.addInterval(value, tickInterval, isTickIntervalNegative);                if (this._options.setTicksAtUnitBeginning && withCorrection !== false) {                    _correctDateWithUnitBeginning(newValue, tickInterval, true);                    this._correctDateWithUnitBeginningCalled = true                }                return newValue            },            _getUnitBeginningMinorTicks: function(minorTicks) {                var that = this,                    ticks = that._ticks,                    tickInterval = that._findMinorTickInterval(ticks[1], ticks[2]),                    isTickIntervalNegative = true,                    isTickIntervalWithPow = false,                    needCorrectTick = false,                    startTick = that._getNextTickValue(ticks[1], tickInterval, isTickIntervalNegative, isTickIntervalWithPow, needCorrectTick);                if (that._isTickIntervalValid(tickInterval))                    minorTicks = that._createTicks(minorTicks, tickInterval, startTick, ticks[0], isTickIntervalNegative, isTickIntervalWithPow, needCorrectTick);                return minorTicks            },            _hasUnitBeginningTickCorrection: function() {                var ticks = this._ticks;                if (ticks.length < 3)                    return false;                return ticks[1] - ticks[0] !== ticks[2] - ticks[1] && this._options.setTicksAtUnitBeginning && this._options.minorTickCount            },            _isTickIntervalValid: function(tickInterval) {                return _isDefined(tickInterval) && _dateToMilliseconds(tickInterval) !== 0            },            _removeBoundedOverlappingDates: function() {                var dates = this._ticks;                if (dates.length > 2 && this.getOverlappingBehavior().mode !== "stagger" && !this._areDisplayValuesValid(dates[0], dates[1]))                    dates.splice(1, 1)            }        })    })(jQuery, DevExpress);    /*! Module viz-core, file logarithmicTickManager.js */    (function($, DX, undefined) {        var core = DX.viz.core,            utils = DX.utils,            _isDefined = utils.isDefined,            _addInterval = utils.addInterval,            _adjustValue = utils.adjustValue,            _getLog = utils.getLog,            _raiseTo = utils.raiseTo,            _math = Math,            _abs = _math.abs,            _ceil = _math.ceil,            _floor = _math.floor,            _round = _math.round;        core.tickManager.logarithmic = $.extend({}, core.tickManager.continuous, {            _correctMax: function() {                var base = this._options.base;                this._max = _adjustValue(_raiseTo(_ceil(_adjustValue(_getLog(this._max, base))), base))            },            _correctMin: function() {                var base = this._options.base;                this._min = _adjustValue(_raiseTo(_floor(_adjustValue(_getLog(this._min, base))), base))            },            _findBusinessDelta: function(min, max, isTickIntervalWithPow) {                var delta;                if (min <= 0 || max <= 0)                    return 0;                if (isTickIntervalWithPow === false)                    delta = core.tickManager.continuous._findBusinessDelta(min, max);                else                    delta = _round(_abs(_getLog(min, this._options.base) - _getLog(max, this._options.base)));                return delta            },            _findTickIntervalForCustomTicks: function() {                return _adjustValue(_getLog(this._customTicks[1] / this._customTicks[0], this._options.base))            },            _getInterval: function(deltaCoef) {                var interval = deltaCoef || this._getDeltaCoef(this._screenDelta, this._businessDelta, this._options.gridSpacingFactor),                    multipliers = this._options.numberMultipliers,                    factor,                    result = 0,                    hasResult = false,                    i;                if (interval !== 0)                    for (factor = 1; !hasResult; factor *= 10)                        for (i = 0; i < multipliers.length; i++) {                            result = multipliers[i] * factor;                            if (interval <= result) {                                hasResult = true;                                break                            }                        }                return _adjustValue(result)            },            _getMinorInterval: function(screenDelta, businessDelta) {                var that = this,                    options = that._options,                    minorTickCount = options.minorTickCount,                    intervalsCount = _isDefined(minorTickCount) ? minorTickCount + 1 : _floor(screenDelta / options.minorGridSpacingFactor),                    count = intervalsCount - 1,                    interval = count > 0 ? businessDelta / intervalsCount : 0;                that._minorTickInterval = interval;                that._minorTickCount = count            },            _getMarginValue: function() {                return null            },            _getNextTickValue: function(value, tickInterval, isTickIntervalNegative, isTickIntervalWithPow) {                var that = this,                    pow,                    nextTickValue;                tickInterval = _isDefined(isTickIntervalNegative) && isTickIntervalNegative ? -tickInterval : tickInterval;                if (isTickIntervalWithPow === false)                    nextTickValue = value + tickInterval;                else {                    pow = _addInterval(_getLog(value, that._options.base), tickInterval, that._min > that._max);                    nextTickValue = _adjustValue(_raiseTo(pow, that._options.base))                }                return nextTickValue            }        })    })(jQuery, DevExpress);    /*! Module viz-core, file tickOverlappingManager.js */    (function($, DX, undefined) {        var core = DX.viz.core,            coreTickManager = core.tickManager,            utils = DX.utils,            _isDefined = utils.isDefined,            _isNumber = utils.isNumber,            _math = Math,            _abs = _math.abs,            _ceil = _math.ceil,            _floor = _math.floor,            _atan = _math.atan,            _max = _math.max,            _each = $.each,            _map = $.map,            _noop = $.noop,            _isFunction = $.isFunction,            SCREEN_DELTA_KOEF = 4,            AXIS_STAGGER_OVERLAPPING_KOEF = 2,            STAGGER = "stagger",            ROTATE = "rotate",            MIN_ARRANGEMENT_TICKS_COUNT = 2;        function nextState(state) {            switch (state) {                case"overlap":                    return STAGGER;                case STAGGER:                    return ROTATE;                default:                    return "end"            }        }        function defaultGetTextFunc(value) {            return value.toString()        }        coreTickManager.overlappingMethods = {};        coreTickManager.overlappingMethods.base = {            _applyOverlappingBehavior: function() {                var that = this,                    options = that._options,                    overlappingBehavior = options && options.overlappingBehavior;                if (overlappingBehavior && overlappingBehavior.mode !== "ignore") {                    that._useAutoArrangement = true;                    that._correctTicks();                    if (overlappingBehavior.mode === "auto") {                        that._applyAutoOverlappingBehavior();                        that._useAutoArrangement = options.overlappingBehavior.isOverlapped                    }                    if (that._useAutoArrangement) {                        if (overlappingBehavior.mode === STAGGER)                            that._screenDelta *= AXIS_STAGGER_OVERLAPPING_KOEF;                        that._applyAutoArrangement()                    }                }            },            _checkBoundedTicksOverlapping: function() {                this._removeBoundedOverlappingDates();                this._applyStartEndTicksCorrection()            },            getMaxLabelParams: function(ticks) {                var that = this,                    getText = that._options.getText || defaultGetTextFunc,                    tickWithMaxLength,                    tickTextWithMaxLength,                    maxLength = 0,                    bbox;                ticks = ticks || that._getMajorTicks();                if (!ticks.length)                    return {                            width: 0,                            height: 0,                            length: 0,                            y: 0                        };                _each(ticks, function(_, item) {                    var text = getText(item, that._options.labelOptions),                        length = text.length;                    if (maxLength < length) {                        maxLength = length;                        tickWithMaxLength = item;                        tickTextWithMaxLength = text                    }                });                bbox = that._getTextElementBbox(tickWithMaxLength, tickTextWithMaxLength);                return {                        width: bbox.width,                        height: bbox.height,                        y: bbox.y,                        length: maxLength                    }            },            _applyAutoArrangement: function() {                var that = this,                    options = that._options,                    arrangementStep,                    maxDisplayValueSize;                if (that._useAutoArrangement) {                    maxDisplayValueSize = that._getTicksSize();                    arrangementStep = that._getAutoArrangementStep(maxDisplayValueSize);                    if (arrangementStep > 1)                        if (_isDefined(that._tickInterval) || _isDefined(that._customTicks))                            that._ticks = that._getAutoArrangementTicks(arrangementStep);                        else {                            options.gridSpacingFactor = maxDisplayValueSize;                            that._ticks = that._createTicks([], that._findTickInterval(), that._min, that._max)                        }                }            },            _getAutoArrangementTicks: function(step) {                var that = this,                    ticks = that._ticks,                    ticksLength = ticks.length,                    resultTicks = ticks,                    decimatedTicks = that._decimatedTicks || [],                    i;                if (step > 1) {                    resultTicks = [];                    for (i = 0; i < ticksLength; i++)                        if (i % step === 0)                            resultTicks.push(ticks[i]);                        else                            decimatedTicks.push(ticks[i]);                    that._correctInterval(step)                }                return resultTicks            },            _isOverlappedTicks: function(screenDelta) {                return this._getAutoArrangementStep(this._getTicksSize(), screenDelta, -1) > 1            },            _areDisplayValuesValid: function(value1, value2) {                var that = this,                    options = that._options,                    getText = options.getText || defaultGetTextFunc,                    rotationAngle = options.overlappingBehavior && _isNumber(options.overlappingBehavior.rotationAngle) ? options.overlappingBehavior.rotationAngle : 0,                    bBox1 = that._getTextElementBbox(value1, getText(value1, options.labelOptions)),                    bBox2 = that._getTextElementBbox(value2, getText(value2, options.labelOptions)),                    horizontalInverted = bBox1.x > bBox2.x,                    verticalInverted = bBox1.y > bBox2.y,                    hasHorizontalOverlapping,                    hasVerticalOverlapping,                    result;                if (rotationAngle !== 0)                    result = that._getDistanceByAngle(bBox1.height, rotationAngle) <= _abs(bBox2.x - bBox1.x);                else {                    hasHorizontalOverlapping = !horizontalInverted ? bBox1.x + bBox1.width > bBox2.x : bBox2.x + bBox2.width > bBox1.x;                    hasVerticalOverlapping = !verticalInverted ? bBox1.y + bBox1.height > bBox2.y : bBox2.y + bBox2.height > bBox1.y;                    result = !(hasHorizontalOverlapping && hasVerticalOverlapping)                }                return result            }        };        coreTickManager.overlappingMethods.circular = $.extend({}, coreTickManager.overlappingMethods.base, {            _correctTicks: _noop,            _applyAutoOverlappingBehavior: function() {                this._options.overlappingBehavior.isOverlapped = true            },            _getTextElementBbox: function(value, text) {                var textOptions = $.extend({}, this._options.textOptions, {rotate: 0}),                    delta = _isFunction(this._options.translate) ? this._options.translate(value) : {                        x: 0,                        y: 0                    },                    bbox;                text = this._options.renderText(text, delta.x, delta.y).css(this._options.textFontStyles).attr(textOptions);                bbox = text.getBBox();                text.remove();                return bbox            },            _getTicksSize: function() {                return this.getMaxLabelParams(this._ticks)            },            _applyStartEndTicksCorrection: function() {                var ticks = this._ticks,                    lastTick = ticks[ticks.length - 1];                if (ticks.length > 1 && !this._areDisplayValuesValid(ticks[0], lastTick))                    ticks.pop()            },            _getAutoArrangementStep: function(maxDisplayValueSize) {                var that = this,                    options = that._options,                    radius = options.circularRadius,                    startAngle = options.circularStartAngle,                    endAngle = options.circularEndAngle,                    circleDelta = startAngle === endAngle ? 360 : _abs(startAngle - endAngle),                    businessDelta = that._businessDelta || that._ticks.length,                    degreesPerTick = that._tickInterval * circleDelta / businessDelta,                    width = maxDisplayValueSize.width,                    height = maxDisplayValueSize.height,                    angle1 = _abs(2 * _atan(height / (2 * radius - width)) * 180 / _math.PI),                    angle2 = _abs(2 * _atan(width / (2 * radius - height)) * 180 / _math.PI),                    minAngleForTick = _max(angle1, angle2),                    step = 1;                if (degreesPerTick < minAngleForTick)                    step = _ceil(minAngleForTick / degreesPerTick);                return _max(1, step)            }        });        coreTickManager.overlappingMethods.linear = $.extend({}, coreTickManager.overlappingMethods.base, {            _correctTicks: function() {                var getIntervalFunc = coreTickManager.continuous._getInterval,                    arrangementStep;                if (this._testingGetIntervalFunc)                    getIntervalFunc = this._testingGetIntervalFunc;                arrangementStep = _ceil(getIntervalFunc.call(this, this._getDeltaCoef(this._screenDelta * SCREEN_DELTA_KOEF, this._ticks.length))) || this._ticks.length;                this._appliedArrangementStep = arrangementStep;                this._ticks = this._getAutoArrangementTicks(arrangementStep)            },            _getTextElementBbox: function(value, text) {                var textOptions = $.extend({}, this._options.textOptions, {rotate: 0}),                    x = 0,                    y = 0,                    delta = _isFunction(this._options.translate) ? this._options.translate(value) : 0,                    bbox;                if (this._options.isHorizontal)                    x += delta;                else                    y += delta;                text = this._options.renderText(text, x, y).css(this._options.textFontStyles).attr(textOptions);                bbox = text.getBBox();                text.remove();                return bbox            },            _applyStartEndTicksCorrection: _noop,            _getAutoArrangementStep: function(maxDisplayValueSize, screenDelta, minArrangementTicksStep) {                var that = this,                    options = that._options,                    requiredValuesCount,                    textSpacing = options.textSpacing || 0,                    addedSpacing = options.isHorizontal ? textSpacing : 0;                screenDelta = screenDelta || that._screenDelta;                minArrangementTicksStep = _isDefined(minArrangementTicksStep) ? minArrangementTicksStep : 1;                if (options.getCustomAutoArrangementStep)                    return options.getCustomAutoArrangementStep(that._ticks, options);                if (maxDisplayValueSize > 0) {                    requiredValuesCount = _floor((screenDelta + textSpacing) / (maxDisplayValueSize + addedSpacing));                    requiredValuesCount = requiredValuesCount <= minArrangementTicksStep ? MIN_ARRANGEMENT_TICKS_COUNT : requiredValuesCount;                    return _ceil((options.ticksCount || that._ticks.length) / requiredValuesCount)                }                return 1            },            _getOptimalRotationAngle: function() {                var that = this,                    options = that._options,                    tick1 = that._ticks[0],                    tick2 = that._ticks[1],                    outOfScreen = core.outOfScreen,                    textOptions = that._textOptions,                    getText = options.getText || defaultGetTextFunc,                    textFontStyles = options.textFontStyles,                    svgElement1 = options.renderText(getText(tick1, options.labelOptions), outOfScreen.x + options.translate(tick1, !options.isHorizontal), outOfScreen.y).css(textFontStyles).attr(textOptions),                    svgElement2 = options.renderText(getText(tick2, options.labelOptions), outOfScreen.x + options.translate(tick2, !options.isHorizontal), outOfScreen.y).css(textFontStyles).attr(textOptions),                    bBox1 = svgElement1.getBBox(),                    bBox2 = svgElement2.getBBox(),                    angle = _math.asin((bBox1.height + options.textSpacing) / (bBox2.x - bBox1.x)) * 180 / Math.PI;                svgElement1.remove();                svgElement2.remove();                return isNaN(angle) ? 90 : _ceil(angle)            },            _applyAutoOverlappingBehavior: function() {                var that = this,                    overlappingBehavior = that._options.overlappingBehavior,                    screenDelta = that._screenDelta,                    isOverlapped = false,                    rotationAngle = null,                    mode = null,                    state = "overlap";                while (state !== "end") {                    isOverlapped = rotationAngle && rotationAngle !== 90 ? false : that._isOverlappedTicks(screenDelta);                    state = nextState(isOverlapped ? state : null);                    switch (state) {                        case STAGGER:                            screenDelta *= AXIS_STAGGER_OVERLAPPING_KOEF;                            mode = state;                            break;                        case ROTATE:                            rotationAngle = that._getOptimalRotationAngle();                            screenDelta = that._screenDelta;                            mode = state;                            break                    }                }                overlappingBehavior.isOverlapped = isOverlapped;                overlappingBehavior.mode = mode;                overlappingBehavior.rotationAngle = rotationAngle            },            _getDistanceByAngle: function(elementHeight, rotationAngle) {                return elementHeight / _abs(_math.sin(rotationAngle * (_math.PI / 180)))            },            _getTicksSize: function() {                var that = this,                    options = that._options,                    ticks = that._ticks,                    ticksString,                    rotationAngle = options.overlappingBehavior ? options.overlappingBehavior.rotationAngle : 0,                    bBox,                    result,                    getText = options.getText || defaultGetTextFunc,                    isRotate = _isNumber(rotationAngle) && rotationAngle !== 0,                    joinNeeded = !isRotate && options.isHorizontal;                if (ticks.length === 0)                    return 0;                ticksString = joinNeeded ? _map(ticks, function(tick) {                    return getText(tick, options.labelOptions)                }).join("\n") : getText(ticks[0], options.labelOptions);                bBox = that._getTextElementBbox(ticksString, ticksString);                result = isRotate ? that._getDistanceByAngle(bBox.height, rotationAngle) : options.isHorizontal ? bBox.width : bBox.height;                return _ceil(result)            }        })    })(jQuery, DevExpress);    /*! Module viz-core, file baseTickManager.js */    (function($, DX, undefined) {        var core = DX.viz.core,            coreTickManager = core.tickManager,            utils = DX.utils,            _isDefined = utils.isDefined,            _isNumber = utils.isNumber,            _addInterval = utils.addInterval,            _adjustValue = utils.adjustValue,            _each = $.each,            _map = $.map,            _inArray = $.inArray,            _noop = $.noop,            DEFAULT_GRID_SPACING_FACTOR = 30,            DEFAULT_MINOR_GRID_SPACING_FACTOR = 15,            DEFAULT_NUMBER_MULTIPLIERS = [1, 2, 3, 5],            TICKS_COUNT_LIMIT = 2000,            MIN_ARRANGEMENT_TICKS_COUNT = 2;        function concatAndSort(array1, array2) {            var array = array1.concat(array2).sort(function(x, y) {                    return _isDefined(x) && _isDefined(y) && x.valueOf() - y.valueOf()                }),                length = array.length,                i;            for (i = length - 1; i > 0; i--)                if (_isDefined(array[i]) && _isDefined(array[i - 1]) && array[i].valueOf() === array[i - 1].valueOf())                    array.splice(i, 1);            return array        }        coreTickManager.discrete = $.extend({}, coreTickManager.continuous, {            _getMinorTicks: _noop,            _findTickInterval: _noop,            _createTicks: function() {                return []            },            _getMarginValue: _noop,            _generateBounds: _noop,            _correctMin: _noop,            _correctMax: _noop,            _findBusinessDelta: _noop,            _addBoundedTicks: _noop,            getFullTicks: function() {                return this._customTicks            },            getMinorTicks: function() {                return this._decimatedTicks || []            },            _findTickIntervalForCustomTicks: function() {                return 1            }        });        coreTickManager.TickManager = DX.Class.inherit({            ctor: function(types, data, options) {                options = options || {};                this.update(types || {}, data || {}, options);                this._initOverlappingMethods(options.overlappingBehaviorType)            },            dispose: function() {                this._ticks = null;                this._minorTicks = null;                this._decimatedTicks = null;                this._boundaryTicks = null;                this._options = null            },            update: function(types, data, options) {                this._updateOptions(options || {});                this._min = data.min;                this._updateTypes(types || {});                this._updateData(data || {})            },            _updateMinMax: function(data) {                var min = data.min || 0,                    max = data.max || 0,                    newMinMax = this._applyMinMaxMargins(min, max);                this._min = this._originalMin = newMinMax.min;                this._max = this._originalMax = newMinMax.max;                this._updateBusinessDelta()            },            _updateBusinessDelta: function() {                this._businessDelta = this._findBusinessDelta && this._findBusinessDelta(this._min, this._max)            },            _updateTypes: function(types) {                var that = this,                    axisType = that._validateAxisType(types.axisType),                    dataType = that._validateDataType(types.dataType);                that._resetMethods();                this._axisType = axisType;                this._dataType = dataType;                this._initMethods()            },            _updateData: function(data) {                data = $.extend({}, data);                data.min = _isDefined(data.min) ? data.min : this._originalMin;                data.max = _isDefined(data.max) ? data.max : this._originalMax;                this._updateMinMax(data);                this._customTicks = data.customTicks && data.customTicks.slice();                this._customMinorTicks = data.customMinorTicks;                this._screenDelta = data.screenDelta || 0            },            _updateOptions: function(options) {                var opt;                this._options = opt = options;                this._useAutoArrangement = !!this._options.useTicksAutoArrangement;                opt.gridSpacingFactor = opt.gridSpacingFactor || DEFAULT_GRID_SPACING_FACTOR;                opt.minorGridSpacingFactor = opt.minorGridSpacingFactor || DEFAULT_MINOR_GRID_SPACING_FACTOR;                opt.numberMultipliers = opt.numberMultipliers || DEFAULT_NUMBER_MULTIPLIERS            },            getTickBounds: function() {                return {                        minVisible: this._minBound,                        maxVisible: this._maxBound                    }            },            getTicks: function(withoutOverlappingBehavior) {                var that = this,                    options = that._options;                that._ticks = that._getMajorTicks();                that._checkLabelFormat();                that._decimatedTicks = [];                that._applyAutoArrangement();                !withoutOverlappingBehavior && that._applyOverlappingBehavior();                that._generateBounds();                if (options.showMinorTicks)                    that._minorTicks = that._customMinorTicks || that._getMinorTicks();                that._addBoundedTicks();                !withoutOverlappingBehavior && that._checkBoundedTicksOverlapping();                return that._ticks            },            getMinorTicks: function() {                var that = this,                    decimatedTicks = that._decimatedTicks || [],                    options = that._options || {},                    hasDecimatedTicks = decimatedTicks.length,                    hasMinorTickOptions = _isDefined(options.minorTickInterval) || _isDefined(options.minorTickCount),                    hasCustomMinorTicks = that._customMinorTicks && that._customMinorTicks.length,                    hasMinorTicks = options.showMinorTicks && (hasMinorTickOptions || hasCustomMinorTicks),                    ticks = hasDecimatedTicks && !hasMinorTicks ? decimatedTicks : that._minorTicks || [];                return concatAndSort(ticks, [])            },            getDecimatedTicks: function() {                return concatAndSort(this._decimatedTicks || [], [])            },            getFullTicks: function() {                return concatAndSort(this._ticks || [], this.getMinorTicks(), this._axisType)            },            getBoundaryTicks: function() {                return concatAndSort(this._boundaryTicks || [], [])            },            getTickInterval: function() {                return this._tickInterval            },            getMinorTickInterval: function() {                return this._minorTickInterval            },            getOverlappingBehavior: function() {                return this._options.overlappingBehavior            },            getOptions: function() {                return this._options            },            _getMajorTicks: function() {                var ticks;                if (this._customTicks) {                    ticks = this._customTicks.slice();                    this._tickInterval = ticks.length > 1 ? this._findTickIntervalForCustomTicks() : 0                }                else                    ticks = this._createTicks([], this._findTickInterval(), this._min, this._max);                return ticks            },            _applyMargin: function(margin, min, max, isNegative) {                var coef,                    value = min;                if (isFinite(margin)) {                    coef = this._getMarginValue(min, max, margin);                    if (coef)                        value = this._getNextTickValue(min, coef, isNegative, false)                }                return value            },            _applyMinMaxMargins: function(min, max) {                var options = this._options,                    newMin = min > max ? max : min,                    newMax = max > min ? max : min;                this._minCorrectionEnabled = this._getCorrectionEnabled(min, "min");                this._maxCorrectionEnabled = this._getCorrectionEnabled(max, "max");                if (options && !options.stick) {                    newMin = this._applyMargin(options.minValueMargin, min, max, true);                    newMax = this._applyMargin(options.maxValueMargin, max, min, false)                }                return {                        min: newMin,                        max: newMax                    }            },            _checkBoundedTickInArray: function(value, array) {                var arrayValues = _map(array || [], function(item) {                        return item.valueOf()                    }),                    minorTicksIndex = _inArray(value.valueOf(), arrayValues);                if (minorTicksIndex !== -1)                    array.splice(minorTicksIndex, 1)            },            _checkLabelFormat: function() {                var options = this._options;                if (this._dataType === "datetime" && !options.hasLabelFormat && this._ticks.length)                    options.labelOptions.format = DX.formatHelper.getDateFormatByTicks(this._ticks)            },            _generateBounds: function() {                var that = this,                    interval = that._getBoundInterval(),                    stick = that._options.stick,                    minStickValue = that._options.minStickValue,                    maxStickValue = that._options.maxStickValue,                    minBound = that._minCorrectionEnabled && !stick ? that._getNextTickValue(that._min, interval, true) : that._originalMin,                    maxBound = that._maxCorrectionEnabled && !stick ? that._getNextTickValue(that._max, interval) : that._originalMax;                that._minBound = minBound < minStickValue ? minStickValue : minBound;                that._maxBound = maxBound > maxStickValue ? maxStickValue : maxBound            },            _initOverlappingMethods: function(type) {                this._initMethods(coreTickManager.overlappingMethods[type || "linear"])            },            _addBoundedTicks: function() {                var that = this,                    tickValues = _map(that._ticks, function(tick) {                        return tick.valueOf()                    }),                    min = that._originalMin,                    max = that._originalMax,                    addMinMax = that._options.addMinMax || {};                that._boundaryTicks = [];                if (addMinMax.min && _inArray(min.valueOf(), tickValues) === -1) {                    that._ticks.splice(0, 0, min);                    that._boundaryTicks.push(min);                    that._checkBoundedTickInArray(min, that._minorTicks);                    that._checkBoundedTickInArray(min, that._decimatedTicks)                }                if (addMinMax.max && _inArray(max.valueOf(), tickValues) === -1) {                    that._ticks.push(max);                    that._boundaryTicks.push(max);                    that._checkBoundedTickInArray(max, that._minorTicks);                    that._checkBoundedTickInArray(max, that._decimatedTicks)                }            },            _getCorrectionEnabled: function(value, marginSelector) {                var options = this._options || {},                    hasPercentStick = options.percentStick && value === 1,                    hasValueMargin = options[marginSelector + "ValueMargin"];                return !hasPercentStick && !hasValueMargin            },            _validateAxisType: function(type) {                var defaultType = "continuous",                    allowedTypes = {                        continuous: true,                        discrete: true,                        logarithmic: true                    };                return allowedTypes[type] ? type : defaultType            },            _validateDataType: function(type) {                var allowedTypes = {                        numeric: true,                        datetime: true,                        string: true                    };                if (!allowedTypes[type])                    type = _isDefined(this._min) ? this._getDataType(this._min) : "numeric";                return type            },            _getDataType: function(value) {                return utils.isDate(value) ? 'datetime' : 'numeric'            },            _getMethods: function() {                var methods;                if (this._axisType === "continuous")                    methods = this._dataType === "datetime" ? coreTickManager.datetime : coreTickManager.continuous;                else                    methods = coreTickManager[this._axisType] || coreTickManager.continuous;                return methods            },            _resetMethods: function() {                var that = this,                    methods = that._getMethods();                _each(methods, function(name) {                    if (that[name])                        delete that[name]                })            },            _initMethods: function(methods) {                var that = this;                methods = methods || that._getMethods();                _each(methods, function(name, func) {                    that[name] = func                })            },            _getDeltaCoef: function(screenDelta, businessDelta, gridSpacingFactor) {                var count;                gridSpacingFactor = gridSpacingFactor || this._options.gridSpacingFactor;                screenDelta = screenDelta || this._screenDelta;                businessDelta = businessDelta || this._businessDelta;                count = screenDelta / gridSpacingFactor;                count = count <= 1 ? MIN_ARRANGEMENT_TICKS_COUNT : count;                return businessDelta / count            },            _adjustNumericTickValue: function(value, interval, min) {                return utils.isExponential(value) ? _adjustValue(value) : utils.applyPrecisionByMinDelta(min, interval, value)            },            _isTickIntervalCorrect: function(tickInterval, tickCountLimit, businessDelta) {                var date;                businessDelta = businessDelta || this._businessDelta;                if (!_isNumber(tickInterval)) {                    date = new Date;                    tickInterval = _addInterval(date, tickInterval) - date;                    if (!tickInterval)                        return false                }                if (_isNumber(tickInterval))                    if (tickInterval > 0 && businessDelta / tickInterval > tickCountLimit) {                        if (this._options.incidentOccured)                            this._options.incidentOccured('W2003')                    }                    else                        return true;                return false            },            _correctValue: function(valueTypeSelector, tickInterval, correctionMethod) {                var that = this,                    correctionEnabledSelector = "_" + valueTypeSelector + "CorrectionEnabled",                    spaceCorrectionSelector = valueTypeSelector + "SpaceCorrection",                    valueSelector = "_" + valueTypeSelector,                    minStickValue = that._options.minStickValue,                    maxStickValue = that._options.maxStickValue;                if (that[correctionEnabledSelector]) {                    if (that._options[spaceCorrectionSelector])                        that[valueSelector] = that._getNextTickValue(that[valueSelector], tickInterval, valueTypeSelector === "min");                    correctionMethod.call(this, tickInterval)                }                if (valueTypeSelector === "min")                    that[valueSelector] = that[valueSelector] < minStickValue ? minStickValue : that[valueSelector];                if (valueTypeSelector === "max")                    that[valueSelector] = that[valueSelector] > maxStickValue ? maxStickValue : that[valueSelector]            },            _findTickInterval: function() {                var that = this,                    options = that._options,                    tickInterval;                tickInterval = that._isTickIntervalValid(options.tickInterval) && that._isTickIntervalCorrect(options.tickInterval, TICKS_COUNT_LIMIT) ? options.tickInterval : that._getInterval();                if (that._isTickIntervalValid(tickInterval)) {                    that._correctValue("min", tickInterval, that._correctMin);                    that._correctValue("max", tickInterval, that._correctMax);                    that._updateBusinessDelta()                }                that._tickInterval = tickInterval;                return tickInterval            },            _findMinorTickInterval: function(firstTick, secondTick) {                var that = this,                    ticks = that._ticks,                    intervals = that._options.stick ? ticks.length - 1 : ticks.length;                if (intervals < 1)                    intervals = 1;                that._getMinorInterval(that._screenDelta / intervals, that._findBusinessDelta(firstTick, secondTick, false));                return that._minorTickInterval            },            _createMinorTicks: function(ticks, firstTick, secondTick) {                var that = this,                    tickInterval = that._findMinorTickInterval(firstTick, secondTick),                    isTickIntervalNegative = false,                    isTickIntervalWithPow = false,                    needCorrectTick = false,                    startTick = that._getNextTickValue(firstTick, tickInterval, isTickIntervalNegative, isTickIntervalWithPow, needCorrectTick);                if (that._isTickIntervalValid(tickInterval))                    ticks = that._createCountedTicks(ticks, tickInterval, startTick, secondTick, that._minorTickCount, isTickIntervalNegative, isTickIntervalWithPow, needCorrectTick);                return ticks            },            _getMinorTicks: function() {                var that = this,                    minorTicks = [],                    ticks = that._ticks,                    ticksLength = ticks.length,                    hasUnitBeginningTick = that._hasUnitBeginningTickCorrection(),                    i = hasUnitBeginningTick ? 1 : 0;                if (ticks.length) {                    minorTicks = that._getBoundedMinorTicks(minorTicks, that._minBound, ticks[0], true);                    if (hasUnitBeginningTick)                        minorTicks = that._getUnitBeginningMinorTicks(minorTicks);                    for (i; i < ticksLength - 1; i++)                        minorTicks = that._createMinorTicks(minorTicks, ticks[i], ticks[i + 1]);                    minorTicks = that._getBoundedMinorTicks(minorTicks, that._maxBound, ticks[ticksLength - 1])                }                else                    minorTicks = that._createMinorTicks(minorTicks, that._minBound, that._maxBound);                return minorTicks            },            _createCountedTicks: function(ticks, tickInterval, min, max, count, isTickIntervalWithPow, needMax) {                var value = min,                    i;                for (i = 0; i < count; i++) {                    if (!(needMax === false && value.valueOf() === max.valueOf()))                        ticks.push(value);                    value = this._getNextTickValue(value, tickInterval, false, isTickIntervalWithPow, false)                }                return ticks            },            _createTicks: function(ticks, tickInterval, min, max, isTickIntervalNegative, isTickIntervalWithPow, withCorrection) {                var that = this,                    value = min,                    newValue = min,                    leftBound,                    rightBound,                    boundedRule;                if (that._isTickIntervalValid(tickInterval)) {                    boundedRule = min - max < 0;                    do {                        value = newValue;                        if (that._options.stick) {                            if (value >= that._originalMin && value <= that._originalMax)                                ticks.push(value)                        }                        else                            ticks.push(value);                        newValue = that._getNextTickValue(value, tickInterval, isTickIntervalNegative, isTickIntervalWithPow, withCorrection);                        if (value.valueOf() === newValue.valueOf())                            break;                        leftBound = newValue - min >= 0;                        rightBound = max - newValue >= 0                    } while (boundedRule === leftBound && boundedRule === rightBound)                }                else                    ticks.push(value);                return ticks            },            _getBoundedMinorTicks: function(minorTicks, boundedTick, tick, isNegative) {                var that = this,                    needCorrectTick = false,                    nextTick = that._tickInterval ? this._getNextTickValue(tick, that._tickInterval, isNegative, true, needCorrectTick) : boundedTick,                    tickInterval = that._findMinorTickInterval(tick, nextTick),                    isTickIntervalCorrect = that._isTickIntervalCorrect(tickInterval, TICKS_COUNT_LIMIT, that._findBusinessDelta(tick, boundedTick, false)),                    startTick,                    endTick,                    boundedTickValue = boundedTick.valueOf();                if (isTickIntervalCorrect && that._isTickIntervalValid(tickInterval) && that._minorTickCount > 0) {                    if (isNegative) {                        if (tick.valueOf() <= boundedTickValue)                            return minorTicks;                        while (nextTick.valueOf() < boundedTickValue)                            nextTick = this._getNextTickValue(nextTick, tickInterval, false, false, needCorrectTick);                        startTick = nextTick;                        endTick = that._getNextTickValue(tick, tickInterval, true, false, false)                    }                    else {                        startTick = that._getNextTickValue(tick, tickInterval, false, false, false);                        endTick = boundedTick                    }                    minorTicks = that._createTicks(minorTicks, tickInterval, startTick, endTick, false, false, needCorrectTick)                }                return minorTicks            },            getTypes: function() {                return {                        axisType: this._axisType,                        dataType: this._dataType                    }            },            getData: function() {                return {                        min: this._min,                        max: this._max,                        customTicks: this._customTicks,                        customMinorTicks: this._customMinorTicks,                        screenDelta: this._screenDelta                    }            }        })    })(jQuery, DevExpress);    /*! Module viz-core, file numericTranslator.js */    (function($, DX, undefined) {        var utils = DX.utils,            isDefined = utils.isDefined,            round = Math.round;        DX.viz.core.numericTranslatorFunctions = {            translate: function(bp) {                var that = this,                    canvasOptions = that._canvasOptions,                    doubleError = canvasOptions.rangeDoubleError,                    specialValue = that.translateSpecialCase(bp);                if (isDefined(specialValue))                    return specialValue;                if (isNaN(bp) || bp.valueOf() + doubleError < canvasOptions.rangeMin || bp.valueOf() - doubleError > canvasOptions.rangeMax)                    return null;                return that._conversionValue(that._calculateProjection((bp - canvasOptions.rangeMinVisible) * canvasOptions.ratioOfCanvasRange))            },            untranslate: function(pos, _directionOffset, enableOutOfCanvas) {                var canvasOptions = this._canvasOptions,                    startPoint = canvasOptions.startPoint;                if (!enableOutOfCanvas && (pos < startPoint || pos > canvasOptions.endPoint) || !isDefined(canvasOptions.rangeMin) || !isDefined(canvasOptions.rangeMax))                    return null;                return this._calculateUnProjection((pos - startPoint) / canvasOptions.ratioOfCanvasRange)            },            getInterval: function() {                return round(this._canvasOptions.ratioOfCanvasRange * (this._businessRange.interval || Math.abs(this._canvasOptions.rangeMax - this._canvasOptions.rangeMin)))            },            _getValue: function(val) {                return val            },            zoom: function(translate, scale) {                var that = this,                    canvasOptions = that._canvasOptions,                    startPoint = canvasOptions.startPoint,                    endPoint = canvasOptions.endPoint,                    newStart = (startPoint + translate) / scale,                    newEnd = (endPoint + translate) / scale,                    minPoint = Math.min(that.translate(that._getValue(canvasOptions.rangeMin)), that.translate(that._getValue(canvasOptions.rangeMax))),                    maxPoint = Math.max(that.translate(that._getValue(canvasOptions.rangeMin)), that.translate(that._getValue(canvasOptions.rangeMax)));                if (minPoint > newStart) {                    newEnd -= newStart - minPoint;                    newStart = minPoint                }                if (maxPoint < newEnd) {                    newStart -= newEnd - maxPoint;                    newEnd = maxPoint                }                if (maxPoint - minPoint < newEnd - newStart) {                    newStart = minPoint;                    newEnd = maxPoint                }                translate = (endPoint - startPoint) * newStart / (newEnd - newStart) - startPoint;                scale = (startPoint + translate) / newStart || 1;                return {                        min: that.untranslate(newStart, undefined, true),                        max: that.untranslate(newEnd, undefined, true),                        translate: translate,                        scale: scale                    }            },            getMinScale: function(zoom) {                return zoom ? 1.1 : 0.9            },            getScale: function(val1, val2) {                var canvasOptions = this._canvasOptions;                val1 = isDefined(val1) ? val1 : canvasOptions.rangeMin;                val2 = isDefined(val2) ? val2 : canvasOptions.rangeMax;                return (canvasOptions.rangeMax - canvasOptions.rangeMin) / Math.abs(val1 - val2)            }        }    })(jQuery, DevExpress);    /*! Module viz-core, file datetimeTranslator.js */    (function($, DX, undefined) {        var core = DX.viz.core,            numericTranslator = core.numericTranslatorFunctions;        core.datetimeTranslatorFunctions = {            translate: numericTranslator.translate,            untranslate: function() {                var result = numericTranslator.untranslate.apply(this, arguments);                return result === null ? result : new Date(result)            },            _getValue: numericTranslator._getValue,            getInterval: numericTranslator.getInterval,            zoom: numericTranslator.zoom,            getMinScale: numericTranslator.getMinScale,            getScale: numericTranslator.getScale        }    })(jQuery, DevExpress);    /*! Module viz-core, file categoryTranslator.js */    (function($, DX, undefined) {        var isDefined = DX.utils.isDefined,            round = Math.round;        DX.viz.core.categoryTranslatorFunctions = {            translate: function(category, directionOffset) {                var that = this,                    canvasOptions = that._canvasOptions,                    categoryRecord = that._categoriesToPoints[category],                    stickDelta,                    specialValue = that.translateSpecialCase(category),                    startPointIndex = canvasOptions.startPointIndex || 0,                    stickInterval = that._businessRange.stick ? 0 : 0.5;                if (isDefined(specialValue))                    return specialValue;                if (!categoryRecord)                    return null;                directionOffset = directionOffset || 0;                directionOffset = canvasOptions.invert ? -directionOffset : directionOffset;                stickDelta = categoryRecord.index + stickInterval - startPointIndex + directionOffset * 0.5;                return round(canvasOptions.startPoint + canvasOptions.interval * stickDelta)            },            untranslate: function(pos, directionOffset, enableOutOfCanvas) {                var that = this,                    canvasOptions = that._canvasOptions,                    startPoint = canvasOptions.startPoint,                    categories = that.visibleCategories || that._categories,                    categoriesLength = categories.length,                    result = 0,                    stickInterval = that._businessRange.stick ? 0.5 : 0;                if (!enableOutOfCanvas && (pos < startPoint || pos > canvasOptions.endPoint))                    return null;                directionOffset = directionOffset || 0;                result = round((pos - startPoint) / canvasOptions.interval + stickInterval - 0.5 - directionOffset * 0.5);                if (categoriesLength === result)                    result--;                if (result === -1)                    result = 0;                if (canvasOptions.invert)                    result = categoriesLength - result - 1;                return categories[result]            },            getInterval: function() {                return this._canvasOptions.interval            },            zoom: function(translate, scale) {                var that = this,                    canvasOptions = that._canvasOptions,                    interval = canvasOptions.interval * scale,                    translateCaltegories = translate / interval,                    stick = that._businessRange.stick,                    startCategoryIndex = parseInt((canvasOptions.startPointIndex || 0) + translateCaltegories + 0.5),                    categoriesLength = parseInt(canvasOptions.canvasLength / interval + (stick ? 1 : 0)) || 1,                    endCategoryIndex,                    newVisibleCategories,                    categories = that._categories,                    newInterval;                canvasOptions.invert && (categories = categories.slice().reverse());                if (startCategoryIndex < 0)                    startCategoryIndex = 0;                endCategoryIndex = startCategoryIndex + categoriesLength;                if (endCategoryIndex > categories.length) {                    endCategoryIndex = categories.length;                    startCategoryIndex = endCategoryIndex - categoriesLength;                    if (startCategoryIndex < 0)                        startCategoryIndex = 0                }                newVisibleCategories = categories.slice(parseInt(startCategoryIndex), parseInt(endCategoryIndex));                newInterval = that._getDiscreteInterval(newVisibleCategories.length, canvasOptions);                scale = newInterval / canvasOptions.interval;                translate = that.translate(newVisibleCategories[0]) * scale - (canvasOptions.startPoint + (stick ? 0 : newInterval / 2));                return {                        min: !canvasOptions.invert ? newVisibleCategories[0] : newVisibleCategories[newVisibleCategories.length - 1],                        max: !canvasOptions.invert ? newVisibleCategories[newVisibleCategories.length - 1] : newVisibleCategories[0],                        translate: translate,                        scale: scale                    }            },            getMinScale: function(zoom) {                var that = this,                    canvasOptions = that._canvasOptions,                    categoriesLength = (that.visibleCategories || that._categories).length;                categoriesLength += (parseInt(categoriesLength * 0.1) || 1) * (zoom ? -2 : 2);                return canvasOptions.canvasLength / (Math.max(categoriesLength, 1) * canvasOptions.interval)            },            getScale: function(min, max) {                var that = this,                    canvasOptions = that._canvasOptions,                    visibleArea = that.getCanvasVisibleArea(),                    stickOffset = !that._businessRange.stick && 1,                    minPoint = that.translate(min, -stickOffset),                    maxPoint = that.translate(max, +stickOffset);                if (!isDefined(minPoint))                    minPoint = canvasOptions.invert ? visibleArea.max : visibleArea.min;                if (!isDefined(maxPoint))                    maxPoint = canvasOptions.invert ? visibleArea.min : visibleArea.max;                return that.canvasLength / Math.abs(maxPoint - minPoint)            }        }    })(jQuery, DevExpress);    /*! Module viz-core, file logarithmicTranslator.js */    (function($, DX, undefined) {        var core = DX.viz.core,            numericTranslator = core.numericTranslatorFunctions,            utils = DX.utils,            raiseTo = utils.raiseTo,            getLog = utils.getLog;        core.logarithmicTranslatorFunctions = {            translate: function(bp) {                var that = this,                    specialValue = that.translateSpecialCase(bp);                if (utils.isDefined(specialValue))                    return specialValue;                return numericTranslator.translate.call(that, getLog(bp, that._businessRange.base))            },            untranslate: function() {                var result = numericTranslator.untranslate.apply(this, arguments);                return result === null ? result : raiseTo(result, this._businessRange.base)            },            getInterval: numericTranslator.getInterval,            _getValue: function(value) {                return Math.pow(this._canvasOptions.base, value)            },            zoom: numericTranslator.zoom,            getMinScale: numericTranslator.getMinScale,            getScale: function(val1, val2) {                var base = this._businessRange.base;                val1 = utils.isDefined(val1) ? getLog(val1, base) : undefined;                val2 = utils.isDefined(val2) ? getLog(val2, base) : undefined;                return numericTranslator.getScale.call(this, val1, val2)            }        }    })(jQuery, DevExpress);    /*! Module viz-core, file translator1D.js */    (function(DX, undefined) {        var _Number = Number;        function Translator1D() {            this.setDomain(arguments[0], arguments[1]).setCodomain(arguments[2], arguments[3])        }        Translator1D.prototype = {            constructor: Translator1D,            setDomain: function(domain1, domain2) {                var that = this;                that._domain1 = _Number(domain1);                that._domain2 = _Number(domain2);                that._domainDelta = that._domain2 - that._domain1;                return that            },            setCodomain: function(codomain1, codomain2) {                var that = this;                that._codomain1 = _Number(codomain1);                that._codomain2 = _Number(codomain2);                that._codomainDelta = that._codomain2 - that._codomain1;                return that            },            getDomain: function() {                return [this._domain1, this._domain2]            },            getCodomain: function() {                return [this._codomain1, this._codomain2]            },            getDomainStart: function() {                return this._domain1            },            getDomainEnd: function() {                return this._domain2            },            getCodomainStart: function() {                return this._codomain1            },            getCodomainEnd: function() {                return this._codomain2            },            getDomainRange: function() {                return this._domainDelta            },            getCodomainRange: function() {                return this._codomainDelta            },            translate: function(value) {                var ratio = (_Number(value) - this._domain1) / this._domainDelta;                return 0 <= ratio && ratio <= 1 ? this._codomain1 + ratio * this._codomainDelta : NaN            },            adjust: function(value) {                var ratio = (_Number(value) - this._domain1) / this._domainDelta,                    result = NaN;                if (ratio < 0)                    result = this._domain1;                else if (ratio > 1)                    result = this._domain2;                else if (0 <= ratio && ratio <= 1)                    result = _Number(value);                return result            }        };        DX.viz.core.Translator1D = Translator1D    })(DevExpress);    /*! Module viz-core, file translator2D.js */    (function($, DX, undefined) {        var core = DX.viz.core,            utils = DX.utils,            getLog = utils.getLog,            getPower = utils.getPower,            isDefined = utils.isDefined,            _abs = Math.abs,            CANVAS_PROP = ["width", "height", "left", "top", "bottom", "right"],            NUMBER_EQUALITY_CORRECTION = 1,            DATETIME_EQUALITY_CORRECTION = 60000,            _noop = $.noop,            _Translator2d;        var validateCanvas = function(canvas) {                $.each(CANVAS_PROP, function(_, prop) {                    canvas[prop] = parseInt(canvas[prop]) || 0                });                return canvas            };        var makeCategoriesToPoints = function(categories, invert) {                var categoriesToPoints = {},                    category,                    length = categories.length,                    i;                for (i = 0; i < length; i++) {                    category = categories[i];                    categoriesToPoints[category] = {                        name: category,                        index: invert ? length - 1 - i : i                    }                }                return categoriesToPoints            };        var validateBusinessRange = function(businessRange) {                function validate(valueSelector, baseValueSeletor) {                    if (!isDefined(businessRange[valueSelector]) && isDefined(businessRange[baseValueSeletor]))                        businessRange[valueSelector] = businessRange[baseValueSeletor]                }                validate("minVisible", "min");                validate("maxVisible", "max");                return businessRange            };        _Translator2d = core.Translator2D = function(businessRange, canvas, options) {            this.update(businessRange, canvas, options)        };        _Translator2d.prototype = {            constructor: _Translator2d,            reinit: function() {                var that = this,                    range = that._businessRange,                    categories = range.categories || [],                    script = {},                    canvasOptions = that._prepareCanvasOptions(),                    visibleCategories = utils.getCategoriesInfo(categories, range.minVisible, range.maxVisible).categories,                    categoriesLength = (visibleCategories || categories).length;                switch (range.axisType) {                    case"logarithmic":                        script = core.logarithmicTranslatorFunctions;                        break;                    case"discrete":                        script = core.categoryTranslatorFunctions;                        that._categories = categories;                        canvasOptions.interval = that._getDiscreteInterval(range.addSpiderCategory ? categoriesLength + 1 : categoriesLength, canvasOptions);                        that._categoriesToPoints = makeCategoriesToPoints(categories, canvasOptions.invert);                        if (visibleCategories && visibleCategories.length) {                            canvasOptions.startPointIndex = that._categoriesToPoints[visibleCategories[canvasOptions.invert ? visibleCategories.length - 1 : 0]].index;                            that.visibleCategories = visibleCategories                        }                        break;                    default:                        if (range.dataType === "datetime")                            script = core.datetimeTranslatorFunctions;                        else                            script = core.numericTranslatorFunctions                }                that.translate = script.translate;                that.untranslate = script.untranslate;                that.getInterval = script.getInterval;                that.zoom = script.zoom;                that.getMinScale = script.getMinScale;                that._getValue = script._getValue;                that.getScale = script.getScale;                that._conversionValue = that._options.conversionValue ? function(value) {                    return value                } : function(value) {                    return Math.round(value)                }            },            _getDiscreteInterval: function(categoriesLength, canvasOptions) {                var correctedCategoriesCount = categoriesLength - (this._businessRange.stick ? 1 : 0);                return correctedCategoriesCount > 0 ? canvasOptions.canvasLength / correctedCategoriesCount : canvasOptions.canvasLength            },            _getCanvasBounds: function(range) {                var min = range.min,                    max = range.max,                    minVisible = range.minVisible,                    maxVisible = range.maxVisible,                    newMin,                    newMax,                    base = range.base,                    isDateTime = utils.isDate(max) || utils.isDate(min),                    correction = isDateTime ? DATETIME_EQUALITY_CORRECTION : NUMBER_EQUALITY_CORRECTION;                if (range.axisType === 'logarithmic') {                    maxVisible = getLog(maxVisible, base);                    minVisible = getLog(minVisible, base);                    min = getLog(min, base);                    max = getLog(max, base)                }                if (isDefined(min) && isDefined(max) && min.valueOf() === max.valueOf()) {                    newMin = min.valueOf() - correction;                    newMax = max.valueOf() + correction;                    if (isDateTime) {                        min = new Date(newMin);                        max = new Date(newMax)                    }                    else {                        min = min !== 0 ? newMin : 0;                        max = newMax                    }                }                if (isDefined(minVisible) && isDefined(maxVisible) && minVisible.valueOf() === maxVisible.valueOf()) {                    newMin = minVisible.valueOf() - correction;                    newMax = maxVisible.valueOf() + correction;                    if (isDateTime) {                        minVisible = newMin < min.valueOf() ? min : new Date(newMin);                        maxVisible = newMax > max.valueOf() ? max : new Date(newMax)                    }                    else {                        if (minVisible !== 0)                            minVisible = newMin < min ? min : newMin;                        maxVisible = newMax > max ? max : newMax                    }                }                return {                        base: base,                        rangeMin: min,                        rangeMax: max,                        rangeMinVisible: minVisible,                        rangeMaxVisible: maxVisible                    }            },            _prepareCanvasOptions: function() {                var that = this,                    businessRange = that._businessRange,                    canvasOptions = that._canvasOptions = that._getCanvasBounds(businessRange),                    length,                    canvas = that._canvas;                if (that._options.direction === "horizontal") {                    canvasOptions.startPoint = canvas.left;                    length = canvas.width;                    canvasOptions.endPoint = canvas.width - canvas.right;                    canvasOptions.invert = businessRange.invert                }                else {                    canvasOptions.startPoint = canvas.top;                    length = canvas.height;                    canvasOptions.endPoint = canvas.height - canvas.bottom;                    canvasOptions.invert = !businessRange.invert                }                that.canvasLength = canvasOptions.canvasLength = canvasOptions.endPoint - canvasOptions.startPoint;                canvasOptions.rangeDoubleError = Math.pow(10, getPower(canvasOptions.rangeMax - canvasOptions.rangeMin) - getPower(length) - 2);                canvasOptions.ratioOfCanvasRange = canvasOptions.canvasLength / (canvasOptions.rangeMaxVisible - canvasOptions.rangeMinVisible);                return canvasOptions            },            updateBusinessRange: function(businessRange) {                this._businessRange = validateBusinessRange(businessRange);                this.reinit()            },            update: function(businessRange, canvas, options) {                var that = this;                that._options = $.extend(that._options || {}, options);                that._canvas = validateCanvas(canvas);                that.updateBusinessRange(businessRange)            },            getBusinessRange: function() {                return this._businessRange            },            getCanvasVisibleArea: function() {                return {                        min: this._canvasOptions.startPoint,                        max: this._canvasOptions.endPoint                    }            },            translateSpecialCase: function(value) {                var that = this,                    canvasOptions = that._canvasOptions,                    startPoint = canvasOptions.startPoint,                    endPoint = canvasOptions.endPoint,                    range = that._businessRange,                    minVisible = range.minVisible,                    maxVisible = range.maxVisible,                    invert,                    result = null;                switch (value) {                    case"canvas_position_default":                        if (minVisible <= 0 && maxVisible >= 0)                            result = that.translate(0);                        else {                            invert = range.invert ^ (minVisible <= 0 && maxVisible <= 0);                            if (that._options.direction === "horizontal")                                result = invert ? endPoint : startPoint;                            else                                result = invert ? startPoint : endPoint                        }                        break;                    case"canvas_position_left":                    case"canvas_position_top":                        result = startPoint;                        break;                    case"canvas_position_center":                    case"canvas_position_middle":                        result = startPoint + canvasOptions.canvasLength / 2;                        break;                    case"canvas_position_right":                    case"canvas_position_bottom":                        result = endPoint;                        break;                    case"canvas_position_start":                        result = canvasOptions.invert ? endPoint : startPoint;                        break;                    case"canvas_position_end":                        result = canvasOptions.invert ? startPoint : endPoint;                        break                }                return result            },            _calculateProjection: function(distance) {                var canvasOptions = this._canvasOptions;                return canvasOptions.invert ? canvasOptions.endPoint - distance : canvasOptions.startPoint + distance            },            _calculateUnProjection: function(distance) {                var canvasOptions = this._canvasOptions;                return canvasOptions.invert ? canvasOptions.rangeMaxVisible.valueOf() - distance : canvasOptions.rangeMinVisible.valueOf() + distance            },            getVisibleCategories: function() {                return this.visibleCategories            },            getMinBarSize: function(minBarSize) {                var visibleArea = this.getCanvasVisibleArea(),                    minValue = this.untranslate(visibleArea.min + minBarSize);                return _abs(this.untranslate(visibleArea.min) - (!isDefined(minValue) ? this.untranslate(visibleArea.max) : minValue))            },            translate: _noop,            untranslate: _noop,            getInterval: _noop,            zoom: _noop,            getMinScale: _noop        }    })(jQuery, DevExpress);    /*! Module viz-core, file polarTranslator.js */    (function($, DX, undefined) {        var utils = DX.utils,            SHIFT_ANGLE = 90,            _round = Math.round;        function PolarTranslator(businessRange, canvas, options) {            var that = this;            that._argCanvas = {                left: 0,                right: 0,                width: this._getAngle()            };            that._valCanvas = {                left: 0,                right: 0            };            that.canvas = canvas;            that._init();            that._arg = new DX.viz.core.Translator2D(businessRange.arg, that._argCanvas, {                direction: "horizontal",                conversionValue: true            });            that._val = new DX.viz.core.Translator2D(businessRange.val, that._valCanvas, {direction: "horizontal"});            that._businessRange = businessRange;            that.startAngle = utils.isNumber(options.startAngle) ? options.startAngle : 0        }        PolarTranslator.prototype = {            constructor: PolarTranslator,            _init: function() {                var canvas = this.canvas;                this._setCoords({                    x: canvas.left + (canvas.width - canvas.right - canvas.left) / 2,                    y: canvas.top + (canvas.height - canvas.top - canvas.bottom) / 2,                    r: Math.min(canvas.width - canvas.left - canvas.right, canvas.height - canvas.top - canvas.bottom) / 2                });                this._valCanvas.width = this._rad            },            reinit: function() {                this._init();                this._arg.reinit();                this._val.reinit()            },            _setCoords: function(coord) {                this._x0 = coord.x;                this._y0 = coord.y;                this._rad = coord.r < 0 ? 0 : coord.r            },            getBusinessRange: function() {                return this._businessRange            },            translate: function(arg, val, offsets) {                var that = this,                    argTranslate = that._arg.translate(arg, offsets && offsets[0]),                    radius = that._val.translate(val, offsets && offsets[1]),                    angle = utils.isDefined(argTranslate) ? argTranslate + that.startAngle - SHIFT_ANGLE : null,                    cossin = utils.getCosAndSin(angle),                    x,                    y;                y = _round(that._y0 + radius * cossin.sin);                x = _round(that._x0 + radius * cossin.cos);                return {                        x: x,                        y: y,                        angle: angle,                        radius: radius                    }            },            getValLength: function() {                return this._rad            },            getCenter: function() {                return {                        x: this._x0,                        y: this._y0                    }            },            getBaseAngle: function() {                return this.startAngle - SHIFT_ANGLE            },            getInterval: function() {                return this._arg.getInterval()            },            getValInterval: function() {                return this._val.getInterval()            },            _getAngle: function() {                return 360            },            getStartAngle: function() {                return this.startAngle            },            getComponent: function(type) {                var that = this,                    translator = this["_" + type];                translator.getRadius = function() {                    return that.getValLength()                };                translator.getCenter = function() {                    return that.getCenter()                };                translator.getStartAngle = function() {                    return that.getStartAngle()                };                return translator            },            _untranslate: function(x, y) {                var radius = utils.getDistance(this._x0, this._y0, x, y),                    angle = Math.atan2(y - this._y0, x - this._x0);                return {                        r: radius,                        phi: angle                    }            },            untranslate: function(x, y) {                var pos = this._untranslate(x, y);                pos.phi = _round(utils.normalizeAngle(pos.phi * 180 / Math.PI));                pos.r = _round(pos.r);                return pos            },            getVisibleCategories: $.noop,            getCanvasVisibleArea: function() {                return {}            },            getMinBarSize: function(minBarSize) {                return this._val.getMinBarSize(minBarSize)            }        };        DX.viz.core.PolarTranslator = PolarTranslator    })(jQuery, DevExpress);    /*! Module viz-core, file rectangle.js */    (function(DX, undefined) {        var isFinite = window.isFinite;        DX.viz.core.Rectangle = DX.Class.inherit({            ctor: function(options) {                var that = this;                options = options || {};                that.left = Number(options.left) || 0;                that.right = Number(options.right) || 0;                that.top = Number(options.top) || 0;                that.bottom = Number(options.bottom) || 0            },            width: function() {                return this.right - this.left            },            height: function() {                return this.bottom - this.top            },            horizontalMiddle: function() {                return (this.left + this.right) / 2            },            verticalMiddle: function() {                return (this.top + this.bottom) / 2            },            raw: function() {                var that = this;                return {                        left: that.left,                        top: that.top,                        right: that.right,                        bottom: that.bottom                    }            },            clone: function() {                return new this.constructor(this.raw())            },            move: function(dx, dy) {                var result = this.clone();                if (isFinite(dx) && isFinite(dy)) {                    result.left += Number(dx);                    result.right += Number(dx);                    result.top += Number(dy);                    result.bottom += Number(dy)                }                return result            },            inflate: function(dx, dy) {                var result = this.clone();                if (isFinite(dx) && isFinite(dy)) {                    result.left -= Number(dx);                    result.right += Number(dx);                    result.top -= Number(dy);                    result.bottom += Number(dy)                }                return result            },            scale: function(factor) {                var that = this;                if (factor > 0)                    return that.inflate(that.width() * (factor - 1) / 2, that.height() * (factor - 1) / 2);                return that.clone()            }        })    })(DevExpress);    /*! Module viz-core, file layoutElement.js */    (function($, DX, undefined) {        var core = DX.viz.core,            _round = Math.round;        var _splitPair = DX.utils.splitPair;        var defaultPosition = ["center", "center"],            defaultOffset = [0, 0];        var getAlignFactor = function(align) {                switch (align) {                    case"center":                        return 0.5;                    case"right":                    case"bottom":                        return 1;                    default:                        return 0                }            };        function WrapperLayoutElement(renderElement, bbox) {            this._renderElement = renderElement;            this._cacheBBox = bbox        }        WrapperLayoutElement.prototype = {            position: function(options) {                var that = this,                    ofBBox = options.of.getBBox ? options.of.getBBox() : options.of,                    myBBox = this.getBBox(),                    at = _splitPair(options.at) || defaultPosition,                    my = _splitPair(options.my) || defaultPosition,                    offset = _splitPair(options.offset) || defaultOffset,                    shiftX = -getAlignFactor(my[0]) * myBBox.width + ofBBox.x - myBBox.x + getAlignFactor(at[0]) * ofBBox.width + parseInt(offset[0]),                    shiftY = -getAlignFactor(my[1]) * myBBox.height + ofBBox.y - myBBox.y + getAlignFactor(at[1]) * ofBBox.height + parseInt(offset[1]);                that._renderElement.move(_round(shiftX), _round(shiftY))            },            getBBox: function() {                return this._cacheBBox || this._renderElement.getBBox()            },            draw: function(){}        };        core.WrapperLayoutElement = WrapperLayoutElement    })(jQuery, DevExpress);    /*! Module viz-core, file themes.js */    (function(DX, $, undefined) {        var themes = {},            themesMapping = {},            themesSchemeMapping = {},            _extend = $.extend,            _each = $.each,            currentThemeName = null,            nextCacheUid = 0,            widgetsCache = {};        function normalizeName(name) {            return name ? String(name).toLowerCase() : null        }        function findTheme(themeName) {            var name = normalizeName(themeName);            return themes[name] || themes[themesMapping[name] || currentThemeName]        }        function findThemeNameByName(name, scheme) {            return themesMapping[name + '.' + scheme] || themesSchemeMapping[name + '.' + scheme] || themesMapping[name]        }        function findThemeNameByPlatform(platform, version, scheme) {            return findThemeNameByName(platform + version, scheme) || findThemeNameByName(platform, scheme)        }        function currentTheme(themeName, colorScheme) {            if (!arguments.length)                return currentThemeName;            var scheme = normalizeName(colorScheme);            currentThemeName = (themeName && themeName.platform ? findThemeNameByPlatform(normalizeName(themeName.platform), themeName.version, scheme) : findThemeNameByName(normalizeName(themeName), scheme)) || currentThemeName;            return this        }        function getThemeInfo(themeName, splitter) {            var k = themeName.indexOf(splitter);            return k > 0 ? {                    name: themeName.substring(0, k),                    scheme: themeName.substring(k + 1)                } : null        }        function registerThemeName(themeName, targetThemeName) {            var themeInfo = getThemeInfo(themeName, '.') || getThemeInfo(themeName, '-') || {name: themeName},                name = themeInfo.name,                scheme = themeInfo.scheme;            if (scheme) {                themesMapping[name] = themesMapping[name] || targetThemeName;                themesMapping[name + '.' + scheme] = themesMapping[name + '-' + scheme] = targetThemeName            }            else                themesMapping[name] = targetThemeName        }        function registerTheme(theme, baseThemeName) {            var themeName = normalizeName(theme && theme.name);            if (themeName) {                registerThemeName(themeName, themeName);                themes[themeName] = _extend(true, {}, findTheme(baseThemeName), patchTheme(theme))            }        }        function registerThemeAlias(alias, theme) {            registerThemeName(normalizeName(alias), normalizeName(theme))        }        function registerThemeSchemeAlias(from, to) {            themesSchemeMapping[from] = to        }        function mergeScalar(target, field, source, sourceValue) {            var _value = source ? source[field] : sourceValue;            if (_value !== undefined && target[field] === undefined)                target[field] = _value        }        function mergeObject(target, field, source, sourceValue) {            var _value = source ? source[field] : sourceValue;            if (_value !== undefined)                target[field] = _extend(true, {}, _value, target[field])        }        function patchTheme(theme) {            theme = _extend(true, {                loadingIndicator: {font: {}},                legend: {                    font: {},                    border: {}                },                title: {font: {}},                tooltip: {font: {}},                "chart:common": {},                "chart:common:axis": {                    grid: {},                    minorGrid: {},                    tick: {},                    minorTick: {},                    title: {font: {}},                    label: {font: {}}                },                chart: {commonSeriesSettings: {candlestick: {}}},                pie: {},                polar: {},                gauge: {scale: {                        majorTick: {},                        minorTick: {},                        label: {font: {}}                    }},                barGauge: {},                map: {background: {}},                rangeSelector: {                    scale: {label: {font: {}}},                    chart: {}                },                sparkline: {},                bullet: {}            }, theme);            mergeScalar(theme.loadingIndicator, "backgroundColor", theme);            mergeScalar(theme.chart.commonSeriesSettings.candlestick, "innerColor", null, theme.backgroundColor);            mergeScalar(theme.map.background, "color", null, theme.backgroundColor);            mergeScalar(theme.title.font, "color", null, theme.primaryTitleColor);            mergeScalar(theme.legend.font, "color", null, theme.secondaryTitleColor);            mergeScalar(theme.legend.border, "color", null, theme.axisColor);            patchAxes(theme);            _each(["chart", "pie", "polar", "gauge", "barGauge", "map", "rangeSelector", "sparkline", "bullet"], function(_, section) {                mergeScalar(theme[section], "redrawOnResize", theme);                mergeScalar(theme[section], "containerBackgroundColor", null, theme.backgroundColor);                mergeObject(theme[section], "tooltip", theme)            });            _each(["chart", "pie", "polar", "gauge", "barGauge", "map", "rangeSelector"], function(_, section) {                mergeObject(theme[section], "loadingIndicator", theme);                mergeObject(theme[section], "legend", theme)            });            _each(["chart", "pie", "polar", "gauge", "barGauge"], function(_, section) {                mergeObject(theme[section], "title", theme)            });            _each(["gauge", "barGauge"], function(_, section) {                mergeObject(theme[section], "subtitle", null, theme.title)            });            _each(["chart", "pie", "polar"], function(_, section) {                mergeObject(theme, section, null, theme["chart:common"])            });            _each(["chart", "polar"], function(_, section) {                theme[section] = theme[section] || {};                mergeObject(theme[section], "commonAxisSettings", null, theme["chart:common:axis"])            });            mergeObject(theme.rangeSelector.chart, "commonSeriesSettings", theme.chart);            mergeObject(theme.rangeSelector.chart, "dataPrepareSettings", theme.chart);            mergeScalar(theme.map.legend, "backgroundColor", theme);            return theme        }        function patchAxes(theme) {            var commonAxisSettings = theme["chart:common:axis"],                colorFieldName = "color";            _each([commonAxisSettings, commonAxisSettings.grid, commonAxisSettings.minorGrid, commonAxisSettings.tick, commonAxisSettings.minorTick], function(_, obj) {                mergeScalar(obj, colorFieldName, null, theme.axisColor)            });            mergeScalar(commonAxisSettings.title.font, colorFieldName, null, theme.secondaryTitleColor);            mergeScalar(commonAxisSettings.label.font, colorFieldName, null, theme.axisLabelColor);            mergeScalar(theme.gauge.scale.label.font, colorFieldName, null, theme.axisLabelColor);            mergeScalar(theme.gauge.scale.majorTick, colorFieldName, null, theme.backgroundColor);            mergeScalar(theme.gauge.scale.minorTick, colorFieldName, null, theme.backgroundColor);            mergeScalar(theme.rangeSelector.scale.label.font, colorFieldName, null, theme.axisLabelColor)        }        function addCacheItem(target) {            var cacheUid = ++nextCacheUid;            target._cache = cacheUid;            widgetsCache[cacheUid] = target        }        function removeCacheItem(target) {            delete widgetsCache[target._cache]        }        function refreshAll() {            _each(widgetsCache, function() {                this.refresh()            });            return this        }        _extend(DX.viz.core, {            findTheme: findTheme,            currentTheme: currentTheme,            registerTheme: registerTheme,            registerThemeAlias: registerThemeAlias,            registerThemeSchemeAlias: registerThemeSchemeAlias,            refreshAll: refreshAll,            addCacheItem: addCacheItem,            removeCacheItem: removeCacheItem        });        _extend(DX.viz.core, {            themes: themes,            themesMapping: themesMapping,            themesSchemeMapping: themesSchemeMapping,            widgetsCache: widgetsCache        })    })(DevExpress, jQuery);    /*! Module viz-core, file palette.js */    (function(DX, $, undefined) {        var _String = window.String,            _floor = Math.floor,            _ceil = Math.ceil,            _Color = DX.Color,            _isArray = DX.utils.isArray,            _isString = DX.utils.isString,            _extend = $.extend;        var palettes = {                'default': {                    simpleSet: ['#5f8b95', '#ba4d51', '#af8a53', '#955f71', '#859666', '#7e688c'],                    indicatingSet: ['#a3b97c', '#e1b676', '#ec7f83'],                    gradientSet: ['#5f8b95', '#ba4d51']                },                'harmony light': {                    simpleSet: ['#fcb65e', '#679ec5', '#ad79ce', '#7abd5c', '#e18e92', '#b6d623', '#b7abea', '#85dbd5'],                    indicatingSet: ['#b6d623', '#fcb65e', '#e18e92'],                    gradientSet: ['#7abd5c', '#fcb65e']                },                'soft pastel': {                    simpleSet: ['#60a69f', '#78b6d9', '#6682bb', '#a37182', '#eeba69', '#90ba58', '#456c68', '#7565a4'],                    indicatingSet: ['#90ba58', '#eeba69', '#a37182'],                    gradientSet: ['#78b6d9', '#eeba69']                },                pastel: {                    simpleSet: ['#bb7862', '#70b3a1', '#bb626a', '#057d85', '#ab394b', '#dac599', '#153459', '#b1d2c6'],                    indicatingSet: ['#70b3a1', '#dac599', '#bb626a'],                    gradientSet: ['#bb7862', '#70b3a1']                },                bright: {                    simpleSet: ['#70c92f', '#f8ca00', '#bd1550', '#e97f02', '#9d419c', '#7e4452', '#9ab57e', '#36a3a6'],                    indicatingSet: ['#70c92f', '#f8ca00', '#bd1550'],                    gradientSet: ['#e97f02', '#f8ca00']                },                soft: {                    simpleSet: ['#cbc87b', '#9ab57e', '#e55253', '#7e4452', '#e8c267', '#565077', '#6babac', '#ad6082'],                    indicatingSet: ['#9ab57e', '#e8c267', '#e55253'],                    gradientSet: ['#9ab57e', '#e8c267']                },                ocean: {                    simpleSet: ['#75c099', '#acc371', '#378a8a', '#5fa26a', '#064970', '#38c5d2', '#00a7c6', '#6f84bb'],                    indicatingSet: ['#c8e394', '#7bc59d', '#397c8b'],                    gradientSet: ['#acc371', '#38c5d2']                },                vintage: {                    simpleSet: ['#dea484', '#efc59c', '#cb715e', '#eb9692', '#a85c4c', '#f2c0b5', '#c96374', '#dd956c'],                    indicatingSet: ['#ffe5c6', '#f4bb9d', '#e57660'],                    gradientSet: ['#efc59c', '#cb715e']                },                violet: {                    simpleSet: ['#d1a1d1', '#eeacc5', '#7b5685', '#7e7cad', '#a13d73', '#5b41ab', '#e287e2', '#689cc1'],                    indicatingSet: ['#d8e2f6', '#d0b2da', '#d56a8a'],                    gradientSet: ['#eeacc5', '#7b5685']                }            };        var currentPaletteName = 'default';        function currentPalette(name) {            if (name === undefined)                return currentPaletteName;            else {                name = String(name).toLowerCase();                currentPaletteName = name in palettes ? name : 'default'            }        }        function getPalette(palette, parameters) {            var result;            if (_isArray(palette))                result = palette;            else {                parameters = parameters || {};                var type = parameters.type || 'simpleSet';                if (_isString(palette)) {                    var name = palette.toLowerCase(),                        baseContainer = palettes[name],                        themedContainer = parameters.theme && palettes[name + '_' + _String(parameters.theme).toLowerCase()];                    result = themedContainer && themedContainer[type] || baseContainer && baseContainer[type]                }                if (!result)                    result = palettes[currentPaletteName][type]            }            return result ? result.slice(0) : null        }        function registerPalette(name, palette, theme) {            var item = {};            if (_isArray(palette))                item.simpleSet = palette.slice(0);            else if (palette) {                item.simpleSet = _isArray(palette.simpleSet) ? palette.simpleSet.slice(0) : undefined;                item.indicatingSet = _isArray(palette.indicatingSet) ? palette.indicatingSet.slice(0) : undefined;                item.gradientSet = _isArray(palette.gradientSet) ? palette.gradientSet.slice(0) : undefined            }            if (item.simpleSet || item.indicatingSet || item.gradientSet) {                var paletteName = _String(name).toLowerCase();                if (theme)                    paletteName = paletteName + '_' + _String(theme).toLowerCase();                _extend(palettes[paletteName] = palettes[paletteName] || {}, item)            }        }        function RingBuf(buf) {            var ind = 0;            this.next = function() {                var res = buf[ind++];                if (ind === buf.length)                    this.reset();                return res            };            this.reset = function() {                ind = 0            }        }        function Palette(palette, parameters) {            parameters = parameters || {};            this._originalPalette = getPalette(palette, parameters);            var stepHighlight = parameters ? parameters.stepHighlight || 0 : 0;            this._paletteSteps = new RingBuf([0, stepHighlight, -stepHighlight]);            this._resetPalette()        }        _extend(Palette.prototype, {            dispose: function() {                this._originalPalette = this._palette = this._paletteSteps = null;                return this            },            getNextColor: function() {                var that = this;                if (that._currentColor >= that._palette.length)                    that._resetPalette();                return that._palette[that._currentColor++]            },            _resetPalette: function() {                var that = this;                that._currentColor = 0;                var step = that._paletteSteps.next(),                    originalPalette = that._originalPalette;                if (step) {                    var palette = that._palette = [],                        i = 0,                        ii = originalPalette.length;                    for (; i < ii; ++i)                        palette[i] = getNewColor(originalPalette[i], step)                }                else                    that._palette = originalPalette.slice(0)            },            reset: function() {                this._paletteSteps.reset();                this._resetPalette();                return this            }        });        function getNewColor(currentColor, step) {            var newColor = new _Color(currentColor).alter(step),                lightness = getLightness(newColor);            if (lightness > 200 || lightness < 55)                newColor = new _Color(currentColor).alter(-step / 2);            return newColor.toHex()        }        function getLightness(color) {            return color.r * 0.3 + color.g * 0.59 + color.b * 0.11        }        function GradientPalette(source, size) {            var palette = getPalette(source, {type: 'gradientSet'});            palette = size > 0 ? createGradientColors(palette, size) : [];            this.getColor = function(index) {                return palette[index] || null            };            this._DEBUG_source = source;            this._DEBUG_size = size        }        function createGradientColors(source, count) {            var ncolors = count - 1,                nsource = source.length - 1,                colors = [],                gradient = [],                i;            for (i = 0; i <= nsource; ++i)                colors.push(new _Color(source[i]));            if (ncolors > 0)                for (i = 0; i <= ncolors; ++i)                    addColor(i / ncolors);            else                addColor(0.5);            return gradient;            function addColor(pos) {                var k = nsource * pos,                    kl = _floor(k),                    kr = _ceil(k);                gradient.push(colors[kl].blend(colors[kr], k - kl).toHex())            }        }        _extend(DX.viz.core, {            registerPalette: registerPalette,            getPalette: getPalette,            Palette: Palette,            GradientPalette: GradientPalette,            currentPalette: currentPalette        });        DX.viz.core._DEBUG_palettes = palettes    })(DevExpress, jQuery);    /*! Module viz-core, file utils.js */    (function(DX, $, undefined) {        var _ceil = Math.ceil,            _min = Math.min,            _round = Math.round;        function selectByKeys(object, keys) {            return $.map(keys, function(key) {                    return object[key] ? object[key] : null                })        }        function decreaseFields(object, keys, eachDecrease, decrease) {            var dec = decrease;            $.each(keys, function(_, key) {                if (object[key]) {                    object[key] -= eachDecrease;                    dec -= eachDecrease                }            });            return dec        }        DX.viz.core.utils = {            decreaseGaps: function(object, keys, decrease) {                var arrayGaps;                do {                    arrayGaps = selectByKeys(object, keys);                    arrayGaps.push(_ceil(decrease / arrayGaps.length));                    decrease = decreaseFields(object, keys, _min.apply(null, arrayGaps), decrease)                } while (decrease > 0 && arrayGaps.length > 1);                return decrease            },            parseScalar: function(value, defaultValue) {                return value !== undefined ? value : defaultValue            },            enumParser: function(values) {                var stored = {},                    i,                    ii;                for (i = 0, ii = values.length; i < ii; ++i)                    stored[String(values[i]).toLowerCase()] = 1;                return function(value, defaultValue) {                        var _value = String(value).toLowerCase();                        return stored[_value] ? _value : defaultValue                    }            },            patchFontOptions: function(options) {                var fontOptions = {};                $.each(options || {}, function(key, value) {                    if (/^(cursor|opacity)$/i.test(key));                    else if (key === "color")                        key = "fill";                    else                        key = "font-" + key;                    fontOptions[key] = value                });                return fontOptions            },            convertPolarToXY: function(centerCoords, startAngle, angle, radius) {                var shiftAngle = 90,                    cossin;                angle = DX.utils.isDefined(angle) ? angle + startAngle - shiftAngle : 0;                cossin = DX.utils.getCosAndSin(angle);                return {                        x: _round(centerCoords.x + radius * cossin.cos),                        y: _round(centerCoords.y + radius * cossin.sin)                    }            },            convertXYToPolar: function(centerCoords, x, y) {                var radius = DX.utils.getDistance(centerCoords.x, centerCoords.y, x, y),                    angle = Math.atan2(y - centerCoords.y, x - centerCoords.x);                return {                        phi: _round(DX.utils.normalizeAngle(angle * 180 / Math.PI)),                        r: _round(radius)                    }            }        }    })(DevExpress, jQuery);    /*! Module viz-core, file baseThemeManager.js */    (function(DX, $, undefined) {        var _isString = DX.utils.isString,            _parseScalar = DX.viz.core.utils.parseScalar,            _findTheme = DX.viz.core.findTheme,            _addCacheItem = DX.viz.core.addCacheItem,            _removeCacheItem = DX.viz.core.removeCacheItem,            _extend = $.extend,            _each = $.each;        function getThemePart(theme, path) {            var _theme = theme;            path && _each(path.split('.'), function(_, pathItem) {                return _theme = _theme[pathItem]            });            return _theme        }        DX.viz.core.BaseThemeManager = DX.Class.inherit({            ctor: function() {                _addCacheItem(this)            },            dispose: function() {                var that = this;                _removeCacheItem(that);                that._callback = that._theme = that._font = null;                return that            },            setCallback: function(callback) {                this._callback = callback;                return this            },            setTheme: function(theme, rtl) {                this._current = theme;                this._rtl = rtl;                return this.refresh()            },            refresh: function() {                var that = this,                    current = that._current || {},                    theme = _findTheme(current.name || current);                that._themeName = theme.name;                that._font = _extend({}, theme.font, current.font);                that._themeSection && _each(that._themeSection.split('.'), function(_, path) {                    theme = _extend(true, {}, theme[path], that._IE8 ? theme[path + 'IE8'] : {})                });                that._theme = _extend(true, {}, theme, _isString(current) ? {} : current);                that._initializeTheme();                if (_parseScalar(that._rtl, that._theme.rtlEnabled))                    _extend(true, that._theme, that._theme._rtl);                that._callback();                return that            },            theme: function(path) {                return getThemePart(this._theme, path)            },            themeName: function() {                return this._themeName            },            _initializeTheme: function() {                var that = this;                _each(that._fontFields || [], function(_, path) {                    that._initializeFont(getThemePart(that._theme, path))                })            },            _initializeFont: function(font) {                _extend(font, this._font, _extend({}, font))            }        })    })(DevExpress, jQuery);    /*! Module viz-core, file parseUtils.js */    (function($, DX) {        var viz = DX.viz,            core = viz.core,            Class = DX.Class,            isDefined = DX.utils.isDefined;        var parseUtils = Class.inherit({                correctValueType: function(type) {                    return type === 'numeric' || type === 'datetime' || type === 'string' ? type : ''                },                _parsers: {                    string: function(val) {                        return isDefined(val) ? '' + val : val                    },                    numeric: function(val) {                        if (!isDefined(val))                            return val;                        var parsedVal = Number(val);                        if (isNaN(parsedVal))                            parsedVal = undefined;                        return parsedVal                    },                    datetime: function(val) {                        if (!isDefined(val))                            return val;                        var parsedVal,                            numVal = Number(val);                        if (!isNaN(numVal))                            parsedVal = new Date(numVal);                        else                            parsedVal = new Date(val);                        if (isNaN(Number(parsedVal)))                            parsedVal = undefined;                        return parsedVal                    }                },                getParser: function(valueType) {                    return this._parsers[this.correctValueType(valueType)] || $.noop                }            });        core.ParseUtils = parseUtils    })(jQuery, DevExpress);    /*! Module viz-core, file loadIndicator.js */    (function(DX, $, undefined) {        var _patchFontOptions = DX.viz.core.utils.patchFontOptions;        var STATE_HIDE = 0,            STATE_SHOW = 1,            STATE_ENDLOADING = 2;        function LoadIndicator(parameters) {            var that = this;            that._$widgetContainer = parameters.container;            that._$container = $("<div>", {css: {                    position: "relative",                    height: 0,                    padding: 0,                    margin: 0,                    border: 0                }}).appendTo(that._$widgetContainer).hide();            that._renderer = new DX.viz.renderers.Renderer({animation: {                    easing: "linear",                    duration: 150                }});            that._renderer.draw(that._$container[0]);            that._rect = that._renderer.rect().attr({opacity: 0}).append(that._renderer.root);            that._text = that._renderer.text().attr({                align: "center",                visibility: "hidden"            }).append(that._renderer.root);            that._createStates(parameters.eventTrigger)        }        LoadIndicator.prototype = {            constructor: LoadIndicator,            _createStates: function(eventTrigger) {                var that = this;                that._states = {};                that._states[STATE_HIDE] = {                    o: 0,                    c: function() {                        that._$container.hide();                        eventTrigger("loadingIndicatorReady")                    }                };                that._states[STATE_SHOW] = {                    o: 0.85,                    c: function() {                        eventTrigger("loadingIndicatorReady")                    }                };                that._states[STATE_ENDLOADING] = {                    o: 1,                    c: function() {                        var onEndLoading = that._onEndLoading;                        that._onEndLoading = null;                        that._noHiding = true;                        onEndLoading && onEndLoading();                        that._noHiding = false;                        that._onCompleteAction && that[that._onCompleteAction]()                    }                }            },            applyCanvas: function(canvas) {                var width = canvas.width,                    height = canvas.height;                this._renderer.resize(width, height);                this._rect.attr({                    width: width,                    height: height                });                this._text.attr({                    x: width / 2,                    y: height / 2                })            },            applyOptions: function(options) {                this._rect.attr({fill: options.backgroundColor});                this._text.css(_patchFontOptions(options.font)).attr({text: options.text})            },            dispose: function() {                var that = this;                that._$container.remove();                that._renderer.dispose();                that._$widgetContainer = that._$container = that._renderer = that._rect = that._text = that._states = null            },            toForeground: function() {                this._$container.appendTo(this._$widgetContainer)            },            forceShow: function() {                this._rect.stopAnimation(false).attr({opacity: 1})            },            _transit: function(stateId) {                var state = this._states[stateId];                this._rect.stopAnimation(true).animate({opacity: state.o}, {complete: state.c})            },            show: function() {                var that = this;                that._isHiding = false;                if (that._onEndLoading)                    that._onCompleteAction = "show";                else {                    that._onCompleteAction = null;                    if (!that._visible) {                        that._visible = true;                        that._$container.show();                        that._renderer.root.css({                            position: "absolute",                            left: 0,                            top: that._$widgetContainer.offset().top - that._$container.offset().top                        });                        that._text.attr({visibility: "visible"})                    }                    that._transit(STATE_SHOW)                }            },            endLoading: function(complete) {                var that = this;                if (!that._onEndLoading)                    if (that._visible) {                        that._onEndLoading = complete;                        that._transit(STATE_ENDLOADING)                    }                    else                        complete && complete()            },            hide: function() {                var that = this;                that._isHiding = false;                if (that._onEndLoading)                    that._onCompleteAction = "hide";                else {                    that._onCompleteAction = null;                    if (that._visible) {                        that._visible = false;                        that._text.attr({visibility: "hidden"});                        that._transit(STATE_HIDE)                    }                }            },            scheduleHiding: function() {                if (!this._noHiding) {                    this._isHiding = true;                    this._onCompleteAction = null                }            },            fulfillHiding: function() {                var isHiding = this._isHiding;                isHiding && this.hide();                return isHiding            }        };        DX.viz.core.LoadIndicator = LoadIndicator    })(DevExpress, jQuery);    /*! Module viz-core, file tooltip.js */    (function(DX, $, doc, undefined) {        var HALF_ARROW_WIDTH = 10,            FORMAT_PRECISION = {                argument: ["argumentFormat", "argumentPrecision"],                percent: ["percent", "percentPrecision"],                value: ["format", "precision"]            },            formatHelper = DX.formatHelper,            mathCeil = Math.ceil;        function hideElement($element) {            $element.css({left: "-9999px"}).detach()        }        function Tooltip(params) {            var that = this,                renderer,                root;            that._eventTrigger = params.eventTrigger;            that._wrapper = $("<div></div>").css({                position: "absolute",                overflow: "visible",                width: 0,                height: 0            }).addClass(params.cssClass);            that._renderer = renderer = new DX.viz.renderers.Renderer({});            root = renderer.root;            root.attr({"pointer-events": "none"});            renderer.draw(that._wrapper.get(0));            that._cloud = renderer.path([], "area").sharp().append(root);            that._shadow = renderer.shadowFilter();            that._textGroup = renderer.g().attr({align: "center"}).append(root);            that._text = renderer.text(undefined, 0, 0).append(that._textGroup);            that._textGroupHtml = $("<div></div>").css({                position: "absolute",                width: 0,                padding: 0,                margin: 0,                border: "0px solid transparent"            }).appendTo(that._wrapper);            that._textHtml = $("<div></div>").css({                position: "relative",                display: "inline-block",                padding: 0,                margin: 0,                border: "0px solid transparent"            }).appendTo(that._textGroupHtml)        }        Tooltip.prototype = {            constructor: Tooltip,            dispose: function() {                this._wrapper.remove();                this._renderer.dispose();                this._options = null            },            setOptions: function(options) {                options = options || {};                var that = this,                    cloudSettings = that._cloudSettigns = {                        opacity: options.opacity,                        filter: that._shadow.ref,                        "stroke-width": null,                        stroke: null                    },                    borderOptions = options.border || {};                that._shadowSettigns = $.extend({                    x: "-50%",                    y: "-50%",                    width: "200%",                    height: "200%"                }, options.shadow);                that._options = options;                if (borderOptions.visible)                    $.extend(cloudSettings, {                        "stroke-width": borderOptions.width,                        stroke: borderOptions.color,                        "stroke-opacity": borderOptions.opacity,                        dashStyle: borderOptions.dashStyle                    });                that._textFontStyles = DX.viz.core.utils.patchFontOptions(options.font);                that._textFontStyles.color = options.font.color;                that._wrapper.css({"z-index": options.zIndex});                that._customizeTooltip = $.isFunction(options.customizeTooltip) ? options.customizeTooltip : null;                return that            },            setRendererOptions: function(options) {                this._renderer.setOptions(options);                this._textGroupHtml.css({direction: options.rtl ? "rtl" : "ltr"});                return this            },            render: function() {                var that = this;                hideElement(that._wrapper);                that._cloud.attr(that._cloudSettigns);                that._shadow.attr(that._shadowSettigns);                that._textGroupHtml.css(that._textFontStyles);                that._textGroup.css(that._textFontStyles);                that._text.css(that._textFontStyles);                that._eventData = null;                return that            },            update: function(options) {                return this.setOptions(options).render()            },            _prepare: function(formatObject, state) {                var options = this._options,                    customize = {};                if (this._customizeTooltip) {                    customize = this._customizeTooltip.call(formatObject, formatObject);                    customize = $.isPlainObject(customize) ? customize : {};                    if ("text" in customize)                        state.text = DX.utils.isDefined(customize.text) ? String(customize.text) : "";                    if ("html" in customize)                        state.html = DX.utils.isDefined(customize.html) ? String(customize.html) : ""                }                if (!("text" in state) && !("html" in state))                    state.text = formatObject.valueText || "";                state.color = customize.color || options.color;                state.borderColor = customize.borderColor || (options.border || {}).color;                state.textColor = customize.fontColor || (options.font || {}).color;                return !!state.text || !!state.html            },            show: function(formatObject, params, eventData) {                var that = this,                    state = {},                    options = that._options,                    plr = options.paddingLeftRight,                    ptb = options.paddingTopBottom,                    textGroupHtml = that._textGroupHtml,                    textHtml = that._textHtml,                    bBox,                    contentSize,                    ss = that._shadowSettigns,                    xOff = ss.offsetX,                    yOff = ss.offsetY,                    blur = ss.blur * 2 + 1;                if (!that._prepare(formatObject, state))                    return false;                that._state = state;                state.tc = {};                that._wrapper.appendTo($("body"));                that._cloud.attr({                    fill: state.color,                    stroke: state.borderColor                });                if (state.html) {                    that._text.attr({text: ""});                    textGroupHtml.css({                        color: state.textColor,                        width: that._getCanvas().width                    });                    textHtml.html(state.html);                    bBox = textHtml.get(0).getBoundingClientRect();                    bBox = {                        x: 0,                        y: 0,                        width: mathCeil(bBox.right - bBox.left),                        height: mathCeil(bBox.bottom - bBox.top)                    };                    textGroupHtml.width(bBox.width);                    textGroupHtml.height(bBox.height)                }                else {                    textHtml.html("");                    that._text.css({fill: state.textColor}).attr({text: state.text});                    bBox = that._textGroup.css({fill: state.textColor}).getBBox()                }                contentSize = state.contentSize = {                    x: bBox.x - plr,                    y: bBox.y - ptb,                    width: bBox.width + 2 * plr,                    height: bBox.height + 2 * ptb,                    lm: blur - xOff > 0 ? blur - xOff : 0,                    rm: blur + xOff > 0 ? blur + xOff : 0,                    tm: blur - yOff > 0 ? blur - yOff : 0,                    bm: blur + yOff > 0 ? blur + yOff : 0                };                contentSize.fullWidth = contentSize.width + contentSize.lm + contentSize.rm;                contentSize.fullHeight = contentSize.height + contentSize.tm + contentSize.bm + options.arrowLength;                that.move(params.x, params.y, params.offset);                that._eventData && that._eventTrigger("tooltipHidden", that._eventData);                that._eventData = eventData;                that._eventTrigger("tooltipShown", that._eventData);                return true            },            hide: function() {                var that = this;                hideElement(that._wrapper);                that._eventData && that._eventTrigger("tooltipHidden", that._eventData);                that._eventData = null            },            move: function(x, y, offset) {                offset = offset || 0;                var that = this,                    canvas = that._getCanvas(),                    state = that._state,                    coords = state.tc,                    contentSize = state.contentSize;                if (that._calculatePosition(x, y, offset)) {                    that._cloud.attr({points: coords.cloudPoints}).move(contentSize.lm, contentSize.tm);                    if (state.html)                        that._textGroupHtml.css({                            left: -contentSize.x + contentSize.lm,                            top: -contentSize.y + contentSize.tm + coords.correction                        });                    else                        that._textGroup.move(-contentSize.x + contentSize.lm, -contentSize.y + contentSize.tm + coords.correction);                    that._renderer.resize(coords.hp === "out" ? canvas.fullWidth - canvas.left : contentSize.fullWidth, coords.vp === "out" ? canvas.fullHeight - canvas.top : contentSize.fullHeight)                }                that._wrapper.css({                    left: coords.x,                    top: coords.y                })            },            formatValue: function(value, specialFormat) {                var formatObj = FORMAT_PRECISION[specialFormat || "value"],                    format = formatObj[0] in this._options ? this._options[formatObj[0]] : specialFormat;                return formatHelper.format(value, format, this._options[formatObj[1]] || 0)            },            getLocation: function() {                return (this._options.location + "").toLowerCase()            },            isEnabled: function() {                return !!this._options.enabled            },            isShared: function() {                return !!this._options.shared            },            _calculatePosition: function(x, y, offset) {                var that = this,                    canvas = that._getCanvas(),                    options = that._options,                    arrowLength = options.arrowLength,                    state = that._state,                    coords = state.tc,                    contentSize = state.contentSize,                    contentWidth = contentSize.width,                    halfContentWidth = contentWidth / 2,                    contentHeight = contentSize.height,                    cTop = y - canvas.top,                    cBottom = canvas.top + canvas.height - y,                    cLeft = x - canvas.left,                    cRight = canvas.width + canvas.left - x,                    tTop = contentHeight + arrowLength + offset + contentSize.tm,                    tBottom = contentHeight + arrowLength + offset + contentSize.bm,                    tLeft = contentWidth + contentSize.lm,                    tRight = contentWidth + contentSize.rm,                    tHalfLeft = halfContentWidth + contentSize.lm,                    tHalfRight = halfContentWidth + contentSize.rm,                    correction = 0,                    cloudPoints,                    arrowPoints = [6, 0],                    x1 = halfContentWidth + HALF_ARROW_WIDTH,                    x2 = halfContentWidth,                    x3 = halfContentWidth - HALF_ARROW_WIDTH,                    y1,                    y3,                    y2 = contentHeight + arrowLength,                    hp = "center",                    vp = "bottom",                    hasDeprecatedPosition;                y1 = y3 = contentHeight;                switch (options.verticalAlignment) {                    case"top":                        vp = "bottom";                        hasDeprecatedPosition = true;                        break;                    case"bottom":                        vp = "top";                        hasDeprecatedPosition = true;                        break                }                if (!hasDeprecatedPosition)                    if (tTop > cTop && tBottom > cBottom)                        vp = "out";                    else if (tTop > cTop)                        vp = "top";                hasDeprecatedPosition = false;                switch (options.horizontalAlignment) {                    case"left":                        hp = "right";                        hasDeprecatedPosition = true;                        break;                    case"center":                        hp = "center";                        hasDeprecatedPosition = true;                        break;                    case"right":                        hp = "left";                        hasDeprecatedPosition = true;                        break                }                if (!hasDeprecatedPosition)                    if (tLeft > cLeft && tRight > cRight)                        hp = "out";                    else if (tHalfLeft > cLeft && tRight < cRight)                        hp = "left";                    else if (tHalfRight > cRight && tLeft < cLeft)                        hp = "right";                if (hp === "out")                    x = canvas.left;                else if (hp === "left") {                    x1 = HALF_ARROW_WIDTH;                    x2 = x3 = 0                }                else if (hp === "right") {                    x1 = x2 = contentWidth;                    x3 = contentWidth - HALF_ARROW_WIDTH;                    x = x - contentWidth                }                else if (hp === "center")                    x = x - halfContentWidth;                if (vp === "out")                    y = canvas.top;                else if (vp === "top") {                    hp !== "out" && (correction = arrowLength);                    arrowPoints[0] = 2;                    y1 = y3 = arrowLength;                    y2 = x1;                    x1 = x3;                    x3 = y2;                    y2 = 0;                    y = y + offset                }                else                    y = y - (contentHeight + arrowLength + offset);                coords.x = x - contentSize.lm;                coords.y = y - contentSize.tm;                coords.correction = correction;                if (hp === coords.hp && vp === coords.vp)                    return false;                coords.hp = hp;                coords.vp = vp;                cloudPoints = [0, 0 + correction, contentWidth, 0 + correction, contentWidth, contentHeight + correction, 0, contentHeight + correction];                if (hp !== "out" && vp !== "out") {                    arrowPoints.splice(2, 0, x1, y1, x2, y2, x3, y3);                    cloudPoints.splice.apply(cloudPoints, arrowPoints)                }                coords.cloudPoints = cloudPoints;                return true            },            _getCanvas: function() {                var html = doc.documentElement,                    body = doc.body,                    win = window;                return {                        left: win.pageXOffset || html.scrollLeft || 0,                        top: win.pageYOffset || html.scrollTop || 0,                        width: html.clientWidth || 0,                        height: html.clientHeight || 0,                        fullWidth: Math.max(body.scrollWidth, html.scrollWidth, body.offsetWidth, html.offsetWidth, body.clientWidth, html.clientWidth),                        fullHeight: Math.max(body.scrollHeight, html.scrollHeight, body.offsetHeight, html.offsetHeight, body.clientHeight, html.clientHeight)                    }            }        };        DX.viz.core.Tooltip = Tooltip    })(DevExpress, jQuery, document);    /*! Module viz-core, file legend.js */    (function(DX, $, undefined) {        var core = DX.viz.core,            coreUtils = core.utils,            WrapperLayoutElement = core.WrapperLayoutElement,            _Number = Number,            _String = String,            _math = Math,            _round = _math.round,            _max = _math.max,            _min = _math.min,            _ceil = _math.ceil,            utils = DX.utils,            _isDefined = utils.isDefined,            _isFunction = utils.isFunction,            _enumParser = coreUtils.enumParser,            _extend = $.extend,            _each = $.each,            _map = $.map,            DEFAULT_MARGIN = 10,            DEFAULT_MARKER_HATCHING_WIDTH = 2,            DEFAULT_MARKER_HATCHING_STEP = 5,            CENTER = "center",            RIGHT = "right",            LEFT = "left",            TOP = "top",            BOTTOM = "bottom",            HORIZONTAL = "horizontal",            VERTICAL = "vertical",            INSIDE = "inside",            OUTSIDE = "outside",            NONE = "none",            HEIGHT = "height",            WIDTH = "width",            parseHorizontalAlignment = _enumParser([LEFT, CENTER, RIGHT]),            parseVerticalAlignment = _enumParser([TOP, BOTTOM]),            parseOrientation = _enumParser([VERTICAL, HORIZONTAL]),            parseItemTextPosition = _enumParser([LEFT, RIGHT, TOP, BOTTOM]),            parsePosition = _enumParser([OUTSIDE, INSIDE]),            parseItemsAlignment = _enumParser([LEFT, CENTER, RIGHT]);        function getPattern(renderer, states, action, color) {            if (!states || !states[action])                return;            var direction = states[action].hatching.direction,                hatching,                colorFromAction = states[action].fill;            color = colorFromAction === NONE ? color : colorFromAction;            direction = !direction || direction === NONE ? RIGHT : direction;            hatching = _extend({}, states[action].hatching, {                direction: direction,                step: DEFAULT_MARKER_HATCHING_STEP,                width: DEFAULT_MARKER_HATCHING_WIDTH            });            return renderer.pattern(color, hatching)        }        function parseMargins(options) {            var margin = options.margin;            if (margin >= 0) {                margin = _Number(options.margin);                margin = {                    top: margin,                    bottom: margin,                    left: margin,                    right: margin                }            }            else                margin = {                    top: margin.top >= 0 ? _Number(margin.top) : DEFAULT_MARGIN,                    bottom: margin.bottom >= 0 ? _Number(margin.bottom) : DEFAULT_MARGIN,                    left: margin.left >= 0 ? _Number(margin.left) : DEFAULT_MARGIN,                    right: margin.right >= 0 ? _Number(margin.right) : DEFAULT_MARGIN                };            options.margin = margin        }        function getSizeItem(options, markerSize, labelBBox) {            var defaultXMargin = 7,                defaultTopMargin = 4,                width,                height;            switch (options.itemTextPosition) {                case LEFT:                case RIGHT:                    width = markerSize + defaultXMargin + labelBBox.width;                    height = _max(markerSize, labelBBox.height);                    break;                case TOP:                case BOTTOM:                    width = _max(markerSize, labelBBox.width);                    height = markerSize + defaultTopMargin + labelBBox.height;                    break            }            return {                    width: width,                    height: height                }        }        function calculateBboxLabelAndMarker(markerBBox, labelBBox) {            var bbox = {};            bbox.left = _min(markerBBox.x, labelBBox.x);            bbox.top = _min(markerBBox.y, labelBBox.y);            bbox.right = _max(markerBBox.x + markerBBox.width, labelBBox.x + labelBBox.width);            bbox.bottom = _max(markerBBox.y + markerBBox.height, labelBBox.y + labelBBox.height);            return bbox        }        function applyMarkerState(id, idToIndexMap, items, stateName) {            var item = idToIndexMap && items[idToIndexMap[id]];            if (item)                item.marker.attr(item.states[stateName])        }        function parseOptions(options, textField) {            if (!options)                return null;            DX.utils.debug.assertParam(options.visible, "Visibility was not passed");            DX.utils.debug.assertParam(options.markerSize, "markerSize was not passed");            DX.utils.debug.assertParam(options.font.color, "fontColor was not passed");            DX.utils.debug.assertParam(options.font.family, "fontFamily was not passed");            DX.utils.debug.assertParam(options.font.size, "fontSize was not passed");            DX.utils.debug.assertParam(options.paddingLeftRight, "paddingLeftRight was not passed");            DX.utils.debug.assertParam(options.paddingTopBottom, "paddingTopBottom was not passed");            DX.utils.debug.assertParam(options.columnItemSpacing, "columnItemSpacing was not passed");            DX.utils.debug.assertParam(options.rowItemSpacing, "rowItemSpacing was not passed");            parseMargins(options);            options.horizontalAlignment = parseHorizontalAlignment(options.horizontalAlignment, RIGHT);            options.verticalAlignment = parseVerticalAlignment(options.verticalAlignment, options.horizontalAlignment === CENTER ? BOTTOM : TOP);            options.orientation = parseOrientation(options.orientation, options.horizontalAlignment === CENTER ? HORIZONTAL : VERTICAL);            options.itemTextPosition = parseItemTextPosition(options.itemTextPosition, options.orientation === HORIZONTAL ? BOTTOM : RIGHT);            options.position = parsePosition(options.position, OUTSIDE);            options.itemsAlignment = parseItemsAlignment(options.itemsAlignment, null);            options.hoverMode = _String(options.hoverMode || "").toLowerCase();            options.customizeText = _isFunction(options.customizeText) ? options.customizeText : function() {                return this[textField]            };            options.customizeHint = _isFunction(options.customizeHint) ? options.customizeHint : $.noop;            return options        }        function createSquareMarker(renderer, size) {            return renderer.rect(0, 0, size, size)        }        function createCircleMarker(renderer, size) {            return renderer.circle(size / 2, size / 2, size / 2)        }        function isCircle(type) {            return _String(type).toLowerCase() === "circle"        }        function getMarkerCreator(type) {            return isCircle(type) ? createCircleMarker : createSquareMarker        }        function inRect(rect, x, y) {            return x >= rect.left && x <= rect.right && y >= rect.top && y <= rect.bottom        }        function checkLinesSize(lines, layoutOptions, countItems) {            var position = {                    x: 0,                    y: 0                },                maxMeasureLength = 0,                maxOrtMeasureLength = 0;            $.each(lines, function(i, line) {                var firstItem = line[0];                $.each(line, function(_, item) {                    var offset = item.offset || layoutOptions.spacing;                    position[layoutOptions.direction] += item[layoutOptions.measure] + offset;                    maxMeasureLength = _max(maxMeasureLength, position[layoutOptions.direction])                });                position[layoutOptions.direction] = 0;                position[layoutOptions.ortDirection] += firstItem[layoutOptions.ortMeasure] + firstItem.ortOffset || layoutOptions.ortSpacing;                maxOrtMeasureLength = _max(maxOrtMeasureLength, position[layoutOptions.ortDirection])            });            if (maxMeasureLength > layoutOptions.length) {                layoutOptions.countItem = decreaseItemCount(layoutOptions, countItems);                return true            }        }        function decreaseItemCount(layoutOptions, countItems) {            layoutOptions.ortCountItem++;            return _ceil(countItems / layoutOptions.ortCountItem)        }        function getLineLength(line, layoutOptions) {            var lineLength = 0;            $.each(line, function(_, item) {                var offset = item.offset || layoutOptions.spacing;                lineLength += item[layoutOptions.measure] + offset            });            return lineLength        }        function getMaxLineLength(lines, layoutOptions) {            var maxLineLength = 0;            $.each(lines, function(_, line) {                maxLineLength = _max(maxLineLength, getLineLength(line, layoutOptions))            });            return maxLineLength        }        function getInitPositionForDirection(line, layoutOptions, maxLineLength) {            var lineLength = getLineLength(line, layoutOptions),                initPosition;            switch (layoutOptions.itemsAlignment) {                case RIGHT:                    initPosition = maxLineLength - lineLength;                    break;                case CENTER:                    initPosition = (maxLineLength - lineLength) / 2;                    break;                default:                    initPosition = 0            }            return initPosition        }        function getPos(layoutOptions) {            switch (layoutOptions.itemTextPosition) {                case BOTTOM:                    return CENTER + " " + TOP;                case TOP:                    return CENTER + " " + BOTTOM;                case LEFT:                    return RIGHT + " " + CENTER;                case RIGHT:                    return LEFT + " " + CENTER            }        }        function getLines(lines, layoutOptions, itemIndex) {            var tableLine = {};            if (itemIndex % layoutOptions.countItem === 0)                if (layoutOptions.markerOffset)                    lines.push([], []);                else                    lines.push([]);            if (layoutOptions.markerOffset) {                tableLine.firstLine = lines[lines.length - 1];                tableLine.secondLine = lines[lines.length - 2]            }            else                tableLine.firstLine = tableLine.secondLine = lines[lines.length - 1];            return tableLine        }        function setMaxInLine(line, mesuare) {            var maxLineSize = 0;            $.each(line, function(_, item) {                if (!item)                    return;                maxLineSize = _max(maxLineSize, item[mesuare])            });            $.each(line, function(_, item) {                if (!item)                    return;                item[mesuare] = maxLineSize            })        }        function transpose(array) {            var width = array.length,                height = array[0].length,                i,                j,                transposeArray = [];            for (i = 0; i < height; i++) {                transposeArray[i] = [];                for (j = 0; j < width; j++)                    transposeArray[i][j] = array[j][i]            }            return transposeArray        }        function getAlign(position) {            switch (position) {                case TOP:                case BOTTOM:                    return CENTER;                case LEFT:                    return RIGHT;                case RIGHT:                    return LEFT            }        }        var _Legend = DX.viz.core.Legend = function(settings) {                var that = this;                that._renderer = settings.renderer;                that._legendGroup = settings.group;                that._backgroundClass = settings.backgroundClass;                that._itemGroupClass = settings.itemGroupClass;                that._textField = settings.textField;                that._getCustomizeObject = settings.getFormatObject;                that._patterns = []            };        _Legend.prototype = {            constructor: _Legend,            update: function(data, options) {                var that = this;                that._data = data;                that._boundingRect = {                    width: 0,                    height: 0,                    x: 0,                    y: 0                };                that._options = parseOptions(options, that._textField);                return that            },            setSize: function(size) {                this._size = {                    width: size.width,                    height: size.height                };                return this            },            draw: function(size) {                var that = this,                    options = that._options,                    renderer = that._renderer,                    items = that._data;                size && that.setSize(size);                that.erase();                if (!(options && options.visible && items && items.length))                    return that;                that._insideLegendGroup = renderer.g().append(that._legendGroup);                that._createBackground();                that._createItems(that._getItemData());                that._locateElements(options);                that._finalUpdate(options);                return that            },            _createItems: function(items) {                var that = this,                    options = that._options,                    initMarkerSize = options.markerSize,                    renderer = that._renderer,                    markersOptions = [],                    maxMarkerSize = 0,                    i = 0,                    bbox,                    maxBboxWidth = 0,                    maxBboxHeight = 0,                    createMarker = getMarkerCreator(options.markerType);                _each(items, function(_i, item) {                    maxMarkerSize = _max(maxMarkerSize, _Number(item.size > 0 ? item.size : initMarkerSize))                });                that._markersId = {};                for (; i < that._patterns.length; i++)                    that._patterns[i].dispose();                that._patterns = [];                that._items = _map(items, function(dataItem, i) {                    var group = that._insideLegendGroup,                        markerSize = _Number(dataItem.size > 0 ? dataItem.size : initMarkerSize),                        stateOfDataItem = dataItem.states,                        normalState = stateOfDataItem.normal,                        normalStateFill = normalState.fill,                        marker = createMarker(renderer, markerSize).attr({                            fill: normalStateFill || options.markerColor,                            opacity: normalState.opacity                        }).append(group),                        label = that._createLabel(dataItem, group),                        hoverPattern = getPattern(renderer, stateOfDataItem, "hover", normalStateFill),                        selectionPattern = getPattern(renderer, stateOfDataItem, "selection", normalStateFill),                        states = {normal: {fill: normalStateFill}},                        labelBBox = label.getBBox();                    if (hoverPattern) {                        states.hovered = {fill: hoverPattern.id};                        that._patterns.push(hoverPattern)                    }                    if (selectionPattern) {                        states.selected = {fill: selectionPattern.id};                        that._patterns.push(selectionPattern)                    }                    if (dataItem.id !== undefined)                        that._markersId[dataItem.id] = i;                    bbox = getSizeItem(options, markerSize, labelBBox);                    maxBboxWidth = _max(maxBboxWidth, bbox.width);                    maxBboxHeight = _max(maxBboxHeight, bbox.height);                    markersOptions.push({                        size: markerSize,                        marker: marker                    });                    that._createHint(dataItem, label);                    return {                            label: label,                            labelBBox: labelBBox,                            group: group,                            bbox: bbox,                            marker: marker,                            markerSize: markerSize,                            tracker: {id: dataItem.id},                            states: states,                            itemTextPosition: options.itemTextPosition,                            markerOffset: 0,                            bboxs: []                        }                });                if (options.equalRowHeight)                    $.each(that._items, function(_, item) {                        item.bbox.height = maxBboxHeight                    })            },            _getItemData: function() {                var items = this._data;                if (this._options.inverted)                    items = items.slice().reverse();                return items            },            _finalUpdate: function(options) {                this._adjustBackgroundSettings(options);                this._setBoundingRect(options.margin)            },            erase: function() {                var that = this,                    insideLegendGroup = that._insideLegendGroup;                insideLegendGroup && insideLegendGroup.dispose();                that._insideLegendGroup = that._x1 = that._x2 = that._y2 = that._y2 = null;                return that            },            _locateElements: function(locationOptions) {                this._moveInInitialValues();                this._locateRowsColumns(locationOptions)            },            _moveInInitialValues: function() {                var that = this;                that._legendGroup && that._legendGroup.move(0, 0);                that._background && that._background.attr({                    x: 0,                    y: 0,                    width: 0,                    height: 0                })            },            applySelected: function(id) {                applyMarkerState(id, this._markersId, this._items, "selected");                return this            },            applyHover: function(id) {                applyMarkerState(id, this._markersId, this._items, "hovered");                return this            },            resetItem: function(id) {                applyMarkerState(id, this._markersId, this._items, "normal");                return this            },            _createLabel: function(data, group) {                var labelFormatObject = this._getCustomizeObject(data),                    align = getAlign(this._options.itemTextPosition),                    text = this._options.customizeText.call(labelFormatObject, labelFormatObject),                    fontStyle = _isDefined(data.textOpacity) ? _extend({}, this._options.font, {opacity: data.textOpacity}) : this._options.font;                return this._renderer.text(text, 0, 0).css(coreUtils.patchFontOptions(fontStyle)).attr({align: align}).append(group)            },            _createHint: function(data, label) {                var labelFormatObject = this._getCustomizeObject(data),                    text = this._options.customizeHint.call(labelFormatObject, labelFormatObject);                if (_isDefined(text) && text !== "")                    label.setTitle(text)            },            _createBackground: function() {                var that = this,                    isInside = that._options.position === INSIDE,                    color = that._options.backgroundColor,                    fill = color || (isInside ? that._options.containerBackgroundColor : NONE);                if (that._options.border.visible || (isInside || color) && color !== NONE)                    that._background = that._renderer.rect(0, 0, 0, 0).attr({                        fill: fill,                        'class': that._backgroundClass                    }).append(that._insideLegendGroup)            },            _locateRowsColumns: function() {                var that = this,                    iteration = 0,                    layoutOptions = that._getItemsLayoutOptions(),                    countItems = that._items.length,                    lines;                do {                    lines = [];                    that._createLines(lines, layoutOptions);                    that._alignLines(lines, layoutOptions);                    iteration++                } while (checkLinesSize(lines, layoutOptions, countItems) && iteration < countItems);                that._applyItemPosition(lines, layoutOptions)            },            _createLines: function(lines, layoutOptions) {                $.each(this._items, function(i, item) {                    var tableLine = getLines(lines, layoutOptions, i),                        labelBox = {                            width: item.labelBBox.width,                            height: item.labelBBox.height,                            element: item.label,                            bbox: item.labelBBox,                            pos: getPos(layoutOptions),                            itemIndex: i                        },                        markerBox = {                            width: item.markerSize,                            height: item.markerSize,                            element: item.marker,                            bbox: {                                width: item.markerSize,                                height: item.markerSize,                                x: 0,                                y: 0                            },                            itemIndex: i                        },                        firstItem,                        secondItem,                        offsetDirection = layoutOptions.markerOffset ? "ortOffset" : "offset";                    if (layoutOptions.inverseLabelPosition) {                        firstItem = labelBox;                        secondItem = markerBox                    }                    else {                        firstItem = markerBox;                        secondItem = labelBox                    }                    firstItem[offsetDirection] = layoutOptions.labelOffset;                    tableLine.secondLine.push(firstItem);                    tableLine.firstLine.push(secondItem)                })            },            _alignLines: function(lines, layoutOptions) {                var i,                    measure = layoutOptions.ortMeasure;                _each(lines, processLine);                measure = layoutOptions.measure;                if (layoutOptions.itemsAlignment) {                    if (layoutOptions.markerOffset)                        for (i = 0; i < lines.length; )                            _each(transpose([lines[i++], lines[i++]]), processLine)                }                else                    _each(transpose(lines), processLine);                function processLine(_, line) {                    setMaxInLine(line, measure)                }            },            _applyItemPosition: function(lines, layoutOptions) {                var that = this,                    position = {                        x: 0,                        y: 0                    },                    maxLineLength = getMaxLineLength(lines, layoutOptions),                    itemIndex = 0;                $.each(lines, function(i, line) {                    var firstItem = line[0],                        ortOffset = firstItem.ortOffset || layoutOptions.ortSpacing;                    position[layoutOptions.direction] = getInitPositionForDirection(line, layoutOptions, maxLineLength);                    $.each(line, function(_, item) {                        var offset = item.offset || layoutOptions.spacing,                            wrap = new WrapperLayoutElement(item.element, item.bbox),                            itemBBox = {                                x: position.x,                                y: position.y,                                width: item.width,                                height: item.height                            },                            itemLegend = that._items[item.itemIndex];                        wrap.position({                            of: itemBBox,                            my: item.pos,                            at: item.pos                        });                        itemLegend.bboxs.push(itemBBox);                        position[layoutOptions.direction] += item[layoutOptions.measure] + offset;                        itemIndex++                    });                    position[layoutOptions.ortDirection] += firstItem[layoutOptions.ortMeasure] + ortOffset                });                $.each(this._items, function(_, item) {                    var itemBBox = calculateBboxLabelAndMarker(item.bboxs[0], item.bboxs[1]),                        horizontal = that._options.columnItemSpacing / 2,                        vertical = that._options.rowItemSpacing / 2;                    item.tracker.left = itemBBox.left - horizontal;                    item.tracker.right = itemBBox.right + horizontal;                    item.tracker.top = itemBBox.top - vertical;                    item.tracker.bottom = itemBBox.bottom + vertical                })            },            _getItemsLayoutOptions: function() {                var that = this,                    options = that._options,                    border = options.border.visible,                    orientation = options.orientation,                    layoutOptions = {                        itemsAlignment: options.itemsAlignment,                        orientation: options.orientation                    },                    width = that._size.width - (border ? 2 * options.paddingLeftRight : 0),                    height = that._size.height - (border ? 2 * options.paddingTopBottom : 0);                if (orientation === HORIZONTAL) {                    layoutOptions.length = width;                    layoutOptions.ortLength = height;                    layoutOptions.spacing = options.columnItemSpacing;                    layoutOptions.direction = "x";                    layoutOptions.measure = WIDTH;                    layoutOptions.ortMeasure = HEIGHT;                    layoutOptions.ortDirection = "y";                    layoutOptions.ortSpacing = options.rowItemSpacing;                    layoutOptions.countItem = options.columnCount;                    layoutOptions.ortCountItem = options.rowCount;                    layoutOptions.marginTextLabel = 4;                    layoutOptions.labelOffset = 7;                    if (options.itemTextPosition === BOTTOM || options.itemTextPosition === TOP) {                        layoutOptions.labelOffset = 4;                        layoutOptions.markerOffset = true                    }                }                else {                    layoutOptions.length = height;                    layoutOptions.ortLength = width;                    layoutOptions.spacing = options.rowItemSpacing;                    layoutOptions.direction = "y";                    layoutOptions.measure = HEIGHT;                    layoutOptions.ortMeasure = WIDTH;                    layoutOptions.ortDirection = "x";                    layoutOptions.ortSpacing = options.columnItemSpacing;                    layoutOptions.countItem = options.rowCount;                    layoutOptions.ortCountItem = options.columnCount;                    layoutOptions.marginTextLabel = 7;                    layoutOptions.labelOffset = 4;                    if (options.itemTextPosition === RIGHT || options.itemTextPosition === LEFT) {                        layoutOptions.labelOffset = 7;                        layoutOptions.markerOffset = true                    }                }                if (!layoutOptions.countItem)                    if (layoutOptions.ortCountItem)                        layoutOptions.countItem = _ceil(that._items.length / layoutOptions.ortCountItem);                    else                        layoutOptions.countItem = that._items.length;                if (options.itemTextPosition === TOP || options.itemTextPosition === LEFT)                    layoutOptions.inverseLabelPosition = true;                layoutOptions.itemTextPosition = options.itemTextPosition;                layoutOptions.ortCountItem = layoutOptions.ortCountItem || _ceil(that._items.length / layoutOptions.countItem);                return layoutOptions            },            _adjustBackgroundSettings: function(locationOptions) {                if (!this._background)                    return;                var border = locationOptions.border,                    legendBox = this._insideLegendGroup.getBBox(),                    backgroundSettings = {                        x: _round(legendBox.x - locationOptions.paddingLeftRight),                        y: _round(legendBox.y - locationOptions.paddingTopBottom),                        width: _round(legendBox.width) + 2 * locationOptions.paddingLeftRight,                        height: _round(legendBox.height) + 2 * locationOptions.paddingTopBottom,                        opacity: locationOptions.backgroundOpacity                    };                if (border.visible && border.width && border.color && border.color !== NONE) {                    backgroundSettings["stroke-width"] = border.width;                    backgroundSettings.stroke = border.color;                    backgroundSettings["stroke-opacity"] = border.opacity;                    backgroundSettings.dashStyle = border.dashStyle;                    backgroundSettings.rx = border.cornerRadius || 0;                    backgroundSettings.ry = border.cornerRadius || 0                }                this._background.attr(backgroundSettings)            },            _setBoundingRect: function(margin) {                if (!this._insideLegendGroup)                    return;                var box = this._insideLegendGroup.getBBox();                box.height += margin.top + margin.bottom;                box.width += margin.left + margin.right;                box.x -= margin.left;                box.y -= margin.top;                this._boundingRect = box            },            changeSize: function() {                this.fit.apply(this, arguments)            },            fit: function(sizeForDecrease) {                var that = this,                    beforeFit = that.getLayoutOptions(),                    afterFit;                function fitLegendToDirection(direction) {                    var size = $.extend({}, that._size);                    size[direction] = beforeFit[direction] - sizeForDecrease[direction];                    that.draw(size);                    afterFit = that.getLayoutOptions();                    if (that._insideLegendGroup)                        if (beforeFit[direction] - sizeForDecrease[direction] < afterFit[direction]) {                            that._options._incidentOccured("W2104");                            that.erase()                        }                }                if (sizeForDecrease.width > 0)                    fitLegendToDirection(WIDTH);                if (sizeForDecrease.height > 0)                    fitLegendToDirection(HEIGHT);                return this            },            getActionCallback: function(point) {                var that = this;                if (that._options.visible)                    return function(act) {                            var pointType = point.type,                                seriesType = pointType || point.series.type;                            if (pointType || seriesType === "pie" || seriesType === "doughnut" || seriesType === "donut")                                that[act] && that[act](point.index)                        };                else                    return $.noop            },            getLayoutOptions: function() {                var options = this._options,                    boundingRect = this._insideLegendGroup ? this._boundingRect : {                        width: 0,                        height: 0,                        x: 0,                        y: 0                    };                if (options) {                    boundingRect.verticalAlignment = options.verticalAlignment;                    boundingRect.horizontalAlignment = options.horizontalAlignment;                    if (options.orientation === HORIZONTAL)                        boundingRect.cutLayoutSide = options.verticalAlignment;                    else                        boundingRect.cutLayoutSide = options.horizontalAlignment === CENTER ? options.verticalAlignment : options.horizontalAlignment;                    return boundingRect                }                return null            },            shift: function(x, y) {                var that = this,                    box = {};                if (that._insideLegendGroup) {                    that._insideLegendGroup.attr({                        translateX: x - that._boundingRect.x,                        translateY: y - that._boundingRect.y                    });                    box = that._legendGroup.getBBox()                }                that._x1 = box.x;                that._y1 = box.y;                that._x2 = box.x + box.width;                that._y2 = box.y + box.height;                return that            },            getPosition: function() {                return this._options.position            },            coordsIn: function(x, y) {                return x >= this._x1 && x <= this._x2 && y >= this._y1 && y <= this._y2            },            getItemByCoord: function(x, y) {                var items = this._items,                    legendGroup = this._insideLegendGroup;                x = x - legendGroup.attr("translateX");                y = y - legendGroup.attr("translateY");                for (var i = 0; i < items.length; i++)                    if (inRect(items[i].tracker, x, y))                        return items[i].tracker;                return null            },            dispose: function() {                var that = this;                that._legendGroup = that._insideLegendGroup = that._renderer = that._options = that._data = that._items = null;                return that            }        };        var __getMarkerCreator = getMarkerCreator;        DX.viz.core._DEBUG_stubMarkerCreator = function(callback) {            getMarkerCreator = function() {                return callback            }        };        DX.viz.core._DEBUG_restoreMarkerCreator = function() {            getMarkerCreator = __getMarkerCreator        }    })(DevExpress, jQuery);    /*! Module viz-core, file range.js */    (function($, DX, undefined) {        var core = DX.viz.core,            utils = DX.utils,            _isDefined = utils.isDefined,            _isDate = utils.isDate,            NUMBER_EQUALITY_CORRECTION = 1,            DATETIME_EQUALITY_CORRECTION = 60000,            minSelector = "min",            maxSelector = "max",            minVisibleSelector = "minVisible",            maxVisibleSelector = "maxVisible",            categoriesSelector = "categories",            baseSelector = "base",            axisTypeSelector = "axisType",            _Range;        function otherLessThan(thisValue, otherValue) {            return otherValue < thisValue        }        function otherGreaterThan(thisValue, otherValue) {            return otherValue > thisValue        }        function compareAndReplace(thisValue, otherValue, setValue, compare) {            var otherValueDefined = _isDefined(otherValue);            if (_isDefined(thisValue)) {                if (otherValueDefined && compare(thisValue, otherValue))                    setValue(otherValue)            }            else if (otherValueDefined)                setValue(otherValue)        }        function returnValue(value) {            return value        }        function returnValueOf(value) {            return value.valueOf()        }        function getUniqueCategories(categories, otherCategories, dataType) {            var length = categories.length,                found,                i,                j,                valueOf = dataType === "datetime" ? returnValueOf : returnValue;            if (otherCategories && otherCategories.length)                for (i = 0; i < otherCategories.length; i++) {                    for (j = 0, found = false; j < length; j++)                        if (valueOf(categories[j]) === valueOf(otherCategories[i])) {                            found = true;                            break                        }                    !found && categories.push(otherCategories[i])                }            return categories        }        DX.viz.core.__NUMBER_EQUALITY_CORRECTION = NUMBER_EQUALITY_CORRECTION;        DX.viz.core.__DATETIME_EQUALITY_CORRECTION = DATETIME_EQUALITY_CORRECTION;        _Range = core.Range = function(range) {            range && $.extend(this, range)        };        _Range.prototype = {            constructor: _Range,            dispose: function() {                this[categoriesSelector] = null            },            addRange: function(otherRange) {                var that = this,                    categories = that[categoriesSelector],                    otherCategories = otherRange[categoriesSelector];                var compareAndReplaceByField = function(field, compare) {                        compareAndReplace(that[field], otherRange[field], function(value) {                            that[field] = value                        }, compare)                    };                var controlValuesByVisibleBounds = function(valueField, visibleValueField, compare) {                        compareAndReplace(that[valueField], that[visibleValueField], function(value) {                            _isDefined(that[valueField]) && (that[valueField] = value)                        }, compare)                    };                var checkField = function(field) {                        that[field] = that[field] || otherRange[field]                    };                if (utils.isDefined(otherRange.stick))                    that.stick = otherRange.stick;                checkField("addSpiderCategory");                checkField("percentStick");                checkField("minSpaceCorrection");                checkField("maxSpaceCorrection");                checkField("invert");                checkField(axisTypeSelector);                checkField("dataType");                if (that[axisTypeSelector] === "logarithmic")                    checkField(baseSelector);                else                    that[baseSelector] = undefined;                compareAndReplaceByField(minSelector, otherLessThan);                compareAndReplaceByField(maxSelector, otherGreaterThan);                if (that[axisTypeSelector] === "discrete") {                    checkField(minVisibleSelector);                    checkField(maxVisibleSelector)                }                else {                    compareAndReplaceByField(minVisibleSelector, otherLessThan);                    compareAndReplaceByField(maxVisibleSelector, otherGreaterThan)                }                compareAndReplaceByField("interval", otherLessThan);                controlValuesByVisibleBounds(minSelector, minVisibleSelector, otherLessThan);                controlValuesByVisibleBounds(minSelector, maxVisibleSelector, otherLessThan);                controlValuesByVisibleBounds(maxSelector, maxVisibleSelector, otherGreaterThan);                controlValuesByVisibleBounds(maxSelector, minVisibleSelector, otherGreaterThan);                if (categories === undefined)                    that[categoriesSelector] = otherCategories;                else                    that[categoriesSelector] = getUniqueCategories(categories, otherCategories, that.dataType);                return this            },            isDefined: function() {                return _isDefined(this[minSelector]) && _isDefined(this[maxSelector]) || _isDefined(this[categoriesSelector])            },            setStubData: function(dataType) {                var that = this,                    year = (new Date).getYear() - 1,                    isDate = dataType === "datetime",                    isCategories = that.axisType === "discrete";                if (isCategories)                    that.categories = ["0", "1", "2"];                else {                    that[minSelector] = isDate ? new Date(year, 0, 1) : 0;                    that[maxSelector] = isDate ? new Date(year, 11, 31) : 10                }                that.stubData = true;                return that            },            correctValueZeroLevel: function() {                var that = this;                if (_isDate(that[maxSelector]) || _isDate(that[minSelector]))                    return that;                function setZeroLevel(min, max) {                    that[min] < 0 && that[max] < 0 && (that[max] = 0);                    that[min] > 0 && that[max] > 0 && (that[min] = 0)                }                setZeroLevel(minSelector, maxSelector);                setZeroLevel(minVisibleSelector, maxVisibleSelector);                return that            },            checkZeroStick: function() {                var that = this;                if (that.min >= 0 && that.max >= 0)                    that.minStickValue = 0;                else if (that.min <= 0 && that.max <= 0)                    that.maxStickValue = 0;                return that            }        }    })(jQuery, DevExpress);    /*! Module viz-core, file svgRenderer.js */    (function($, DX, doc, undefined) {        var rendererNS = DX.viz.renderers = {},            math = Math,            mathMin = math.min,            mathMax = math.max,            mathCeil = math.ceil,            mathFloor = math.floor,            mathRound = math.round,            mathSin = math.sin,            mathCos = math.cos,            mathAbs = math.abs,            mathPI = math.PI,            PI_DIV_180 = mathPI / 180,            _parseInt = parseInt,            MAX_PIXEL_COUNT = 1E10,            SHARPING_CORRECTION = 0.5,            ARC_COORD_PREC = 5;        var pxAddingExceptions = {                "column-count": true,                "fill-opacity": true,                "flex-grow": true,                "flex-shrink": true,                "font-weight": true,                "line-height": true,                opacity: true,                order: true,                orphans: true,                widows: true,                "z-index": true,                zoom: true            };        var KEY_TEXT = "text",            KEY_STROKE = "stroke",            KEY_STROKE_WIDTH = "stroke-width",            KEY_STROKE_OPACITY = "stroke-opacity",            KEY_FONT_SIZE = "font-size",            KEY_FONT_STYLE = "font-style",            KEY_FONT_WEIGHT = "font-weight",            KEY_TEXT_DECORATION = "text-decoration",            NONE = "none";        var DEFAULTS = {                scaleX: 1,                scaleY: 1            };        var getNextDefsSvgId = function() {                var numDefsSvgElements = 1;                return function() {                        return "DevExpress_" + numDefsSvgElements++                    }            }();        function isObjectArgument(value) {            return typeof value !== "string"        }        function isDefined(value) {            return value !== null && value !== undefined        }        function isArray(value) {            return Object.prototype.toString.call(value) === "[object Array]"        }        function isObject(value) {            return Object.prototype.toString.call(value) === "[object Object]"        }        function createElement(tagName) {            return doc.createElementNS("http://www.w3.org/2000/svg", tagName)        }        function getPatternUrl(id, pathModified) {            return id !== null ? "url(" + (pathModified ? window.location.href : "") + "#" + id + ")" : ""        }        function extend(a, b, skipNonDefined) {            var value;            for (var key in b) {                value = b[key];                if (!skipNonDefined || skipNonDefined && value !== undefined && value !== null)                    a[key] = value            }            return a        }        function rotateBBox(bbox, center, angle) {            var cos = Number(mathCos(angle * PI_DIV_180).toFixed(3)),                sin = Number(mathSin(angle * PI_DIV_180).toFixed(3)),                w2 = bbox.width / 2,                h2 = bbox.height / 2,                xc = bbox.x + w2,                yc = bbox.y + h2,                w2_ = mathAbs(w2 * cos) + mathAbs(h2 * sin),                h2_ = mathAbs(w2 * sin) + mathAbs(h2 * cos),                xc_ = center[0] + (xc - center[0]) * cos + (yc - center[1]) * sin,                yc_ = center[1] - (xc - center[0]) * sin + (yc - center[1]) * cos;            return normalizeBBox({                    x: xc_ - w2_,                    y: yc_ - h2_,                    width: 2 * w2_,                    height: 2 * h2_                })        }        function normalizeBBoxField(value) {            return -MAX_PIXEL_COUNT < value && value < +MAX_PIXEL_COUNT ? value : 0        }        function normalizeBBox(bbox) {            var rxl = normalizeBBoxField(mathFloor(bbox.x)),                ryt = normalizeBBoxField(mathFloor(bbox.y)),                rxr = normalizeBBoxField(mathCeil(bbox.width + bbox.x)),                ryb = normalizeBBoxField(mathCeil(bbox.height + bbox.y)),                result = {                    x: rxl,                    y: ryt,                    width: rxr - rxl,                    height: ryb - ryt                };            result.isEmpty = !result.x && !result.y && !result.width && !result.height;            return result        }        function getPreserveAspectRatio(location) {            return {                    full: NONE,                    lefttop: "xMinYMin",                    leftcenter: "xMinYMid",                    leftbottom: "xMinYMax",                    centertop: "xMidYMin",                    center: "xMidYMid",                    centerbottom: "xMidYMax",                    righttop: "xMaxYMin",                    rightcenter: "xMaxYMid",                    rightbottom: "xMaxYMax"                }[(location || "").toLowerCase()] || NONE        }        rendererNS._normalizeArcParams = function(x, y, innerR, outerR, startAngle, endAngle) {            var isCircle,                noArc = true;            if (mathRound(startAngle) !== mathRound(endAngle)) {                if (mathAbs(endAngle - startAngle) % 360 === 0) {                    startAngle = 0;                    endAngle = 360;                    isCircle = true;                    endAngle -= 0.01                }                if (startAngle > 360)                    startAngle = startAngle % 360;                if (endAngle > 360)                    endAngle = endAngle % 360;                if (startAngle > endAngle)                    startAngle -= 360;                noArc = false            }            startAngle = startAngle * PI_DIV_180;            endAngle = endAngle * PI_DIV_180;            return [x, y, mathMin(outerR, innerR), mathMax(outerR, innerR), mathCos(startAngle), mathSin(startAngle), mathCos(endAngle), mathSin(endAngle), isCircle, mathFloor(mathAbs(endAngle - startAngle) / mathPI) % 2 ? "1" : "0", noArc]        };        var buildArcPath = function(x, y, innerR, outerR, startAngleCos, startAngleSin, endAngleCos, endAngleSin, isCircle, longFlag) {                return ["M", (x + outerR * startAngleCos).toFixed(ARC_COORD_PREC), (y - outerR * startAngleSin).toFixed(ARC_COORD_PREC), "A", outerR.toFixed(ARC_COORD_PREC), outerR.toFixed(ARC_COORD_PREC), 0, longFlag, 0, (x + outerR * endAngleCos).toFixed(ARC_COORD_PREC), (y - outerR * endAngleSin).toFixed(ARC_COORD_PREC), isCircle ? "M" : "L", (x + innerR * endAngleCos).toFixed(5), (y - innerR * endAngleSin).toFixed(ARC_COORD_PREC), "A", innerR.toFixed(ARC_COORD_PREC), innerR.toFixed(ARC_COORD_PREC), 0, longFlag, 1, (x + innerR * startAngleCos).toFixed(ARC_COORD_PREC), (y - innerR * startAngleSin).toFixed(ARC_COORD_PREC), "Z"].join(" ")            };        function buildPathSegments(points, type) {            var list = [["M", 0, 0]];            switch (type) {                case"line":                    list = buildLineSegments(points);                    break;                case"area":                    list = buildLineSegments(points, true);                    break;                case"bezier":                    list = buildCurveSegments(points);                    break;                case"bezierarea":                    list = buildCurveSegments(points, true);                    break            }            return list        }        function buildLineSegments(points, close) {            return buildSegments(points, buildSimpleLineSegment, close)        }        function buildCurveSegments(points, close) {            return buildSegments(points, buildSimpleCurveSegment, close)        }        function buildSegments(points, buildSimpleSegment, close) {            var i = 0,                ii = (points || []).length,                list = [];            if (isArray(points[0]))                for (; i < ii; )                    buildSimpleSegment(points[i++], close, list);            else                buildSimpleSegment(points, close, list);            return list        }        function buildSimpleLineSegment(points, close, list) {            var i = 0,                ii = (points || []).length;            if (ii)                if (isObject(points[0]))                    for (; i < ii; )                        list.push([!i ? "M" : "L", points[i].x, points[i++].y]);                else                    for (; i < ii; )                        list.push([!i ? "M" : "L", points[i++], points[i++]]);            else                list.push(["M", 0, 0]);            close && list.push(["Z"]);            return list        }        function buildSimpleCurveSegment(points, close, list) {            var i = 2,                ii = (points || []).length;            if (ii)                if (isObject(points[0])) {                    i = 1;                    list.push(["M", points[0].x, points[0].y]);                    for (; i < ii; )                        list.push(["C", points[i].x, points[i++].y, points[i].x, points[i++].y, points[i].x, points[i++].y])                }                else {                    list.push(["M", points[0], points[1]]);                    for (; i < ii; )                        list.push(["C", points[i++], points[i++], points[i++], points[i++], points[i++], points[i++]])                }            else                list.push(["M", 0, 0]);            close && list.push(["Z"]);            return list        }        function combinePathParam(segments) {            var d = [],                i = 0,                length = segments.length;            for (; i < length; i++)                d.push(segments[i].join(" "));            return d.join(" ")        }        function compensateSegments(oldSegments, newSegments, type) {            var oldLength = oldSegments.length,                newLength = newSegments.length,                i,                originalNewSegments,                makeEqualSegments = type.indexOf("area") !== -1 ? makeEqualAreaSegments : makeEqualLineSegments;            if (oldLength === 0)                for (i = 0; i < newLength; i++)                    oldSegments.push(newSegments[i].slice(0));            else if (oldLength < newLength)                makeEqualSegments(oldSegments, newSegments, type);            else if (oldLength > newLength) {                originalNewSegments = newSegments.slice(0);                makeEqualSegments(newSegments, oldSegments, type)            }            return originalNewSegments        }        function prepareConstSegment(constSeg, type) {            var x = constSeg[constSeg.length - 2],                y = constSeg[constSeg.length - 1];            switch (type) {                case"line":                case"area":                    constSeg[0] = "L";                    break;                case"bezier":                case"bezierarea":                    constSeg[0] = "C";                    constSeg[1] = constSeg[3] = constSeg[5] = x;                    constSeg[2] = constSeg[4] = constSeg[6] = y;                    break            }        }        function makeEqualLineSegments(short, long, type) {            var constSeg = short[short.length - 1].slice(),                i = short.length;            prepareConstSegment(constSeg, type);            for (; i < long.length; i++)                short[i] = constSeg.slice(0)        }        function makeEqualAreaSegments(short, long, type) {            var i,                head,                shortLength = short.length,                longLength = long.length,                constsSeg1,                constsSeg2;            if ((shortLength - 1) % 2 === 0 && (longLength - 1) % 2 === 0) {                i = (shortLength - 1) / 2 - 1;                head = short.slice(0, i + 1);                constsSeg1 = head[head.length - 1].slice(0);                constsSeg2 = short.slice(i + 1)[0].slice(0);                prepareConstSegment(constsSeg1, type);                prepareConstSegment(constsSeg2, type);                for (var j = i; j < (longLength - 1) / 2 - 1; j++) {                    short.splice(j + 1, 0, constsSeg1);                    short.splice(j + 3, 0, constsSeg2)                }            }        }        function baseCss(styles) {            var elemStyles = this._styles,                str = "",                key,                value;            extend(elemStyles, styles || {}, true);            for (key in elemStyles) {                value = elemStyles[key];                if (value === "")                    continue;                if (typeof value === "number" && !pxAddingExceptions[key])                    value += "px";                str += key + ":" + value + ";"            }            str && this.element.setAttribute("style", str);            return this        }        function baseAttr(attrs) {            attrs = attrs || {};            var that = this,                settings = that._settings,                attributes = {},                key,                value,                elem = that.element,                renderer = that.renderer,                rtl = renderer.rtl,                hasTransformations,                recalculateDashStyle,                sw,                i;            if (!isObjectArgument(attrs)) {                if (attrs in settings)                    return settings[attrs];                if (attrs in DEFAULTS)                    return DEFAULTS[attrs];                return 0            }            extend(attributes, attrs);            for (key in attributes) {                value = attributes[key];                if (value === undefined)                    continue;                settings[key] = value;                if (key === "align") {                    key = "text-anchor";                    value = {                        left: rtl ? "end" : "start",                        center: "middle",                        right: rtl ? "start" : "end"                    }[value] || ""                }                else if (key === "dashStyle") {                    recalculateDashStyle = true;                    continue                }                else if (key === KEY_STROKE_WIDTH)                    recalculateDashStyle = true;                else if (key === "clipId") {                    key = "clip-path";                    value = getPatternUrl(value, renderer.pathModified)                }                else if (/^(translate(X|Y)|rotate[XY]?|scale(X|Y)|sharp)$/i.test(key)) {                    hasTransformations = true;                    continue                }                else if (/^(x|y|d)$/i.test(key))                    hasTransformations = true;                if (value === null)                    elem.removeAttribute(key);                else                    elem.setAttribute(key, value)            }            if (recalculateDashStyle && "dashStyle" in settings) {                value = settings.dashStyle;                sw = ("_originalSW" in that ? that._originalSW : settings[KEY_STROKE_WIDTH]) || 1;                key = "stroke-dasharray";                value = value === null ? "" : value.toLowerCase();                if (value === "" || value === "solid" || value === NONE)                    that.element.removeAttribute(key);                else {                    value = value.replace(/longdash/g, "8,3,").replace(/dash/g, "4,3,").replace(/dot/g, "1,3,").replace(/,$/, "").split(",");                    i = value.length;                    while (i--)                        value[i] = _parseInt(value[i]) * sw;                    that.element.setAttribute(key, value.join(","))                }            }            if (hasTransformations)                that._applyTransformation();            return that        }        function createPathAttr(baseAttr) {            return function(attrs, inh) {                    var that = this,                        segments;                    if (isObjectArgument(attrs)) {                        attrs = extend({}, attrs);                        segments = attrs.segments;                        if ("points" in attrs) {                            segments = buildPathSegments(attrs.points, that.type);                            delete attrs.points                        }                        if (segments) {                            attrs.d = combinePathParam(segments);                            that.segments = segments;                            delete attrs.segments                        }                    }                    return baseAttr.call(that, attrs, inh)                }        }        function createArcAttr(baseAttr, buildArcPath) {            return function(attrs, inh) {                    var settings = this._settings,                        x,                        y,                        innerRadius,                        outerRadius,                        startAngle,                        endAngle;                    if (isObjectArgument(attrs)) {                        attrs = extend({}, attrs);                        if ("x" in attrs || "y" in attrs || "innerRadius" in attrs || "outerRadius" in attrs || "startAngle" in attrs || "endAngle" in attrs) {                            settings.x = x = "x" in attrs ? attrs.x : settings.x;                            delete attrs.x;                            settings.y = y = "y" in attrs ? attrs.y : settings.y;                            delete attrs.y;                            settings.innerRadius = innerRadius = "innerRadius" in attrs ? attrs.innerRadius : settings.innerRadius;                            delete attrs.innerRadius;                            settings.outerRadius = outerRadius = "outerRadius" in attrs ? attrs.outerRadius : settings.outerRadius;                            delete attrs.outerRadius;                            settings.startAngle = startAngle = "startAngle" in attrs ? attrs.startAngle : settings.startAngle;                            delete attrs.startAngle;                            settings.endAngle = endAngle = "endAngle" in attrs ? attrs.endAngle : settings.endAngle;                            delete attrs.endAngle;                            attrs.d = buildArcPath.apply(this, rendererNS._normalizeArcParams(x, y, innerRadius, outerRadius, startAngle, endAngle))                        }                    }                    return baseAttr.call(this, attrs, inh)                }        }        function createRectAttr(baseAttr) {            return function(attrs, inh) {                    var that = this,                        x,                        y,                        width,                        height,                        sw,                        maxSW,                        newSW;                    if (isObjectArgument(attrs)) {                        attrs = extend({}, attrs);                        if (!inh && (attrs.x !== undefined || attrs.y !== undefined || attrs.width !== undefined || attrs.height !== undefined || attrs[KEY_STROKE_WIDTH] !== undefined)) {                            attrs.x !== undefined ? x = that._originalX = attrs.x : x = that._originalX || 0;                            attrs.y !== undefined ? y = that._originalY = attrs.y : y = that._originalY || 0;                            attrs.width !== undefined ? width = that._originalWidth = attrs.width : width = that._originalWidth || 0;                            attrs.height !== undefined ? height = that._originalHeight = attrs.height : height = that._originalHeight || 0;                            attrs[KEY_STROKE_WIDTH] !== undefined ? sw = that._originalSW = attrs[KEY_STROKE_WIDTH] : sw = that._originalSW;                            maxSW = ~~((width < height ? width : height) / 2);                            newSW = (sw || 0) < maxSW ? sw || 0 : maxSW;                            attrs.x = x + newSW / 2;                            attrs.y = y + newSW / 2;                            attrs.width = width - newSW;                            attrs.height = height - newSW;                            ((sw || 0) !== newSW || !(newSW === 0 && sw === undefined)) && (attrs[KEY_STROKE_WIDTH] = newSW)                        }                        if ("sharp" in attrs)                            delete attrs.sharp                    }                    return baseAttr.call(that, attrs, inh)                }        }        var pathAttr = createPathAttr(baseAttr),            arcAttr = createArcAttr(baseAttr, buildArcPath),            rectAttr = createRectAttr(baseAttr);        function textAttr(attrs) {            var that = this,                settings,                isResetRequired,                wasStroked,                isStroked;            if (!isObjectArgument(attrs))                return baseAttr.call(that, attrs);            attrs = extend({}, attrs);            settings = that._settings;            wasStroked = isDefined(settings[KEY_STROKE]) && isDefined(settings[KEY_STROKE_WIDTH]);            if (attrs[KEY_TEXT] !== undefined) {                settings[KEY_TEXT] = attrs[KEY_TEXT];                delete attrs[KEY_TEXT];                isResetRequired = true            }            if (attrs[KEY_STROKE] !== undefined) {                settings[KEY_STROKE] = attrs[KEY_STROKE];                delete attrs[KEY_STROKE]            }            if (attrs[KEY_STROKE_WIDTH] !== undefined) {                settings[KEY_STROKE_WIDTH] = attrs[KEY_STROKE_WIDTH];                delete attrs[KEY_STROKE_WIDTH]            }            if (attrs[KEY_STROKE_OPACITY] !== undefined) {                settings[KEY_STROKE_OPACITY] = attrs[KEY_STROKE_OPACITY];                delete attrs[KEY_STROKE_OPACITY]            }            isStroked = isDefined(settings[KEY_STROKE]) && isDefined(settings[KEY_STROKE_WIDTH]);            baseAttr.call(that, attrs);            isResetRequired = isResetRequired || isStroked !== wasStroked && settings[KEY_TEXT];            if (isResetRequired)                createTextNodes(that, settings.text, isStroked);            if (isResetRequired || attrs["x"] !== undefined || attrs["y"] !== undefined)                locateTextNodes(that);            if (isStroked)                strokeTextNodes(that);            return that        }        function textCss(styles) {            styles = styles || {};            baseCss.call(this, styles);            if (KEY_FONT_SIZE in styles)                locateTextNodes(this);            return this        }        function orderHtmlTree(strCount, node, textArray) {            var nodeParams = node.params = node.params || {style: {}},                nodeStyle = nodeParams.style,                parentStyle = node.parentNode && node.parentNode.params && node.parentNode.params.style || {},                nativeElementStyle = node.style,                childCount = node.childNodes.length,                count = 0;            if (node.nodeName !== '#text')                extend(nodeStyle, parentStyle);            switch (node.tagName) {                case'B':                case'STRONG':                    nodeStyle[KEY_FONT_WEIGHT] = 'bold';                    break;                case'I':                case'EM':                    nodeStyle[KEY_FONT_STYLE] = 'italic';                    break;                case'U':                    nodeStyle[KEY_TEXT_DECORATION] = 'underline';                    break;                case'BR':                    strCount++;                    break            }            if (nativeElementStyle) {                if (nativeElementStyle.fontSize)                    nodeStyle[KEY_FONT_SIZE] = (_parseInt(nativeElementStyle.fontSize, 10) || nodeStyle[KEY_FONT_SIZE]) + 'px';                nodeStyle.fill = nativeElementStyle.color || nodeStyle.fill;                nodeStyle[KEY_FONT_STYLE] = nativeElementStyle.fontStyle || nodeStyle[KEY_FONT_STYLE];                nodeStyle[KEY_FONT_WEIGHT] = nativeElementStyle.fontWeight || nodeStyle[KEY_FONT_WEIGHT];                nodeStyle[KEY_TEXT_DECORATION] = nativeElementStyle.textDecoration || nodeStyle[KEY_TEXT_DECORATION]            }            while (count !== childCount)                strCount = orderHtmlTree(strCount, node.childNodes[count++], textArray);            if (node.wholeText !== undefined) {                extend(nodeStyle, parentStyle);                textArray.push({                    value: node.wholeText,                    style: nodeStyle,                    line: strCount,                    height: _parseInt(nodeStyle[KEY_FONT_SIZE], 10) || 0                })            }            return strCount        }        function adjustLineHeights(items) {            var i,                ii,                currentItem = items[0],                item;            for (i = 1, ii = items.length; i < ii; ++i) {                item = items[i];                if (item.line === currentItem.line) {                    currentItem.height = mathMax(currentItem.height, item.height);                    currentItem.inherits = currentItem.inherits || item.height === 0;                    item.height = NaN                }                else                    currentItem = item            }        }        function parseHTML(text) {            var items = [],                div = doc.createElement("div");            div.innerHTML = text.replace(/\r/g, "").replace(/\n/g, "<br/>");            orderHtmlTree(0, div, items);            adjustLineHeights(items);            return items        }        function parseMultiline(text) {            var texts = text.replace(/\r/g, "").split("\n"),                i = 0,                items = [];            for (; i < texts.length; i++)                items.push({                    value: texts[i],                    height: 0                });            return items        }        function createTspans(items, element, fieldName) {            var i,                ii,                item;            for (i = 0, ii = items.length; i < ii; ++i) {                item = items[i];                item[fieldName] = createElement("tspan");                item[fieldName].appendChild(doc.createTextNode(item.value));                item.style && baseCss.call({                    element: item[fieldName],                    _styles: {}                }, item.style);                element.appendChild(item[fieldName])            }        }        function createTextNodes(wrapper, text, isStroked) {            var items;            wrapper._texts = null;            wrapper.clear();            if (text === null)                return;            text = "" + text;            if (!wrapper.renderer.encodeHtml && (text.indexOf("<") !== -1 || text.indexOf("&") !== -1))                items = parseHTML(text);            else if (text.indexOf("\n") !== -1)                items = parseMultiline(text);            else if (isStroked)                items = [{                        value: text,                        height: 0                    }];            if (items) {                if (items.length) {                    wrapper._texts = items;                    if (isStroked)                        createTspans(items, wrapper.element, KEY_STROKE);                    createTspans(items, wrapper.element, "tspan")                }            }            else                wrapper.element.appendChild(doc.createTextNode(text))        }        function setTextNodeAttribute(item, name, value) {            item.tspan.setAttribute(name, value);            item.stroke && item.stroke.setAttribute(name, value)        }        function locateTextNodes(wrapper) {            if (!wrapper._texts)                return;            var items = wrapper._texts,                x = wrapper._settings.x,                lineHeight = wrapper._styles[KEY_FONT_SIZE] || 12,                i,                ii,                item = items[0];            setTextNodeAttribute(item, "x", x);            setTextNodeAttribute(item, "y", wrapper._settings.y);            for (i = 1, ii = items.length; i < ii; ++i) {                item = items[i];                if (item.height >= 0) {                    setTextNodeAttribute(item, "x", x);                    setTextNodeAttribute(item, "dy", item.inherits ? mathMax(item.height, lineHeight) : item.height || lineHeight)                }            }        }        function strokeTextNodes(wrapper) {            if (!wrapper._texts)                return;            var items = wrapper._texts,                stroke = wrapper._settings[KEY_STROKE],                strokeWidth = wrapper._settings[KEY_STROKE_WIDTH],                strokeOpacity = wrapper._settings[KEY_STROKE_OPACITY] || 1,                tspan,                i,                ii;            for (i = 0, ii = items.length; i < ii; ++i) {                tspan = items[i].stroke;                tspan.setAttribute(KEY_STROKE, stroke);                tspan.setAttribute(KEY_STROKE_WIDTH, strokeWidth);                tspan.setAttribute(KEY_STROKE_OPACITY, strokeOpacity);                tspan.setAttribute("stroke-linejoin", "round")            }        }        function baseAnimate(params, options, complete) {            options = options || {};            var that = this,                key,                value,                renderer = that.renderer,                settings = that._settings,                animationParams = {};            var defaults = {                    translateX: 0,                    translateY: 0,                    scaleX: 1,                    scaleY: 1,                    rotate: 0,                    rotateX: 0,                    rotateY: 0                };            if (complete)                options.complete = complete;            if (renderer.animationEnabled()) {                for (key in params) {                    value = params[key];                    if (/^(translate(X|Y)|rotate[XY]?|scale(X|Y))$/i.test(key)) {                        animationParams.transform = animationParams.transform || {                            from: {},                            to: {}                        };                        animationParams.transform.from[key] = key in settings ? settings[key] : defaults[key];                        animationParams.transform.to[key] = value                    }                    else if (key === "arc" || key === "segments")                        animationParams[key] = value;                    else                        animationParams[key] = {                            from: key in settings ? settings[key] : parseFloat(that.element.getAttribute(key) || 0),                            to: value                        }                }                renderer.animateElement(that, animationParams, extend(extend({}, renderer._animation), options))            }            else {                options.step && options.step.call(that, 1, 1);                options.complete && options.complete.call(that);                that.attr(params)            }            return that        }        function pathAnimate(params, options, complete) {            var that = this,                curSegments = that.segments || [],                newSegments,                endSegments;            if (that.renderer.animationEnabled() && "points" in params) {                newSegments = buildPathSegments(params.points, that.type);                endSegments = compensateSegments(curSegments, newSegments, that.type);                params.segments = {                    from: curSegments,                    to: newSegments,                    end: endSegments                };                delete params.points            }            return baseAnimate.call(that, params, options, complete)        }        function arcAnimate(params, options, complete) {            var that = this,                settings = that._settings,                arcParams = {                    from: {},                    to: {}                };            if (that.renderer.animationEnabled() && ("x" in params || "y" in params || "innerRadius" in params || "outerRadius" in params || "startAngle" in params || "endAngle" in params)) {                arcParams.from.x = settings.x || 0;                arcParams.from.y = settings.y || 0;                arcParams.from.innerRadius = settings.innerRadius || 0;                arcParams.from.outerRadius = settings.outerRadius || 0;                arcParams.from.startAngle = settings.startAngle || 0;                arcParams.from.endAngle = settings.endAngle || 0;                arcParams.to.x = "x" in params ? params.x : settings.x;                delete params.x;                arcParams.to.y = "y" in params ? params.y : settings.y;                delete params.y;                arcParams.to.innerRadius = "innerRadius" in params ? params.innerRadius : settings.innerRadius;                delete params.innerRadius;                arcParams.to.outerRadius = "outerRadius" in params ? params.outerRadius : settings.outerRadius;                delete params.outerRadius;                arcParams.to.startAngle = "startAngle" in params ? params.startAngle : settings.startAngle;                delete params.startAngle;                arcParams.to.endAngle = "endAngle" in params ? params.endAngle : settings.endAngle;                delete params.endAngle;                params.arc = arcParams            }            return baseAnimate.call(that, params, options, complete)        }        rendererNS.__mockPrivateFunctions = function(fs) {            fs = fs || {};            function mockFunction(mock, orig) {                if (!mock)                    return orig;                var originalFunction = orig;                orig = mock;                orig._originalFunction = originalFunction;                return orig            }            createElement = mockFunction(fs.createElement, createElement);            baseAttr = mockFunction(fs.baseAttr, baseAttr);            baseAnimate = mockFunction(fs.baseAnimate, baseAnimate);            getNextDefsSvgId = mockFunction(fs.getNextDefsSvgId, getNextDefsSvgId);            compensateSegments = mockFunction(fs.compensateSegments, compensateSegments);            buildPathSegments = mockFunction(fs.buildPathSegments, buildPathSegments);            buildArcPath = mockFunction(fs.buildArcPath, buildArcPath);            pathAttr = createPathAttr(baseAttr);            arcAttr = createArcAttr(baseAttr, buildArcPath);            rectAttr = createRectAttr(baseAttr);            return {                    createElement: createElement,                    baseAttr: baseAttr,                    baseAnimate: baseAnimate,                    getNextDefsSvgId: getNextDefsSvgId,                    compensateSegments: compensateSegments,                    buildPathSegments: buildPathSegments,                    buildArcPath: buildArcPath                }        };        rendererNS.__restoreMockPrivateFunctions = function() {            function restoreFunction(func) {                return func._originalFunction || func            }            createElement = restoreFunction(createElement);            baseAttr = restoreFunction(baseAttr);            baseAnimate = restoreFunction(baseAnimate);            getNextDefsSvgId = restoreFunction(getNextDefsSvgId);            compensateSegments = restoreFunction(compensateSegments);            buildPathSegments = restoreFunction(buildPathSegments);            buildArcPath = restoreFunction(buildArcPath);            pathAttr = createPathAttr(baseAttr);            arcAttr = createArcAttr(baseAttr, buildArcPath);            rectAttr = createRectAttr(baseAttr)        };        function SvgElement() {            this.ctor.apply(this, arguments)        }        rendererNS.SvgElement = SvgElement;        SvgElement.prototype = {            ctor: function(renderer, tagName, type) {                var that = this;                that.renderer = renderer;                that.element = createElement(tagName);                that._settings = {};                that._styles = {};                if (tagName === "path")                    that.type = type || "line";                if (tagName === "text") {                    that.attr = textAttr;                    that.css = textCss                }                else if (tagName === "path")                    if (that.type === "arc") {                        that.attr = arcAttr;                        that.animate = arcAnimate                    }                    else {                        that.attr = pathAttr;                        that.animate = pathAnimate                    }                else if (tagName === "rect") {                    that.attr = rectAttr;                    that.sharp = function() {                        return this                    }                }                that._$element = $(that.element)            },            dispose: function() {                this._$element.remove();                return this            },            append: function(parent) {                parent = parent || this.renderer.root;                (parent.element || parent).appendChild(this.element);                return this            },            remove: function() {                var elem = this.element,                    parent = elem.parentNode;                parent && parent.removeChild(elem);                return this            },            clear: function() {                this._$element.empty();                return this            },            toBackground: function() {                var elem = this.element,                    parent = elem.parentNode;                parent && parent.insertBefore(elem, parent.firstChild);                return this            },            toForeground: function() {                var elem = this.element,                    parent = elem.parentNode;                parent && parent.appendChild(elem);                return this            },            css: baseCss,            attr: baseAttr,            sharp: function(pos) {                return this.attr({sharp: pos || true})            },            _applyTransformation: function() {                var tr = this._settings,                    scaleXDefined,                    scaleYDefined,                    transformations = [],                    rotateX,                    rotateY,                    sharpMode = tr.sharp,                    strokeOdd = tr[KEY_STROKE_WIDTH] % 2,                    correctionX = strokeOdd && (sharpMode === "h" || sharpMode === true) ? SHARPING_CORRECTION : 0,                    correctionY = strokeOdd && (sharpMode === "v" || sharpMode === true) ? SHARPING_CORRECTION : 0;                if (!("rotateX" in tr))                    rotateX = tr.x;                else                    rotateX = tr.rotateX;                if (!("rotateY" in tr))                    rotateY = tr.y;                else                    rotateY = tr.rotateY;                transformations.push("translate(" + ((tr.translateX || 0) + correctionX) + "," + ((tr.translateY || 0) + correctionY) + ")");                if (tr.rotate)                    transformations.push("rotate(" + tr.rotate + "," + (rotateX || 0) + "," + (rotateY || 0) + ")");                scaleXDefined = isDefined(tr.scaleX);                scaleYDefined = isDefined(tr.scaleY);                if (scaleXDefined || scaleYDefined)                    transformations.push("scale(" + (scaleXDefined ? tr.scaleX : 1) + "," + (scaleYDefined ? tr.scaleY : 1) + ")");                if (transformations.length)                    this.element.setAttribute("transform", transformations.join(" "))            },            move: function(x, y, animate, animOptions) {                var obj = {};                isDefined(x) && (obj.translateX = x);                isDefined(y) && (obj.translateY = y);                if (!animate)                    this.attr(obj);                else                    this.animate(obj, animOptions);                return this            },            rotate: function(angle, x, y, animate, animOptions) {                var obj = {rotate: angle || 0};                isDefined(x) && (obj.rotateX = x);                isDefined(y) && (obj.rotateY = y);                if (!animate)                    this.attr(obj);                else                    this.animate(obj, animOptions);                return this            },            getBBox: function() {                var elem = this.element,                    transformation = this._settings,                    bBox;                try {                    bBox = elem.getBBox && elem.getBBox()                }                catch(e) {}                bBox = bBox || {                    x: 0,                    y: 0,                    width: elem.offsetWidth || 0,                    height: elem.offsetHeight || 0                };                if (transformation.rotate)                    bBox = rotateBBox(bBox, [("rotateX" in transformation ? transformation.rotateX : transformation.x) || 0, ("rotateY" in transformation ? transformation.rotateY : transformation.y) || 0], -transformation.rotate);                else                    bBox = normalizeBBox(bBox);                return bBox            },            markup: function() {                var temp = doc.createElement('div'),                    node = this.element.cloneNode(true);                temp.appendChild(node);                return temp.innerHTML            },            getOffset: function() {                return this._$element.offset()            },            animate: baseAnimate,            stopAnimation: function(disableComplete) {                var animation = this.animation;                animation && animation.stop(true, disableComplete);                return this            },            setTitle: function(text) {                var titleElem = createElement('title');                titleElem.textContent = text || '';                this.element.appendChild(titleElem)            },            on: function() {                $.fn.on.apply(this._$element, arguments);                return this            },            off: function() {                $.fn.off.apply(this._$element, arguments);                return this            },            trigger: function() {                $.fn.trigger.apply(this._$element, arguments);                return this            },            data: function() {                $.fn.data.apply(this._$element, arguments);                return this            }        };        function SvgRenderer(options) {            var that = this;            that.root = that._createElement("svg", {                xmlns: "http://www.w3.org/2000/svg",                "xmlns:xlink": "http://www.w3.org/1999/xlink",                version: "1.1",                fill: NONE,                stroke: NONE,                "stroke-width": 0,                "class": options.cssClass            }).css({                "line-height": "normal",                "-ms-user-select": NONE,                "-moz-user-select": NONE,                "-webkit-user-select": NONE,                "-webkit-tap-highlight-color": "rgba(0, 0, 0, 0)",                display: "block",                overflow: "hidden"            });            that._defs = that._createElement("defs");            that._animationController = new rendererNS.AnimationController(that.root.element);            that._animation = {                enabled: true,                duration: 1000,                easing: "easeOutCubic"            }        }        rendererNS.SvgRenderer = SvgRenderer;        SvgRenderer.prototype = {            constructor: SvgRenderer,            setOptions: function(options) {                var that = this;                that.pathModified = !!options.pathModified;                that.rtl = !!options.rtl;                that.encodeHtml = !!options.encodeHtml,                that.updateAnimationOptions(options.animation || {});                that.root.attr({direction: that.rtl ? "rtl" : "ltr"})            },            _createElement: function(tagName, attr, type) {                var elem = new rendererNS.SvgElement(this, tagName, type);                attr && elem.attr(attr);                return elem            },            draw: function(container) {                var that = this;                if (!container || that.drawn)                    return that;                that.root.append(container);                that._defs.append(that.root);                that.drawn = true;                return that            },            resize: function(width, height) {                if (width >= 0 && height >= 0)                    this.root.attr({                        width: width,                        height: height                    });                return this            },            clear: function() {                var that = this;                that.root.remove();                that._defs.remove();                that.drawn = null;                return this            },            dispose: function() {                var that = this,                    key;                that.root.dispose();                that._defs.dispose();                that._animationController.dispose();                for (key in that)                    that[key] = null;                return null            },            animationEnabled: function() {                return !!this._animation.enabled            },            updateAnimationOptions: function(newOptions) {                extend(this._animation, newOptions);                return this            },            stopAllAnimations: function(lock) {                this._animationController[lock ? "lock" : "stop"]();                return this            },            animateElement: function(element, params, options) {                this._animationController.animateElement(element, params, options);                return this            },            svg: function() {                return this.root.markup()            },            getRootOffset: function() {                return this.root.getOffset()            },            onEndAnimation: function(endAnimation) {                this._animationController.onEndAnimation(endAnimation)            },            rect: function(x, y, width, height) {                return this._createElement("rect", {                        x: x || 0,                        y: y || 0,                        width: width || 0,                        height: height || 0                    })            },            circle: function(x, y, r) {                return this._createElement("circle", {                        cx: x || 0,                        cy: y || 0,                        r: r || 0                    })            },            g: function() {                return this._createElement("g")            },            image: function(x, y, w, h, href, location) {                var image = this._createElement("image", {                        x: x || 0,                        y: y || 0,                        width: w || 0,                        height: h || 0,                        preserveAspectRatio: getPreserveAspectRatio(location)                    });                image.element.setAttributeNS("http://www.w3.org/1999/xlink", "href", href || "");                return image            },            path: function(points, type) {                return this._createElement("path", {points: points || []}, type)            },            arc: function(x, y, innerRadius, outerRadius, startAngle, endAngle) {                return this._createElement("path", {                        x: x || 0,                        y: y || 0,                        innerRadius: innerRadius || 0,                        outerRadius: outerRadius || 0,                        startAngle: startAngle || 0,                        endAngle: endAngle || 0                    }, "arc")            },            text: function(text, x, y) {                return this._createElement("text", {                        text: text,                        x: x || 0,                        y: y || 0                    })            },            pattern: function(color, hatching) {                hatching = hatching || {};                var that = this,                    id,                    d,                    pattern,                    rect,                    path,                    step = hatching.step || 6,                    stepTo2 = step / 2,                    stepBy15 = step * 1.5,                    direction = (hatching.direction || "").toLowerCase();                if (direction !== "right" && direction !== "left")                    return {                            id: color,                            append: function() {                                return this                            },                            clear: function(){},                            dispose: function(){},                            remove: function(){}                        };                id = getNextDefsSvgId();                d = direction === "right" ? "M " + stepTo2 + " " + -stepTo2 + " L " + -stepTo2 + " " + stepTo2 + " M 0 " + step + " L " + step + " 0 M " + stepBy15 + " " + stepTo2 + " L " + stepTo2 + " " + stepBy15 : "M 0 0 L " + step + " " + step + " M " + -stepTo2 + " " + stepTo2 + " L " + stepTo2 + " " + stepBy15 + " M " + stepTo2 + " " + -stepTo2 + " L " + stepBy15 + " " + stepTo2;                pattern = that._createElement("pattern", {                    id: id,                    width: step,                    height: step,                    patternUnits: "userSpaceOnUse"                }).append(that._defs);                pattern.id = getPatternUrl(id, that.pathModified);                rect = that.rect(0, 0, step, step).attr({                    fill: color,                    opacity: hatching.opacity                }).append(pattern);                path = that._createElement("path", {                    d: d,                    "stroke-width": hatching.width || 1,                    stroke: color                }).append(pattern);                pattern.rect = rect;                pattern.path = path;                return pattern            },            clipRect: function(x, y, width, height) {                var that = this,                    id = getNextDefsSvgId(),                    clipPath = that._createElement("clipPath", {id: id}).append(that._defs),                    rect = that.rect(x, y, width, height).append(clipPath);                rect.id = id;                rect.clipPath = clipPath;                rect.remove = function() {                    throw"Not implemented";                };                rect.dispose = function() {                    clipPath.dispose();                    clipPath = null;                    return this                };                return rect            },            shadowFilter: function(x, y, width, height, offsetX, offsetY, blur, color, opacity) {                var that = this,                    id = getNextDefsSvgId(),                    filter = that._createElement("filter", {                        id: id,                        x: x || 0,                        y: y || 0,                        width: width || 0,                        height: height || 0                    }).append(that._defs),                    gaussianBlur = that._createElement("feGaussianBlur", {                        "in": "SourceGraphic",                        result: "gaussianBlurResult",                        stdDeviation: blur || 0                    }).append(filter),                    offset = that._createElement("feOffset", {                        "in": "gaussianBlurResult",                        result: "offsetResult",                        dx: offsetX || 0,                        dy: offsetY || 0                    }).append(filter),                    flood = that._createElement("feFlood", {                        result: "floodResult",                        "flood-color": color || "",                        "flood-opacity": opacity                    }).append(filter),                    composite = that._createElement("feComposite", {                        "in": "floodResult",                        in2: "offsetResult",                        operator: "in",                        result: "compositeResult"                    }).append(filter),                    finalComposite = that._createElement("feComposite", {                        "in": "SourceGraphic",                        in2: "compositeResult",                        operator: "over"                    }).append(filter);                filter.ref = getPatternUrl(id, that.pathModified);                filter.gaussianBlur = gaussianBlur;                filter.offset = offset;                filter.flood = flood;                filter.composite = composite;                filter.finalComposite = finalComposite;                filter.attr = function(attrs) {                    var that = this,                        filterAttrs = {},                        offsetAttrs = {},                        floodAttrs = {};                    "x" in attrs && (filterAttrs.x = attrs.x);                    "y" in attrs && (filterAttrs.y = attrs.y);                    "width" in attrs && (filterAttrs.width = attrs.width);                    "height" in attrs && (filterAttrs.height = attrs.height);                    baseAttr.call(that, filterAttrs);                    "blur" in attrs && that.gaussianBlur.attr({stdDeviation: attrs.blur});                    "offsetX" in attrs && (offsetAttrs.dx = attrs.offsetX);                    "offsetY" in attrs && (offsetAttrs.dy = attrs.offsetY);                    that.offset.attr(offsetAttrs);                    "color" in attrs && (floodAttrs["flood-color"] = attrs.color);                    "opacity" in attrs && (floodAttrs["flood-opacity"] = attrs.opacity);                    that.flood.attr(floodAttrs);                    return that                };                return filter            }        };        rendererNS.rotateBBox = rotateBBox;        rendererNS._createArcAttr = createArcAttr;        rendererNS._createPathAttr = createPathAttr;        rendererNS._createRectAttr = createRectAttr    })(jQuery, DevExpress, document);    /*! Module viz-core, file vmlRenderer.js */    (function($, DX, doc) {        DX.viz.renderers = DX.viz.renderers || {};        var rendererNS = DX.viz.renderers,            math = Math,            mathMin = math.min,            mathMax = math.max,            mathFloor = math.floor,            mathSin = math.sin,            mathCos = math.cos,            baseElementPrototype = rendererNS.SvgElement.prototype,            documentFragment = doc.createDocumentFragment(),            DEFAULT_STYLE = {                behavior: "url(#default#VML)",                display: "inline-block",                position: "absolute"            },            DEFAULT_ATTRS = {xmlns: 'urn:schemas-microsoft-com:vml'},            INHERITABLE_PROPERTIES = {                stroke: true,                fill: true,                opacity: true,                'stroke-width': true,                align: true,                dashStyle: true,                "stroke-opacity": true,                'fill-opacity': true,                rotate: true,                rotateX: true,                rotateY: true            },            stub = function(){},            stubReturnedThis = function() {                return this            },            svgToVmlConv = {                circle: "oval",                g: "div",                path: "shape",                text: "span"            },            FONT_HEIGHT_OFFSET_K = 0.55 + 0.45 / 2,            DEFAULTS = {                scaleX: 1,                scaleY: 1            },            pathAttr = rendererNS._createPathAttr(vmlAttr),            arcAttr = rendererNS._createArcAttr(vmlAttr, buildArcPath),            rectAttr = rendererNS._createRectAttr(vmlAttr);        function isDefined(value) {            return value !== null && value !== undefined        }        function extend(a, b) {            for (var key in b)                a[key] = b[key];            return a        }        function inArray(array, elem) {            var i = 0;            for (; i < array.length; i++)                if (elem === array[i])                    return i;            return -1        }        function buildArcPath(x, y, innerR, outerR, startAngleCos, startAngleSin, endAngleCos, endAngleSin, isCircle, longFlag, noArc) {            var xOuterStart = x + outerR * startAngleCos,                yOuterStart = y - outerR * startAngleSin,                xOuterEnd = x + outerR * endAngleCos,                yOuterEnd = y - outerR * endAngleSin,                xInnerStart = x + innerR * endAngleCos,                yInnerStart = y - innerR * endAngleSin,                xInnerEnd = x + innerR * startAngleCos,                yInnerEnd = y - innerR * startAngleSin;            return !noArc ? ['wr', mathFloor(x - innerR), mathFloor(y - innerR), mathFloor(x + innerR), mathFloor(y + innerR), mathFloor(xInnerStart), mathFloor(yInnerStart), mathFloor(xInnerEnd), mathFloor(yInnerEnd), isCircle ? 'wr ' : 'at ', mathFloor(x - outerR), mathFloor(y - outerR), mathFloor(x + outerR), mathFloor(y + outerR), mathFloor(xOuterStart), mathFloor(yOuterStart), mathFloor(xOuterEnd), mathFloor(yOuterEnd), 'x e'].join(" ") : "m 0 0 x e"        }        function getInheritSettings(settings) {            var result = {},                prop,                value;            for (prop in INHERITABLE_PROPERTIES) {                value = settings[prop];                value !== undefined && (result[prop] = value)            }            return result        }        function correctBoundingRectWithStrokeWidth(rect, strokeWidth) {            strokeWidth = Math.ceil(parseInt(strokeWidth) / 2);            if (strokeWidth && strokeWidth > 1) {                rect.left -= strokeWidth;                rect.top -= strokeWidth;                rect.right += strokeWidth;                rect.bottom += strokeWidth            }            return rect        }        function shapeBBox() {            var points = (this._settings.d || "").match(/[-0-9]+/g),                i,                value,                resultRect = {};            for (i = 0; i < points.length; i++) {                value = parseInt(points[i]);                if (i % 2) {                    resultRect.top = resultRect.top === undefined || value < resultRect.top ? value : resultRect.top;                    resultRect.bottom = resultRect.bottom === undefined || value > resultRect.bottom ? value : resultRect.bottom                }                else {                    resultRect.left = resultRect.left === undefined || value < resultRect.left ? value : resultRect.left;                    resultRect.right = resultRect.right === undefined || value > resultRect.right ? value : resultRect.right                }            }            resultRect.left = resultRect.left || 0;            resultRect.top = resultRect.top || 0;            resultRect.right = resultRect.right || 0;            resultRect.bottom = resultRect.bottom || 0;            return correctBoundingRectWithStrokeWidth(resultRect, this._fullSettings["stroke-width"])        }        function baseAttr(attrs, inh) {            var element = this.element,                settings = this._settings,                fullSettings = this._fullSettings,                value,                key,                params = {style: {}},                appliedAttr,                elem;            if (typeof attrs === "string") {                if (attrs in settings)                    return settings[attrs];                if (attrs in DEFAULTS)                    return DEFAULTS[attrs];                return 0            }            for (key in attrs) {                value = attrs[key];                if (value === undefined)                    continue;                appliedAttr = fullSettings[key];                !inh && (settings[key] = value);                fullSettings[key] = value;                if (INHERITABLE_PROPERTIES[key])                    value = value === null ? this._parent && this._parent._fullSettings[key] || value : value;                appliedAttr !== value && this.processAttr(element, key, value, params)            }            this._applyTransformation(params);            this.css(params.style);            for (var i = 0; i < this._children.length; i++) {                elem = this._children[i];                elem !== this._clipRect && elem.attr(extend(getInheritSettings(this._fullSettings), elem._settings), true);                elem._applyStyleSheet()            }            !inh && this._applyStyleSheet();            return this        }        function vmlAttr() {            var elem = this.element,                result = baseAttr.apply(this, arguments);            for (var i = 0; i < elem.childNodes.length; i++) {                elem.childNodes[i].xmlns = 'urn:schemas-microsoft-com:vml';                elem.childNodes[i].style.behavior = "url(#default#VML)";                elem.childNodes[i].style.display = "inline-block"            }            return result        }        function processVmlAttr(element, attr, value, params) {            switch (attr) {                case"stroke":                    value = value || "none";                    element.stroked = value === 'none' ? 'f' : 't';                    attr += "color";                    break;                case"fill":                    value = value || "none";                    element.filled = value === 'none' ? 'f' : 't';                    attr += "color";                    break;                case"stroke-width":                    attr = "strokeweight";                    value = value + 'px';                    break;                case"stroke-linejoin":                    element.stroke.joinstyle = value;                    return;                case"stroke-linecap":                    element.stroke.endcap = value === "butt" ? "flat" : value;                    return;                case"opacity":                    value = adjustOpacityValue(value);                    element.fill.opacity = value;                    element.stroke.opacity = value;                    return;                case"fill-opacity":                    element.fill.opacity = adjustOpacityValue(value);                    return;                case"stroke-opacity":                    element.stroke.opacity = adjustOpacityValue(value);                    return;                case"dashStyle":                    if (value === null)                        element.stroke[attr] = "";                    else {                        value = value.toLowerCase();                        if (value === "solid" || value === "none")                            value = "";                        else                            value = value.replace(/longdash/g, "8,3,").replace(/dash/g, "4,3,").replace(/dot/g, "1,3,").replace(/,$/, "");                        element.stroke[attr] = value                    }                    return;                case"d":                    attr = "path";                    value = (value + '').toLowerCase().replace("z", "x e").replace(/([.]\d+)/g, "");                    break;                case"href":                    attr = "src";                    break;                case"width":                case"height":                case"visibility":                    params.style[attr] = value || "";                    return;                case"class":                    attr += "Name";                    break;                case"translateX":                case"translateY":                case"rotate":                case"rotateX":                case"rotateY":                case"scale":                case"scaleX":                case"scaleY":                case"x":                case"y":                    return            }            element[attr] = value        }        function adjustOpacityValue(value) {            return value >= 0.002 ? value : value === null ? 1 : 0.002        }        function createElement(tagName) {            var element = document.createElement(tagName);            return documentFragment.appendChild(element)        }        var VmlElement = function() {                this.ctor.apply(this, arguments)            };        function processAttr(element, attr, value, params) {            if (!INHERITABLE_PROPERTIES[attr])                if (attr === "visibility")                    params.style[attr] = value || "";                else if (attr === "width" || attr === "height")                    params.style[attr] = value;                else if (attr === "clipId")                    this.applyClipID(value);                else if (attr === "translateX" || attr === "translateY" || attr === "x" || attr === "y")                    return;                else if (attr === "class")                    element.className = value;                else                    element[attr] = value        }        var elementMixin = {                div: {                    processAttr: processAttr,                    attr: baseAttr,                    _applyTransformation: function(params) {                        var style = params.style,                            settings = this._settings,                            fullSettings = this._fullSettings;                        if (fullSettings.rotate) {                            fullSettings.rotateX = fullSettings.rotateX || 0;                            fullSettings.rotateY = fullSettings.rotateY || 0                        }                        style.left = (settings.x || 0) + (settings.translateX || 0);                        style.top = (settings.y || 0) + (settings.translateY || 0)                    },                    _getBBox: function() {                        var left = Infinity,                            top = Infinity,                            right = -Infinity,                            bottom = -Infinity,                            i = 0,                            child,                            children = this._children,                            translateX,                            translateY,                            childBBox,                            childSettings;                        if (!children.length)                            left = top = bottom = right = 0;                        else                            for (; i < children.length; i++) {                                child = children[i];                                if (child === this._clipRect)                                    continue;                                translateX = child._fullSettings.translateX || 0;                                translateY = child._fullSettings.translateY || 0;                                childSettings = child._fullSettings;                                childBBox = child._getBBox();                                left = mathMin(left, childBBox.left + translateX);                                right = mathMax(right, childBBox.right + translateX);                                top = mathMin(top, childBBox.top + translateY);                                bottom = mathMax(bottom, childBBox.bottom + translateY)                            }                        return {                                left: left,                                right: right,                                top: top,                                bottom: bottom                            }                    },                    defaultAttrs: {},                    defaultStyle: {position: "absolute"}                },                shape: {                    defaultAttrs: extend({                        coordsize: "1,1",                        "stroke-linejoin": "miter"                    }, DEFAULT_ATTRS),                    defaultStyle: extend({                        width: 1,                        height: 1                    }, DEFAULT_STYLE),                    _getBBox: shapeBBox                },                image: {processAttr: function(element, attr, value, params) {                        if (attr === "fill" || attr === "stroke")                            return;                        processVmlAttr(element, attr, value, params)                    }},                oval: {                    processAttr: function(element, attr, value, params) {                        if (attr === "cx" || attr === "cy")                            attr = attr[1];                        else if (attr === "r") {                            value *= 2;                            processVmlAttr(element, "width", value, params);                            attr = "height"                        }                        else if (attr === "x" || attr === "y")                            return;                        processVmlAttr(element, attr, value, params)                    },                    _getBBox: function() {                        var settings = this._fullSettings,                            x = settings.cx || 0,                            y = settings.cy || 0,                            r = settings.r || 0;                        return correctBoundingRectWithStrokeWidth({                                left: x - r,                                top: y - r,                                right: x + r,                                bottom: y + r                            }, settings["stroke-width"] || 1)                    }                },                span: {                    defaultAttrs: {},                    defaultStyle: {                        position: 'absolute',                        whiteSpace: 'nowrap'                    },                    processAttr: function(element, attr, value, params) {                        if (attr === "text") {                            value = isDefined(value) ? value.toString().replace(/\r/g, "") : "";                            if (this.renderer.encodeHtml)                                value = value.replace(/</g, "<").replace(/>/g, ">");                            element.innerHTML = value.replace(/\n/g, "<br/>");                            this.css({filter: ""});                            this._bbox = null                        }                        else                            processAttr(element, attr, value, params)                    },                    attr: baseAttr,                    _applyTransformation: function(params) {                        this.element.offsetHeight;                        var that = this,                            style = params.style,                            settings = that._fullSettings,                            x = isDefined(settings.x) ? settings.x : 0,                            y = isDefined(settings.y) ? settings.y : 0,                            bbox = that._bbox || that.element.getBoundingClientRect(),                            textHeight = bbox.bottom - bbox.top,                            textWidth = bbox.right - bbox.left,                            rotateAngle = settings.rotate,                            cos = 1,                            sin = 0,                            rotateX = isDefined(settings.rotateX) ? settings.rotateX : x,                            rotateY = isDefined(settings.rotateY) ? settings.rotateY : y,                            radianAngle,                            marginLeft = 0,                            marginTop = 0,                            fontHeightOffset = textHeight * FONT_HEIGHT_OFFSET_K,                            filter = "",                            alignMultiplier = {                                center: 0.5,                                right: 1                            }[settings.align],                            opacity = this._styles.opacity || settings.opacity || settings["fill-opacity"];                        if (textHeight && textWidth) {                            if (rotateAngle) {                                radianAngle = rotateAngle * Math.PI / 180.0;                                cos = mathCos(radianAngle);                                sin = mathSin(radianAngle);                                marginLeft = (x - rotateX) * cos - (y - rotateY) * sin + rotateX - x;                                marginTop = (x - rotateX) * sin + (y - rotateY) * cos + rotateY - y;                                filter = 'progid:DXImageTransform.Microsoft.Matrix(sizingMethod="auto expand", M11 = ' + cos.toFixed(5) + ', M12 = ' + (-sin).toFixed(5) + ', M21 = ' + sin.toFixed(5) + ', M22 = ' + cos.toFixed(5) + ')'                            }                            if (rotateAngle < 90) {                                marginTop -= fontHeightOffset * cos;                                marginLeft -= (textHeight - fontHeightOffset) * sin                            }                            else if (rotateAngle < 180) {                                marginTop += (textHeight - fontHeightOffset) * cos;                                marginLeft += textWidth * cos - (textHeight - fontHeightOffset) * sin                            }                            else if (rotateAngle < 270) {                                marginTop += (textHeight - fontHeightOffset) * cos + textWidth * sin;                                marginLeft += textWidth * cos + fontHeightOffset * sin                            }                            else {                                marginTop += textWidth * sin - fontHeightOffset * cos;                                marginLeft += fontHeightOffset * sin                            }                            if (rotateAngle && this.renderer.rtl)                                marginLeft -= textWidth - (textHeight * Math.abs(sin) + textWidth * Math.abs(cos));                            if (alignMultiplier) {                                marginLeft -= textWidth * alignMultiplier * cos;                                marginTop -= textWidth * alignMultiplier * sin                            }                            if (isDefined(opacity))                                filter += " progid:DXImageTransform.Microsoft.Alpha(Opacity=" + opacity * 100 + ")";                            x += marginLeft;                            y += marginTop;                            this._bbox = bbox;                            style.filter = (style.filter || "") + filter;                            style.left = x + (settings.translateX || 0);                            style.top = y + (settings.translateY || 0)                        }                    },                    _getBBox: function textBBox() {                        var element = this.element,                            settings = this._fullSettings,                            parentRect = (element.parentNode && element.parentNode.getBoundingClientRect ? element.parentNode : this.renderer.root.element).getBoundingClientRect(),                            boundingRect = element.getBoundingClientRect(),                            left = boundingRect.left - (settings.translateX || 0) - parentRect.left,                            top = boundingRect.top - (settings.translateY || 0) - parentRect.top;                        return {                                left: left,                                top: top,                                right: left + element.offsetWidth,                                bottom: top + element.offsetHeight                            }                    }                }            };        extend(VmlElement.prototype, baseElementPrototype);        extend(VmlElement.prototype, {            defaultStyle: DEFAULT_STYLE,            defaultAttrs: DEFAULT_ATTRS,            ctor: function(renderer, tagName, type) {                var that = this,                    tagPrefix = '<';                that.renderer = renderer;                that.type = type;                that._children = [];                that._settings = {};                that._fullSettings = {};                that._styles = {};                if (tagName !== "div" && tagName !== "span")                    tagPrefix = "<vml:";                if (tagName === "shape")                    if (that.type === "arc")                        that.attr = arcAttr;                    else                        that.attr = pathAttr;                else if (tagName === "rect")                    that.attr = rectAttr;                extend(that, elementMixin[tagName]);                that.element = createElement(tagPrefix + tagName + "/>");                that.css(that.defaultStyle).attr(that.defaultAttrs);                that._$element = $(that.element)            },            dispose: function() {                this.remove();                this._$element.remove();                return this            },            attr: vmlAttr,            processAttr: processVmlAttr,            css: function(css) {                var elem = this.element,                    value,                    appliedValue,                    key;                for (key in css) {                    appliedValue = this._styles[key];                    value = css[key];                    if (!isDefined(value))                        continue;                    this._styles[key] = value;                    if (appliedValue === value)                        continue;                    switch (key) {                        case"fill":                            key = "color";                            break;                        case"font-size":                            key = "fontSize";                            if (typeof value === "number")                                value += "px";                            break;                        case"font-weight":                            key = "fontWeight";                            break;                        case"z-index":                            key = "zIndex";                            break;                        case"opacity":                            continue                    }                    try {                        elem.style[key] = value                    }                    catch(_) {                        continue                    }                }                return this            },            applyClipID: function(id) {                var clipRect,                    cssValue,                    renderer = this.renderer;                clipRect = renderer.getClipRect(id);                if (clipRect) {                    cssValue = clipRect.getValue();                    clipRect.addElement(this)                }                else                    cssValue = "rect(-9999px 9999px 9999px -9999px)";                this._clipRect = this._clipRect || renderer.rect(0, 0, 0, 0).attr({                    "class": "dxc-vml-clip",                    fill: "none",                    opacity: 0.001                });                this._clipRect.attr({                    width: renderer.root.attr("width"),                    height: renderer.root.attr("height")                });                this.css({                    clip: cssValue,                    width: renderer.root.attr("width"),                    height: renderer.root.attr("height")                })            },            append: function(parent) {                parent = parent || this.renderer.root;                (parent.element || parent).appendChild(this.element);                if (parent._children) {                    this._parent = parent;                    if (inArray(parent._children, this) === -1)                        parent._children.push(this);                    this.attr(extend(getInheritSettings(parent._fullSettings), this._settings), true)                }                this._applyStyleSheet();                if (parent._clipRect && this !== parent._clipRect)                    parent._clipRect.append(parent);                return this            },            _applyTransformation: function(params) {                var that = this,                    style = params.style,                    element = that.element,                    settings = that._fullSettings,                    x = that.type !== "arc" ? settings.x || settings.cx - settings.r || 0 : 0,                    y = that.type !== "arc" ? settings.y || settings.cy - settings.r || 0 : 0;                if (settings.rotate) {                    var radianAngle = settings.rotate * Math.PI / 180.0,                        rotateX = isDefined(settings.rotateX) ? settings.rotateX : x,                        rotateY = isDefined(settings.rotateY) ? settings.rotateY : y,                        rx = x + (settings.width || 0 || parseInt(element.style.width || 0)) / 2,                        ry = y + (settings.height || 0 || parseInt(element.style.height || 0)) / 2,                        cos = mathCos(radianAngle),                        sin = mathSin(radianAngle),                        marginLeft = (rx - rotateX) * cos - (ry - rotateY) * sin + rotateX - rx,                        marginTop = (rx - rotateX) * sin + (ry - rotateY) * cos + rotateY - ry;                    x += marginLeft;                    y += marginTop;                    style.rotation = settings.rotate                }                style.left = x + (settings.translateX || 0);                style.top = y + (settings.translateY || 0)            },            remove: function() {                var that = this,                    parent = that._parent;                if (parent)                    parent._children.splice(inArray(parent._children, that), 1);                that._parent = null;                return baseElementPrototype.remove.call(that)            },            clear: function() {                this._children = [];                return baseElementPrototype.clear.call(this)            },            getBBox: function() {                var clientRect = this._getBBox(),                    x = clientRect.left,                    y = clientRect.top,                    width = clientRect.right - x,                    height = clientRect.bottom - y;                return {                        x: x,                        y: y,                        width: width,                        height: height,                        isEmpty: !x && !y && !width && !height                    }            },            _getBBox: function() {                var element = this.element,                    settings = this._fullSettings,                    x = settings.x || 0,                    y = settings.y || 0,                    width = parseInt(element.style.width || 0),                    height = parseInt(element.style.height || 0);                return correctBoundingRectWithStrokeWidth({                        left: x,                        top: y,                        right: x + width,                        bottom: y + height                    }, settings["stroke-width"] || 1)            },            _applyStyleSheet: function() {                if (this._useCSSTheme)                    this.attr(getInheritSettings(this.element.currentStyle), true)            },            setTitle: function(text) {                this.element.setAttribute('title', text)            }        });        var ClipRect = function() {                this.ctor.apply(this, arguments)            };        extend(ClipRect.prototype, VmlElement.prototype);        extend(ClipRect.prototype, {            ctor: function(renderer, id) {                this._settings = this._fullSettings = {};                this.renderer = renderer;                this._children = [];                this._elements = [];                this.id = id            },            attr: function() {                var result = baseAttr.apply(this, arguments),                    elements = this._elements.slice(),                    element,                    i;                if (result === this)                    for (i = 0; i < elements.length; i++) {                        element = elements[i];                        if (element._fullSettings.clipId === this.id)                            elements[i].applyClipID(this.id);                        else                            this.removeElement(element)                    }                return result            },            processAttr: stub,            _applyTransformation: stub,            append: stubReturnedThis,            dispose: function() {                this._elements = null;                this.renderer.removeClipRect(this.id);                return this            },            addElement: function(element) {                var elements = this._elements;                if (inArray(elements, element) === -1)                    elements.push(element)            },            removeElement: function(element) {                var index = inArray(this._elements, element);                index > -1 && this._elements.splice(index, 1)            },            getValue: function() {                var settings = this._settings,                    left = (settings.x || 0) + (settings.translateX || 0),                    top = (settings.y || 0) + (settings.translateY || 0);                return "rect(" + top + "px, " + (left + (settings.width || 0)) + "px, " + (top + (settings.height || 0)) + "px, " + left + "px)"            },            css: stubReturnedThis,            remove: stubReturnedThis        });        var VmlRenderer = function(options) {                var that = this;                that.root = that._createElement("div", {                    fill: "none",                    stroke: "none",                    "stroke-width": 0                }).css({                    position: "relative",                    display: "inline-block",                    overflow: "hidden"                });                that._clipRects = [];                that._animation = {enabled: false};                that._defs = {                    clear: stubReturnedThis,                    remove: stubReturnedThis,                    append: stubReturnedThis,                    dispose: stubReturnedThis                };                that.setOptions(options)            };        extend(VmlRenderer.prototype, rendererNS.SvgRenderer.prototype);        extend(VmlRenderer.prototype, {            constructor: VmlRenderer,            setOptions: function() {                rendererNS.SvgRenderer.prototype.setOptions.apply(this, arguments);                this.root.css({direction: this.rtl ? "rtl" : "ltr"})            },            _createElement: function(tagName, attr, type) {                tagName = svgToVmlConv[tagName] || tagName;                var elem = new rendererNS.VmlElement(this, tagName, type);                attr && elem.attr(attr);                return elem            },            dispose: function() {                this.root.dispose();                return null            },            shadowFilter: function() {                return {                        ref: null,                        append: stubReturnedThis,                        dispose: stubReturnedThis,                        attr: stubReturnedThis,                        css: stubReturnedThis                    }            },            clipRect: function(x, y, width, height) {                var clipRects = this._clipRects,                    id = clipRects.length,                    clipRect = new ClipRect(this, id).attr({                        x: x || 0,                        y: y || 0,                        width: width || 0,                        height: height || 0                    });                clipRects.push(clipRect);                return clipRect            },            getClipRect: function(id) {                return this._clipRects[id]            },            removeClipRect: function(id) {                delete this._clipRects[id]            },            pattern: function(color) {                return {                        id: color,                        append: stubReturnedThis,                        remove: stubReturnedThis,                        dispose: stubReturnedThis                    }            },            image: function(x, y, w, h, href, location) {                var image = this._createElement("image", {                        x: x || 0,                        y: y || 0,                        width: w || 0,                        height: h || 0,                        location: location,                        href: href                    });                return image            },            updateAnimationOptions: stubReturnedThis,            stopAllAnimations: stubReturnedThis,            svg: function() {                return ""            },            onEndAnimation: function(callback) {                callback()            }        });        rendererNS.VmlRenderer = VmlRenderer;        rendererNS.VmlElement = VmlElement;        rendererNS._VmlClipRect = ClipRect    })(jQuery, DevExpress, document);    /*! Module viz-core, file animation.js */    (function(DX) {        var rendererNS = DX.viz.renderers,            noop = function(){},            easingFunctions = {                easeOutCubic: function(pos, start, end) {                    return pos === 1 ? end : (1 - Math.pow(1 - pos, 3)) * (end - start) + +start                },                linear: function(pos, start, end) {                    return pos === 1 ? end : pos * (end - start) + +start                }            };        rendererNS.easingFunctions = easingFunctions;        rendererNS.animationSvgStep = {            segments: function(elem, params, progress, easing, currentParams) {                var from = params.from,                    to = params.to,                    curSeg,                    seg,                    i,                    j,                    segments = [];                for (i = 0; i < from.length; i++) {                    curSeg = from[i];                    seg = [curSeg[0]];                    if (curSeg.length > 1)                        for (j = 1; j < curSeg.length; j++)                            seg.push(easing(progress, curSeg[j], to[i][j]));                    segments.push(seg)                }                currentParams.segments = params.end && progress === 1 ? params.end : segments;                elem.attr({segments: segments})            },            arc: function(elem, params, progress, easing) {                var from = params.from,                    to = params.to,                    current = {};                for (var i in from)                    current[i] = easing(progress, from[i], to[i]);                elem.attr(current)            },            transform: function(elem, params, progress, easing, currentParams) {                var from = params.from,                    to = params.to,                    current = {};                for (var i in from)                    current[i] = currentParams[i] = easing(progress, from[i], to[i]);                elem.attr(current)            },            base: function(elem, params, progress, easing, currentParams, attributeName) {                var obj = {};                obj[attributeName] = currentParams[attributeName] = easing(progress, params.from, params.to);                elem.attr(obj)            },            _: noop,            complete: function(element, currentSettings) {                element.attr(currentSettings)            }        };        function Animation(element, params, options) {            var that = this;            that._progress = 0;            that.element = element;            that.params = params;            that.options = options;            that.duration = options.partitionDuration ? options.duration * options.partitionDuration : options.duration;            that._animateStep = options.animateStep || rendererNS.animationSvgStep;            that._easing = easingFunctions[options.easing] || easingFunctions["easeOutCubic"];            that._currentParams = {};            that.tick = that._start        }        Animation.prototype = {            _calcProgress: function(now) {                return Math.min(1, (now - this._startTime) / this.duration)            },            _step: function(now) {                var that = this,                    animateStep = that._animateStep,                    attrName;                that._progress = that._calcProgress(now);                for (attrName in that.params) {                    var anim = animateStep[attrName] || animateStep.base;                    anim(that.element, that.params[attrName], that._progress, that._easing, that._currentParams, attrName)                }                that.options.step && that.options.step(that._easing(that._progress, 0, 1), that._progress);                if (that._progress === 1)                    return that.stop();                return true            },            _start: function(now) {                this._startTime = now;                this.tick = this._step;                return true            },            _end: function(disableComplete) {                var that = this;                that.stop = noop;                that.tick = noop;                that._animateStep.complete && that._animateStep.complete(that.element, that._currentParams);                that.options.complete && !disableComplete && that.options.complete()            },            tick: function() {                return true            },            stop: function(breakAnimation, disableComplete) {                var that = this,                    options = that.options;                if (!breakAnimation && options.repeatCount && --options.repeatCount > 0) {                    that.tick = that._start;                    return true                }                else                    that._end(disableComplete)            }        };        function AnimationController(element) {            var that = this;            that._animationCount = 0;            that._timerId = null;            that._animations = {};            that.element = element        }        rendererNS.AnimationController = AnimationController;        AnimationController.prototype = {            _loop: function() {                var that = this,                    animations = that._animations,                    activeAnimation = 0,                    now = (new Date).getTime(),                    an,                    endAnimation = that._endAnimation;                for (an in animations) {                    if (!animations[an].tick(now))                        delete animations[an];                    activeAnimation++                }                if (activeAnimation === 0) {                    that.stop();                    that._endAnimationTimer = endAnimation && setTimeout(function() {                        if (that._animationCount === 0) {                            endAnimation();                            that._endAnimation = null                        }                    });                    return                }                that._timerId = DX.requestAnimationFrame.call(null, function() {                    that._loop()                }, that.element)            },            addAnimation: function(animation) {                var that = this;                that._animations[that._animationCount++] = animation;                clearTimeout(that._endAnimationTimer);                if (!that._timerId) {                    clearTimeout(that._startDelay);                    that._startDelay = setTimeout(function() {                        that._timerId = 1;                        that._loop()                    }, 0)                }            },            animateElement: function(elem, params, options) {                if (elem && params && options) {                    elem.animation && elem.animation.stop(true);                    this.addAnimation(elem.animation = new Animation(elem, params, options))                }            },            onEndAnimation: function(endAnimation) {                this._animationCount ? this._endAnimation = endAnimation : endAnimation()            },            dispose: function() {                this.stop();                this.element = null            },            stop: function() {                var that = this;                that._animations = {};                that._animationCount = 0;                DX.cancelAnimationFrame(that._timerId);                clearTimeout(that._startDelay);                clearTimeout(that._endAnimationTimer);                that._timerId = null            },            lock: function() {                var an,                    animations = this._animations;                for (an in animations)                    animations[an].stop(true, true);                this.stop()            }        };        rendererNS.Animation = Animation;        rendererNS.noop = noop    })(DevExpress);    /*! Module viz-core, file renderer.js */    (function($, DX, document) {        var renderers = DX.viz.renderers,            browser = DX.browser;        function isSvg() {            return !(browser.msie && browser.version < 9) || !!document.createElementNS && !!document.createElementNS('http://www.w3.org/2000/svg', "svg").createSVGRect        }        if (!isSvg()) {            if (document.namespaces && !document.namespaces.vml) {                document.namespaces.add('vml', 'urn:schemas-microsoft-com:vml');                document.createStyleSheet().cssText = 'vml\\:* { behavior:url(#default#VML); display: inline-block; } '            }            renderers.Renderer = renderers.VmlRenderer        }        else            renderers.Renderer = renderers.SvgRenderer;        renderers.isSvg = isSvg    })(jQuery, DevExpress, document);    /*! Module viz-core, file seriesConsts.js */    (function(DX) {        DX.viz.core.series = DX.viz.core.series || {};        DX.viz.core.series.helpers = DX.viz.core.series.helpers || {};        DX.viz.core.series.helpers.consts = {            events: {                mouseover: "mouseover",                mouseout: "mouseout",                mousemove: "mousemove",                touchstart: "touchstart",                touchmove: "touchmove",                touchend: "touchend",                mousedown: "mousedown",                mouseup: "mouseup",                click: "click",                selectSeries: "selectseries",                deselectSeries: "deselectseries",                selectPoint: "selectpoint",                deselectPoint: "deselectpoint",                showPointTooltip: "showpointtooltip",                hidePointTooltip: "hidepointtooltip"            },            states: {                hover: "hover",                normal: "normal",                selected: "selected",                normalMark: 0,                hoverMark: 1,                selectedMark: 2            },            animations: {                showDuration: {duration: 400},                hideGroup: {opacity: 0.0001},                showGroup: {opacity: 1}            },            pieLabelIndent: 30        }    })(DevExpress);    /*! Module viz-core, file seriesFamily.js */    (function($, DX, undefined) {        var utils = DX.utils,            _math = Math,            _round = _math.round,            _abs = _math.abs,            _pow = _math.pow,            _each = $.each;        DX.viz.core.series.helpers.SeriesFamily = DX.Class.inherit(function() {            var ctor = function(options) {                    var debug = DX.utils.debug;                    debug.assert(options.type, "type was not passed or empty");                    var that = this,                        stubFunction = $.noop;                    that.type = options.type.toLowerCase();                    that.pane = options.pane;                    that.series = [];                    that.updateOptions(options);                    switch (that.type) {                        case"bar":                            that.adjustSeriesDimensions = adjustBarSeriesDimensions;                            that.adjustSeriesValues = stubFunction;                            that.updateSeriesValues = updateBarSeriesValues;                            break;                        case"rangebar":                            that.adjustSeriesDimensions = adjustBarSeriesDimensions;                            that.adjustSeriesValues = stubFunction;                            that.updateSeriesValues = stubFunction;                            break;                        case"fullstackedbar":                            that.fullStacked = true;                            that.adjustSeriesDimensions = adjustStackedBarSeriesDimensions;                            that.adjustSeriesValues = adjustStackedSeriesValues;                            that.updateSeriesValues = updateStackedSeriesValues;                            break;                        case"stackedbar":                            that.adjustSeriesDimensions = adjustStackedBarSeriesDimensions;                            that.adjustSeriesValues = adjustStackedSeriesValues;                            that.updateSeriesValues = updateStackedSeriesValues;                            break;                        case"fullstackedarea":                        case"fullstackedline":                        case"fullstackedspline":                        case"fullstackedsplinearea":                            that.fullStacked = true;                            that.adjustSeriesDimensions = stubFunction;                            that.adjustSeriesValues = adjustStackedSeriesValues;                            that.updateSeriesValues = stubFunction;                            break;                        case"stackedarea":                        case"stackedsplinearea":                        case"stackedline":                        case"stackedspline":                            that.adjustSeriesDimensions = stubFunction;                            that.adjustSeriesValues = adjustStackedSeriesValues;                            that.updateSeriesValues = stubFunction;                            break;                        case"candlestick":                        case"stock":                            that.adjustSeriesDimensions = adjustCandlestickSeriesDimensions;                            that.adjustSeriesValues = stubFunction;                            that.updateSeriesValues = stubFunction;                            break;                        case"bubble":                            that.adjustSeriesDimensions = adjustBubbleSeriesDimensions;                            that.adjustSeriesValues = stubFunction;                            that.updateSeriesValues = stubFunction;                            break;                        default:                            that.adjustSeriesDimensions = stubFunction;                            that.adjustSeriesValues = stubFunction;                            that.updateSeriesValues = stubFunction;                            break                    }                };            var updateOptions = function(options) {                    this.equalBarWidth = options.equalBarWidth;                    this.minBubbleSize = options.minBubbleSize;                    this.maxBubbleSize = options.maxBubbleSize                };            var dispose = function() {                    this.series = null;                    this.translators = null                };            var add = function(series) {                    var that = this,                        singleSeries,                        i;                    if (!$.isArray(series))                        series = [series];                    for (i = 0; i < series.length; i++) {                        singleSeries = series[i];                        if (singleSeries.type.toLowerCase() === that.type)                            that.series.push(singleSeries)                    }                };            function correctPointCoordinates(points, width, offset) {                _each(points, function(_, point) {                    point.correctCoordinates({                        width: width,                        offset: offset                    })                })            }            function getStacksWithArgument(stackKeepers, argument) {                var stacksWithArgument = [];                _each(stackKeepers, function(stackName, seriesInStack) {                    _each(seriesInStack, function(_, singleSeries) {                        var points = singleSeries.getPointsByArg(argument),                            pointsLength = points.length,                            i;                        for (i = 0; i < pointsLength; ++i)                            if (points[i] && points[i].value) {                                stacksWithArgument.push(stackName);                                return false                            }                    })                });                return stacksWithArgument            }            function correctPointCoordinatesForStacks(stackKeepers, stacksWithArgument, argument, middleIndex, width, spacing) {                _each(stackKeepers, function(stackName, seriesInStack) {                    var stackIndex = $.inArray(stackName, stacksWithArgument),                        offset;                    if (stackIndex === -1)                        return;                    offset = (stackIndex - middleIndex + 0.5) * width - (middleIndex - stackIndex - 0.5) * spacing;                    _each(seriesInStack, function(_, singleSeries) {                        _each(singleSeries.getPointsByArg(argument) || [], function(_, point) {                            if (point && point.value)                                point.correctCoordinates({                                    width: width,                                    offset: offset                                })                        })                    })                })            }            var adjustBarSeriesDimensionsCore = function(series, interval, stackCount, equalBarWidth, seriesStackIndexCallback) {                    var spacing,                        width,                        maxWidth,                        middleIndex,                        stackIndex,                        i,                        points,                        seriesOffset,                        stackName,                        argumentsKeeper = {},                        stackKeepers = {},                        stacksWithArgument,                        count;                    if (equalBarWidth) {                        width = equalBarWidth.width && equalBarWidth.width < 0 ? 0 : equalBarWidth.width;                        spacing = equalBarWidth.spacing && equalBarWidth.spacing < 0 ? 0 : equalBarWidth.spacing;                        if (!spacing)                            if (stackCount > 1) {                                spacing = width ? _round((interval * 0.7 - width * stackCount) / (stackCount - 1)) : _round(interval * 0.7 / stackCount * 0.2);                                if (spacing < 1)                                    spacing = 1                            }                            else                                spacing = 0;                        if (!width) {                            width = _round((interval * 0.7 - spacing * (stackCount - 1)) / stackCount);                            if (width < 2)                                width = 2                        }                        if (width * stackCount + spacing * (stackCount - 1) > interval) {                            spacing = _round((interval * 0.7 - width * stackCount) / (stackCount - 1));                            if (spacing < 1) {                                spacing = 1;                                maxWidth = _round((interval * 0.7 - spacing * (stackCount - 1)) / stackCount)                            }                        }                        middleIndex = stackCount / 2;                        for (i = 0; i < series.length; i++) {                            stackIndex = seriesStackIndexCallback(i);                            points = series[i].getPoints();                            seriesOffset = (stackIndex - middleIndex + 0.5) * (maxWidth || width) - (middleIndex - stackIndex - 0.5) * spacing;                            correctPointCoordinates(points, width, seriesOffset)                        }                    }                    else {                        _each(series, function(i, singleSeries) {                            stackName = singleSeries.getStackName && singleSeries.getStackName();                            stackName = stackName || i.toString();                            if (!stackKeepers[stackName])                                stackKeepers[stackName] = [];                            stackKeepers[stackName].push(singleSeries)                        });                        _each(series, function(i, singleSeries) {                            _each(singleSeries.getPoints(), function(_, point) {                                var argument = point.argument;                                if (!argumentsKeeper.hasOwnProperty(argument))                                    argumentsKeeper[argument.valueOf()] = 1                            })                        });                        for (var argument in argumentsKeeper) {                            if (!argumentsKeeper.hasOwnProperty(argument))                                continue;                            stacksWithArgument = getStacksWithArgument(stackKeepers, argument);                            count = stacksWithArgument.length;                            spacing = _round(interval * 0.7 / count * 0.2);                            if (spacing < 1)                                spacing = 1;                            width = _round((interval * 0.7 - spacing * (count - 1)) / count);                            if (width < 2)                                width = 2;                            middleIndex = count / 2;                            correctPointCoordinatesForStacks(stackKeepers, stacksWithArgument, argument, middleIndex, width, spacing)                        }                    }                };            function checkMinBarSize(value, minShownValue) {                return _abs(value) < minShownValue ? value >= 0 ? minShownValue : -minShownValue : value            }            function getValueType(value) {                return value >= 0 ? "positive" : "negative"            }            function getVisibleSeries(that) {                return $.map(that.series, function(s) {                        return s.isVisible() ? s : null                    })            }            function getAbsStackSumByArg(stackKeepers, stackName, argument) {                var positiveStackValue = (stackKeepers.positive[stackName] || {})[argument] || 0,                    negativeStackValue = -(stackKeepers.negative[stackName] || {})[argument] || 0;                return positiveStackValue + negativeStackValue            }            var adjustBarSeriesDimensions = function(translators) {                    var debug = DX.utils.debug;                    debug.assert(translators, "translator was not passed or empty");                    var that = this,                        equalBarWidth = that.equalBarWidth,                        series = getVisibleSeries(that);                    adjustBarSeriesDimensionsCore(series, getInterval(that, translators), series.length, equalBarWidth, function(seriesIndex) {                        return seriesIndex                    })                };            var adjustStackedBarSeriesDimensions = function(translators) {                    var debug = DX.utils.debug;                    debug.assert(translators, "translators was not passed or empty");                    var that = this,                        series = getVisibleSeries(that),                        stackIndexes = {},                        stackCount = 0,                        equalBarWidth = that.equalBarWidth;                    _each(series, function() {                        var stackName = this.getStackName();                        if (!stackIndexes.hasOwnProperty(stackName))                            stackIndexes[stackName] = stackCount++                    });                    adjustBarSeriesDimensionsCore(series, getInterval(that, translators), stackCount, equalBarWidth, function(seriesIndex) {                        return stackIndexes[series[seriesIndex].getStackName()]                    })                };            var adjustStackedSeriesValues = function() {                    var that = this,                        series = getVisibleSeries(that),                        stackKeepers = {                            positive: {},                            negative: {}                        },                        holesStack = {                            left: {},                            right: {}                        };                    _each(series, function(seriesIndex, singleSeries) {                        var points = singleSeries.getPoints(),                            hole = false;                        singleSeries._prevSeries = series[seriesIndex - 1],                        singleSeries.holes = $.extend(true, {}, holesStack);                        _each(points, function(index, point) {                            var value = point.initialValue,                                argument = point.argument.valueOf(),                                stackName = singleSeries.getStackName(),                                stacks = value >= 0 ? stackKeepers.positive : stackKeepers.negative,                                currentStack;                            stacks[stackName] = stacks[stackName] || {};                            currentStack = stacks[stackName];                            if (currentStack[argument]) {                                point.correctValue(currentStack[argument]);                                currentStack[argument] += value                            }                            else {                                currentStack[argument] = value;                                point.resetCorrection()                            }                            if (!point.hasValue()) {                                var prevPoint = points[index - 1];                                if (!hole && prevPoint && prevPoint.hasValue()) {                                    argument = prevPoint.argument.valueOf();                                    prevPoint._skipSetRightHole = true;                                    holesStack.right[argument] = (holesStack.right[argument] || 0) + (prevPoint.value - (isFinite(prevPoint.minValue) ? prevPoint.minValue : 0))                                }                                hole = true                            }                            else if (hole) {                                hole = false;                                holesStack.left[argument] = (holesStack.left[argument] || 0) + (point.value - (isFinite(point.minValue) ? point.minValue : 0));                                point._skipSetLeftHole = true                            }                        })                    });                    _each(series, function(seriesIndex, singleSeries) {                        var points = singleSeries.getPoints(),                            holes = singleSeries.holes;                        _each(points, function(index, point) {                            var argument = point.argument.valueOf();                            point.resetHoles();                            !point._skipSetLeftHole && point.setHole(holes.left[argument] || holesStack.left[argument] && 0, "left");                            !point._skipSetRightHole && point.setHole(holes.right[argument] || holesStack.right[argument] && 0, "right");                            point._skipSetLeftHole = null;                            point._skipSetRightHole = null                        })                    });                    that._stackKeepers = stackKeepers;                    setPercentStackedValues(series, stackKeepers, that.fullStacked, holesStack)                };            var setPercentStackedValues = function(series, stackKeepers, fullStacked, holeStack) {                    _each(series, function(_, singleSeries) {                        _each(singleSeries.getPoints(), function(_, point) {                            var argument = point.argument.valueOf();                            point.setPercentValue(getAbsStackSumByArg(stackKeepers, singleSeries.getStackName(), argument), fullStacked, holeStack.left[argument], holeStack.right[argument])                        })                    })                };            var updateStackedSeriesValues = function(translators) {                    var that = this,                        series = getVisibleSeries(that),                        stack = that._stackKeepers,                        stackKeepers = {                            positive: {},                            negative: {}                        };                    _each(series, function(_, singleSeries) {                        var minBarSize = singleSeries.getOptions().minBarSize,                            minShownBusinessValue = minBarSize && translators.val.getMinBarSize(minBarSize),                            stackName = singleSeries.getStackName();                        _each(singleSeries.getPoints(), function(index, point) {                            if (!point.hasValue())                                return;                            var value = point.initialValue,                                argument = point.argument.valueOf(),                                updateValue,                                valueType,                                currentStack;                            if (that.fullStacked)                                value = _abs(value) / getAbsStackSumByArg(stack, stackName, argument) || 0;                            updateValue = checkMinBarSize(value, minShownBusinessValue);                            valueType = getValueType(updateValue);                            currentStack = stackKeepers[valueType][stackName] = stackKeepers[valueType][stackName] || {};                            if (currentStack[argument]) {                                point.minValue = currentStack[argument];                                currentStack[argument] += updateValue                            }                            else                                currentStack[argument] = updateValue;                            point.value = currentStack[argument]                        })                    });                    if (that.fullStacked)                        updateFullStackedSeriesValues(series, stackKeepers)                };            var updateFullStackedSeriesValues = function(series, stackKeepers) {                    _each(series, function(_, singleSeries) {                        var stackName = singleSeries.getStackName ? singleSeries.getStackName() : "default";                        _each(singleSeries.getPoints(), function(index, point) {                            var value = _abs(point.value),                                argument = point.argument.valueOf(),                                valueType = getValueType(value),                                currentStack;                            stackKeepers[valueType][stackName] = stackKeepers[valueType][stackName] || {};                            currentStack = stackKeepers[valueType][stackName];                            point.value = point.value / currentStack[argument] || 0;                            if (utils.isNumber(point.minValue))                                point.minValue = point.minValue / currentStack[argument] || 0                        })                    })                };            var updateBarSeriesValues = function(translators) {                    _each(this.series, function(_, singleSeries) {                        var minBarSize = singleSeries.getOptions().minBarSize,                            minShownBusinessValue = minBarSize && translators.val.getMinBarSize(minBarSize);                        if (minShownBusinessValue)                            _each(singleSeries.getPoints(), function(index, point) {                                if (point.hasValue())                                    point.value = checkMinBarSize(point.initialValue, minShownBusinessValue)                            })                    })                };            var adjustCandlestickSeriesDimensions = function(translators) {                    var debug = DX.utils.debug;                    debug.assert(translators, "translator was not passed or empty");                    var that = this,                        series = getVisibleSeries(that);                    adjustBarSeriesDimensionsCore(series, getInterval(that, translators), series.length, true, function(seriesIndex) {                        return seriesIndex                    })                };            var getInterval = function(that, translators) {                    var argTranslator = translators.arg;                    that.interval = argTranslator.getInterval();                    return that.interval                };            var adjustBubbleSeriesDimensions = function(translators) {                    var debug = DX.utils.debug;                    debug.assert(translators, "translator was not passed or empty");                    var that = this,                        series = getVisibleSeries(that),                        visibleAreaX = translators.arg.getCanvasVisibleArea(),                        visibleAreaY = translators.val.getCanvasVisibleArea(),                        min = Math.min(visibleAreaX.max - visibleAreaX.min, visibleAreaY.max - visibleAreaY.min),                        minBubbleArea = _pow(that.minBubbleSize, 2),                        maxBubbleArea = _pow(min * that.maxBubbleSize, 2),                        equalBubbleSize = (min * that.maxBubbleSize + that.minBubbleSize) / 2,                        minPointSize = Infinity,                        maxPointSize = 0,                        pointSize,                        bubbleArea,                        sizeProportion,                        sizeDispersion,                        areaDispersion;                    _each(series, function(_, seriesItem) {                        _each(seriesItem.getPoints(), function(_, point) {                            maxPointSize = maxPointSize > point.size ? maxPointSize : point.size;                            minPointSize = minPointSize < point.size ? minPointSize : point.size                        })                    });                    sizeDispersion = maxPointSize - minPointSize;                    areaDispersion = _abs(maxBubbleArea - minBubbleArea);                    minPointSize = minPointSize < 0 ? 0 : minPointSize;                    _each(series, function(_, seriesItem) {                        _each(seriesItem.getPoints(), function(_, point) {                            if (maxPointSize === minPointSize)                                pointSize = _round(equalBubbleSize);                            else {                                sizeProportion = _abs(point.size - minPointSize) / sizeDispersion;                                bubbleArea = areaDispersion * sizeProportion + minBubbleArea;                                pointSize = _round(Math.sqrt(bubbleArea))                            }                            point.correctCoordinates(pointSize)                        })                    })                };            return {                    ctor: ctor,                    dispose: dispose,                    add: add,                    updateOptions: updateOptions                }        }())    })(jQuery, DevExpress);    /*! Module viz-core, file baseSeries.js */    (function($, DX) {        var viz = DX.viz,            core = viz.core,            seriesNS = core.series,            utils = DX.utils,            _isDefined = utils.isDefined,            _each = $.each,            _extend = $.extend,            _isEmptyObject = $.isEmptyObject,            _Event = $.Event,            _noop = $.noop,            SELECTED_STATE = 2,            HOVER_STATE = 1,            NONE_MODE = "none",            INCLUDE_POINTS = "includepoints",            EXLUDE_POINTS = "excludepoints",            NEAREST_POINT = "nearestpoint",            APPLY_SELECTED = "applySelected",            APPLY_HOVER = "applyHover",            SYMBOL_POINT = "symbolPoint",            POLAR_SYMBOL_POINT = "polarSymbolPoint",            BAR_POINT = "barPoint",            POLAR_BAR_POINT = "polarBarPoint",            PIE_POINT = "piePoint",            HOVER = "hover",            NORMAL = "normal",            SELECTION = "selection",            getEmptyBusinessRange = function() {                return {                        arg: {},                        val: {}                    }            };        function triggerEvent(element, event, point) {            element && element.trigger(event, point)        }        seriesNS.mixins = {            chart: {pointTypes: {                    scatter: SYMBOL_POINT,                    line: SYMBOL_POINT,                    spline: SYMBOL_POINT,                    stepline: SYMBOL_POINT,                    stackedline: SYMBOL_POINT,                    fullstackedline: SYMBOL_POINT,                    stackedspline: SYMBOL_POINT,                    fullstackedspline: SYMBOL_POINT,                    stackedsplinearea: SYMBOL_POINT,                    fullstackedsplinearea: SYMBOL_POINT,                    area: SYMBOL_POINT,                    splinearea: SYMBOL_POINT,                    steparea: SYMBOL_POINT,                    stackedarea: SYMBOL_POINT,                    fullstackedarea: SYMBOL_POINT,                    rangearea: "rangeSymbolPoint",                    bar: BAR_POINT,                    stackedbar: BAR_POINT,                    fullstackedbar: BAR_POINT,                    rangebar: "rangeBarPoint",                    bubble: "bubblePoint",                    stock: "stockPoint",                    candlestick: "candlestickPoint"                }},            pie: {pointTypes: {                    pie: PIE_POINT,                    doughnut: PIE_POINT,                    donut: PIE_POINT                }},            polar: {pointTypes: {                    scatter: POLAR_SYMBOL_POINT,                    line: POLAR_SYMBOL_POINT,                    area: POLAR_SYMBOL_POINT,                    bar: POLAR_BAR_POINT,                    stackedbar: POLAR_BAR_POINT                }}        };        function includePointsMode(mode) {            return mode === INCLUDE_POINTS || mode === "allseriespoints"        }        function Series() {            this.ctor.apply(this, arguments)        }        function applyPointStyle(point, styleName) {            !point.isSelected() && point.applyStyle(styleName)        }        seriesNS.Series = Series;        Series.prototype = {            ctor: function(renderSettings, options) {                var that = this;                that.fullState = 0;                that._extGroups = renderSettings;                that._renderer = renderSettings.renderer;                that._group = renderSettings.renderer.g().attr({"class": "dxc-series"});                that.updateOptions(options)            },            update: function(data, options) {                this.updateOptions(options);                this.updateData(data)            },            _createLegendState: _noop,            getLegendStyles: function() {                return this._styles.legendStyles            },            _createStyles: function(options) {                var that = this,                    mainSeriesColor = options.mainSeriesColor,                    specialMainColor = that._getSpecialColor(mainSeriesColor);                that._styles = {                    normal: that._parseStyle(options, mainSeriesColor, mainSeriesColor),                    hover: that._parseStyle(options.hoverStyle || {}, specialMainColor, mainSeriesColor),                    selection: that._parseStyle(options.selectionStyle || {}, specialMainColor, mainSeriesColor),                    legendStyles: {                        normal: that._createLegendState(options, mainSeriesColor),                        hover: that._createLegendState(options.hoverStyle || {}, specialMainColor),                        selection: that._createLegendState(options.selectionStyle || {}, specialMainColor)                    }                }            },            setAdjustSeriesLabels: function(adjustSeriesLabels) {                _each(this._points || [], function(_, point) {                    point.setAdjustSeriesLabels(adjustSeriesLabels)                })            },            setClippingParams: function(baseId, wideId, forceClipping) {                this._paneClipRectID = baseId;                this._widePaneClipRectID = wideId;                this._forceClipping = forceClipping            },            applyClip: function() {                this._group.attr({clipId: this._paneClipRectID})            },            resetClip: function() {                this._group.attr({clipId: null})            },            getTagField: function() {                return this._options.tagField || "tag"            },            getValueFields: _noop,            getArgumentField: _noop,            getPoints: function() {                return this._points            },            _createPoint: function(data, pointsArray, index) {                data.index = index;                var that = this,                    point = pointsArray[index],                    pointsByArgument = that.pointsByArgument,                    options;                if (that._checkData(data)) {                    options = that._customizePoint(data) || that._getCreatingPointOptions();                    if (point)                        point.update(data, options);                    else {                        point = core.CoreFactory.createPoint(that, data, options);                        pointsArray.push(point)                    }                    pointsByArgument[point.argument.valueOf()] = pointsByArgument[point.argument.valueOf()] || [];                    pointsByArgument[point.argument.valueOf()].push(point);                    return true                }            },            getRangeData: function(zoomArgs, calcIntervalFunction) {                return this._visible ? _extend(true, {}, this._getRangeData(zoomArgs, calcIntervalFunction)) : getEmptyBusinessRange()            },            _deleteGroup: function(groupName) {                var group = this[groupName];                if (group) {                    group.dispose();                    this[groupName] = null                }            },            _saveOldAnimationMethods: function() {                var that = this;                that._oldClearingAnimation = that._clearingAnimation;                that._oldUpdateElement = that._updateElement;                that._oldgetAffineCoordOptions = that._getAffineCoordOptions            },            _deleteOldAnimationMethods: function() {                this._oldClearingAnimation = null;                this._oldUpdateElement = null;                this._oldgetAffineCoordOptions = null            },            updateOptions: function(newOptions) {                var that = this,                    widgetType = newOptions.widgetType,                    oldType = that.type,                    newType = newOptions.type;                that.type = newType && newType.toString().toLowerCase();                if (!that._checkType(widgetType) || that._checkPolarBarType(widgetType, newOptions)) {                    that.dispose();                    that.isUpdated = false;                    return                }                if (oldType !== that.type) {                    that._firstDrawing = true;                    that._saveOldAnimationMethods();                    that._resetType(oldType, widgetType);                    that._setType(that.type, widgetType)                }                that._options = newOptions;                that._pointOptions = null;                that._deletePatterns();                that._patterns = [];                that.name = newOptions.name;                that.pane = newOptions.pane;                that.axis = newOptions.axis;                that.tag = newOptions.tag;                that._createStyles(newOptions);                that._updateOptions(newOptions);                that._visible = newOptions.visible;                that.isUpdated = true            },            _disposePoints: function(points) {                _each(points || [], function(_, p) {                    p.dispose()                })            },            _correctPointsLength: function(length, points) {                this._disposePoints(this._oldPoints);                this._oldPoints = points.splice(length, points.length)            },            _getTicksForAggregation: function(min, max, screenDelta, pointSize) {                var types = {                        axisType: "continuous",                        dataType: utils.isDate(min) ? "datetime" : "numeric"                    },                    data = {                        min: min,                        max: max,                        screenDelta: screenDelta                    },                    options = {                        gridSpacingFactor: pointSize,                        labelOptions: {},                        stick: true                    },                    tickManager = new viz.core.tickManager.TickManager(types, data, options);                return {                        ticks: tickManager.getTicks(true),                        tickInterval: tickManager.getTickInterval()                    }            },            _getRangeCorrector: _noop,            updateDataType: function(settings) {                var that = this;                that.argumentType = settings.argumentType;                that.valueType = settings.valueType;                that.argumentAxisType = settings.argumentAxisType;                that.valueAxisType = settings.valueAxisType;                that.showZero = settings.showZero;                return that            },            getOptions: function() {                return this._options            },            _resetRangeData: function() {                this._rangeData = getEmptyBusinessRange()            },            updateData: function(data) {                var that = this,                    points = that._originalPoints || [],                    lastPointIndex = 0,                    options = that._options,                    pointData,                    rangeCorrector;                that._rangeErrorBarCorrector = rangeCorrector = that._getRangeCorrector();                that.pointsByArgument = {};                that._resetRangeData();                if (data && data.length)                    that._canRenderCompleteHandle = true;                that._beginUpdateData(data);                _each(data, function(_, dataItem) {                    pointData = that._getPointData(dataItem, options);                    if (that._createPoint(pointData, points, lastPointIndex)) {                        that._processRange(points[lastPointIndex], lastPointIndex > 0 ? points[lastPointIndex - 1] : null, rangeCorrector);                        lastPointIndex++                    }                });                that._disposePoints(that._aggregatedPoints);                that._aggregatedPoints = null;                that._points = that._originalPoints = points;                that._correctPointsLength(lastPointIndex, points);                that._endUpdateData()            },            getTeamplatedFields: function() {                var that = this,                    fields = that.getValueFields(),                    teampleteFields = [];                fields.push(that.getTagField());                _each(fields, function(_, field) {                    var fieldsObject = {};                    fieldsObject.teamplateField = field + that.name;                    fieldsObject.originalField = field;                    teampleteFields.push(fieldsObject)                });                return teampleteFields            },            resamplePoints: function(argTranslator, min, max) {                var that = this,                    originalPoints = that.getAllPoints(),                    minI,                    maxI,                    sizePoint,                    tickObject,                    ticks,                    tickInterval;                if (originalPoints.length) {                    _each(originalPoints, function(i, point) {                        minI = point.argument - min <= 0 ? i : minI;                        if (!maxI)                            maxI = point.argument - max > 0 ? i : null                    });                    minI = minI ? minI : 1;                    maxI = _isDefined(maxI) ? maxI : originalPoints.length - 1;                    min = originalPoints[minI - 1].argument;                    max = originalPoints[maxI].argument;                    sizePoint = that._getPointSize();                    if (that.argumentAxisType !== "discrete" && that.valueAxisType !== "discrete") {                        tickObject = that._getTicksForAggregation(min, max, argTranslator.canvasLength, sizePoint);                        ticks = tickObject.ticks;                        tickInterval = tickObject.tickInterval;                        if (ticks.length === 1) {                            that._points = originalPoints;                            return                        }                    }                    else                        ticks = argTranslator.canvasLength / sizePoint;                    that._points = that._resample(ticks, tickInterval, argTranslator)                }            },            _removeOldSegments: function(startIndex) {                var that = this;                _each(that._graphics.splice(startIndex, that._graphics.length) || [], function(_, elem) {                    that._removeElement(elem)                });                if (that._trackers)                    _each(that._trackers.splice(startIndex, that._trackers.length) || [], function(_, elem) {                        elem.remove()                    })            },            draw: function(translators, animationEnabled, hideLayoutLabels, legendCallback) {                var that = this,                    drawComplete;                if (that._oldClearingAnimation && animationEnabled && that._firstDrawing) {                    drawComplete = function() {                        that._draw(translators, true, hideLayoutLabels)                    };                    that._oldClearingAnimation(translators, drawComplete)                }                else                    that._draw(translators, animationEnabled, hideLayoutLabels, legendCallback)            },            _clearSeries: function() {                var that = this;                that._deleteGroup("_elementsGroup");                that._deleteGroup("_bordersGroup");                that._deleteTrackers();                that._graphics = [];                that._trackers = []            },            _draw: function(translators, animationEnabled, hideLayoutLabels, legendCallback) {                var that = this,                    points = that._points || [],                    segment = [],                    segmentCount = 0,                    firstDrawing = that._firstDrawing,                    closeSegment = points[0] && points[0].hasValue() && that._options.closed,                    groupForPoint;                that._graphics = that._graphics || [];                that._prepareSeriesToDrawing();                if (!that._visible) {                    animationEnabled = false;                    that._group.remove();                    return                }                that._group.append(that._extGroups.seriesGroup);                that.translators = translators;                that._createGroups(animationEnabled, undefined, firstDrawing);                that._segments = [];                that._drawedPoints = [];                that._firstDrawing = points.length ? false : true;                groupForPoint = {                    markers: that._markersGroup,                    labels: that._labelsGroup,                    errorBars: that._errorBarGroup                };                _each(points, function(i, p) {                    p.translate(translators);                    if (p.hasValue()) {                        that._drawPoint({                            point: p,                            groups: groupForPoint,                            hasAnimation: animationEnabled,                            firstDrawing: firstDrawing,                            legendCallback: legendCallback                        });                        segment.push(p)                    }                    else if (segment.length) {                        that._drawSegment(segment, animationEnabled, segmentCount++);                        segment = []                    }                });                segment.length && that._drawSegment(segment, animationEnabled, segmentCount++, closeSegment);                that._removeOldSegments(segmentCount);                that._defaultSegments = that._generateDefaultSegments();                hideLayoutLabels && that.hideLabels();                animationEnabled && that._animate(firstDrawing);                if (that.isSelected())                    that._changeStyle(legendCallback, APPLY_SELECTED);                else if (that.isHovered())                    that._changeStyle(legendCallback, APPLY_HOVER)            },            _checkType: function(widgetType) {                return !!seriesNS.mixins[widgetType][this.type]            },            _checkPolarBarType: function(widgetType, options) {                return widgetType === "polar" && options.spiderWidget && this.type.indexOf("bar") !== -1            },            _resetType: function(seriesType, widgetType) {                var that = this;                if (seriesType)                    _each(seriesNS.mixins[widgetType][seriesType], function(methodName) {                        delete that[methodName]                    })            },            _setType: function(seriesType, widgetType) {                var that = this;                _each(seriesNS.mixins[widgetType][seriesType], function(methodName, method) {                    that[methodName] = method                })            },            setSelectedState: function(state, mode, legendCallback) {                var that = this;                that.lastSelectionMode = (mode || that._options.selectionMode).toLowerCase();                if (state && !that.isSelected()) {                    that.fullState = that.fullState | SELECTED_STATE;                    that._nearestPoint && applyPointStyle(that._nearestPoint, "normal");                    that._nearestPoint = null;                    that._changeStyle(legendCallback, APPLY_SELECTED)                }                else if (!state && that.isSelected()) {                    that.fullState = that.fullState & ~SELECTED_STATE;                    if (that.isHovered())                        that._changeStyle(legendCallback, APPLY_HOVER, SELECTION);                    else                        that._changeStyle(legendCallback, "resetItem")                }            },            setHoverState: function(state, mode, legendCallback) {                var that = this;                that.lastHoverMode = (mode || that._options.hoverMode).toLowerCase();                if (state && !that.isHovered()) {                    that.fullState = that.fullState | HOVER_STATE;                    !that.isSelected() && that._changeStyle(legendCallback, APPLY_HOVER)                }                else if (!state && that.isHovered()) {                    that._nearestPoint = null;                    that.fullState = that.fullState & ~HOVER_STATE;                    !that.isSelected() && that._changeStyle(legendCallback, "resetItem")                }            },            isFullStackedSeries: function() {                return this.type.indexOf("fullstacked") === 0            },            isStackedSeries: function() {                return this.type.indexOf("stacked") === 0            },            isFinancialSeries: function() {                return this.type === "stock" || this.type === "candlestick"            },            _changeStyle: function(legendCallBack, legendAction, prevStyle) {                var that = this,                    style = that._calcStyle(prevStyle),                    pointStyle;                if (style.mode === NONE_MODE)                    return;                legendCallBack && legendCallBack(legendAction);                if (includePointsMode(style.mode)) {                    pointStyle = style.pointStyle;                    _each(that._points || [], function(_, p) {                        applyPointStyle(p, pointStyle)                    })                }                that._applyStyle(style.series)            },            _calcStyle: function(prevStyle) {                var that = this,                    styles = that._styles,                    pointNormalState = false,                    result;                switch (that.fullState & 3) {                    case 0:                        result = {                            pointStyle: NORMAL,                            mode: INCLUDE_POINTS,                            series: styles.normal                        };                        break;                    case 1:                        pointNormalState = prevStyle === SELECTION && that.lastHoverMode === EXLUDE_POINTS || that.lastHoverMode === NEAREST_POINT && includePointsMode(that.lastSelectionMode);                        result = {                            pointStyle: pointNormalState ? NORMAL : HOVER,                            mode: pointNormalState ? INCLUDE_POINTS : that.lastHoverMode,                            series: styles.hover                        };                        break;                    case 2:                        result = {                            pointStyle: SELECTION,                            mode: that.lastSelectionMode,                            series: styles.selection                        };                        break;                    case 3:                        pointNormalState = that.lastSelectionMode === EXLUDE_POINTS && includePointsMode(that.lastHoverMode);                        result = {                            pointStyle: pointNormalState ? NORMAL : SELECTION,                            mode: pointNormalState ? INCLUDE_POINTS : that.lastSelectionMode,                            series: styles.selection                        }                }                return result            },            updateHover: function(x, y) {                var that = this,                    currentNearestPoint = that._nearestPoint,                    point = that.isHovered() && that.lastHoverMode === NEAREST_POINT && that.getNeighborPoint(x, y);                if (point !== currentNearestPoint && !that.isSelected()) {                    currentNearestPoint && applyPointStyle(currentNearestPoint, "normal");                    if (point) {                        applyPointStyle(point, "hover");                        that._nearestPoint = point                    }                }            },            _getMainAxisName: function() {                return this._options.rotated ? "X" : "Y"            },            areLabelsVisible: function() {                return !_isDefined(this._options.maxLabelCount) || this._points.length <= this._options.maxLabelCount            },            getLabelVisibility: function() {                return this.areLabelsVisible() && this._options.label && this._options.label.visible            },            _customizePoint: function(pointData) {                var that = this,                    options = that._options,                    customizePoint = options.customizePoint,                    customizeObject,                    pointOptions,                    customLabelOptions,                    customOptions,                    customizeLabel = options.customizeLabel,                    useLabelCustomOptions,                    usePointCustomOptions;                if (customizeLabel && customizeLabel.call) {                    customizeObject = _extend({seriesName: that.name}, pointData);                    customizeObject.series = that;                    customLabelOptions = customizeLabel.call(customizeObject, customizeObject);                    useLabelCustomOptions = customLabelOptions && !_isEmptyObject(customLabelOptions);                    customLabelOptions = useLabelCustomOptions ? _extend(true, {}, options.label, customLabelOptions) : null                }                if (customizePoint && customizePoint.call) {                    customizeObject = customizeObject || _extend({seriesName: that.name}, pointData);                    customizeObject.series = that;                    customOptions = customizePoint.call(customizeObject, customizeObject);                    usePointCustomOptions = customOptions && !_isEmptyObject(customOptions)                }                if (useLabelCustomOptions || usePointCustomOptions) {                    pointOptions = that._parsePointOptions(that._preparePointOptions(customOptions), customLabelOptions || options.label, true);                    pointOptions.styles.useLabelCustomOptions = useLabelCustomOptions;                    pointOptions.styles.usePointCustomOptions = usePointCustomOptions                }                return pointOptions            },            _getLabelOptions: function(labelOptions, defaultColor) {                var opt = labelOptions || {},                    labelFont = opt.font || {},                    labelBorder = opt.border || {},                    labelConnector = opt.connector || {},                    labelAttributes = {font: {                            color: opt.backgroundColor === "none" && labelFont.color.toLowerCase() === "#ffffff" && opt.position !== "inside" ? defaultColor : labelFont.color,                            family: labelFont.family,                            weight: labelFont.weight,                            size: labelFont.size,                            opacity: labelFont.opacity                        }},                    backgroundAttr = {                        fill: opt.backgroundColor || defaultColor,                        "stroke-width": labelBorder.visible ? labelBorder.width || 0 : 0,                        stroke: labelBorder.visible && labelBorder.width ? labelBorder.color : "none",                        dashStyle: labelBorder.dashStyle                    },                    connectorAttr = {                        stroke: labelConnector.visible && labelConnector.width ? labelConnector.color || defaultColor : "none",                        "stroke-width": labelConnector.visible ? labelConnector.width || 0 : 0                    };                return {                        alignment: opt.alignment,                        format: opt.format,                        argumentFormat: opt.argumentFormat,                        precision: opt.precision,                        argumentPrecision: opt.argumentPrecision,                        percentPrecision: opt.percentPrecision,                        customizeText: $.isFunction(opt.customizeText) ? opt.customizeText : undefined,                        attributes: labelAttributes,                        visible: labelFont.size !== 0 ? opt.visible : false,                        showForZeroValues: opt.showForZeroValues,                        horizontalOffset: opt.horizontalOffset,                        verticalOffset: opt.verticalOffset,                        radialOffset: opt.radialOffset,                        background: backgroundAttr,                        position: opt.position,                        connector: connectorAttr,                        rotationAngle: opt.rotationAngle                    }            },            show: function() {                if (!this._visible)                    this._changeVisibility(true)            },            hide: function() {                if (this._visible)                    this._changeVisibility(false)            },            _changeVisibility: function(visibility) {                var that = this;                that._visible = that._options.visible = visibility;                that._updatePointsVisibility();                that.hidePointTooltip();                that._options.visibilityChanged()            },            _updatePointsVisibility: $.noop,            hideLabels: function() {                _each(this._points, function(_, point) {                    point._label.hide()                })            },            _parsePointOptions: function(pointOptions, labelOptions, isCustomPointOptions) {                var that = this,                    options = that._options,                    styles = that._createPointStyles(pointOptions, isCustomPointOptions),                    parsedOptions = _extend(true, {}, pointOptions, {                        type: options.type,                        tag: that.tag,                        rotated: options.rotated,                        styles: styles,                        widgetType: options.widgetType,                        visibilityChanged: options.visibilityChanged                    });                parsedOptions.label = that._getLabelOptions(labelOptions, styles.normal.fill);                parsedOptions.errorBars = options.valueErrorBar;                return parsedOptions            },            _resample: function(ticks, ticksInterval, argTranslator) {                var that = this,                    fusPoints = [],                    arrayFusPoints,                    nowIndexTicks = 0,                    lastPointIndex = 0,                    originalPoints = that.getAllPoints(),                    visibleArea;                if (that.argumentAxisType === "discrete" || that.valueAxisType === "discrete") {                    visibleArea = argTranslator.getCanvasVisibleArea();                    originalPoints = $.map(originalPoints, function(p) {                        var pos = argTranslator.translate(p.argument),                            result;                        if (pos >= visibleArea.min && pos <= visibleArea.max)                            result = p;                        else {                            p.setInvisibility();                            result = null                        }                        return result                    });                    ticksInterval = originalPoints.length / ticks;                    arrayFusPoints = $.map(originalPoints, function(point, index) {                        if (Math.floor(nowIndexTicks) <= index) {                            nowIndexTicks += ticksInterval;                            return point                        }                        point.setInvisibility();                        return null                    });                    return arrayFusPoints                }                that._aggregatedPoints = that._aggregatedPoints || [];                _each(originalPoints, function(_, point) {                    point.setInvisibility();                    switch (that._isInInterval(point.argument, ticks, nowIndexTicks, ticksInterval)) {                        case true:                            fusPoints.push(point);                            break;                        case"nextInterval":                            var pointData = that._fusionPoints(fusPoints, ticks[nowIndexTicks], nowIndexTicks);                            while (that._isInInterval(point.argument, ticks, nowIndexTicks, ticksInterval) === "nextInterval")                                nowIndexTicks++;                            fusPoints = [];                            that._isInInterval(point.argument, ticks, nowIndexTicks, ticksInterval) === true && fusPoints.push(point);                            if (that._createPoint(pointData, that._aggregatedPoints, lastPointIndex))                                lastPointIndex++                    }                });                if (fusPoints.length) {                    var pointData = that._fusionPoints(fusPoints, ticks[nowIndexTicks], nowIndexTicks);                    if (that._createPoint(pointData, that._aggregatedPoints, lastPointIndex))                        lastPointIndex++                }                that._correctPointsLength(lastPointIndex, that._aggregatedPoints);                that._endUpdateData();                return that._aggregatedPoints            },            _isInInterval: function(argument, ticks, nowIndexTicks, ticksInterval) {                var minTick = ticks[nowIndexTicks],                    maxTick = ticks[nowIndexTicks + 1],                    sumMinTickTicksInterval;                ticksInterval = $.isNumeric(ticksInterval) ? ticksInterval : utils.dateToMilliseconds(ticksInterval);                sumMinTickTicksInterval = utils.isDate(minTick) ? new Date(minTick.getTime() + ticksInterval) : minTick + ticksInterval;                if (argument >= minTick && argument < sumMinTickTicksInterval)                    return true;                if (argument < minTick || maxTick === undefined)                    return false;                return "nextInterval"            },            canRenderCompleteHandle: function() {                var result = this._canRenderCompleteHandle;                delete this._canRenderCompleteHandle;                return !!result            },            isHovered: function() {                return !!(this.fullState & 1)            },            isSelected: function() {                return !!(this.fullState & 2)            },            isVisible: function() {                return this._visible            },            getAllPoints: function() {                return (this._originalPoints || []).slice()            },            getPointByPos: function(pos) {                return (this._points || [])[pos]            },            getVisiblePoints: function() {                return (this._drawedPoints || []).slice()            },            setPointHoverState: function(point, legendCallback) {                point.fullState = point.fullState | HOVER_STATE;                if (!(this.isSelected() && includePointsMode(this.lastSelectionMode)) && !point.isSelected()) {                    point.applyStyle(HOVER);                    legendCallback && legendCallback("applyHover")                }            },            releasePointHoverState: function(point, legendCallback) {                var that = this;                point.fullState = point.fullState & ~HOVER_STATE;                if (!(that.isSelected() && includePointsMode(that.lastSelectionMode)) && !point.isSelected())                    if (!(that.isHovered() && includePointsMode(that.lastHoverMode)) || that.isSelected() && that.lastSelectionMode === EXLUDE_POINTS) {                        point.applyStyle(NORMAL);                        legendCallback && legendCallback("resetItem")                    }            },            setPointSelectedState: function(point, legendCallback) {                point.fullState = point.fullState | SELECTED_STATE;                point.applyStyle(SELECTION);                legendCallback && legendCallback("applySelected")            },            releasePointSelectedState: function(point, legendCallback) {                var that = this;                point.fullState = point.fullState & ~SELECTED_STATE;                if (that.isHovered() && includePointsMode(that.lastHoverMode) || point.isHovered()) {                    point.applyStyle(HOVER);                    legendCallback && legendCallback("applyHover")                }                else if (that.isSelected() && includePointsMode(that.lastSelectionMode)) {                    point.applyStyle(SELECTION);                    legendCallback && legendCallback("applySelected")                }                else {                    point.applyStyle(NORMAL);                    legendCallback && legendCallback("resetItem")                }            },            selectPoint: function(point) {                triggerEvent(this._extGroups.seriesGroup, new _Event("selectpoint"), point)            },            deselectPoint: function(point) {                triggerEvent(this._extGroups.seriesGroup, new _Event("deselectpoint"), point)            },            showPointTooltip: function(point) {                triggerEvent(this._extGroups.seriesGroup, new _Event("showpointtooltip"), point)            },            hidePointTooltip: function(point) {                triggerEvent(this._extGroups.seriesGroup, new _Event("hidepointtooltip"), point)            },            select: function() {                var that = this;                triggerEvent(that._extGroups.seriesGroup, new _Event("selectseries", {target: that}), that._options.selectionMode);                that._group.toForeground()            },            clearSelection: function clearSelection() {                var that = this;                triggerEvent(that._extGroups.seriesGroup, new _Event("deselectseries", {target: that}), that._options.selectionMode)            },            getPointByArg: function(arg) {                return this.getPointsByArg(arg)[0] || null            },            getPointsByArg: function(arg) {                return this.pointsByArgument[arg.valueOf()] || []            },            _deletePoints: function() {                var that = this;                that._disposePoints(that._originalPoints);                that._disposePoints(that._aggregatedPoints);                that._disposePoints(that._oldPoints);                that._points = null;                that._oldPoints = null;                that._aggregatedPoints = null;                that._originalPoints = null;                that._drawedPoints = null            },            _deletePatterns: function() {                _each(this._patterns || [], function(_, pattern) {                    pattern && pattern.dispose()                });                this._patterns = null            },            _deleteTrackers: function() {                var that = this;                _each(that._trackers || [], function(_, tracker) {                    tracker.remove()                });                that._trackersGroup && that._trackersGroup.dispose();                that._trackers = that._trackersGroup = null            },            dispose: function() {                var that = this;                that._deletePoints();                that._group.dispose();                that._labelsGroup && that._labelsGroup.dispose();                that._errorBarGroup && that._errorBarGroup.dispose();                that._deletePatterns();                that._deleteTrackers();                that._group = that._extGroups = that._markersGroup = that._elementsGroup = that._bordersGroup = that._labelsGroup = that._errorBarGroup = that._graphics = that._rangeData = that._renderer = that.translators = that._styles = that._options = that._pointOptions = that._drawedPoints = that._aggregatedPoints = that.pointsByArgument = that._segments = that._prevSeries = null            },            correctPosition: _noop,            drawTrackers: _noop,            getNeighborPoint: _noop,            areErrorBarsVisible: _noop,            getColor: function() {                return this.getLegendStyles().normal.fill            },            getOpacity: function() {                return this._options.opacity            },            getStackName: function() {                return this.type === "stackedbar" || this.type === "fullstackedbar" ? this._stackName : null            },            getPointByCoord: function(x, y) {                var point = this.getNeighborPoint(x, y);                return point && point.coordsIn(x, y) ? point : null            }        }    })(jQuery, DevExpress);    /*! Module viz-core, file rangeDataCalculator.js */    (function($, DX, undefined) {        var _math = Math,            _abs = _math.abs,            _min = _math.min,            _max = _math.max,            _each = $.each,            _isEmptyObject = $.isEmptyObject,            _isDefined = DX.utils.isDefined,            _isFinite = isFinite,            MIN_VISIBLE = "minVisible",            MAX_VISIBLE = "maxVisible",            DISCRETE = "discrete";        function _truncateValue(data, value) {            var min = data.min,                max = data.max;            data.min = value < min || !_isDefined(min) ? value : min;            data.max = value > max || !_isDefined(max) ? value : max        }        function _processValue(series, type, value, prevValue, calcInterval) {            var axis = type === "arg" ? "argument" : "value",                data = series._rangeData[type],                minInterval = data.interval,                interval;            if (series[axis + "AxisType"] === DISCRETE) {                data.categories = data.categories || [];                data.categories.push(value)            }            else {                _truncateValue(data, value);                if (type === "arg") {                    interval = (_isDefined(prevValue) ? _abs(calcInterval ? calcInterval(value, prevValue) : value - prevValue) : interval) || minInterval;                    data.interval = _isDefined(interval) && (interval < minInterval || !_isDefined(minInterval)) ? interval : minInterval                }            }        }        function _addToVisibleRange(series, value) {            var data = series._rangeData.val,                isDiscrete = series.valueAxisType === DISCRETE;            if (!isDiscrete) {                if (value < data.minVisible || !_isDefined(data.minVisible))                    data.minVisible = value;                if (value > data.maxVisible || !_isDefined(data.maxVisible))                    data.maxVisible = value            }        }        function _processRangeValue(series, val, minVal) {            var data = series._rangeData.val;            if (series.valueAxisType === DISCRETE) {                data.categories = data.categories || [];                data.categories.push(val, minVal)            }            else {                _truncateValue(data, val);                _truncateValue(data, minVal)            }        }        function _unique(array) {            var values = {};            return $.map(array, function(item) {                    var result = !values[item] ? item : null;                    values[item] = true;                    return result                })        }        function _processZoomArgument(series, zoomArgs, isDiscrete) {            var data = series._rangeData.arg,                minArg,                maxArg;            if (isDiscrete) {                data.minVisible = zoomArgs.minArg;                data.maxVisible = zoomArgs.maxArg;                return            }            minArg = zoomArgs.minArg < zoomArgs.maxArg ? zoomArgs.minArg : zoomArgs.maxArg;            maxArg = zoomArgs.maxArg > zoomArgs.minArg ? zoomArgs.maxArg : zoomArgs.minArg;            data.min = minArg < data.min ? minArg : data.min;            data.max = maxArg > data.max ? maxArg : data.max;            data.minVisible = minArg;            data.maxVisible = maxArg        }        function _correctZoomValue(series, zoomArgs) {            var minVal,                maxVal;            if (_isDefined(zoomArgs.minVal) && _isDefined(zoomArgs.maxVal)) {                minVal = zoomArgs.minVal < zoomArgs.maxVal ? zoomArgs.minVal : zoomArgs.maxVal;                maxVal = zoomArgs.maxVal > zoomArgs.minVal ? zoomArgs.maxVal : zoomArgs.minVal            }            if (_isDefined(zoomArgs.minVal)) {                series._rangeData.val.min = minVal < series._rangeData.val.min ? minVal : series._rangeData.val.min;                series._rangeData.val.minVisible = minVal            }            if (_isDefined(zoomArgs.maxVal)) {                series._rangeData.val.max = maxVal > series._rangeData.val.max ? maxVal : series._rangeData.val.max;                series._rangeData.val.maxVisible = maxVal            }        }        function _processZoomValue(series, zoomArgs) {            var adjustOnZoom = zoomArgs.adjustOnZoom,                points = series._points || [],                lastVisibleIndex,                prevPointAdded = false,                rangeData = series._rangeData,                errorBarCorrector = series._rangeErrorBarCorrector;            _each(points, function(index, point) {                var arg = point.argument,                    prevPoint = index > 0 ? points[index - 1] : null;                if (adjustOnZoom && series.argumentAxisType !== DISCRETE && arg >= rangeData.arg.minVisible && arg <= rangeData.arg.maxVisible) {                    if (!prevPointAdded) {                        if (prevPoint && prevPoint.hasValue()) {                            _addToVisibleRange(series, prevPoint.value);                            _correctMinMaxByErrorBar(rangeData.val, prevPoint, errorBarCorrector, MIN_VISIBLE, MAX_VISIBLE)                        }                        prevPointAdded = true                    }                    if (point.hasValue()) {                        _addToVisibleRange(series, point.value);                        _correctMinMaxByErrorBar(rangeData.val, point, errorBarCorrector, MIN_VISIBLE, MAX_VISIBLE)                    }                    lastVisibleIndex = index                }            });            if (_isDefined(lastVisibleIndex) && lastVisibleIndex < points.length - 1 && points[lastVisibleIndex + 1].hasValue())                _addToVisibleRange(series, points[lastVisibleIndex + 1].value);            _correctZoomValue(series, zoomArgs)        }        function _processZoomRangeValue(series, zoomArgs, maxValueName, minValueName) {            var adjustOnZoom = zoomArgs.adjustOnZoom,                points = series._points || [],                argRangeData = series._rangeData.arg,                lastVisibleIndex,                prevPointAdded = false;            _each(points, function(index, point) {                var arg = point.argument,                    prevPoint = index > 0 ? points[index - 1] : null;                if (adjustOnZoom && series.argumentAxisType !== DISCRETE && arg >= argRangeData.minVisible && arg <= argRangeData.maxVisible) {                    if (!prevPointAdded) {                        if (prevPoint && prevPoint.hasValue()) {                            _addToVisibleRange(series, prevPoint[maxValueName]);                            _addToVisibleRange(series, prevPoint[minValueName])                        }                        prevPointAdded = true                    }                    if (point.hasValue()) {                        _addToVisibleRange(series, point[maxValueName]);                        _addToVisibleRange(series, point[minValueName])                    }                    lastVisibleIndex = index                }            });            if (_isDefined(lastVisibleIndex) && lastVisibleIndex < points.length - 1 && points[lastVisibleIndex + 1].hasValue())                _addToVisibleRange(series, points[lastVisibleIndex + 1].value);            _correctZoomValue(series, zoomArgs)        }        function _processNewInterval(series, calcInterval) {            var data = series._rangeData,                points = series._points || [],                isArgumentAxisDiscrete = series.argumentAxisType === DISCRETE;            delete data.arg.interval;            _each(points, function(index, point) {                var arg = point.argument,                    prevPoint = index > 0 ? points[index - 1] : null,                    prevArg = prevPoint && prevPoint.argument;                !isArgumentAxisDiscrete && _processValue(series, "arg", arg, prevArg, calcInterval)            })        }        function _fillRangeData(series) {            var data = series._rangeData;            data.arg.categories && (data.arg.categories = _unique(data.arg.categories));            data.val.categories && (data.val.categories = _unique(data.val.categories));            data.arg.axisType = series.argumentAxisType;            data.arg.dataType = series.argumentType;            data.val.axisType = series.valueAxisType;            data.val.dataType = series.valueType;            data.val.isValueRange = true        }        function processTwoValues(series, point, prevPoint, highValueName, lowValueName) {            var val = point[highValueName],                minVal = point[lowValueName],                arg = point.argument,                prevVal = prevPoint && prevPoint[highValueName],                prevMinVal = prevPoint && prevPoint[lowValueName],                prevArg = prevPoint && prevPoint.argument;            point.hasValue() && _processRangeValue(series, val, minVal, prevVal, prevMinVal);            _processValue(series, "arg", arg, prevArg)        }        function calculateRangeMinValue(series, zoomArgs) {            var data = series._rangeData.val,                minVisible = data[MIN_VISIBLE],                maxVisible = data[MAX_VISIBLE];            zoomArgs = zoomArgs || {};            if (data)                if (series.valueAxisType !== "logarithmic" && series.valueType !== "datetime" && series.showZero !== false) {                    data[MIN_VISIBLE] = minVisible > (zoomArgs.minVal || 0) ? zoomArgs.minVal || 0 : minVisible;                    data[MAX_VISIBLE] = maxVisible < (zoomArgs.maxVal || 0) ? zoomArgs.maxVal || 0 : maxVisible;                    data.min = data.min > 0 ? 0 : data.min;                    data.max = data.max < 0 ? 0 : data.max                }        }        function processFullStackedRange(series) {            var data = series._rangeData.val,                isRangeEmpty = _isEmptyObject(data);            data.percentStick = true;            !isRangeEmpty && (data.min = 0)        }        function _correctMinMaxByErrorBar(data, point, getMinMaxCorrector, minSelector, maxSelector) {            if (!getMinMaxCorrector)                return;            var correctionData = getMinMaxCorrector(point),                minError = _min.apply(undefined, correctionData),                maxError = _max.apply(undefined, correctionData);            if (_isFinite(minError) && data[minSelector] > minError)                data[minSelector] = minError;            if (_isFinite(maxError) && data[maxSelector] < maxError)                data[maxSelector] = maxError        }        function processRange(series, point, prevPoint, getMinMaxCorrector) {            var val = point.value,                arg = point.argument,                prevVal = prevPoint && prevPoint.value,                prevArg = prevPoint && prevPoint.argument;            point.hasValue() && _processValue(series, "val", val, prevVal);            _processValue(series, "arg", arg, prevArg);            _correctMinMaxByErrorBar(series._rangeData.val, point, getMinMaxCorrector, "min", "max")        }        function addLabelPaddings(series) {            var labelOptions = series.getOptions().label,                valueData;            if (series.areLabelsVisible() && labelOptions && labelOptions.visible && labelOptions.position !== "inside") {                valueData = series._rangeData.val;                if (valueData.min < 0)                    valueData.minSpaceCorrection = true;                if (valueData.max > 0)                    valueData.maxSpaceCorrection = true            }        }        function addRangeSeriesLabelPaddings(series) {            var data = series._rangeData.val;            if (series.areLabelsVisible() && series._options.label.visible && series._options.label.position !== "inside")                data.minSpaceCorrection = data.maxSpaceCorrection = true        }        function calculateRangeData(series, zoomArgs, calcIntervalFunction, maxValueName, minValueName) {            var valueData = series._rangeData.val,                isRangeSeries = !!maxValueName && !!minValueName,                isDiscrete = series.argumentAxisType === DISCRETE;            if (zoomArgs && _isDefined(zoomArgs.minArg) && _isDefined(zoomArgs.maxArg)) {                if (!isDiscrete) {                    valueData[MIN_VISIBLE] = zoomArgs.minVal;                    valueData[MAX_VISIBLE] = zoomArgs.maxVal                }                _processZoomArgument(series, zoomArgs, isDiscrete);                if (isRangeSeries)                    _processZoomRangeValue(series, zoomArgs, maxValueName, minValueName);                else                    _processZoomValue(series, zoomArgs)            }            else if (!zoomArgs && calcIntervalFunction)                _processNewInterval(series, calcIntervalFunction);            _fillRangeData(series)        }        DX.viz.core.series.helpers.rangeDataCalculator = {            processRange: processRange,            calculateRangeData: calculateRangeData,            addLabelPaddings: addLabelPaddings,            addRangeSeriesLabelPaddings: addRangeSeriesLabelPaddings,            processFullStackedRange: processFullStackedRange,            calculateRangeMinValue: calculateRangeMinValue,            processTwoValues: processTwoValues        }    })(jQuery, DevExpress);    /*! Module viz-core, file scatterSeries.js */    (function($, DX) {        var series = DX.viz.core.series,            rangeCalculator = series.helpers.rangeDataCalculator,            chartSeries = series.mixins.chart,            _each = $.each,            _extend = $.extend,            _map = $.map,            _noop = $.noop,            _utils = DX.utils,            _isDefined = _utils.isDefined,            _isString = _utils.isString,            math = Math,            _floor = math.floor,            _abs = math.abs,            _sqrt = math.sqrt,            _min = math.min,            _max = math.max,            DEFAULT_SYMBOL_POINT_SIZE = 2,            DEFAULT_TRACKER_WIDTH = 20,            DEFAULT_DURATION = 400,            HIGH_ERROR = "highError",            LOW_ERROR = "lowError",            ORIGINAL = "original",            VARIANCE = "variance",            STANDARD_DEVIATION = "stddeviation",            STANDARD_ERROR = "stderror",            PERCENT = "percent",            FIXED = "fixed",            UNDEFINED = "undefined",            DISCRETE = "discrete",            LOGARITHMIC = "logarithmic",            DATETIME = "datetime";        function sum(array) {            var summa = 0;            _each(array, function(_, value) {                summa += value            });            return summa        }        function toLowerCase(value) {            return value.toLowerCase()        }        function isErrorBarTypeCorrect(type) {            return $.inArray(type, [FIXED, PERCENT, VARIANCE, STANDARD_DEVIATION, STANDARD_ERROR, UNDEFINED]) !== -1        }        function variance(array, expectedValue) {            return sum($.map(array, function(value) {                    return (value - expectedValue) * (value - expectedValue)                })) / array.length        }        var baseScatterMethods = {                _defaultDuration: DEFAULT_DURATION,                _defaultTrackerWidth: DEFAULT_TRACKER_WIDTH,                _applyStyle: _noop,                _updateOptions: _noop,                _parseStyle: _noop,                _prepareSegment: _noop,                _drawSegment: _noop,                _generateDefaultSegments: _noop,                _prepareSeriesToDrawing: function() {                    var that = this;                    that._deleteOldAnimationMethods();                    that._firstDrawing && that._clearSeries();                    that._disposePoints(that._oldPoints);                    that._oldPoints = null                },                _createLegendState: function(styleOptions, defaultColor) {                    return {                            fill: styleOptions.color || defaultColor,                            hatching: styleOptions.hatching                        }                },                updateTeamplateFieldNames: function() {                    var that = this,                        options = that._options;                    options.valueField = that.getValueFields()[0] + that.name;                    options.tagField = that.getTagField() + that.name                },                _applyElementsClipRect: function(settings) {                    settings.clipId = this._paneClipRectID                },                _applyMarkerClipRect: function(settings) {                    settings.clipId = this._forceClipping ? this._paneClipRectID : null                },                _createGroup: function(groupName, parent, target, settings) {                    var group = parent[groupName] = parent[groupName] || this._renderer.g();                    group.attr(settings).append(target)                },                _applyClearingSettings: function(settings) {                    settings.opacity = null;                    settings.scale = null;                    if (this._options.rotated)                        settings.translateX = null;                    else                        settings.translateY = null                },                _createMarkerGroup: function() {                    var that = this,                        settings = that._getPointOptions().styles.normal;                    settings["class"] = "dxc-markers";                    settings.opacity = 1;                    that._applyMarkerClipRect(settings);                    that._createGroup("_markersGroup", that, that._group, settings)                },                _createLabelGroup: function() {                    var that = this,                        settings = {                            "class": "dxc-labels",                            visibility: that.getLabelVisibility() ? "visible" : "hidden"                        };                    that._applyElementsClipRect(settings);                    that._applyClearingSettings(settings);                    that._createGroup("_labelsGroup", that, that._extGroups.labelsGroup, settings)                },                areErrorBarsVisible: function() {                    var errorBarOptions = this._options.valueErrorBar || {};                    return this._errorBarsEnabled() && errorBarOptions.displayMode !== "none" && (isErrorBarTypeCorrect(toLowerCase(errorBarOptions.type + "")) || _isDefined(errorBarOptions.lowValueField) || _isDefined(errorBarOptions.highValueField))                },                _createErrorBarGroup: function(animationEnabled) {                    var that = this,                        errorBarOptions = that._options.valueErrorBar || {},                        settings;                    if (that.areErrorBarsVisible()) {                        settings = {                            "class": "dxc-error-bars",                            stroke: errorBarOptions.color,                            'stroke-width': errorBarOptions.lineWidth,                            opacity: animationEnabled ? 0.001 : errorBarOptions.opacity || 1,                            "stroke-linecap": "square",                            sharp: true,                            clipId: that._forceClipping ? that._paneClipRectID : that._widePaneClipRectID                        };                        that._createGroup("_errorBarGroup", that, that._group, settings)                    }                },                _createGroups: function(animationEnabled) {                    var that = this;                    that._createMarkerGroup();                    that._createLabelGroup();                    that._createErrorBarGroup(animationEnabled);                    animationEnabled && that._labelsGroup && that._labelsGroup.attr({opacity: 0.001})                },                _getCreatingPointOptions: function() {                    var that = this,                        defaultPointOptions,                        creatingPointOptions = that._predefinedPointOptions,                        normalStyle;                    if (!creatingPointOptions) {                        defaultPointOptions = that._getPointOptions();                        that._predefinedPointOptions = creatingPointOptions = _extend(true, {styles: {}}, defaultPointOptions);                        normalStyle = defaultPointOptions.styles && defaultPointOptions.styles.normal || {};                        creatingPointOptions.styles = creatingPointOptions.styles || {};                        creatingPointOptions.styles.normal = {                            "stroke-width": normalStyle["stroke-width"],                            r: normalStyle.r,                            opacity: normalStyle.opacity                        }                    }                    return creatingPointOptions                },                _getSpecialColor: function(mainSeriesColor) {                    return mainSeriesColor                },                _getPointOptions: function() {                    return this._parsePointOptions(this._preparePointOptions(), this._options.label)                },                _preparePointOptions: function(customOptions) {                    var point = this._options.point;                    return customOptions ? _extend(true, {}, point, customOptions) : point                },                _parsePointStyle: function(style, defaultColor, defaultBorderColor) {                    var border = style.border || {};                    return {                            fill: style.color || defaultColor,                            stroke: border.color || defaultBorderColor,                            "stroke-width": border.visible ? border.width : 0,                            r: style.size / 2 + (border.visible && style.size !== 0 ? ~~(border.width / 2) || 0 : 0)                        }                },                _createPointStyles: function(pointOptions) {                    var that = this,                        mainPointColor = pointOptions.color || that._options.mainSeriesColor,                        containerColor = that._options.containerBackgroundColor,                        normalStyle = that._parsePointStyle(pointOptions, mainPointColor, mainPointColor);                    normalStyle.visibility = pointOptions.visible ? "visible" : "hidden";                    return {                            normal: normalStyle,                            hover: that._parsePointStyle(pointOptions.hoverStyle, containerColor, mainPointColor),                            selection: that._parsePointStyle(pointOptions.selectionStyle, containerColor, mainPointColor)                        }                },                _checkData: function(data) {                    return _isDefined(data.argument) && data.value !== undefined                },                _getRangeCorrector: function() {                    var errorBars = this.getOptions().valueErrorBar || {},                        mode = toLowerCase(errorBars.displayMode + "");                    return errorBars ? function(point) {                            var lowError = point.lowError,                                highError = point.highError;                            switch (mode) {                                case"low":                                    return [lowError];                                case"high":                                    return [highError];                                case"none":                                    return [];                                default:                                    return [lowError, highError]                            }                        } : undefined                },                _processRange: function(point, prevPoint, errorBarCorrector) {                    rangeCalculator.processRange(this, point, prevPoint, errorBarCorrector)                },                _getRangeData: function(zoomArgs, calcIntervalFunction) {                    rangeCalculator.calculateRangeData(this, zoomArgs, calcIntervalFunction);                    rangeCalculator.addLabelPaddings(this);                    return this._rangeData                },                _getPointData: function(data, options) {                    var pointData = {                            value: data[options.valueField || "val"],                            argument: data[options.argumentField || "arg"],                            tag: data[options.tagField || "tag"]                        };                    this._fillErrorBars(data, pointData, options);                    return pointData                },                _errorBarsEnabled: function() {                    return this.valueAxisType !== DISCRETE && this.valueAxisType !== LOGARITHMIC && this.valueType !== DATETIME                },                _fillErrorBars: function(data, pointData, options) {                    var errorBars = options.valueErrorBar || {};                    if (this._errorBarsEnabled()) {                        pointData.lowError = data[errorBars.lowValueField || LOW_ERROR];                        pointData.highError = data[errorBars.highValueField || HIGH_ERROR]                    }                },                _drawPoint: function(options) {                    var point = options.point;                    if (point.isInVisibleArea()) {                        point.clearVisibility();                        point.draw(this._renderer, options.groups, options.hasAnimation, options.firstDrawing);                        this._drawedPoints.push(point)                    }                    else                        point.setInvisibility()                },                _clearingAnimation: function(translators, drawComplete) {                    var that = this,                        params = {opacity: 0.001},                        options = {                            duration: that._defaultDuration,                            partitionDuration: 0.5                        };                    that._labelsGroup && that._labelsGroup.animate(params, options, function() {                        that._markersGroup && that._markersGroup.animate(params, options, drawComplete)                    })                },                _animateComplete: function() {                    var that = this,                        animationSettings = {duration: that._defaultDuration};                    that._labelsGroup && that._labelsGroup.animate({opacity: 1}, animationSettings);                    that._errorBarGroup && that._errorBarGroup.animate({opacity: (that._options.valueErrorBar || {}).opacity || 1}, animationSettings)                },                _animate: function() {                    var that = this,                        lastPointIndex = that._drawedPoints.length - 1;                    _each(that._drawedPoints || [], function(i, p) {                        p.animate(i === lastPointIndex ? function() {                            that._animateComplete()                        } : undefined, {                            translateX: p.x,                            translateY: p.y                        })                    })                },                _getPointSize: function() {                    return this._options.point.visible ? this._options.point.size : DEFAULT_SYMBOL_POINT_SIZE                },                _calcMedianValue: function(fusionPoints, valueField) {                    var result,                        allValue = _map(fusionPoints, function(point) {                            return point[valueField]                        });                    allValue.sort(function(a, b) {                        return a - b                    });                    result = allValue[_floor(allValue.length / 2)];                    return _isDefined(result) ? result : null                },                _calcErrorBarValues: function(fusionPoints) {                    if (!fusionPoints.length)                        return {};                    var lowValue = fusionPoints[0].lowError,                        highValue = fusionPoints[0].highError,                        i = 1,                        length = fusionPoints.length,                        lowError,                        highError;                    for (i; i < length; i++) {                        lowError = fusionPoints[i].lowError;                        highError = fusionPoints[i].highError;                        if (_isDefined(lowError) && _isDefined(highError)) {                            lowValue = _min(lowError, lowValue);                            highValue = _max(highError, highValue)                        }                    }                    return {                            low: lowValue,                            high: highValue                        }                },                _fusionPoints: function(fusionPoints, tick, index) {                    var errorBarValues = this._calcErrorBarValues(fusionPoints);                    return {                            value: this._calcMedianValue(fusionPoints, "value"),                            argument: tick,                            tag: null,                            index: index,                            seriesName: this.name,                            lowError: errorBarValues.low,                            highError: errorBarValues.high                        }                },                _endUpdateData: function() {                    delete this._predefinedPointOptions                },                getArgumentField: function() {                    return this._options.argumentField || "arg"                },                getValueFields: function() {                    var options = this._options,                        errorBarsOptions = options.valueErrorBar || {},                        valueFields = [options.valueField || "val"],                        lowValueField = errorBarsOptions.lowValueField,                        highValueField = errorBarsOptions.highValueField;                    _isString(lowValueField) && valueFields.push(lowValueField);                    _isString(highValueField) && valueFields.push(highValueField);                    return valueFields                },                _calculateErrorBars: function(data) {                    var that = this,                        options = that._options,                        errorBarsOptions = options.valueErrorBar || {},                        errorBarType = toLowerCase(errorBarsOptions.type + ""),                        floatErrorValue = parseFloat(errorBarsOptions.value),                        valueField = that.getValueFields()[0],                        value,                        lowValueField = errorBarsOptions.lowValueField || LOW_ERROR,                        highValueField = errorBarsOptions.highValueField || HIGH_ERROR,                        valueArray,                        valueArrayLength,                        meanValue,                        processDataItem,                        addSubError = function(_i, item) {                            value = item[valueField];                            item[lowValueField] = value - floatErrorValue;                            item[highValueField] = value + floatErrorValue                        };                    if (!that._errorBarsEnabled() || !isErrorBarTypeCorrect(errorBarType))                        return;                    switch (errorBarType) {                        case FIXED:                            processDataItem = addSubError;                            break;                        case PERCENT:                            processDataItem = function(_, item) {                                value = item[valueField];                                var error = value * floatErrorValue / 100;                                item[lowValueField] = value - error;                                item[highValueField] = value + error                            };                            break;                        case UNDEFINED:                            processDataItem = function(_, item) {                                item[lowValueField] = item[ORIGINAL + lowValueField];                                item[highValueField] = item[ORIGINAL + highValueField]                            };                            break;                        default:                            valueArray = $.map(data, function(item) {                                return item[valueField]                            });                            valueArrayLength = valueArray.length;                            floatErrorValue = floatErrorValue || 1;                            switch (errorBarType) {                                case VARIANCE:                                    floatErrorValue = variance(valueArray, sum(valueArray) / valueArrayLength) * floatErrorValue;                                    processDataItem = addSubError;                                    break;                                case STANDARD_DEVIATION:                                    meanValue = sum(valueArray) / valueArrayLength;                                    floatErrorValue = _sqrt(variance(valueArray, meanValue)) * floatErrorValue;                                    processDataItem = function(_, item) {                                        item[lowValueField] = meanValue - floatErrorValue;                                        item[highValueField] = meanValue + floatErrorValue                                    };                                    break;                                case STANDARD_ERROR:                                    floatErrorValue = _sqrt(variance(valueArray, sum(valueArray) / valueArrayLength) / valueArrayLength) * floatErrorValue;                                    processDataItem = addSubError;                                    break                            }                    }                    processDataItem && _each(data, processDataItem)                },                _beginUpdateData: function(data) {                    this._calculateErrorBars(data)                }            };        chartSeries.scatter = _extend({}, baseScatterMethods, {            drawTrackers: function() {                var that = this,                    trackers,                    trackersGroup,                    segments = that._segments || [],                    rotated = that._options.rotated,                    cat = [];                if (!that.isVisible())                    return;                if (segments.length) {                    trackers = that._trackers = that._trackers || [];                    trackersGroup = that._trackersGroup = (that._trackersGroup || that._renderer.g().attr({                        fill: "gray",                        opacity: 0.001,                        stroke: "gray",                        "class": "dxc-trackers"                    })).attr({clipId: this._paneClipRectID || null}).append(that._group);                    _each(segments, function(i, segment) {                        if (!trackers[i])                            trackers[i] = that._drawTrackerElement(segment).data({series: that}).append(trackersGroup);                        else                            that._updateTrackerElement(segment, trackers[i])                    })                }                that._trackersTranslator = cat;                _each(that.getVisiblePoints(), function(_, p) {                    var pointCoord = parseInt(rotated ? p.vy : p.vx);                    if (!cat[pointCoord])                        cat[pointCoord] = p;                    else                        $.isArray(cat[pointCoord]) ? cat[pointCoord].push(p) : cat[pointCoord] = [cat[pointCoord], p]                })            },            getNeighborPoint: function(x, y) {                var pCoord = this._options.rotated ? y : x,                    nCoord = pCoord,                    cat = this._trackersTranslator,                    point = null,                    minDistance,                    oppositeCoord = this._options.rotated ? x : y,                    opositeCoordName = this._options.rotated ? "vx" : "vy";                if (this.isVisible() && cat) {                    point = cat[pCoord];                    do {                        point = cat[nCoord] || cat[pCoord];                        pCoord--;                        nCoord++                    } while ((pCoord >= 0 || nCoord < cat.length) && !point);                    if ($.isArray(point)) {                        minDistance = _abs(point[0][opositeCoordName] - oppositeCoord);                        _each(point, function(i, p) {                            var distance = _abs(p[opositeCoordName] - oppositeCoord);                            if (minDistance >= distance) {                                minDistance = distance;                                point = p                            }                        })                    }                }                return point            }        });        series.mixins.polar.scatter = _extend({}, baseScatterMethods, {            drawTrackers: function() {                chartSeries.scatter.drawTrackers.call(this);                var cat = this._trackersTranslator,                    index;                if (!this.isVisible())                    return;                _each(cat, function(i, category) {                    if (category) {                        index = i;                        return false                    }                });                cat[index + 360] = cat[index]            },            getNeighborPoint: function(x, y) {                var pos = this.translators.untranslate(x, y);                return chartSeries.scatter.getNeighborPoint.call(this, pos.phi, pos.r)            }        })    })(jQuery, DevExpress);    /*! Module viz-core, file lineSeries.js */    (function($, DX) {        var core = DX.viz.core,            series = core.series,            chartSeries = series.mixins.chart,            polarSeries = series.mixins.polar,            utils = DX.utils,            scatterSeries = chartSeries.scatter,            rangeCalculator = core.series.helpers.rangeDataCalculator,            CANVAS_POSITION_START = "canvas_position_start",            CANVAS_POSITION_TOP = "canvas_position_top",            DISCRETE = "discrete",            _extend = $.extend,            _map = $.map,            _each = $.each;        function clonePoint(point, newX, newY, newAngle) {            var p = utils.clone(point);            p.x = newX;            p.y = newY;            p.angle = newAngle;            return p        }        function getTangentPoint(point, prevPoint, centerPoint, tan, nextStepAngle) {            var currectAngle = point.angle + nextStepAngle,                cossin = utils.getCosAndSin(currectAngle),                x = centerPoint.x + (point.radius + tan * nextStepAngle) * cossin.cos,                y = centerPoint.y - (point.radius + tan * nextStepAngle) * cossin.sin;            return clonePoint(prevPoint, x, y, currectAngle)        }        var lineMethods = {                _createElementsGroup: function(elementsStyle) {                    var that = this,                        settings = _extend({"class": "dxc-elements"}, elementsStyle);                    that._applyElementsClipRect(settings);                    that._createGroup("_elementsGroup", that, that._group, settings)                },                _createBordersGroup: function(borderStyle) {                    var that = this,                        settings = _extend({"class": "dxc-borders"}, borderStyle);                    that._applyElementsClipRect(settings);                    that._createGroup("_bordersGroup", that, that._group, settings)                },                _createGroups: function(animationEnabled, style) {                    var that = this;                    style = style || that._styles.normal;                    that._createElementsGroup(style.elements);                    that._areBordersVisible() && that._createBordersGroup(style.border);                    scatterSeries._createGroups.call(that, animationEnabled, {});                    animationEnabled && that._markersGroup && that._markersGroup.attr({opacity: 0.001})                },                _areBordersVisible: function() {                    return false                },                _getDefaultSegment: function(segment) {                    return {line: _map(segment.line || [], function(pt) {                                return pt.getDefaultCoords()                            })}                },                _prepareSegment: function(points) {                    return {line: points}                },                _parseLineOptions: function(options, defaultColor) {                    return {                            stroke: options.color || defaultColor,                            "stroke-width": options.width,                            dashStyle: options.dashStyle || 'solid'                        }                },                _parseStyle: function(options, defaultColor) {                    return {elements: this._parseLineOptions(options, defaultColor)}                },                _applyStyle: function(style) {                    var that = this;                    that._elementsGroup && that._elementsGroup.attr(style.elements);                    _each(that._graphics || [], function(_, graphic) {                        graphic.line && graphic.line.attr({'stroke-width': style.elements["stroke-width"]}).sharp()                    })                },                _drawElement: function(segment, group) {                    return {line: this._createMainElement(segment.line, {"stroke-width": this._styles.normal.elements["stroke-width"]}).append(group)}                },                _removeElement: function(element) {                    element.line.remove()                },                _generateDefaultSegments: function() {                    var that = this;                    return _map(that._segments || [], function(segment) {                            return that._getDefaultSegment(segment)                        })                },                _updateElement: function(element, segment, animate, animateParams, complete) {                    var params = {points: segment.line},                        lineElement = element.line;                    animate ? lineElement.animate(params, animateParams, complete) : lineElement.attr(params)                },                _clearingAnimation: function(translator, drawComplete) {                    var that = this,                        lastIndex = that._graphics.length - 1,                        settings = {opacity: 0.001},                        options = {                            duration: that._defaultDuration,                            partitionDuration: 0.5                        };                    that._labelsGroup && that._labelsGroup.animate(settings, options, function() {                        that._markersGroup && that._markersGroup.animate(settings, options, function() {                            _each(that._defaultSegments || [], function(i, segment) {                                that._oldUpdateElement(that._graphics[i], segment, true, {partitionDuration: 0.5}, i === lastIndex ? drawComplete : undefined)                            })                        })                    })                },                _animateComplete: function() {                    var that = this;                    scatterSeries._animateComplete.call(this);                    that._markersGroup && that._markersGroup.animate({opacity: 1}, {duration: that._defaultDuration})                },                _animate: function() {                    var that = this,                        lastIndex = that._graphics.length - 1;                    _each(that._graphics || [], function(i, elem) {                        that._updateElement(elem, that._segments[i], true, {complete: i === lastIndex ? function() {                                that._animateComplete()                            } : undefined})                    })                },                _drawPoint: function(options) {                    scatterSeries._drawPoint.call(this, {                        point: options.point,                        groups: options.groups                    })                },                _createMainElement: function(points, settings) {                    return this._renderer.path(points, "line").attr(settings).sharp()                },                _drawSegment: function(points, animationEnabled, segmentCount, lastSegment) {                    var that = this,                        segment = that._prepareSegment(points, that._options.rotated, lastSegment);                    that._segments.push(segment);                    if (!that._graphics[segmentCount])                        that._graphics[segmentCount] = that._drawElement(animationEnabled ? that._getDefaultSegment(segment) : segment, that._elementsGroup);                    else if (!animationEnabled)                        that._updateElement(that._graphics[segmentCount], segment)                },                _getTrackerSettings: function() {                    var that = this,                        elements = that._styles.normal.elements;                    return {                            "stroke-width": elements["stroke-width"] > that._defaultTrackerWidth ? elements["stroke-width"] : that._defaultTrackerWidth,                            fill: "none"                        }                },                _getMainPointsFromSegment: function(segment) {                    return segment.line                },                _drawTrackerElement: function(segment) {                    return this._createMainElement(this._getMainPointsFromSegment(segment), this._getTrackerSettings(segment))                },                _updateTrackerElement: function(segment, element) {                    var settings = this._getTrackerSettings(segment);                    settings.points = this._getMainPointsFromSegment(segment);                    element.attr(settings)                }            };        chartSeries.line = _extend({}, scatterSeries, lineMethods);        chartSeries.stepline = _extend({}, chartSeries.line, {            _calculateStepLinePoints: function(points) {                var segment = [];                _each(points, function(i, pt) {                    var stepY,                        point;                    if (!i) {                        segment.push(pt);                        return                    }                    stepY = segment[segment.length - 1].y;                    if (stepY !== pt.y) {                        point = utils.clone(pt);                        point.y = stepY;                        segment.push(point)                    }                    segment.push(pt)                });                return segment            },            _prepareSegment: function(points) {                return chartSeries.line._prepareSegment(this._calculateStepLinePoints(points))            }        });        chartSeries.stackedline = _extend({}, chartSeries.line, {});        chartSeries.fullstackedline = _extend({}, chartSeries.line, {_getRangeData: function(zoomArgs, calcIntervalFunction) {                var that = this;                rangeCalculator.calculateRangeData(that, zoomArgs, calcIntervalFunction);                rangeCalculator.addLabelPaddings(that);                rangeCalculator.processFullStackedRange(that);                return that._rangeData            }});        chartSeries.spline = _extend({}, chartSeries.line, {            _calculateBezierPoints: function(src, rotated) {                var bezierPoints = [],                    pointsCopy = src,                    checkExtr = function(otherPointCoord, pointCoord, controlCoord) {                        return otherPointCoord > pointCoord && controlCoord > otherPointCoord || otherPointCoord < pointCoord && controlCoord < otherPointCoord ? otherPointCoord : controlCoord                    };                if (pointsCopy.length !== 1)                    _each(pointsCopy, function(i, curPoint) {                        var leftControlX,                            leftControlY,                            rightControlX,                            rightControlY,                            prevPoint,                            nextPoint,                            xCur,                            yCur,                            x1,                            x2,                            y1,                            y2,                            lambda = 0.5,                            curIsExtremum,                            leftPoint,                            rightPoint,                            a,                            b,                            c,                            xc,                            yc,                            shift;                        if (!i) {                            bezierPoints.push(curPoint);                            bezierPoints.push(curPoint);                            return                        }                        prevPoint = pointsCopy[i - 1];                        if (i < pointsCopy.length - 1) {                            nextPoint = pointsCopy[i + 1];                            xCur = curPoint.x;                            yCur = curPoint.y;                            x1 = prevPoint.x;                            x2 = nextPoint.x;                            y1 = prevPoint.y;                            y2 = nextPoint.y;                            curIsExtremum = !!(!rotated && (yCur <= prevPoint.y && yCur <= nextPoint.y || yCur >= prevPoint.y && yCur >= nextPoint.y) || rotated && (xCur <= prevPoint.x && xCur <= nextPoint.x || xCur >= prevPoint.x && xCur >= nextPoint.x));                            if (curIsExtremum)                                if (!rotated) {                                    rightControlY = leftControlY = yCur;                                    rightControlX = (xCur + nextPoint.x) / 2;                                    leftControlX = (xCur + prevPoint.x) / 2                                }                                else {                                    rightControlX = leftControlX = xCur;                                    rightControlY = (yCur + nextPoint.y) / 2;                                    leftControlY = (yCur + prevPoint.y) / 2                                }                            else {                                a = y2 - y1;                                b = x1 - x2;                                c = y1 * x2 - x1 * y2;                                if (!rotated) {                                    xc = xCur;                                    yc = -1 * (a * xc + c) / b;                                    shift = yc - yCur || 0;                                    y1 -= shift;                                    y2 -= shift                                }                                else {                                    yc = yCur;                                    xc = -1 * (b * yc + c) / a;                                    shift = xc - xCur || 0;                                    x1 -= shift;                                    x2 -= shift                                }                                rightControlX = (xCur + lambda * x2) / (1 + lambda);                                rightControlY = (yCur + lambda * y2) / (1 + lambda);                                leftControlX = (xCur + lambda * x1) / (1 + lambda);                                leftControlY = (yCur + lambda * y1) / (1 + lambda)                            }                            if (!rotated) {                                leftControlY = checkExtr(prevPoint.y, yCur, leftControlY);                                rightControlY = checkExtr(nextPoint.y, yCur, rightControlY)                            }                            else {                                leftControlX = checkExtr(prevPoint.x, xCur, leftControlX);                                rightControlX = checkExtr(nextPoint.x, xCur, rightControlX)                            }                            leftPoint = clonePoint(curPoint, leftControlX, leftControlY);                            rightPoint = clonePoint(curPoint, rightControlX, rightControlY);                            bezierPoints.push(leftPoint, curPoint, rightPoint)                        }                        else {                            bezierPoints.push(curPoint, curPoint);                            return                        }                    });                else                    bezierPoints.push(pointsCopy[0]);                return bezierPoints            },            _prepareSegment: function(points, rotated) {                return chartSeries.line._prepareSegment(this._calculateBezierPoints(points, rotated))            },            _createMainElement: function(points, settings) {                return this._renderer.path(points, "bezier").attr(settings).sharp()            }        });        polarSeries.line = _extend({}, polarSeries.scatter, lineMethods, {            _prepareSegment: function(points, rotated, lastSegment) {                var preparedPoints = [],                    centerPoint = this.translators.translate(CANVAS_POSITION_START, CANVAS_POSITION_TOP),                    i;                lastSegment && this._closeSegment(points);                if (this.argumentAxisType !== DISCRETE && this.valueAxisType !== DISCRETE) {                    for (i = 1; i < points.length; i++)                        preparedPoints = preparedPoints.concat(this._getTangentPoints(points[i], points[i - 1], centerPoint));                    if (!preparedPoints.length)                        preparedPoints = points                }                else                    return chartSeries.line._prepareSegment.apply(this, arguments);                return {line: preparedPoints}            },            _getRemainingAngle: function(angle) {                var normAngle = utils.normalizeAngle(angle);                return angle >= 0 ? 360 - normAngle : -normAngle            },            _closeSegment: function(points) {                var point,                    differenceAngle;                if (this._segments.length)                    point = this._segments[0].line[0];                else                    point = clonePoint(points[0], points[0].x, points[0].y, points[0].angle);                if (points[points.length - 1].angle !== point.angle) {                    if (utils.normalizeAngle(Math.round(points[points.length - 1].angle)) === utils.normalizeAngle(Math.round(point.angle)))                        point.angle = points[points.length - 1].angle;                    else {                        differenceAngle = points[points.length - 1].angle - point.angle;                        point.angle = points[points.length - 1].angle + this._getRemainingAngle(differenceAngle)                    }                    points.push(point)                }            },            _getTangentPoints: function(point, prevPoint, centerPoint) {                var tangentPoints = [],                    betweenAngle = Math.round(prevPoint.angle - point.angle),                    tan = (prevPoint.radius - point.radius) / betweenAngle,                    i;                if (betweenAngle === 0)                    tangentPoints = [prevPoint, point];                else if (betweenAngle > 0)                    for (i = betweenAngle; i >= 0; i--)                        tangentPoints.push(getTangentPoint(point, prevPoint, centerPoint, tan, i));                else                    for (i = 0; i >= betweenAngle; i--)                        tangentPoints.push(getTangentPoint(point, prevPoint, centerPoint, tan, betweenAngle - i));                return tangentPoints            }        })    })(jQuery, DevExpress);    /*! Module viz-core, file areaSeries.js */    (function($, DX) {        var core = DX.viz.core,            utils = DX.utils,            series = core.series,            chartSeries = series.mixins.chart,            polarSeries = series.mixins.polar,            lineSeries = chartSeries.line,            rangeCalculator = core.series.helpers.rangeDataCalculator,            _map = $.map,            _extend = $.extend,            HOVER_COLOR_HIGHLIGHTING = 20;        var baseAreaMethods = {                _createBorderElement: lineSeries._createMainElement,                _createLegendState: function(styleOptions, defaultColor) {                    var legendState = chartSeries.scatter._createLegendState.call(this, styleOptions, defaultColor);                    legendState.opacity = styleOptions.opacity;                    return legendState                },                _getSpecialColor: function(color) {                    return this._options._IE8 ? new DX.Color(color).highlight(HOVER_COLOR_HIGHLIGHTING) : color                },                _getRangeData: function(zoomArgs, calcIntervalFunction) {                    rangeCalculator.calculateRangeData(this, zoomArgs, calcIntervalFunction);                    rangeCalculator.addLabelPaddings(this);                    rangeCalculator.calculateRangeMinValue(this, zoomArgs);                    return this._rangeData                },                _getDefaultSegment: function(segment) {                    var defaultSegment = lineSeries._getDefaultSegment(segment);                    defaultSegment.area = defaultSegment.line.concat(defaultSegment.line.slice().reverse());                    return defaultSegment                },                _updateElement: function(element, segment, animate, animateParams, complete) {                    var lineParams = {points: segment.line},                        areaParams = {points: segment.area},                        borderElement = element.line;                    if (animate) {                        borderElement && borderElement.animate(lineParams, animateParams);                        element.area.animate(areaParams, animateParams, complete)                    }                    else {                        borderElement && borderElement.attr(lineParams);                        element.area.attr(areaParams)                    }                },                _removeElement: function(element) {                    element.line && element.line.remove();                    element.area.remove()                },                _drawElement: function(segment) {                    return {                            line: this._bordersGroup && this._createBorderElement(segment.line, {"stroke-width": this._styles.normal.border["stroke-width"]}).append(this._bordersGroup),                            area: this._createMainElement(segment.area).append(this._elementsGroup)                        }                },                _applyStyle: function(style) {                    var that = this;                    that._elementsGroup && that._elementsGroup.attr(style.elements);                    that._bordersGroup && that._bordersGroup.attr(style.border);                    $.each(that._graphics || [], function(_, graphic) {                        graphic.line && graphic.line.attr({'stroke-width': style.border["stroke-width"]}).sharp()                    })                },                _createPattern: function(color, hatching, custom) {                    if (hatching && utils.isObject(hatching)) {                        var pattern = this._renderer.pattern(color, hatching);                        pattern._custom = custom;                        this._patterns.push(pattern);                        return pattern.id                    }                    return color                },                _parseStyle: function(options, defaultColor, defaultBorderColor) {                    var borderOptions = options.border || {},                        borderStyle = lineSeries._parseLineOptions(borderOptions, defaultBorderColor);                    borderStyle["stroke-width"] = borderOptions.visible ? borderStyle["stroke-width"] : 0;                    return {                            border: borderStyle,                            elements: {                                stroke: "none",                                fill: this._createPattern(options.color || defaultColor, options.hatching),                                opacity: options.opacity                            }                        }                },                _areBordersVisible: function() {                    var options = this._options;                    return options.border.visible || options.hoverStyle.border.visible || options.selectionStyle.border.visible                },                _createMainElement: function(points, settings) {                    return this._renderer.path(points, "area").attr(settings)                },                _getTrackerSettings: function(segment) {                    return {"stroke-width": segment.singlePointSegment ? this._defaultTrackerWidth : 0}                },                _getMainPointsFromSegment: function(segment) {                    return segment.area                }            };        chartSeries.area = _extend({}, lineSeries, baseAreaMethods, {            _prepareSegment: function(points, rotated) {                var processedPoints = this._processSinglePointsAreaSegment(points, rotated);                return {                        line: processedPoints,                        area: _map(processedPoints, function(pt) {                            return pt.getCoords()                        }).concat(_map(processedPoints.slice().reverse(), function(pt) {                            return pt.getCoords(true)                        })),                        singlePointSegment: processedPoints !== points                    }            },            _processSinglePointsAreaSegment: function(points, rotated) {                if (points.length === 1) {                    var p = points[0],                        p1 = utils.clone(p);                    p1[rotated ? "y" : "x"] += 1;                    p1.argument = null;                    return [p, p1]                }                return points            }        });        polarSeries.area = _extend({}, polarSeries.line, baseAreaMethods, {            _prepareSegment: function(points, rotated, lastSegment) {                lastSegment && polarSeries.line._closeSegment.call(this, points);                var preparedPoints = chartSeries.area._prepareSegment.call(this, points);                return preparedPoints            },            _processSinglePointsAreaSegment: function(points) {                return polarSeries.line._prepareSegment.call(this, points).line            }        });        chartSeries.steparea = _extend({}, chartSeries.area, {_prepareSegment: function(points, rotated) {                points = chartSeries.area._processSinglePointsAreaSegment(points, rotated);                return chartSeries.area._prepareSegment.call(this, chartSeries.stepline._calculateStepLinePoints(points))            }});        chartSeries.splinearea = _extend({}, chartSeries.area, {            _areaPointsToSplineAreaPoints: function(areaPoints) {                var lastFwPoint = areaPoints[areaPoints.length / 2 - 1],                    firstBwPoint = areaPoints[areaPoints.length / 2];                areaPoints.splice(areaPoints.length / 2, 0, {                    x: lastFwPoint.x,                    y: lastFwPoint.y                }, {                    x: firstBwPoint.x,                    y: firstBwPoint.y                });                if (lastFwPoint.defaultCoords)                    areaPoints[areaPoints.length / 2].defaultCoords = true;                if (firstBwPoint.defaultCoords)                    areaPoints[areaPoints.length / 2 - 1].defaultCoords = true            },            _prepareSegment: function(points, rotated) {                var areaSeries = chartSeries.area,                    processedPoints = areaSeries._processSinglePointsAreaSegment(points, rotated),                    areaSegment = areaSeries._prepareSegment.call(this, chartSeries.spline._calculateBezierPoints(processedPoints, rotated));                this._areaPointsToSplineAreaPoints(areaSegment.area);                areaSegment.singlePointSegment = processedPoints !== points;                return areaSegment            },            _getDefaultSegment: function(segment) {                var areaDefaultSegment = chartSeries.area._getDefaultSegment(segment);                this._areaPointsToSplineAreaPoints(areaDefaultSegment.area);                return areaDefaultSegment            },            _createMainElement: function(points, settings) {                return this._renderer.path(points, "bezierarea").attr(settings)            },            _createBorderElement: chartSeries.spline._createMainElement        })    })(jQuery, DevExpress);    /*! Module viz-core, file barSeries.js */    (function($, DX) {        var viz = DX.viz,            series = viz.core.series,            chartSeries = series.mixins.chart,            polarSeries = series.mixins.polar,            scatterSeries = chartSeries.scatter,            areaSeries = chartSeries.area,            _extend = $.extend,            _each = $.each,            DEFAULT_BAR_POINT_SIZE = 3;        var baseBarSeriesMethods = {                _getSpecialColor: areaSeries._getSpecialColor,                _createPattern: areaSeries._createPattern,                _updateOptions: function(options) {                    this._stackName = "axis_" + (options.axis || "default") + "_stack_" + (options.stack || "default")                },                _parsePointStyle: function(style, defaultColor, defaultBorderColor, isCustomPointOptions) {                    var color = this._createPattern(style.color || defaultColor, style.hatching, isCustomPointOptions),                        base = scatterSeries._parsePointStyle.call(this, style, color, defaultBorderColor);                    base.fill = color;                    base.dashStyle = style.border && style.border.dashStyle || "solid";                    delete base.r;                    return base                },                _applyMarkerClipRect: function(settings) {                    settings.clipId = null                },                _clearingAnimation: function(translators, drawComplete) {                    var that = this,                        settings = that._oldgetAffineCoordOptions(translators) || that._getAffineCoordOptions(translators);                    that._labelsGroup && that._labelsGroup.animate({opacity: 0.001}, {                        duration: that._defaultDuration,                        partitionDuration: 0.5                    }, function() {                        that._markersGroup.animate(settings, {partitionDuration: 0.5}, function() {                            that._markersGroup.attr({                                scaleX: null,                                scaleY: null,                                translateX: 0,                                translateY: 0                            });                            drawComplete()                        })                    })                },                _createGroups: function(animationEnabled, style, firstDrawing) {                    var that = this,                        settings = {};                    scatterSeries._createGroups.apply(that, arguments);                    if (animationEnabled && firstDrawing)                        settings = this._getAffineCoordOptions(that.translators, true);                    else if (!animationEnabled)                        settings = {                            scaleX: 1,                            scaleY: 1,                            translateX: 0,                            translateY: 0                        };                    that._markersGroup.attr(settings)                },                _drawPoint: function(options) {                    options.hasAnimation = options.hasAnimation && !options.firstDrawing;                    options.firstDrawing = false;                    scatterSeries._drawPoint.call(this, options)                },                _getMainColor: function() {                    return this._options.mainSeriesColor                },                _createPointStyles: function(pointOptions, isCustomPointOptions) {                    var that = this,                        mainColor = pointOptions.color || that._getMainColor(),                        specialMainColor = that._getSpecialColor(mainColor);                    return {                            normal: that._parsePointStyle(pointOptions, mainColor, mainColor, isCustomPointOptions),                            hover: that._parsePointStyle(pointOptions.hoverStyle || {}, specialMainColor, mainColor, isCustomPointOptions),                            selection: that._parsePointStyle(pointOptions.selectionStyle || {}, specialMainColor, mainColor, isCustomPointOptions)                        }                },                _updatePointsVisibility: function() {                    var visibility = this._options.visible;                    $.each(this._points, function(_, point) {                        point._options.visible = visibility                    })                },                _preparePointOptions: function(customOptions) {                    var options = this._options;                    return customOptions ? _extend(true, {}, options, customOptions) : options                },                _animate: function(firstDrawing) {                    var that = this,                        complete = function() {                            that._animateComplete()                        },                        animateFunc = function(drawedPoints, complete) {                            var lastPointIndex = drawedPoints.length - 1;                            _each(drawedPoints || [], function(i, point) {                                point.animate(i === lastPointIndex ? complete : undefined, point.getMarkerCoords())                            })                        };                    that._animatePoints(firstDrawing, complete, animateFunc)                },                _getPointSize: function() {                    return DEFAULT_BAR_POINT_SIZE                },                _beginUpdateData: function(data) {                    scatterSeries._beginUpdateData.call(this, data);                    this._patterns = $.map(this._patterns, function(pattern) {                        if (pattern._custom) {                            pattern.remove();                            return null                        }                        else                            return pattern                    })                }            };        chartSeries.bar = _extend({}, scatterSeries, baseBarSeriesMethods, {            _getAffineCoordOptions: function(translators) {                var rotated = this._options.rotated,                    direction = rotated ? "x" : "y",                    settings = {                        scaleX: rotated ? 0.001 : 1,                        scaleY: rotated ? 1 : 0.001                    };                settings["translate" + direction.toUpperCase()] = translators[direction].translate("canvas_position_default");                return settings            },            _getRangeData: function() {                var rangeData = areaSeries._getRangeData.apply(this, arguments);                rangeData.arg.stick = false;                return rangeData            },            _animatePoints: function(firstDrawing, complete, animateFunc) {                var that = this;                that._markersGroup.animate({                    scaleX: 1,                    scaleY: 1,                    translateY: 0,                    translateX: 0                }, undefined, complete);                if (!firstDrawing)                    animateFunc(that._drawedPoints, complete)            }        });        polarSeries.bar = _extend({}, polarSeries.scatter, baseBarSeriesMethods, {            _animatePoints: function(firstDrawing, complete, animateFunc) {                animateFunc(this._drawedPoints, complete)            },            _createGroups: function() {                scatterSeries._createGroups.apply(this, arguments)            },            _drawPoint: function(point, groups, animationEnabled) {                scatterSeries._drawPoint.call(this, point, groups, animationEnabled)            },            _parsePointStyle: function(style) {                var base = baseBarSeriesMethods._parsePointStyle.apply(this, arguments);                base.opacity = style.opacity;                return base            },            _createMarkerGroup: function() {                var that = this,                    markersSettings = that._getPointOptions().styles.normal,                    groupSettings;                markersSettings["class"] = "dxc-markers";                that._applyMarkerClipRect(markersSettings);                groupSettings = _extend({}, markersSettings);                delete groupSettings.opacity;                that._createGroup("_markersGroup", that, that._group, groupSettings)            },            _createLegendState: areaSeries._createLegendState,            _getRangeData: areaSeries._getRangeData        })    })(jQuery, DevExpress);    /*! Module viz-core, file rangeSeries.js */    (function($, DX) {        var core = DX.viz.core,            series = core.series.mixins.chart,            _extend = $.extend,            _isDefined = DX.utils.isDefined,            _noop = $.noop,            rangeCalculator = core.series.helpers.rangeDataCalculator,            areaSeries = series.area;        var baseRangeSeries = {                _beginUpdateData: _noop,                areErrorBarsVisible: _noop,                _createErrorBarGroup: _noop,                _checkData: function(data) {                    return _isDefined(data.argument) && data.value !== undefined && data.minValue !== undefined                },                updateTeamplateFieldNames: function() {                    var that = this,                        options = that._options,                        valueFields = that.getValueFields(),                        name = that.name;                    options.rangeValue1Field = valueFields[0] + name;                    options.rangeValue2Field = valueFields[1] + name;                    options.tagField = that.getTagField() + name                },                _processRange: function(point, prevPoint) {                    rangeCalculator.processTwoValues(this, point, prevPoint, "value", "minValue")                },                _getRangeData: function(zoomArgs, calcIntervalFunction) {                    rangeCalculator.calculateRangeData(this, zoomArgs, calcIntervalFunction, "value", "minValue");                    rangeCalculator.addRangeSeriesLabelPaddings(this);                    return this._rangeData                },                _getPointData: function(data, options) {                    return {                            tag: data[options.tagField || "tag"],                            minValue: data[options.rangeValue1Field || "val1"],                            value: data[options.rangeValue2Field || "val2"],                            argument: data[options.argumentField || "arg"]                        }                },                _fusionPoints: function(fusionPoints, tick) {                    var calcMedianValue = series.scatter._calcMedianValue,                        value = calcMedianValue.call(this, fusionPoints, "value"),                        minValue = calcMedianValue.call(this, fusionPoints, "minValue");                    if (value === null || minValue === null)                        value = minValue = null;                    return {                            minValue: minValue,                            value: value,                            argument: tick,                            tag: null                        }                },                getValueFields: function() {                    return [this._options.rangeValue1Field || "val1", this._options.rangeValue2Field || "val2"]                }            };        series.rangebar = _extend({}, series.bar, baseRangeSeries);        series.rangearea = _extend({}, areaSeries, {            _drawPoint: function(options) {                var point = options.point;                if (point.isInVisibleArea()) {                    point.clearVisibility();                    point.draw(this._renderer, options.groups);                    this._drawedPoints.push(point);                    if (!point.visibleTopMarker)                        point.hideMarker("top");                    if (!point.visibleBottomMarker)                        point.hideMarker("bottom")                }                else                    point.setInvisibility()            },            _prepareSegment: function(points, rotated) {                var processedPoints = this._processSinglePointsAreaSegment(points, rotated),                    processedMinPointsCoords = $.map(processedPoints, function(pt) {                        return pt.getCoords(true)                    });                return {                        line: processedPoints,                        bottomLine: processedMinPointsCoords,                        area: $.map(processedPoints, function(pt) {                            return pt.getCoords()                        }).concat(processedMinPointsCoords.slice().reverse()),                        singlePointSegment: processedPoints !== points                    }            },            _getDefaultSegment: function(segment) {                var defaultSegment = areaSeries._getDefaultSegment.call(this, segment);                defaultSegment.bottomLine = defaultSegment.line;                return defaultSegment            },            _removeElement: function(element) {                areaSeries._removeElement.call(this, element);                element.bottomLine && element.bottomLine.remove()            },            _drawElement: function(segment, group) {                var that = this,                    drawnElement = areaSeries._drawElement.call(that, segment, group);                drawnElement.bottomLine = that._bordersGroup && that._createBorderElement(segment.bottomLine, {"stroke-width": that._styles.normal.border["stroke-width"]}).append(that._bordersGroup);                return drawnElement            },            _applyStyle: function(style) {                var that = this,                    elementsGroup = that._elementsGroup,                    bordersGroup = that._bordersGroup;                elementsGroup && elementsGroup.attr(style.elements);                bordersGroup && bordersGroup.attr(style.border);                $.each(that._graphics || [], function(_, graphic) {                    graphic.line && graphic.line.attr({"stroke-width": style.border["stroke-width"]});                    graphic.bottomLine && graphic.bottomLine.attr({"stroke-width": style.border["stroke-width"]})                })            },            _updateElement: function(element, segment, animate, animateParams, complete) {                areaSeries._updateElement.call(this, element, segment, animate, animateParams, complete);                var bottomLineParams = {points: segment.bottomLine},                    bottomBorderElement = element.bottomLine;                if (bottomBorderElement)                    animate ? bottomBorderElement.animate(bottomLineParams, animateParams) : bottomBorderElement.attr(bottomLineParams)            }        }, baseRangeSeries)    })(jQuery, DevExpress);    /*! Module viz-core, file bubbleSeries.js */    (function($, DX) {        var mixins = DX.viz.core.series.mixins,            series = mixins.chart,            scatterSeries = series.scatter,            barSeries = series.bar,            _isDefined = DX.utils.isDefined,            _extend = $.extend,            _each = $.each,            _noop = $.noop;        series.bubble = _extend({}, scatterSeries, {            _fillErrorBars: _noop,            _getRangeCorrector: _noop,            _calculateErrorBars: _noop,            _getMainColor: barSeries._getMainColor,            _createPointStyles: barSeries._createPointStyles,            _createPattern: barSeries._createPattern,            _updatePointsVisibility: barSeries._updatePointsVisibility,            _preparePointOptions: barSeries._preparePointOptions,            _getSpecialColor: barSeries._getSpecialColor,            _applyMarkerClipRect: series.line._applyElementsClipRect,            _parsePointStyle: mixins.polar.bar._parsePointStyle,            _createLegendState: series.area._createLegendState,            _createMarkerGroup: mixins.polar.bar._createMarkerGroup,            areErrorBarsVisible: _noop,            _createErrorBarGroup: _noop,            _checkData: function(data) {                return _isDefined(data.argument) && _isDefined(data.size) && data.value !== undefined            },            _getPointData: function(data, options) {                var pointData = scatterSeries._getPointData.call(this, data, options);                pointData.size = data[options.sizeField || "size"];                return pointData            },            _fusionPoints: function(fusionPoints, tick) {                var calcMedianValue = scatterSeries._calcMedianValue;                return {                        size: calcMedianValue.call(this, fusionPoints, "size"),                        value: calcMedianValue.call(this, fusionPoints, "value"),                        argument: tick,                        tag: null                    }            },            getValueFields: function() {                var options = this._options;                return [options.valueField || "val", options.sizeField || "size"]            },            updateTeamplateFieldNames: function() {                var that = this,                    options = that._options,                    valueFields = that.getValueFields(),                    name = that.name;                options.valueField = valueFields[0] + name;                options.sizeField = valueFields[1] + name;                options.tagField = that.getTagField() + name            },            _clearingAnimation: function(translators, drawComplete) {                var that = this,                    partitionDuration = 0.5,                    lastPointIndex = that._drawedPoints.length - 1,                    labelsGroup = that._labelsGroup;                labelsGroup && labelsGroup.animate({opacity: 0.001}, {                    duration: that._defaultDuration,                    partitionDuration: partitionDuration                }, function() {                    _each(that._drawedPoints || [], function(i, p) {                        p.animate(i === lastPointIndex ? drawComplete : undefined, {r: 0}, partitionDuration)                    })                })            },            _animate: function() {                var that = this,                    lastPointIndex = that._drawedPoints.length - 1,                    labelsGroup = that._labelsGroup,                    labelAnimFunc = function() {                        labelsGroup && labelsGroup.animate({opacity: 1}, {duration: that._defaultDuration})                    };                _each(that._drawedPoints || [], function(i, p) {                    p.animate(i === lastPointIndex ? labelAnimFunc : undefined, {                        r: p.bubbleSize,                        translateX: p.x,                        translateY: p.y                    })                })            },            _beginUpdateData: barSeries._beginUpdateData        })    })(jQuery, DevExpress);    /*! Module viz-core, file pieSeries.js */    (function($, DX) {        var mixins = DX.viz.core.series.mixins,            pieSeries = mixins.pie,            _utils = DX.utils,            scatterSeries = mixins.chart.scatter,            barSeries = mixins.chart.bar,            _extend = $.extend,            _each = $.each,            _noop = $.noop,            _map = $.map,            _isFinite = isFinite,            _max = Math.max;        pieSeries.pie = _extend({}, barSeries, {            _createLabelGroup: scatterSeries._createLabelGroup,            _createGroups: scatterSeries._createGroups,            _createErrorBarGroup: _noop,            _drawPoint: function(options) {                var point = options.point,                    legendCallback = options.legendCallback;                scatterSeries._drawPoint.call(this, options);                !point.isVisible() && point.setInvisibility();                legendCallback && point.isSelected() && legendCallback(point)("applySelected")            },            adjustLabels: function() {                var that = this,                    points = that._points || [],                    maxLabelLength,                    labelsBBoxes = [];                _each(points, function(_, point) {                    if (point._label.isVisible() && point._label.getLayoutOptions().position !== "inside") {                        point.setLabelEllipsis();                        labelsBBoxes.push(point._label.getBoundingRect().width)                    }                });                if (labelsBBoxes.length)                    maxLabelLength = _max.apply(null, labelsBBoxes);                _each(points, function(_, point) {                    if (point._label.isVisible() && point._label.getLayoutOptions().position !== "inside") {                        point._maxLabelLength = maxLabelLength;                        point.updateLabelCoord()                    }                })            },            _processRange: _noop,            _applyElementsClipRect: _noop,            getColor: _noop,            areErrorBarsVisible: _noop,            _prepareSeriesToDrawing: _noop,            _endUpdateData: scatterSeries._prepareSeriesToDrawing,            resetLabelSetups: function() {                _each(this._points || [], function(_, point) {                    point._label.clearVisibility()                })            },            drawLabelsWOPoints: function(translators) {                var that = this,                    options = that._options,                    points = that._points || [],                    labelsGroup;                if (options.label.position === "inside")                    return false;                that._createGroups();                labelsGroup = that._labelsGroup;                _each(points, function(_, point) {                    point.drawLabel(translators, that._renderer, labelsGroup)                });                return true            },            _getCreatingPointOptions: function() {                return this._getPointOptions()            },            _updateOptions: function(options) {                this.labelSpace = 0;                this.innerRadius = this.type === "pie" ? 0 : options.innerRadius            },            _checkData: function(data) {                var base = barSeries._checkData(data);                return this._options.paintNullPoints ? base : base && data.value !== null            },            _createMarkerGroup: function() {                var that = this;                if (!that._markersGroup)                    that._markersGroup = that._renderer.g().attr({"class": "dxc-markers"}).append(that._group)            },            _getMainColor: function() {                return this._options.mainSeriesColor()            },            _getPointOptions: function() {                return this._parsePointOptions(this._preparePointOptions(), this._options.label)            },            _getRangeData: function() {                return this._rangeData            },            _getArrangeTotal: function(points) {                var total = 0;                _each(points, function(_, point) {                    if (point.isVisible())                        total += point.initialValue                });                return total            },            _createPointStyles: function(pointOptions) {                var that = this,                    mainColor = pointOptions.color || that._getMainColor(),                    specialMainColor = that._getSpecialColor(mainColor);                return {                        normal: that._parsePointStyle(pointOptions, mainColor, mainColor),                        hover: that._parsePointStyle(pointOptions.hoverStyle, specialMainColor, mainColor),                        selection: that._parsePointStyle(pointOptions.selectionStyle, specialMainColor, mainColor),                        legendStyles: {                            normal: that._createLegendState(pointOptions, mainColor),                            hover: that._createLegendState(pointOptions.hoverStyle, specialMainColor),                            selection: that._createLegendState(pointOptions.selectionStyle, specialMainColor)                        }                    }            },            _getArrangeMinShownValue: function(points, total) {                var minSegmentSize = this._options.minSegmentSize,                    totalMinSegmentSize = 0,                    totalNotMinValues = 0;                total = total || points.length;                _each(points, function(_, point) {                    if (point.isVisible())                        if (point.initialValue < minSegmentSize * total / 360)                            totalMinSegmentSize += minSegmentSize;                        else                            totalNotMinValues += point.initialValue                });                return totalMinSegmentSize < 360 ? minSegmentSize * totalNotMinValues / (360 - totalMinSegmentSize) : 0            },            _applyArrangeCorrection: function(points, minShownValue, total) {                var options = this._options,                    isClockWise = options.segmentsDirection !== "anticlockwise",                    shiftedAngle = _isFinite(options.startAngle) ? _utils.normalizeAngle(options.startAngle) : 0,                    minSegmentSize = options.minSegmentSize,                    percent,                    correction = 0,                    zeroTotalCorrection = 0;                if (total === 0) {                    total = points.length;                    zeroTotalCorrection = 1                }                _each(isClockWise ? points : points.concat([]).reverse(), function(_, point) {                    var val = point.isVisible() ? zeroTotalCorrection || point.initialValue : 0,                        updatedZeroValue;                    if (minSegmentSize && point.isVisible() && val < minShownValue)                        updatedZeroValue = minShownValue;                    percent = val / total;                    point.correctValue(correction, percent, zeroTotalCorrection + (updatedZeroValue || 0));                    point.shiftedAngle = shiftedAngle;                    correction = correction + (updatedZeroValue || val)                });                this._rangeData = {val: {                        min: 0,                        max: correction                    }}            },            arrangePoints: function() {                var that = this,                    originalPoints = that._originalPoints || [],                    minSegmentSize = that._options.minSegmentSize,                    minShownValue,                    pointIndex = 0,                    total,                    isAllPointsNegative = _max.apply(null, _map(originalPoints, function(p) {                        return p.value                    })) <= 0,                    points = that._originalPoints = that._points = _map(originalPoints, function(point) {                        if (point.value === null || !isAllPointsNegative && point.value < 0 || point.value === 0 && !minSegmentSize) {                            point.dispose();                            return null                        }                        else {                            point.index = pointIndex++;                            return point                        }                    });                total = that._getArrangeTotal(points);                if (minSegmentSize)                    minShownValue = this._getArrangeMinShownValue(points, total);                that._applyArrangeCorrection(points, minShownValue, total)            },            correctPosition: function(correction) {                var debug = DX.utils.debug;                debug.assert(correction, "correction was not passed");                debug.assertParam(correction.centerX, "correction.centerX was not passed");                debug.assertParam(correction.centerY, "correction.centerY was not passed");                debug.assertParam(correction.radiusInner, "correction.radiusInner was not passed");                debug.assertParam(correction.radiusOuter, "correction.radiusOuter was not passed");                _each(this._points, function(_, point) {                    point.correctPosition(correction)                });                this._centerX = correction.centerX;                this._centerY = correction.centerY;                this._radiusOuter = correction.radiusOuter            },            _animate: function(firstDrawing) {                var that = this,                    index = 0,                    timeThreshold = 0.2,                    points = that._points,                    pointsCount = points && points.length,                    duration = 1 / (timeThreshold * (pointsCount - 1) + 1),                    completeFunc = function() {                        that._animateComplete()                    },                    animateP = function() {                        points[index] && points[index].animate(index === pointsCount - 1 ? completeFunc : undefined, duration, stepFunc);                        index++                    },                    stepFunc = function(_, progress) {                        if (progress >= timeThreshold) {                            this.step = null;                            animateP()                        }                    };                if (firstDrawing)                    animateP();                else                    $.each(points, function(i, p) {                        p.animate(i === pointsCount - 1 ? completeFunc : undefined)                    })            },            getVisiblePoints: function() {                return _map(this._points, function(p) {                        return p.isVisible() ? p : null                    })            },            getPointByCoord: function(x, y) {                var points = this._points;                for (var i = 0; i < points.length; i++)                    if (points[i].coordsIn(x, y))                        return points[i]            },            _beginUpdateData: function() {                this._deletePatterns();                this._patterns = []            },            getCenter: function() {                return {                        x: this._centerX,                        y: this._centerY                    }            }        });        pieSeries.doughnut = pieSeries.donut = pieSeries.pie    })(jQuery, DevExpress);    /*! Module viz-core, file financialSeries.js */    (function($, DX) {        var viz = DX.viz,            seriesNS = viz.core.series,            series = seriesNS.mixins.chart,            scatterSeries = series.scatter,            barSeries = series.bar,            rangeCalculator = seriesNS.helpers.rangeDataCalculator,            _isDefined = DX.utils.isDefined,            _extend = $.extend,            _each = $.each,            _noop = $.noop,            DEFAULT_FINANCIAL_POINT_SIZE = 10;        series.stock = _extend({}, scatterSeries, {            _animate: _noop,            _applyMarkerClipRect: function(settings) {                settings.clipId = this._forceClipping ? this._paneClipRectID : this._widePaneClipRectID            },            _updatePointsVisibility: barSeries._updatePointsVisibility,            _preparePointOptions: barSeries._preparePointOptions,            _getRangeCorrector: _noop,            _createErrorBarGroup: _noop,            areErrorBarsVisible: _noop,            _createMarkerGroup: function() {                var that = this,                    markersGroup,                    styles = that._getPointOptions().styles,                    defaultStyle = styles.normal,                    defaultPositiveStyle = styles.positive.normal,                    reductionStyle = styles.reduction.normal,                    reductionPositiveStyle = styles.reductionPositive.normal,                    markerSettings = {"class": "dxc-markers"};                that._applyMarkerClipRect(markerSettings);                defaultStyle["class"] = "default-markers";                defaultPositiveStyle["class"] = "default-positive-markers";                reductionStyle["class"] = "reduction-markers";                reductionPositiveStyle["class"] = "reduction-positive-markers";                that._createGroup("_markersGroup", that, that._group, markerSettings);                markersGroup = that._markersGroup;                that._createGroup("defaultMarkersGroup", markersGroup, markersGroup, defaultStyle);                that._createGroup("reductionMarkersGroup", markersGroup, markersGroup, reductionStyle);                that._createGroup("defaultPositiveMarkersGroup", markersGroup, markersGroup, defaultPositiveStyle);                that._createGroup("reductionPositiveMarkersGroup", markersGroup, markersGroup, reductionPositiveStyle)            },            _createGroups: function() {                scatterSeries._createGroups.call(this, false)            },            _clearingAnimation: function(translators, drawComplete) {                drawComplete()            },            _getCreatingPointOptions: function() {                var that = this,                    defaultPointOptions,                    creatingPointOptions = that._predefinedPointOptions;                if (!creatingPointOptions) {                    defaultPointOptions = this._getPointOptions();                    that._predefinedPointOptions = creatingPointOptions = _extend(true, {styles: {}}, defaultPointOptions);                    creatingPointOptions.styles.normal = creatingPointOptions.styles.positive.normal = creatingPointOptions.styles.reduction.normal = creatingPointOptions.styles.reductionPositive.normal = {"stroke-width": defaultPointOptions.styles && defaultPointOptions.styles.normal && defaultPointOptions.styles.normal["stroke-width"]}                }                return creatingPointOptions            },            _checkData: function(data) {                return _isDefined(data.argument) && data.highValue !== undefined && data.lowValue !== undefined && data.openValue !== undefined && data.closeValue !== undefined            },            _processRange: function(point, prevPoint) {                rangeCalculator.processTwoValues(this, point, prevPoint, "highValue", "lowValue")            },            _getRangeData: function(zoomArgs, calcIntervalFunction) {                rangeCalculator.calculateRangeData(this, zoomArgs, calcIntervalFunction, "highValue", "lowValue");                rangeCalculator.addRangeSeriesLabelPaddings(this);                return this._rangeData            },            _getPointData: function(data, options) {                var that = this,                    level,                    openValueField = options.openValueField || "open",                    closeValueField = options.closeValueField || "close",                    highValueField = options.highValueField || "high",                    lowValueField = options.lowValueField || "low",                    reductionValue;                that.level = options.reduction.level;                switch ((that.level || "").toLowerCase()) {                    case"open":                        level = openValueField;                        break;                    case"high":                        level = highValueField;                        break;                    case"low":                        level = lowValueField;                        break;                    default:                        level = closeValueField;                        that.level = "close";                        break                }                reductionValue = data[level];                return {                        argument: data[options.argumentField || "date"],                        highValue: data[highValueField],                        lowValue: data[lowValueField],                        closeValue: data[closeValueField],                        openValue: data[openValueField],                        reductionValue: reductionValue,                        tag: data[options.tagField || "tag"],                        isReduction: that._checkReduction(reductionValue)                    }            },            _parsePointStyle: function(style, defaultColor, innerColor) {                return {                        stroke: style.color || defaultColor,                        "stroke-width": style.width,                        fill: style.color || innerColor                    }            },            updateTeamplateFieldNames: function() {                var that = this,                    options = that._options,                    valueFields = that.getValueFields(),                    name = that.name;                options.openValueField = valueFields[0] + name;                options.highValueField = valueFields[1] + name;                options.lowValueField = valueFields[2] + name;                options.closeValueField = valueFields[3] + name;                options.tagField = that.getTagField() + name            },            _getDefaultStyle: function(options, isCustomPointOptions) {                var that = this,                    mainPointColor = options.color || that._options.mainSeriesColor;                return {                        normal: that._parsePointStyle(options, mainPointColor, mainPointColor, isCustomPointOptions),                        hover: that._parsePointStyle(options.hoverStyle, mainPointColor, mainPointColor, isCustomPointOptions),                        selection: that._parsePointStyle(options.selectionStyle, mainPointColor, mainPointColor, isCustomPointOptions)                    }            },            _getReductionStyle: function(options, isCustomPointOptions) {                var that = this,                    reductionColor = options.reduction.color;                return {                        normal: that._parsePointStyle({                            color: reductionColor,                            width: options.width,                            hatching: options.hatching                        }, reductionColor, reductionColor, isCustomPointOptions),                        hover: that._parsePointStyle(options.hoverStyle, reductionColor, reductionColor, isCustomPointOptions),                        selection: that._parsePointStyle(options.selectionStyle, reductionColor, reductionColor, isCustomPointOptions)                    }            },            _createPointStyles: function(pointOptions, isCustomPointOptions) {                var that = this,                    innerColor = that._options.innerColor,                    styles = that._getDefaultStyle(pointOptions, isCustomPointOptions),                    positiveStyle,                    reductionStyle,                    reductionPositiveStyle;                positiveStyle = _extend(true, {}, styles);                reductionStyle = that._getReductionStyle(pointOptions, isCustomPointOptions);                reductionPositiveStyle = _extend(true, {}, reductionStyle);                positiveStyle.normal.fill = positiveStyle.hover.fill = positiveStyle.selection.fill = innerColor;                reductionPositiveStyle.normal.fill = reductionPositiveStyle.hover.fill = reductionPositiveStyle.selection.fill = innerColor;                styles.positive = positiveStyle;                styles.reduction = reductionStyle;                styles.reductionPositive = reductionPositiveStyle;                return styles            },            _endUpdateData: function() {                delete this.prevLevelValue;                delete this._predefinedPointOptions            },            _checkReduction: function(value) {                var that = this,                    result = false;                if (value !== null) {                    if (_isDefined(that.prevLevelValue))                        result = value < that.prevLevelValue;                    that.prevLevelValue = value                }                return result            },            _fusionPoints: function(fusionPoints, tick) {                var fusedPointData = {},                    reductionLevel,                    highValue = -Infinity,                    lowValue = +Infinity,                    openValue,                    closeValue;                if (!fusionPoints.length)                    return {};                _each(fusionPoints, function(_, point) {                    if (!point.hasValue())                        return;                    highValue = Math.max(highValue, point.highValue);                    lowValue = Math.min(lowValue, point.lowValue);                    openValue = openValue !== undefined ? openValue : point.openValue;                    closeValue = point.closeValue !== undefined ? point.closeValue : closeValue                });                fusedPointData.argument = tick;                fusedPointData.openValue = openValue;                fusedPointData.closeValue = closeValue;                fusedPointData.highValue = highValue;                fusedPointData.lowValue = lowValue;                fusedPointData.tag = null;                switch ((this.level || "").toLowerCase()) {                    case"open":                        reductionLevel = openValue;                        break;                    case"high":                        reductionLevel = highValue;                        break;                    case"low":                        reductionLevel = lowValue;                        break;                    default:                        reductionLevel = closeValue;                        break                }                fusedPointData.reductionValue = reductionLevel;                fusedPointData.isReduction = this._checkReduction(reductionLevel);                return fusedPointData            },            _getPointSize: function() {                return DEFAULT_FINANCIAL_POINT_SIZE            },            getValueFields: function() {                var options = this._options;                return [options.openValueField || "open", options.highValueField || "high", options.lowValueField || "low", options.closeValueField || "close"]            },            getArgumentField: function() {                return this._options.argumentField || "date"            },            _beginUpdateData: _noop        });        series.candlestick = _extend({}, series.stock, {            _createPattern: barSeries._createPattern,            _beginUpdateData: barSeries._beginUpdateData,            _parsePointStyle: function(style, defaultColor, innerColor, isCustomPointOptions) {                var color = this._createPattern(style.color || innerColor, style.hatching, isCustomPointOptions),                    base = series.stock._parsePointStyle.call(this, style, defaultColor, color);                base.fill = color;                return base            }        })    })(jQuery, DevExpress);    /*! Module viz-core, file stackedSeries.js */    (function($, DX) {        var core = DX.viz.core,            series = core.series,            chartSeries = series.mixins.chart,            polarSeries = series.mixins.polar,            areaSeries = chartSeries.area,            barSeries = chartSeries.bar,            lineSeries = chartSeries.line,            rangeCalculator = core.series.helpers.rangeDataCalculator,            _extend = $.extend,            utils = DX.utils,            _noop = $.noop,            baseStackedSeries = {                _processRange: _noop,                _getRangeCorrector: _noop,                _fillErrorBars: _noop,                _calculateErrorBars: _noop,                _processStackedRange: function() {                    var that = this,                        prevPoint;                    that._resetRangeData();                    $.each(that.getAllPoints(), function(i, p) {                        rangeCalculator.processRange(that, p, prevPoint);                        prevPoint = p                    })                },                _getRangeData: function() {                    this._processStackedRange();                    return areaSeries._getRangeData.apply(this, arguments)                }            },            baseFullStackedSeries = _extend({}, baseStackedSeries, {                _getRangeData: function(zoomArgs, calcIntervalFunction) {                    var that = this;                    that._processStackedRange();                    rangeCalculator.calculateRangeData(that, zoomArgs, calcIntervalFunction);                    rangeCalculator.addLabelPaddings(that);                    rangeCalculator.processFullStackedRange(that);                    rangeCalculator.calculateRangeMinValue(that, zoomArgs);                    return that._rangeData                },                isFullStackedSeries: function() {                    return true                }            });        chartSeries.stackedline = _extend({}, lineSeries, baseStackedSeries, {_getRangeData: function() {                this._processStackedRange();                return lineSeries._getRangeData.apply(this, arguments)            }});        chartSeries.stackedspline = _extend({}, chartSeries.spline, baseStackedSeries, {_getRangeData: chartSeries.stackedline._getRangeData});        chartSeries.fullstackedline = _extend({}, lineSeries, baseFullStackedSeries, {_getRangeData: function(zoomArgs, calcIntervalFunction) {                var that = this;                that._processStackedRange();                rangeCalculator.calculateRangeData(that, zoomArgs, calcIntervalFunction);                rangeCalculator.addLabelPaddings(that);                rangeCalculator.processFullStackedRange(that);                return that._rangeData            }});        chartSeries.fullstackedspline = _extend({}, chartSeries.spline, baseFullStackedSeries, {_getRangeData: chartSeries.fullstackedline._getRangeData});        chartSeries.stackedbar = _extend({}, barSeries, baseStackedSeries, {_getRangeData: function() {                this._processStackedRange();                return barSeries._getRangeData.apply(this, arguments)            }});        chartSeries.fullstackedbar = _extend({}, barSeries, baseFullStackedSeries, {_getRangeData: function() {                var rangeData = baseFullStackedSeries._getRangeData.apply(this, arguments);                rangeData.arg.stick = false;                return rangeData            }});        function clonePoint(point, value, minValue, position) {            point = utils.clone(point);            point.value = value;            point.minValue = minValue;            point.translate();            point.argument = point.argument + position;            return point        }        function preparePointsForStackedAreaSegment(points) {            points = $.map(points, function(p) {                var result = [p];                if (p.leftHole)                    result = [clonePoint(p, p.leftHole, p.minLeftHole, "left"), p];                if (p.rightHole)                    result.push(clonePoint(p, p.rightHole, p.minRightHole, "right"));                return result            });            return points        }        chartSeries.stackedarea = _extend({}, areaSeries, baseStackedSeries, {_prepareSegment: function(points, rotated) {                return areaSeries._prepareSegment.call(this, preparePointsForStackedAreaSegment(points, this._prevSeries), rotated)            }});        function getPointsByArgFromPrevSeries(prevSeries, argument) {            var result;            while (prevSeries) {                result = prevSeries._segmentByArg[argument];                if (result)                    break;                prevSeries = prevSeries._prevSeries            }            return result        }        chartSeries.stackedsplinearea = _extend({}, chartSeries.splinearea, baseStackedSeries, {_prepareSegment: function(points, rotated) {                var that = this,                    areaSegment;                points = preparePointsForStackedAreaSegment(points, that._prevSeries);                if (!this._prevSeries || points.length === 1)                    areaSegment = chartSeries.splinearea._prepareSegment.call(this, points, rotated);                else {                    var fwPoints = chartSeries.spline._calculateBezierPoints(points, rotated),                        bwPoints = $.map(points, function(p) {                            var point = p.getCoords(true);                            point.argument = p.argument;                            return point                        }),                        prevSeriesFwPoints = $.map(that._prevSeries._segments, function(seg) {                            return seg.line                        }),                        pointByArg = {};                    $.each(prevSeriesFwPoints, function(_, p) {                        if (p.argument !== null) {                            var argument = p.argument.valueOf();                            if (!pointByArg[argument])                                pointByArg[argument] = [p];                            else                                pointByArg[argument].push(p)                        }                    });                    that._prevSeries._segmentByArg = pointByArg;                    bwPoints = chartSeries.spline._calculateBezierPoints(bwPoints, rotated);                    $.each(bwPoints, function(i, p) {                        var argument = p.argument.valueOf(),                            prevSeriesPoints;                        if (i % 3 === 0) {                            prevSeriesPoints = pointByArg[argument] || getPointsByArgFromPrevSeries(that._prevSeries, argument);                            if (prevSeriesPoints) {                                bwPoints[i - 1] && prevSeriesPoints[0] && (bwPoints[i - 1] = prevSeriesPoints[0]);                                bwPoints[i + 1] && (bwPoints[i + 1] = prevSeriesPoints[2] || p)                            }                        }                    });                    areaSegment = {                        line: fwPoints,                        area: fwPoints.concat(bwPoints.reverse())                    };                    that._areaPointsToSplineAreaPoints(areaSegment.area)                }                return areaSegment            }});        chartSeries.fullstackedarea = _extend({}, areaSeries, baseFullStackedSeries, {_prepareSegment: chartSeries.stackedarea._prepareSegment});        chartSeries.fullstackedsplinearea = _extend({}, chartSeries.splinearea, baseFullStackedSeries, {_prepareSegment: chartSeries.stackedsplinearea._prepareSegment});        polarSeries.stackedbar = _extend({}, polarSeries.bar, baseStackedSeries, {_getRangeData: function() {                this._processStackedRange();                return polarSeries.bar._getRangeData.apply(this, arguments)            }})    })(jQuery, DevExpress);    /*! Module viz-core, file basePoint.js */    (function($, DX) {        var seriesNS = DX.viz.core.series,            statesConsts = seriesNS.helpers.consts.states,            _each = $.each,            _extend = $.extend,            _isDefined = DX.utils.isDefined,            seiresMixins = seriesNS.mixins,            _noop = $.noop;        function Point() {            this.ctor.apply(this, arguments)        }        seriesNS.points = {Point: Point};        Point.prototype = {            ctor: function(series, dataItem, options) {                this.series = series;                this.update(dataItem, options);                this._emptySettings = {                    fill: null,                    stroke: null,                    dashStyle: null                }            },            getColor: function() {                return this._styles.normal.fill || this.series.getColor()            },            _getStyle: function() {                var that = this,                    styles = that._styles,                    style;                if (that.isSelected())                    style = styles.selection;                else if (that.isHovered())                    style = styles.hover;                else {                    that.fullState = statesConsts.normalMark;                    style = styles.normal                }                that._currentStyle = style;                return style            },            update: function(dataItem, options) {                this.updateOptions(options);                this.updateData(dataItem)            },            updateData: function(dataItem) {                var that = this;                that.argument = that.initialArgument = that.originalArgument = dataItem.argument;                that.tag = dataItem.tag;                that.index = dataItem.index;                that.lowError = dataItem.lowError;                that.highError = dataItem.highError;                that._updateData(dataItem);                !that.hasValue() && that.setInvisibility();                that._fillStyle();                that._updateLabelData()            },            deleteMarker: function() {                var that = this;                if (that.graphic)                    that.graphic.dispose();                that.graphic = null            },            _drawErrorBar: _noop,            draw: function(renderer, groups, animationEnabled, firstDrawing) {                var that = this;                if (that._needDeletingOnDraw) {                    that.deleteMarker();                    that._needDeletingOnDraw = false                }                if (that._needClearingOnDraw) {                    that.clearMarker();                    that._needClearingOnDraw = false                }                if (!that._hasGraphic())                    that._getMarkerVisibility() && that._drawMarker(renderer, groups.markers, animationEnabled, firstDrawing);                else                    that._updateMarker(animationEnabled, undefined, groups.markers);                that._drawLabel(renderer, groups.labels);                that._drawErrorBar(renderer, groups.errorBars, animationEnabled)            },            applyStyle: function(style) {                var that = this;                if (that.graphic) {                    if (style === "normal") {                        if (that.isHovered()) {                            that.applyStyle("hover");                            return                        }                        that.clearMarker()                    }                    else                        that.graphic.toForeground();                    that._currentStyle = that._styles[style];                    that._updateMarker(true, that._currentStyle)                }            },            setHoverState: function() {                this.series.setPointHoverState(this)            },            releaseHoverState: function(callback) {                var that = this;                that.series.releasePointHoverState(that, callback);                if (that.graphic)                    !that.isSelected() && that.graphic.toBackground()            },            setSelectedState: function() {                this.series.setPointSelectedState(this)            },            releaseSelectedState: function() {                this.series.releasePointSelectedState(this)            },            select: function() {                this.series.selectPoint(this)            },            clearSelection: function() {                this.series.deselectPoint(this)            },            showTooltip: function() {                this.series.showPointTooltip(this)            },            hideTooltip: function() {                this.series.hidePointTooltip(this)            },            _checkLabelsChanging: function(oldType, newType) {                if (oldType) {                    var isNewRange = ~newType.indexOf("range"),                        isOldRange = ~oldType.indexOf("range");                    return isOldRange && !isNewRange || !isOldRange && isNewRange                }                else                    return false            },            updateOptions: function(newOptions) {                if (!_isDefined(newOptions))                    return;                var that = this,                    oldOptions = that._options,                    widgetType = newOptions.widgetType,                    oldType = oldOptions && oldOptions.type,                    newType = newOptions.type;                if (seiresMixins[widgetType].pointTypes[oldType] !== seiresMixins[widgetType].pointTypes[newType]) {                    that._needDeletingOnDraw = true;                    that._needClearingOnDraw = false;                    that._checkLabelsChanging(oldType, newType) && that.deleteLabel();                    that._resetType(oldType, widgetType);                    that._setType(newType, widgetType)                }                else {                    that._needDeletingOnDraw = that._checkSymbol(oldOptions, newOptions);                    that._needClearingOnDraw = that._checkCustomize(oldOptions, newOptions)                }                that._options = newOptions;                that._fillStyle();                that._updateLabelOptions(seiresMixins[widgetType].pointTypes[newType])            },            translate: function(translators) {                var that = this;                that.translators = translators || that.translators;                that.translators && that.hasValue() && that._translate(that.translators)            },            _checkCustomize: function(oldOptions, newOptions) {                return oldOptions.styles.usePointCustomOptions && !newOptions.styles.usePointCustomOptions            },            _getCustomLabelVisibility: function() {                return this._styles.useLabelCustomOptions ? !!this._options.label.visible : null            },            getBoundingRect: function() {                return this._getGraphicBbox()            },            _resetType: function(type, widgetType) {                var that = this;                if (type)                    _each(seriesNS.points.mixins[seiresMixins[widgetType].pointTypes[type]], function(methodName) {                        delete that[methodName]                    })            },            _setType: function(type, widgetType) {                var that = this;                _each(seriesNS.points.mixins[seiresMixins[widgetType].pointTypes[type]], function(methodName, method) {                    that[methodName] = method                })            },            isInVisibleArea: function() {                return this.inVisibleArea            },            isSelected: function() {                return !!(this.fullState & statesConsts.selectedMark)            },            isHovered: function() {                return !!(this.fullState & statesConsts.hoverMark)            },            getOptions: function() {                return this._options            },            animate: function(complete, settings, partitionDuration) {                if (!this.graphic) {                    complete && complete();                    return                }                this.graphic.animate(settings, {partitionDuration: partitionDuration}, complete)            },            getCoords: function(min) {                var that = this;                if (!min)                    return {                            x: that.x,                            y: that.y                        };                if (!that._options.rotated)                    return {                            x: that.x,                            y: that.minY                        };                return {                        x: that.minX,                        y: that.y                    }            },            getDefaultCoords: function() {                var that = this;                return !that._options.rotated ? {                        x: that.x,                        y: that.defaultY                    } : {                        x: that.defaultX,                        y: that.y                    }            },            _calculateVisibility: function(x, y, width, height) {                var that = this,                    visibleAreaX,                    visibleAreaY,                    rotated = that._options.rotated;                if (that.translators) {                    visibleAreaX = that.translators.x.getCanvasVisibleArea();                    visibleAreaY = that.translators.y.getCanvasVisibleArea();                    if (visibleAreaX.min > x + (width || 0) || visibleAreaX.max < x || visibleAreaY.min > y + (height || 0) || visibleAreaY.max < y || rotated && _isDefined(width) && width !== 0 && (visibleAreaX.min === x + width || visibleAreaX.max === x) || !rotated && _isDefined(height) && height !== 0 && (visibleAreaY.min === y + height || visibleAreaY.max === y))                        that.inVisibleArea = false;                    else                        that.inVisibleArea = true                }            },            correctPosition: _noop,            hasValue: function() {                return this.value !== null && this.minValue !== null            },            getBoundaryCoords: function() {                return this.getBoundingRect()            },            getCrosshairCoords: _noop,            getPointRadius: _noop,            _populatePointShape: _noop,            _checkSymbol: _noop,            getMarkerCoords: _noop,            hide: _noop,            show: _noop,            hideMarker: _noop,            setInvisibility: _noop,            clearVisibility: _noop,            isVisible: _noop,            resetCorrection: _noop,            correctValue: _noop,            setPercentValue: _noop,            correctCoordinates: _noop,            coordsIn: _noop,            getTooltipParams: _noop,            setLabelEllipsis: _noop,            updateLabelCoord: _noop,            drawLabel: _noop,            dispose: function() {                var that = this;                that.deleteMarker();                that.deleteLabel();                that._errorBar && this._errorBar.dispose();                that._options = that._styles = that.series = that.translators = that._errorBar = null            },            getTooltipFormatObject: function(tooltip) {                var that = this,                    tooltipFormatObject = that._getFormatObject(tooltip),                    sharedTooltipValuesArray = [],                    tooltipStackPointsFormatObject = [];                if (that.stackPoints) {                    _each(that.stackPoints, function(_, point) {                        if (!point.isVisible())                            return;                        var formatObject = point._getFormatObject(tooltip);                        tooltipStackPointsFormatObject.push(formatObject);                        sharedTooltipValuesArray.push(formatObject.seriesName + ": " + formatObject.valueText)                    });                    _extend(tooltipFormatObject, {                        points: tooltipStackPointsFormatObject,                        valueText: sharedTooltipValuesArray.join("\n"),                        stackName: that.stackPoints.stackName                    })                }                return tooltipFormatObject            },            setHole: function(holeValue, position) {                var that = this,                    minValue = isFinite(that.minValue) ? that.minValue : 0;                if (_isDefined(holeValue))                    if (position === "left") {                        that.leftHole = that.value - holeValue;                        that.minLeftHole = minValue - holeValue                    }                    else {                        that.rightHole = that.value - holeValue;                        that.minRightHole = minValue - holeValue                    }            },            resetHoles: function() {                this.leftHole = null;                this.minLeftHole = null;                this.rightHole = null;                this.minRightHole = null            },            getLabel: function() {                return this._label            }        }    })(jQuery, DevExpress);    /*! Module viz-core, file label.js */    (function(DX, $, undefined) {        var _degreesToRadians = DX.utils.degreesToRadians,            _patchFontOptions = DX.viz.core.utils.patchFontOptions,            _round = Math.round,            _abs = Math.abs,            _min = Math.min,            _max = Math.max,            _ceil = Math.ceil,            _getCosAndSin = DX.utils.getCosAndSin,            _rotateBBox = DX.viz.renderers.rotateBBox,            LABEL_BACKGROUND_PADDING_X = 8,            LABEL_BACKGROUND_PADDING_Y = 4;        function getClosestCoord(point, coords) {            var closestDistase = Infinity,                closestCoord;            $.each(coords, function(_, coord) {                var x = point[0] - coord[0],                    y = point[1] - coord[1],                    distance = x * x + y * y;                if (distance < closestDistase) {                    closestDistase = distance;                    closestCoord = coord                }            });            return closestCoord        }        var barPointStrategy = {                isLabelInside: function(labelPoint, figure) {                    return labelPoint.x >= figure.x && labelPoint.x <= figure.x + figure.width && labelPoint.y >= figure.y && labelPoint.y <= figure.y + figure.height                },                prepareLabelPoints: function(points, center, angle, hasBackground) {                    return !hasBackground ? points : [center]                },                getFigureCenter: function(figure) {                    return [figure.x + figure.width / 2, figure.y + figure.height / 2]                },                findFigurePoint: function(figure, labelPoint) {                    var figureCenter = barPointStrategy.getFigureCenter(figure),                        point = getClosestCoord(labelPoint, [[figure.x, figureCenter[1]], [figureCenter[0], figure.y + figure.height], [figure.x + figure.width, figureCenter[1]], [figureCenter[0], figure.y]]);                    return [_round(point[0]), _round(point[1])]                }            };        var symbolPointStrategy = {                isLabelInside: function() {                    return false                },                prepareLabelPoints: barPointStrategy.prepareLabelPoints,                getFigureCenter: function(figure) {                    return [figure.x, figure.y]                },                findFigurePoint: function(figure, labelPoint) {                    var angle = Math.atan2(figure.y - labelPoint[1], labelPoint[0] - figure.x);                    return [_round(figure.x + figure.r * Math.cos(angle)), _round(figure.y - figure.r * Math.sin(angle))]                }            };        var piePointStrategy = {                isLabelInside: function(_0, _1, isOutside) {                    return !isOutside                },                prepareLabelPoints: function(points, center, angle) {                    var rotatedPoints = [],                        x0 = center[0],                        y0 = center[1],                        cossin = _getCosAndSin(angle || 0);                    $.each(points, function(_, point) {                        rotatedPoints.push([_round((point[0] - x0) * cossin.cos + (point[1] - y0) * cossin.sin + x0), _round(-(point[0] - x0) * cossin.sin + (point[1] - y0) * cossin.cos + y0)])                    });                    return rotatedPoints                },                getFigureCenter: symbolPointStrategy.getFigureCenter,                findFigurePoint: function(figure, labelPoint) {                    var x = figure.x + (figure.y - labelPoint[1]) / Math.tan(_degreesToRadians(figure.angle)),                        point = [figure.x, figure.y];                    if (figure.x <= x && x <= labelPoint[0] || figure.x >= x && x >= labelPoint[0])                        point.push(_round(x), labelPoint[1]);                    return point                }            };        function selectStrategy(figure) {            return figure.angle !== undefined && piePointStrategy || figure.r !== undefined && symbolPointStrategy || barPointStrategy        }        function disposeItem(obj, field) {            obj[field] && obj[field].dispose();            obj[field] = null        }        function checkBackground(background) {            return background && (background.fill && background.fill !== "none" || background["stroke-width"] > 0 && background.stroke && background.stroke !== "none")        }        function checkConnector(connector) {            return connector && connector["stroke-width"] > 0 && connector.stroke && connector.stroke !== "none"        }        function formatValue(value, format, precision) {            return DX.formatHelper.format(value, format, precision)        }        function formatText(data, options) {            var format = options.format,                precision = options.precision;            data.valueText = formatValue(data.value, format, precision);            data.argumentText = formatValue(data.argument, options.argumentFormat, options.argumentPrecision);            if (data.percent !== undefined)                data.percentText = formatValue(data.percent, "percent", options.percentPrecision);            if (data.total !== undefined)                data.totalText = formatValue(data.total, format, precision);            if (data.openValue !== undefined)                data.openValueText = formatValue(data.openValue, format, precision);            if (data.closeValue !== undefined)                data.closeValueText = formatValue(data.closeValue, format, precision);            if (data.lowValue !== undefined)                data.lowValueText = formatValue(data.lowValue, format, precision);            if (data.highValue !== undefined)                data.highValueText = formatValue(data.highValue, format, precision);            if (data.reductionValue !== undefined)                data.reductionValueText = formatValue(data.reductionValue, format, precision);            return options.customizeText ? options.customizeText.call(data, data) : data.valueText        }        function Label(){}        Label.prototype = {            constructor: Label,            _setVisibility: function(value, state) {                this._group && this._group.attr({visibility: value});                this._visible = state            },            clearVisibility: function() {                this._setVisibility(null, true)            },            hide: function() {                this._setVisibility("hidden", false)            },            show: function() {                this._setVisibility("visible", true)            },            isVisible: function() {                return this._visible            },            setColor: function(color) {                this._color = color            },            setOptions: function(options) {                this._options = options            },            setData: function(data) {                this._data = data            },            setDataField: function(fieldName, fieldValue) {                this._data = this._data || {};                this._data[fieldName] = fieldValue            },            getData: function() {                return this._data            },            setFigureToDrawConnector: function(figure) {                this._figure = figure            },            dispose: function() {                var that = this;                disposeItem(that, "_group");                that._data = that._options = that._textContent = that._visible = that._insideGroup = that._text = that._background = that._connector = that._figure = null            },            draw: function(renderer, container, customVisibility) {                var that = this,                    options = that._options || {},                    text = that._textContent = formatText(that._data, that._options) || null;                that.clearVisibility();                if (text) {                    if (!that._group) {                        that._group = renderer.g().append(container);                        that._insideGroup = renderer.g().append(that._group);                        that._text = renderer.text("", 0, 0).append(that._insideGroup)                    }                    that._text.css(options.attributes ? _patchFontOptions(options.attributes.font) : {});                    if (checkBackground(options.background)) {                        that._background = that._background || renderer.rect().append(that._insideGroup).toBackground();                        that._background.attr(options.background);                        that._color && that._background.attr({fill: that._color})                    }                    else                        disposeItem(that, "_background");                    if (checkConnector(options.connector)) {                        that._connector = that._connector || renderer.path([], "line").sharp().append(that._group).toBackground();                        that._connector.attr(options.connector);                        that._color && that._connector.attr({stroke: that._color})                    }                    else                        disposeItem(that, "_connector");                    that._updateText(text);                    if (customVisibility !== null)                        customVisibility ? that.show() : that.hide()                }                else                    that.hide();                return that            },            _updateText: function(text) {                var that = this,                    bbox = that._text.attr({text: text}).getBBox();                that._textSize = [bbox.width, bbox.height];                if (that._background) {                    bbox.x -= LABEL_BACKGROUND_PADDING_X;                    bbox.y -= LABEL_BACKGROUND_PADDING_Y;                    bbox.width += 2 * LABEL_BACKGROUND_PADDING_X;                    bbox.height += 2 * LABEL_BACKGROUND_PADDING_Y;                    that._background.attr(bbox)                }                that._labelSize = [bbox.width / 2, bbox.height / 2];                if (that._options.rotationAngle) {                    that._insideGroup.rotate(that._options.rotationAngle, bbox.x + bbox.width / 2, bbox.y + bbox.height / 2);                    bbox = _rotateBBox(bbox, [bbox.x + bbox.width / 2, bbox.y + bbox.height / 2], -that._options.rotationAngle)                }                that._bbox = bbox            },            _getConnectorPoints: function() {                var that = this,                    figure = that._figure,                    strategy = selectStrategy(figure),                    bbox = that.getBoundingRect(),                    labelPoint,                    figurePoint,                    xc,                    yc,                    points = [];                if (!strategy.isLabelInside(bbox, figure, that._options.position !== "inside")) {                    xc = bbox.x + bbox.width / 2;                    yc = bbox.y + bbox.height / 2;                    points = strategy.prepareLabelPoints([[xc, yc - that._labelSize[1]], [xc + that._labelSize[0], yc], [xc, yc + that._labelSize[1]], [xc - that._labelSize[0], yc]], [xc, yc], -that._options.rotationAngle || 0, !!that._background);                    labelPoint = getClosestCoord(strategy.getFigureCenter(figure), points);                    labelPoint = [_round(labelPoint[0]), _round(labelPoint[1])];                    figurePoint = strategy.findFigurePoint(figure, labelPoint);                    points = figurePoint.concat(labelPoint)                }                return points            },            fit: function(size) {                var that = this;                if (!that._textContent)                    return that;                var cossin = _getCosAndSin(-that._options.rotationAngle || 0),                    textSize = _min(_abs(that._textSize[0] / cossin.cos), _abs(that._textSize[1] / cossin.sin)),                    requiredTextSize = _min(_abs(size.width / cossin.cos), _abs(size.height / cossin.sin)),                    text = that._textContent,                    i,                    ii,                    line,                    lines,                    lineLength,                    requiredLineLength;                if (textSize > requiredTextSize) {                    lines = text.split("<br/>");                    for (i = 0, ii = lines.length, lineLength = 0; i < ii; ++i) {                        line = lines[i] = lines[i].replace(/<[^>]+>/g, '');                        lineLength = _max(lineLength, line.length)                    }                    requiredLineLength = _ceil(lineLength * requiredTextSize / textSize);                    for (i = 0; i < ii; ++i)                        lines[i] = (line = lines[i]).length > requiredLineLength ? line.substr(0, requiredLineLength - 4) + "..." : line;                    text = lines.join("<br/>")                }                that._updateText(text);                return that            },            shift: function(x, y) {                var that = this;                if (that._textContent) {                    that._insideGroup.attr({                        translateX: that._x = _round(x - that._bbox.x),                        translateY: that._y = _round(y - that._bbox.y)                    });                    if (that._connector)                        that._connector.attr({points: that._getConnectorPoints()})                }                return that            },            getBoundingRect: function() {                var bbox = this._bbox;                return this._textContent ? {                        x: bbox.x + this._x,                        y: bbox.y + this._y,                        width: bbox.width,                        height: bbox.height                    } : {}            },            getLayoutOptions: function() {                var options = this._options;                return {                        alignment: options.alignment,                        background: checkBackground(options.background),                        horizontalOffset: options.horizontalOffset,                        verticalOffset: options.verticalOffset,                        radialOffset: options.radialOffset,                        position: options.position                    }            }        };        DX.viz.core.series.points.Label = Label;        Label._DEBUG_formatText = formatText    })(DevExpress, jQuery);    /*! Module viz-core, file symbolPoint.js */    (function($, DX) {        var core = DX.viz.core,            seriesNS = core.series,            _extend = $.extend,            _isDefined = DX.utils.isDefined,            _math = Math,            _round = _math.round,            _floor = _math.floor,            _ceil = _math.ceil,            _abs = _math.abs,            DEFAULT_IMAGE_WIDTH = 20,            DEFAULT_IMAGE_HEIGHT = 20,            LABEL_OFFSET = 10,            CANVAS_POSITION_DEFAULT = "canvas_position_default";        function getSquareMarkerCoords(radius) {            return [-radius, -radius, radius, -radius, radius, radius, -radius, radius, -radius, -radius]        }        function getPolygonMarkerCoords(radius) {            var r = _ceil(radius);            return [-r, 0, 0, -r, r, 0, 0, r, -r, 0]        }        function getCrossMarkerCoords(radius) {            var r = _ceil(radius),                floorHalfRadius = _floor(r / 2),                ceilHalfRadius = _ceil(r / 2);            return [-r, -floorHalfRadius, -floorHalfRadius, -r, 0, -ceilHalfRadius, floorHalfRadius, -r, r, -floorHalfRadius, ceilHalfRadius, 0, r, floorHalfRadius, floorHalfRadius, r, 0, ceilHalfRadius, -floorHalfRadius, r, -r, floorHalfRadius, -ceilHalfRadius, 0]        }        function getTriangleDownMarkerCoords(radius) {            return [-radius, -radius, radius, -radius, 0, radius, -radius, -radius]        }        function getTriangleUpMarkerCoords(radius) {            return [-radius, radius, radius, radius, 0, -radius, -radius, radius]        }        seriesNS.points.mixins = seriesNS.points.mixins || {};        seriesNS.points.mixins.symbolPoint = {            deleteLabel: function() {                this._label.dispose();                this._label = null            },            _hasGraphic: function() {                return this.graphic            },            clearVisibility: function() {                var that = this,                    graphic = that.graphic;                if (graphic && graphic.attr("visibility"))                    graphic.attr({visibility: null});                that._label.clearVisibility()            },            isVisible: function() {                return this.inVisibleArea && this.series.isVisible()            },            setInvisibility: function() {                var that = this,                    graphic = that.graphic;                if (graphic && graphic.attr("visibility") !== "hidden")                    graphic.attr({visibility: "hidden"});                that._errorBar && that._errorBar.attr({visibility: "hidden"});                that._label.hide()            },            clearMarker: function() {                var graphic = this.graphic;                graphic && graphic.attr(this._emptySettings)            },            setAdjustSeriesLabels: function(adjustSeriesLabels) {                this.adjustSeriesLabels = adjustSeriesLabels            },            _createLabel: function() {                this._label = core.CoreFactory.createLabel()            },            _updateLabelData: function() {                this._label.setData(this._getLabelFormatObject())            },            _updateLabelOptions: function() {                !this._label && this._createLabel();                this._label.setOptions(this._options.label)            },            _checkImage: function(image) {                return _isDefined(image) && (typeof image === "string" || _isDefined(image.url))            },            _fillStyle: function() {                this._styles = this._options.styles            },            _checkSymbol: function(oldOptions, newOptions) {                var oldSymbol = oldOptions.symbol,                    newSymbol = newOptions.symbol,                    symbolChanged = oldSymbol === "circle" && newSymbol !== "circle" || oldSymbol !== "circle" && newSymbol === "circle",                    imageChanged = this._checkImage(oldOptions.image) !== this._checkImage(newOptions.image);                return !!(symbolChanged || imageChanged)            },            _populatePointShape: function(symbol, radius) {                switch (symbol) {                    case"square":                        return getSquareMarkerCoords(radius);                    case"polygon":                        return getPolygonMarkerCoords(radius);                    case"triangle":                    case"triangleDown":                        return getTriangleDownMarkerCoords(radius);                    case"triangleUp":                        return getTriangleUpMarkerCoords(radius);                    case"cross":                        return getCrossMarkerCoords(radius)                }            },            correctValue: function(correction) {                var that = this;                if (that.hasValue()) {                    that.value = that.initialValue + correction;                    that.minValue = correction;                    that.translate()                }            },            resetCorrection: function() {                this.value = this.initialValue;                this.minValue = CANVAS_POSITION_DEFAULT            },            _getTranslates: function(animationEnabled) {                var translateX = this.x,                    translateY = this.y;                if (animationEnabled)                    if (this._options.rotated)                        translateX = this.defaultX;                    else                        translateY = this.defaultY;                return {                        x: translateX,                        y: translateY                    }            },            _createImageMarker: function(renderer, settings, options) {                var width = options.width || DEFAULT_IMAGE_WIDTH,                    height = options.height || DEFAULT_IMAGE_HEIGHT;                return renderer.image(-_round(width * 0.5), -_round(height * 0.5), width, height, options.url ? options.url.toString() : options.toString(), "center").attr({                        translateX: settings.translateX,                        translateY: settings.translateY,                        visibility: settings.visibility                    })            },            _createSymbolMarker: function(renderer, pointSettings) {                var marker,                    options = this._options;                switch (options.symbol) {                    case"circle":                        delete pointSettings.points;                        marker = renderer.circle().attr(pointSettings);                        break;                    case"square":                    case"polygon":                    case"triangle":                    case"triangleDown":                    case"triangleUp":                    case"cross":                        marker = renderer.path([], "area").attr(pointSettings).sharp();                        break                }                return marker            },            _createMarker: function(renderer, group, image, settings, animationEnabled) {                var that = this,                    marker = that._checkImage(image) ? that._createImageMarker(renderer, settings, image) : that._createSymbolMarker(renderer, settings, animationEnabled);                if (marker)                    marker.data({point: that}).append(group);                return marker            },            _getSymbolBbox: function(x, y, r) {                return {                        x: x - r,                        y: y - r,                        width: r * 2,                        height: r * 2                    }            },            _getImageBbox: function(x, y) {                var image = this._options.image,                    width = image.width || DEFAULT_IMAGE_WIDTH,                    height = image.height || DEFAULT_IMAGE_HEIGHT;                return {                        x: x - _round(width / 2),                        y: y - _round(height / 2),                        width: width,                        height: height                    }            },            _getGraphicBbox: function() {                var that = this,                    options = that._options,                    x = that.x,                    y = that.y,                    bbox;                if (options.visible)                    bbox = that._checkImage(options.image) ? that._getImageBbox(x, y) : that._getSymbolBbox(x, y, options.styles.normal.r);                else                    bbox = {                        x: x,                        y: y,                        width: 0,                        height: 0                    };                return bbox            },            _getVisibleArea: function() {                var translators = this.translators,                    visibleX,                    visibleY;                if (translators) {                    visibleX = translators.x.getCanvasVisibleArea();                    visibleY = translators.y.getCanvasVisibleArea();                    return {                            minX: visibleX.min,                            maxX: visibleX.max,                            minY: visibleY.min,                            maxY: visibleY.max                        }                }            },            _isLabelInsidePoint: $.noop,            _getShiftLabelCoords: function(label) {                var coord = this._addLabelAlignmentAndOffset(label, this._getLabelCoords(label));                return this._checkLabelPosition(label, coord)            },            _drawLabel: function(renderer, group) {                var that = this,                    customVisibility = that._getCustomLabelVisibility(),                    coord,                    label = that._label;                if ((that.series.getLabelVisibility() || customVisibility !== null) && that.hasValue() && that._showForZeroValues()) {                    label.draw(renderer, group, customVisibility);                    if (!that._isLabelInsidePoint(label)) {                        coord = that._getShiftLabelCoords(label);                        label.setFigureToDrawConnector(that._getLabelConnector());                        label.shift(_round(coord.x), _round(coord.y))                    }                }                else                    label.hide()            },            _showForZeroValues: function() {                return true            },            _getLabelConnector: function() {                var bbox = this._getGraphicBbox(),                    w2 = bbox.width / 2,                    h2 = bbox.height / 2;                return {                        x: bbox.x + w2,                        y: bbox.y + h2,                        r: this._options.visible ? Math.max(w2, h2) : 0                    }            },            _getPositionFromLocation: function() {                return {                        x: this.x,                        y: this.y                    }            },            _isPointInVisibleArea: function(visibleArea, graphicBbox) {                return visibleArea.minX <= graphicBbox.x + graphicBbox.width && visibleArea.maxX >= graphicBbox.x && visibleArea.minY <= graphicBbox.y + graphicBbox.height && visibleArea.maxY >= graphicBbox.y            },            _checkLabelPosition: function(label, coord, pointPosition) {                var that = this,                    visibleArea = that._getVisibleArea(),                    labelBbox = label.getBoundingRect(),                    graphicBbox = that._getGraphicBbox(pointPosition),                    offset = LABEL_OFFSET;                if (that._isPointInVisibleArea(visibleArea, graphicBbox))                    if (!that._options.rotated) {                        if (visibleArea.minX > coord.x && that.adjustSeriesLabels)                            coord.x = visibleArea.minX;                        if (visibleArea.maxX < coord.x + labelBbox.width && that.adjustSeriesLabels)                            coord.x = visibleArea.maxX - labelBbox.width;                        if (visibleArea.minY > coord.y)                            coord.y = graphicBbox.y + graphicBbox.height + offset;                        if (visibleArea.maxY < coord.y + labelBbox.height)                            coord.y = graphicBbox.y - labelBbox.height - offset                    }                    else {                        if (visibleArea.minX > coord.x)                            coord.x = graphicBbox.x + graphicBbox.width + offset;                        if (visibleArea.maxX < coord.x + labelBbox.width)                            coord.x = graphicBbox.x - offset - labelBbox.width;                        if (visibleArea.minY > coord.y && that.adjustSeriesLabels)                            coord.y = visibleArea.minY;                        if (visibleArea.maxY < coord.y + labelBbox.height && that.adjustSeriesLabels)                            coord.y = visibleArea.maxY - labelBbox.height                    }                return coord            },            _addLabelAlignmentAndOffset: function(label, coord) {                var labelBBox = label.getBoundingRect(),                    labelOptions = label.getLayoutOptions();                if (!this._options.rotated)                    if (labelOptions.alignment === "left")                        coord.x += labelBBox.width / 2;                    else if (labelOptions.alignment === "right")                        coord.x -= labelBBox.width / 2;                coord.x += labelOptions.horizontalOffset;                coord.y += labelOptions.verticalOffset;                return coord            },            _getLabelCoords: function(label, pointPosition) {                return this._getLabelCoordOfPosition(label, this._getLabelPosition(pointPosition), pointPosition)            },            _getLabelCoordOfPosition: function(label, position, pointPosition) {                var that = this,                    labelBBox = label.getBoundingRect(),                    graphicBbox = that._getGraphicBbox(pointPosition),                    offset = LABEL_OFFSET,                    centerY = graphicBbox.height / 2 - labelBBox.height / 2,                    centerX = graphicBbox.width / 2 - labelBBox.width / 2,                    x = graphicBbox.x,                    y = graphicBbox.y;                switch (position) {                    case"left":                        x -= labelBBox.width + offset;                        y += centerY;                        break;                    case"right":                        x += graphicBbox.width + offset;                        y += centerY;                        break;                    case"top":                        x += centerX;                        y -= labelBBox.height + offset;                        break;                    case"bottom":                        x += centerX;                        y += graphicBbox.height + offset;                        break;                    case"inside":                        x += centerX;                        y += centerY;                        break                }                return {                        x: x,                        y: y                    }            },            _drawMarker: function(renderer, group, animationEnabled) {                var that = this,                    options = that._options,                    translates = that._getTranslates(animationEnabled),                    style = that._getStyle();                that.graphic = that._createMarker(renderer, group, options.image, _extend({                    translateX: translates.x,                    translateY: translates.y,                    points: that._populatePointShape(options.symbol, style.r)                }, style), animationEnabled)            },            _getErrorBarSettings: function() {                return {visibility: "visible"}            },            _drawErrorBar: function(renderer, group) {                var that = this,                    errorBarOptions = that._options.errorBars || {},                    points = [],                    settings,                    pos = that._errorBarPos,                    high = that._highErrorCoord,                    low = that._lowErrorCoord,                    displayMode = (errorBarOptions.displayMode + "").toLowerCase(),                    isHighDisplayMode = displayMode === "high",                    isLowDisplayMode = displayMode === "low",                    edgeLength = _floor(parseInt(errorBarOptions.edgeLength) / 2),                    highErrorOnly = (isHighDisplayMode || !_isDefined(low)) && _isDefined(high) && !isLowDisplayMode,                    lowErrorOnly = (isLowDisplayMode || !_isDefined(high)) && _isDefined(low) && !isHighDisplayMode;                highErrorOnly && (low = that._baseErrorBarPos);                lowErrorOnly && (high = that._baseErrorBarPos);                if (displayMode !== "none" && _isDefined(high) && _isDefined(low) && _isDefined(pos)) {                    !lowErrorOnly && points.push([pos - edgeLength, high, pos + edgeLength, high]);                    points.push([pos, high, pos, low]);                    !highErrorOnly && points.push([pos + edgeLength, low, pos - edgeLength, low]);                    that._options.rotated && $.each(points, function(_, p) {                        p.reverse()                    });                    settings = that._getErrorBarSettings(errorBarOptions);                    if (!that._errorBar)                        that._errorBar = renderer.path(points, "line").attr(settings).append(group);                    else {                        settings.points = points;                        that._errorBar.attr(settings)                    }                }                else                    that._errorBar && that._errorBar.attr({visibility: "hidden"})            },            getTooltipParams: function() {                var that = this,                    graphic = that.graphic;                return {                        x: that.x,                        y: that.y,                        offset: graphic ? graphic.getBBox().height / 2 : 0                    }            },            hasValue: function() {                return this.value !== null && this.minValue !== null            },            setPercentValue: function(total, fullStacked, leftHoleTotal, rightHoleTotal) {                var that = this,                    valuePercent = _abs(that.value / total || 0),                    minValuePercent = _abs(that.minValue / total || 0),                    percent = valuePercent - minValuePercent;                that._label.setDataField("percent", percent);                that._label.setDataField("total", total);                if (that.series.isFullStackedSeries() && that.hasValue()) {                    if (that.leftHole) {                        that.leftHole /= total - leftHoleTotal;                        that.minLeftHole /= total - leftHoleTotal                    }                    if (that.rightHole) {                        that.rightHole /= total - rightHoleTotal;                        that.minRightHole /= total - rightHoleTotal                    }                    that.value = valuePercent;                    that.minValue = !minValuePercent ? that.minValue : minValuePercent;                    that.translate()                }            },            _storeTrackerR: function() {                var that = this,                    navigator = window.navigator,                    r = that._options.styles.normal.r,                    minTrackerSize;                navigator = that.__debug_navigator || navigator;                that.__debug_browserNavigator = navigator;                minTrackerSize = "ontouchstart" in window || navigator.msPointerEnabled && navigator.msMaxTouchPoints || navigator.pointerEnabled && navigator.maxTouchPoints ? 20 : 6;                that._options.trackerR = r < minTrackerSize ? minTrackerSize : r;                return that._options.trackerR            },            _translateErrorBars: function(valueTranslator) {                var that = this,                    options = that._options,                    errorBars = options.errorBars || {};                _isDefined(that.lowError) && (that._lowErrorCoord = valueTranslator.translate(that.lowError));                _isDefined(that.highError) && (that._highErrorCoord = valueTranslator.translate(that.highError));                that._errorBarPos = _floor(that._options.rotated ? that.vy : that.vx);                that._baseErrorBarPos = errorBars.type === "stdDeviation" ? that._lowErrorCoord + (that._highErrorCoord - that._lowErrorCoord) / 2 : that._options.rotated ? that.vx : that.vy            },            _translate: function(translators) {                var that = this,                    valueAxis = that._options.rotated ? "x" : "y",                    upperValueAxis = valueAxis.toUpperCase(),                    valueTranslator = translators[valueAxis],                    argumentAxis = that._options.rotated ? "y" : "x";                that["v" + valueAxis] = that[valueAxis] = valueTranslator.translate(that.value);                that["v" + argumentAxis] = that[argumentAxis] = translators[argumentAxis].translate(that.argument);                that["min" + upperValueAxis] = valueTranslator.translate(that.minValue);                that["default" + upperValueAxis] = valueTranslator.translate(CANVAS_POSITION_DEFAULT);                that._translateErrorBars(valueTranslator);                that._calculateVisibility(that.x, that.y)            },            _updateData: function(data) {                var that = this;                that.value = that.initialValue = that.originalValue = data.value;                that.minValue = that.initialMinValue = that.originalMinValue = _isDefined(data.minValue) ? data.minValue : CANVAS_POSITION_DEFAULT            },            _getImageSettings: function(image) {                return {                        href: image.url || image.toString(),                        width: image.width || DEFAULT_IMAGE_WIDTH,                        height: image.height || DEFAULT_IMAGE_HEIGHT                    }            },            getCrosshairCoords: function() {                return {                        x: this.vx,                        y: this.vy                    }            },            getPointRadius: function() {                var style = this._currentStyle || this._getStyle(),                    options = this._options,                    r = style.r,                    extraSpace,                    symbol = options.symbol,                    isSquare = symbol === "square",                    isTriangle = symbol === "triangle" || symbol === "triangleDown" || symbol === "triangleUp";                if (options.visible && !options.image && r) {                    extraSpace = style["stroke-width"] / 2;                    return (isSquare || isTriangle ? 1.4 * r : r) + extraSpace                }                return 0            },            _updateMarker: function(animationEnabled, style) {                var that = this,                    options = that._options,                    settings,                    image = options.image,                    visibility = !that.isVisible() ? {visibility: "hidden"} : {};                style = style || that._getStyle();                if (that._checkImage(image))                    settings = _extend({}, {visibility: style.visibility}, visibility, that._getImageSettings(image));                else                    settings = _extend({}, style, visibility, {points: that._populatePointShape(options.symbol, style.r)});                if (!animationEnabled) {                    settings.translateX = that.x;                    settings.translateY = that.y                }                that.graphic.attr(settings).sharp()            },            _getLabelFormatObject: function() {                var that = this;                return {                        argument: that.initialArgument,                        value: that.initialValue,                        originalArgument: that.originalArgument,                        originalValue: that.originalValue,                        seriesName: that.series.name,                        lowErrorValue: that.lowError,                        highErrorValue: that.highError,                        point: that                    }            },            _getLabelPosition: function() {                var rotated = this._options.rotated;                if (this.series.isFullStackedSeries() || this.initialValue > 0)                    return rotated ? "right" : "top";                else                    return rotated ? "left" : "bottom"            },            _getFormatObject: function(tooltip) {                var that = this,                    labelFormatObject = that._label.getData();                return _extend({}, labelFormatObject, {                        argumentText: tooltip.formatValue(that.initialArgument, "argument"),                        valueText: tooltip.formatValue(that.initialValue)                    }, _isDefined(labelFormatObject.percent) ? {percentText: tooltip.formatValue(labelFormatObject.percent, "percent")} : {}, _isDefined(labelFormatObject.total) ? {totalText: tooltip.formatValue(labelFormatObject.total)} : {})            },            _getMarkerVisibility: function() {                return this._options.visible            },            coordsIn: function(x, y) {                var trackerRadius = this._storeTrackerR();                return x >= this.x - trackerRadius && x <= this.x + trackerRadius && y >= this.y - trackerRadius && y <= this.y + trackerRadius            }        }    })(jQuery, DevExpress);    /*! Module viz-core, file barPoint.js */    (function($, DX) {        var points = DX.viz.core.series.points.mixins,            _extend = $.extend,            _math = Math,            _floor = _math.floor,            _abs = _math.abs,            _min = _math.min,            CANVAS_POSITION_DEFAULT = "canvas_position_default",            DEFAULT_BAR_TRACKER_SIZE = 9,            CORRECTING_BAR_TRACKER_VALUE = 4,            RIGHT = "right",            LEFT = "left",            TOP = "top",            BOTTOM = "bottom";        points.barPoint = _extend({}, points.symbolPoint, {            correctCoordinates: function(correctOptions) {                var correction = _floor(correctOptions.offset - correctOptions.width / 2),                    rotated = this._options.rotated,                    valueSelector = rotated ? "height" : "width",                    correctionSelector = (rotated ? "y" : "x") + "Correction";                this[valueSelector] = correctOptions.width;                this[correctionSelector] = correction            },            _getGraphicBbox: function() {                var that = this,                    bbox = {};                bbox.x = that.x;                bbox.y = that.y;                bbox.width = that.width;                bbox.height = that.height;                return bbox            },            _getLabelConnector: function() {                return this._getGraphicBbox()            },            _getLabelPosition: function() {                var that = this,                    position,                    translators = that.translators,                    initialValue = that.initialValue,                    invertX = translators.x.getBusinessRange().invert,                    invertY = translators.y.getBusinessRange().invert,                    isDiscreteValue = that.series.valueAxisType === "discrete",                    isFullStacked = that.series.isFullStackedSeries(),                    notVerticalInverted = !isDiscreteValue && (initialValue >= 0 && !invertY || initialValue < 0 && invertY) || isDiscreteValue && !invertY || isFullStacked,                    notHorizontalInverted = !isDiscreteValue && (initialValue >= 0 && !invertX || initialValue < 0 && invertX) || isDiscreteValue && !invertX || isFullStacked;                if (!that._options.rotated)                    position = notVerticalInverted ? TOP : BOTTOM;                else                    position = notHorizontalInverted ? RIGHT : LEFT;                return position            },            _getLabelCoords: function(label) {                var that = this,                    coords;                if (that.initialValue === 0 && that.series.isFullStackedSeries())                    if (!this._options.rotated)                        coords = that._getLabelCoordOfPosition(label, TOP);                    else                        coords = that._getLabelCoordOfPosition(label, RIGHT);                else if (label.getLayoutOptions().position === "inside")                    coords = that._getLabelCoordOfPosition(label, "inside");                else                    coords = points.symbolPoint._getLabelCoords.call(this, label);                return coords            },            _checkLabelPosition: function(label, coord) {                var that = this,                    visibleArea = that._getVisibleArea(),                    rotated = that._options.rotated,                    graphicBbox = that._getGraphicBbox(),                    labelBbox = label.getBoundingRect();                if (that._isPointInVisibleArea(visibleArea, graphicBbox))                    return that._moveLabelOnCanvas(coord, visibleArea, labelBbox, that.adjustSeriesLabels || rotated, that.adjustSeriesLabels || !rotated);                return coord            },            _isLabelInsidePoint: function(label) {                var that = this,                    graphicBbox = that._getGraphicBbox(),                    labelBbox = label.getBoundingRect();                if (that._options.resolveLabelsOverlapping && label.getLayoutOptions().position === "inside")                    if (labelBbox.width > graphicBbox.width || labelBbox.height > graphicBbox.height) {                        label.hide();                        return true                    }                return false            },            _moveLabelOnCanvas: function(coord, visibleArea, labelBbox, horizontalAdjust, verticalAdjust) {                var x = coord.x,                    y = coord.y;                if (visibleArea.minX > x && horizontalAdjust)                    x = visibleArea.minX;                if (visibleArea.maxX < x + labelBbox.width && horizontalAdjust)                    x = visibleArea.maxX - labelBbox.width;                if (visibleArea.minY > y && verticalAdjust)                    y = visibleArea.minY;                if (visibleArea.maxY < y + labelBbox.height && verticalAdjust)                    y = visibleArea.maxY - labelBbox.height;                return {                        x: x,                        y: y                    }            },            _showForZeroValues: function() {                return this._options.label.showForZeroValues || this.initialValue            },            _drawMarker: function(renderer, group, animationEnabled) {                var that = this,                    style = that._getStyle(),                    x = that.x,                    y = that.y,                    width = that.width,                    height = that.height,                    r = that._options.cornerRadius;                if (animationEnabled)                    if (that._options.rotated) {                        width = 0;                        x = that.defaultX                    }                    else {                        height = 0;                        y = that.defaultY                    }                that.graphic = renderer.rect(x, y, width, height).attr({                    rx: r,                    ry: r                }).attr(style).data({point: that}).append(group)            },            _getSettingsForTracker: function() {                var that = this,                    y = that.y,                    height = that.height,                    x = that.x,                    width = that.width;                if (that._options.rotated) {                    if (width === 1) {                        width = DEFAULT_BAR_TRACKER_SIZE;                        x -= CORRECTING_BAR_TRACKER_VALUE                    }                }                else if (height === 1) {                    height = DEFAULT_BAR_TRACKER_SIZE;                    y -= CORRECTING_BAR_TRACKER_VALUE                }                return {                        x: x,                        y: y,                        width: width,                        height: height                    }            },            getGraphicSettings: function() {                var graphic = this.graphic;                return {                        x: graphic.attr("x"),                        y: graphic.attr("y"),                        height: graphic.attr("height"),                        width: graphic.attr("width")                    }            },            _getEdgeTooltipParams: function(x, y, width, height) {                var isPositive = this.value >= 0,                    invertedY = this.translators.y.getBusinessRange().invert,                    invertedX = this.translators.x.getBusinessRange().invert,                    xCoord,                    yCoord;                if (this._options.rotated) {                    yCoord = y + height / 2;                    if (invertedX)                        xCoord = isPositive ? x : x + width;                    else                        xCoord = isPositive ? x + width : x                }                else {                    xCoord = x + width / 2;                    if (invertedY)                        yCoord = isPositive ? y + height : y;                    else                        yCoord = isPositive ? y : y + height                }                return {                        x: xCoord,                        y: yCoord,                        offset: 0                    }            },            getTooltipParams: function(location) {                var x = this.x,                    y = this.y,                    width = this.width,                    height = this.height;                return location === 'edge' ? this._getEdgeTooltipParams(x, y, width, height) : {                        x: x + width / 2,                        y: y + height / 2,                        offset: 0                    }            },            _truncateCoord: function(coord, minBounce, maxBounce) {                if (coord < minBounce)                    return minBounce;                if (coord > maxBounce)                    return maxBounce;                return coord            },            _translateErrorBars: function(valueTranslator, argVisibleArea) {                points.symbolPoint._translateErrorBars.call(this, valueTranslator);                if (this._errorBarPos < argVisibleArea.min || this._errorBarPos > argVisibleArea.max)                    this._errorBarPos = undefined            },            _translate: function(translators) {                var that = this,                    rotated = that._options.rotated,                    valAxis = rotated ? "x" : "y",                    argAxis = rotated ? "y" : "x",                    valIntervalName = rotated ? "width" : "height",                    argIntervalName = rotated ? "height" : "width",                    argTranslator = translators[argAxis],                    valTranslator = translators[valAxis],                    argVisibleArea = argTranslator.getCanvasVisibleArea(),                    valVisibleArea = valTranslator.getCanvasVisibleArea(),                    arg,                    minArg,                    val,                    minVal;                arg = minArg = argTranslator.translate(that.argument) + (that[argAxis + "Correction"] || 0);                val = valTranslator.translate(that.value);                minVal = valTranslator.translate(that.minValue);                that["v" + valAxis] = val;                that["v" + argAxis] = arg + that[argIntervalName] / 2;                that[valIntervalName] = _abs(val - minVal);                that._calculateVisibility(rotated ? _min(val, minVal) : _min(arg, minArg), rotated ? _min(arg, minArg) : _min(val, minVal), that.width, that.height);                val = that._truncateCoord(val, valVisibleArea.min, valVisibleArea.max);                minVal = that._truncateCoord(minVal, valVisibleArea.min, valVisibleArea.max);                that[argAxis] = arg;                that["min" + argAxis.toUpperCase()] = minArg;                that[valIntervalName] = _abs(val - minVal);                that[valAxis] = _min(val, minVal) + (that[valAxis + "Correction"] || 0);                that["min" + valAxis.toUpperCase()] = minVal + (that[valAxis + "Correction"] || 0);                that["default" + valAxis.toUpperCase()] = valTranslator.translate(CANVAS_POSITION_DEFAULT);                that._translateErrorBars(valTranslator, argVisibleArea);                if (that.inVisibleArea) {                    if (that[argAxis] < argVisibleArea.min) {                        that[argIntervalName] = that[argIntervalName] - (argVisibleArea.min - that[argAxis]);                        that[argAxis] = argVisibleArea.min;                        that["min" + argAxis.toUpperCase()] = argVisibleArea.min                    }                    if (that[argAxis] + that[argIntervalName] > argVisibleArea.max)                        that[argIntervalName] = argVisibleArea.max - that[argAxis]                }            },            _updateMarker: function(animationEnabled, style) {                this.graphic.attr(_extend({}, style || this._getStyle(), !animationEnabled ? this.getMarkerCoords() : {}))            },            getMarkerCoords: function() {                return {                        x: this.x,                        y: this.y,                        width: this.width,                        height: this.height                    }            },            coordsIn: function(x, y) {                var that = this;                return x >= that.x && x <= that.x + that.width && y >= that.y && y <= that.y + that.height            }        })    })(jQuery, DevExpress);    /*! Module viz-core, file bubblePoint.js */    (function($, DX) {        var points = DX.viz.core.series.points.mixins,            _extend = $.extend,            MIN_BUBBLE_HEIGHT = 20;        points.bubblePoint = _extend({}, points.symbolPoint, {            correctCoordinates: function(diameter) {                this.bubbleSize = diameter / 2            },            _drawMarker: function(renderer, group, animationEnabled) {                var that = this,                    attr = _extend({                        translateX: that.x,                        translateY: that.y                    }, that._getStyle());                that.graphic = renderer.circle(0, 0, animationEnabled ? 0 : that.bubbleSize).attr(attr).data({point: that}).append(group)            },            getTooltipParams: function(location) {                var that = this,                    graphic = that.graphic,                    height;                if (!graphic)                    return;                height = graphic.getBBox().height;                return {                        x: that.x,                        y: height < MIN_BUBBLE_HEIGHT || location === 'edge' ? this.y - height / 2 : this.y,                        offset: 0                    }            },            _getLabelFormatObject: function() {                var formatObject = points.symbolPoint._getLabelFormatObject.call(this);                formatObject.size = this.initialSize;                return formatObject            },            _updateData: function(data) {                points.symbolPoint._updateData.call(this, data);                this.size = this.initialSize = data.size            },            _getGraphicBbox: function() {                var that = this;                return that._getSymbolBbox(that.x, that.y, that.bubbleSize)            },            _updateMarker: function(animationEnabled, style) {                var that = this;                style = style || that._getStyle();                if (!animationEnabled)                    style = $.extend({                        r: that.bubbleSize,                        translateX: that.x,                        translateY: that.y                    }, style);                that.graphic.attr(style)            },            _getFormatObject: function(tooltip) {                var formatObject = points.symbolPoint._getFormatObject.call(this, tooltip);                formatObject.sizeText = tooltip.formatValue(this.initialSize);                return formatObject            },            _storeTrackerR: function() {                return this.bubbleSize            },            _getLabelCoords: function(label) {                var coords;                if (label.getLayoutOptions().position === "inside")                    coords = this._getLabelCoordOfPosition(label, "inside");                else                    coords = points.symbolPoint._getLabelCoords.call(this, label);                return coords            }        })    })(jQuery, DevExpress);    /*! Module viz-core, file piePoint.js */    (function($, DX) {        var CONNECTOR_LENGTH = 20,            series = DX.viz.core.series,            points = series.points.mixins,            _extend = $.extend,            _round = Math.round,            _sqrt = Math.sqrt,            _acos = Math.acos,            DEG = 180 / Math.PI,            _abs = Math.abs,            _normalizeAngle = DX.utils.normalizeAngle,            _getCosAndSin = DX.utils.getCosAndSin,            _isDefined = DX.utils.isDefined,            INDENT_FROM_PIE = series.helpers.consts.pieLabelIndent;        function getVerticallyShiftedAngularCoords(bbox, dy, center) {            var isPositive = bbox.x + bbox.width / 2 >= center.x,                dx1 = (isPositive ? bbox.x : bbox.x + bbox.width) - center.x,                dy1 = bbox.y - center.y,                dy2 = dy1 + dy,                dx2 = _round(_sqrt(dx1 * dx1 + dy1 * dy1 - dy2 * dy2)),                dx = (isPositive ? +dx2 : -dx2) || dx1;            return {                    x: center.x + (isPositive ? dx : dx - bbox.width),                    y: bbox.y + dy                }        }        DX.viz.core.utils.getVerticallyShiftedAngularCoords = getVerticallyShiftedAngularCoords;        points.piePoint = _extend({}, points.symbolPoint, {            _updateData: function(data) {                var that = this;                points.symbolPoint._updateData.call(this, data);                that._visible = true;                that.minValue = that.initialMinValue = that.originalMinValue = _isDefined(data.minValue) ? data.minValue : 0            },            animate: function(complete, duration, step) {                var that = this;                that.graphic.animate({                    x: that.centerX,                    y: that.centerY,                    outerRadius: that.radiusOuter,                    innerRadius: that.radiusInner,                    startAngle: that.toAngle,                    endAngle: that.fromAngle                }, {                    partitionDuration: duration,                    step: step                }, complete)            },            correctPosition: function(correction) {                var that = this;                that.radiusInner = correction.radiusInner;                that.radiusOuter = correction.radiusOuter;                that.centerX = correction.centerX;                that.centerY = correction.centerY            },            correctValue: function(correction, percent, base) {                var that = this;                that.value = (base || that.initialValue) + correction;                that.minValue = correction;                that.percent = percent;                that._label.setDataField("percent", percent)            },            _updateLabelData: function() {                this._label.setData(this._getLabelFormatObject())            },            _updateLabelOptions: function() {                var that = this;                !that._label && that._createLabel();                that._label.setOptions(that._options.label)            },            _getShiftLabelCoords: function() {                var that = this,                    bbox = that._label.getBoundingRect(),                    coord = that._getLabelCoords(that._label),                    visibleArea = that._getVisibleArea();                if (that._isLabelDrawingWithoutPoints)                    return that._checkLabelPosition(coord, bbox, visibleArea);                else                    return that._getLabelExtraCoord(coord, that._checkVerticalLabelPosition(coord, bbox, visibleArea), bbox)            },            _getLabelPosition: function(options) {                return options.position            },            _getLabelCoords: function(label) {                var that = this,                    bbox = label.getBoundingRect(),                    options = label.getLayoutOptions(),                    angleFunctions = _getCosAndSin(that.middleAngle),                    position = that._getLabelPosition(options),                    radiusInner = that.radiusInner,                    radiusOuter = that.radiusOuter,                    rad,                    x;                if (position === 'inside') {                    rad = radiusInner + (radiusOuter - radiusInner) / 2 + options.radialOffset;                    x = that.centerX + rad * angleFunctions.cos - bbox.width / 2                }                else {                    rad = radiusOuter + options.radialOffset + INDENT_FROM_PIE;                    if (angleFunctions.cos > 0.1)                        x = that.centerX + rad * angleFunctions.cos;                    else if (angleFunctions.cos < -0.1)                        x = that.centerX + rad * angleFunctions.cos - bbox.width;                    else                        x = that.centerX + rad * angleFunctions.cos - bbox.width / 2                }                return {                        x: x,                        y: _round(that.centerY - rad * angleFunctions.sin - bbox.height / 2)                    }            },            _getColumnsCoord: function(coord) {                var that = this,                    label = that._label,                    bbox = label.getBoundingRect(),                    options = label.getLayoutOptions(),                    rad = that.radiusOuter + options.radialOffset,                    canvas = that.series.canvas,                    rightBorderX = canvas.width - canvas.right - bbox.width,                    leftBorderX = canvas.left,                    angleOfPoint = _normalizeAngle(that.middleAngle),                    x;                if (options.position !== 'columns')                    return coord;                rad += CONNECTOR_LENGTH;                if (angleOfPoint < 90 || angleOfPoint >= 270) {                    x = that._maxLabelLength ? that.centerX + rad + that._maxLabelLength - bbox.width : rightBorderX;                    x = x > rightBorderX ? rightBorderX : x                }                else {                    x = that._maxLabelLength ? that.centerX - rad - that._maxLabelLength : leftBorderX;                    x = x < leftBorderX ? leftBorderX : x                }                coord.x = x;                return coord            },            drawLabel: function(translators, renderer, group) {                this.translate(translators);                this._isLabelDrawingWithoutPoints = true;                this._drawLabel(renderer, group);                this._isLabelDrawingWithoutPoints = false            },            updateLabelCoord: function() {                var that = this,                    bbox = that._label.getBoundingRect(),                    coord = that._getColumnsCoord(bbox);                coord = that._checkHorizontalLabelPosition(coord, bbox, that._getVisibleArea());                that._label.shift(_round(coord.x), _round(bbox.y))            },            _checkVerticalLabelPosition: function(coord, box, visibleArea) {                var x = coord.x,                    y = coord.y;                if (coord.y + box.height > visibleArea.maxY)                    y = visibleArea.maxY - box.height;                else if (coord.y < visibleArea.minY)                    y = visibleArea.minY;                return {                        x: x,                        y: y                    }            },            _getLabelExtraCoord: function(coord, shiftCoord, box) {                return coord.y !== shiftCoord.y ? getVerticallyShiftedAngularCoords({                        x: coord.x,                        y: coord.y,                        width: box.width,                        height: box.height                    }, shiftCoord.y - coord.y, {                        x: this.centerX,                        y: this.centerY                    }) : coord            },            _checkHorizontalLabelPosition: function(coord, box, visibleArea) {                var x = coord.x,                    y = coord.y;                if (coord.x + box.width > visibleArea.maxX)                    x = visibleArea.maxX - box.width;                else if (coord.x < visibleArea.minX)                    x = visibleArea.minX;                return {                        x: x,                        y: y                    }            },            setLabelEllipsis: function() {                var that = this,                    bbox = that._label.getBoundingRect(),                    coord = that._checkHorizontalLabelPosition(bbox, bbox, that._getVisibleArea());                that._label.fit({                    width: bbox.width - _abs(coord.x - bbox.x),                    height: bbox.height - _abs(coord.y - bbox.y)                })            },            _getVisibleArea: function() {                var canvas = this.series.canvas;                return {                        minX: canvas.left,                        maxX: canvas.width - canvas.right,                        minY: canvas.top,                        maxY: canvas.height - canvas.bottom                    }            },            _checkLabelPosition: function(coord, bbox, visibleArea) {                coord = this._checkHorizontalLabelPosition(coord, bbox, visibleArea);                return this._checkVerticalLabelPosition(coord, bbox, visibleArea)            },            getBoundaryCoords: function() {                var that = this,                    rad = that.radiusOuter,                    seriesStyle = that._options.styles.normal,                    strokeWidthBy2 = seriesStyle["stroke-width"] / 2,                    borderWidth = that.series.getOptions().containerBackgroundColor === seriesStyle.stroke ? _round(strokeWidthBy2) : _round(-strokeWidthBy2),                    angleFunctions = _getCosAndSin(_round(that.middleAngle));                return {                        x: _round(that.centerX + (rad - borderWidth) * angleFunctions.cos),                        y: _round(that.centerY - (rad - borderWidth) * angleFunctions.sin)                    }            },            _getLabelConnector: function() {                var coords = this.getBoundaryCoords();                coords.angle = this.middleAngle;                return coords            },            _drawMarker: function(renderer, group, animationEnabled, firstDrawing) {                var that = this,                    radiusOuter = that.radiusOuter,                    radiusInner = that.radiusInner,                    fromAngle = that.fromAngle,                    toAngle = that.toAngle;                if (animationEnabled) {                    radiusInner = radiusOuter = 0;                    if (!firstDrawing)                        fromAngle = toAngle = that.shiftedAngle                }                that.graphic = renderer.arc(that.centerX, that.centerY, radiusInner, radiusOuter, toAngle, fromAngle).attr({"stroke-linejoin": "round"}).attr(that._getStyle()).data({point: that}).sharp().append(group)            },            getTooltipParams: function() {                var that = this,                    angleFunctions = _getCosAndSin(that.middleAngle),                    radiusInner = that.radiusInner,                    radiusOuter = that.radiusOuter;                return {                        x: that.centerX + (radiusInner + (radiusOuter - radiusInner) / 2) * angleFunctions.cos,                        y: that.centerY - (radiusInner + (radiusOuter - radiusInner) / 2) * angleFunctions.sin,                        offset: 0                    }            },            _translate: function(translator) {                var that = this,                    angle = that.shiftedAngle || 0,                    value = that.value,                    minValue = that.minValue;                that.fromAngle = translator.translate(minValue) + angle;                that.toAngle = translator.translate(value) + angle;                that.middleAngle = translator.translate((value - minValue) / 2 + minValue) + angle;                if (!that.isVisible())                    that.middleAngle = that.toAngle = that.fromAngle = that.fromAngle || angle            },            _getMarkerVisibility: function() {                return true            },            _updateMarker: function(animationEnabled, style) {                var that = this;                style = style || that._getStyle();                if (!animationEnabled)                    style = _extend({                        x: that.centerX,                        y: that.centerY,                        outerRadius: that.radiusOuter,                        innerRadius: that.radiusInner,                        startAngle: that.toAngle,                        endAngle: that.fromAngle                    }, style);                that.graphic.attr(style).sharp()            },            getLegendStyles: function() {                return this._styles.legendStyles            },            isInVisibleArea: function() {                return true            },            hide: function() {                var that = this;                if (that._visible) {                    that._visible = false;                    that.hideTooltip();                    that._options.visibilityChanged(that)                }            },            show: function() {                var that = this;                if (!that._visible) {                    that._visible = true;                    that._options.visibilityChanged(that)                }            },            setInvisibility: function() {                this._label.hide()            },            isVisible: function() {                return this._visible            },            _getFormatObject: function(tooltip) {                var formatObject = points.symbolPoint._getFormatObject.call(this, tooltip),                    percent = this.percent;                formatObject.percent = percent;                formatObject.percentText = tooltip.formatValue(percent, "percent");                return formatObject            },            getColor: function() {                return this._styles.normal.fill            },            coordsIn: function(x, y) {                var that = this,                    lx = x - that.centerX,                    ly = y - that.centerY,                    r = _sqrt(lx * lx + ly * ly),                    fromAngle = that.fromAngle % 360,                    toAngle = that.toAngle % 360,                    angle;                if (r < that.radiusInner || r > that.radiusOuter || r === 0)                    return false;                angle = _acos(lx / r) * DEG * (ly > 0 ? -1 : 1);                if (angle < 0)                    angle += 360;                if (fromAngle === toAngle && _abs(that.toAngle - that.fromAngle) > 1E-4)                    return true;                else                    return fromAngle >= toAngle ? angle <= fromAngle && angle >= toAngle : !(angle >= fromAngle && angle <= toAngle)            }        })    })(jQuery, DevExpress);    /*! Module viz-core, file rangeSymbolPoint.js */    (function($, DX) {        var core = DX.viz.core,            points = core.series.points.mixins,            _extend = $.extend,            _isDefined = DX.utils.isDefined,            _math = Math,            _abs = _math.abs,            _min = _math.min,            _max = _math.max,            _round = _math.round,            DEFAULT_IMAGE_WIDTH = 20,            DEFAULT_IMAGE_HEIGHT = 20;        points.rangeSymbolPoint = _extend({}, points.symbolPoint, {            deleteLabel: function() {                var that = this;                that._topLabel.dispose();                that._topLabel = null;                that._bottomLabel.dispose();                that._bottomLabel = null            },            hideMarker: function(type) {                var graphic = this.graphic,                    marker = graphic && graphic[type + "Marker"],                    label = this["_" + type + "Label"];                if (marker && marker.attr("visibility") !== "hidden")                    marker.attr({visibility: "hidden"});                label.hide()            },            setInvisibility: function() {                this.hideMarker("top");                this.hideMarker("bottom")            },            clearVisibility: function() {                var that = this,                    graphic = that.graphic,                    topMarker = graphic && graphic.topMarker,                    bottomMarker = graphic && graphic.bottomMarker;                if (topMarker && topMarker.attr("visibility"))                    topMarker.attr({visibility: null});                if (bottomMarker && bottomMarker.attr("visibility"))                    bottomMarker.attr({visibility: null});                that._topLabel.clearVisibility();                that._bottomLabel.clearVisibility()            },            clearMarker: function() {                var that = this,                    graphic = that.graphic,                    topMarker = graphic && graphic.topMarker,                    bottomMarker = graphic && graphic.bottomMarker,                    emptySettings = that._emptySettings;                topMarker && topMarker.attr(emptySettings);                bottomMarker && bottomMarker.attr(emptySettings)            },            _getLabelPosition: function(markerType) {                var position,                    labelsInside = this._options.label.position === "inside";                if (!this._options.rotated)                    position = markerType === "top" ^ labelsInside ? "top" : "bottom";                else                    position = markerType === "top" ^ labelsInside ? "right" : "left";                return position            },            _getLabelMinFormatObject: function() {                var that = this;                return {                        index: 0,                        argument: that.initialArgument,                        value: that.initialMinValue,                        seriesName: that.series.name,                        originalValue: that.originalMinValue,                        originalArgument: that.originalArgument,                        point: that                    }            },            _updateLabelData: function() {                var maxFormatObject = this._getLabelFormatObject();                maxFormatObject.index = 1;                this._topLabel.setData(maxFormatObject);                this._bottomLabel.setData(this._getLabelMinFormatObject())            },            _updateLabelOptions: function() {                var that = this,                    options = this._options.label;                (!that._topLabel || !that._bottomLabel) && that._createLabel();                that._topLabel.setOptions(options);                that._bottomLabel.setOptions(options)            },            _createLabel: function() {                this._topLabel = core.CoreFactory.createLabel();                this._bottomLabel = core.CoreFactory.createLabel()            },            _getGraphicBbox: function(location) {                location = location || this._labelLocation;                var options = this._options,                    images = this._getImage(options.image),                    image = location === "top" ? this._checkImage(images.top) : this._checkImage(images.bottom),                    bbox,                    coord = this._getPositionFromLocation(location);                if (options.visible)                    bbox = image ? this._getImageBbox(coord.x, coord.y) : this._getSymbolBbox(coord.x, coord.y, options.styles.normal.r);                else                    bbox = {                        x: coord.x,                        y: coord.y,                        width: 0,                        height: 0                    };                return bbox            },            _getPositionFromLocation: function(location) {                var x,                    y,                    isTop = location === "top";                if (!this._options.rotated) {                    x = this.x;                    y = isTop ? _min(this.y, this.minY) : _max(this.y, this.minY)                }                else {                    x = isTop ? _max(this.x, this.minX) : _min(this.x, this.minX);                    y = this.y                }                return {                        x: x,                        y: y                    }            },            _checkOverlay: function(bottomCoord, topCoord, topValue) {                return bottomCoord < topCoord + topValue            },            _getOverlayCorrections: function(type, topCoords, bottomCoords) {                var isVertical = type === "vertical",                    coordSelector = isVertical ? "y" : "x",                    valueSelector = isVertical ? "height" : "width",                    visibleArea = this.translators[coordSelector].getCanvasVisibleArea(),                    minBound = visibleArea.min,                    maxBound = visibleArea.max,                    delta = _round((topCoords[coordSelector] + topCoords[valueSelector] - bottomCoords[coordSelector]) / 2),                    coord1 = topCoords[coordSelector] - delta,                    coord2 = bottomCoords[coordSelector] + delta;                if (coord1 < minBound) {                    delta = minBound - topCoords[coordSelector];                    coord1 += delta;                    coord2 += delta                }                else if (coord2 + bottomCoords[valueSelector] > maxBound) {                    delta = -(bottomCoords[coordSelector] + bottomCoords[valueSelector] - maxBound);                    coord1 += delta;                    coord2 += delta                }                return {                        coord1: coord1,                        coord2: coord2                    }            },            _checkLabelsOverlay: function(topLocation) {                var that = this,                    topCoords = that._topLabel.getBoundingRect(),                    bottomCoords = that._bottomLabel.getBoundingRect(),                    corrections = {};                if (!that._options.rotated) {                    if (topLocation === "top") {                        if (this._checkOverlay(bottomCoords.y, topCoords.y, topCoords.height)) {                            corrections = this._getOverlayCorrections("vertical", topCoords, bottomCoords);                            that._topLabel.shift(topCoords.x, corrections.coord1);                            that._bottomLabel.shift(bottomCoords.x, corrections.coord2)                        }                    }                    else if (this._checkOverlay(topCoords.y, bottomCoords.y, bottomCoords.height)) {                        corrections = this._getOverlayCorrections("vertical", bottomCoords, topCoords);                        that._topLabel.shift(topCoords.x, corrections.coord2);                        that._bottomLabel.shift(bottomCoords.x, corrections.coord1)                    }                }                else if (topLocation === "top") {                    if (this._checkOverlay(topCoords.x, bottomCoords.x, bottomCoords.width)) {                        corrections = this._getOverlayCorrections("horizontal", bottomCoords, topCoords);                        that._topLabel.shift(corrections.coord2, topCoords.y);                        that._bottomLabel.shift(corrections.coord1, bottomCoords.y)                    }                }                else if (this._checkOverlay(bottomCoords.x, topCoords.x, topCoords.width)) {                    corrections = this._getOverlayCorrections("horizontal", topCoords, bottomCoords);                    that._topLabel.shift(corrections.coord1, topCoords.y);                    that._bottomLabel.shift(corrections.coord2, bottomCoords.y)                }            },            _drawLabel: function(renderer, group) {                var that = this,                    coord,                    labels = [],                    notInverted = that._options.rotated ? that.x >= that.minX : that.y < that.minY,                    customVisibility = that._getCustomLabelVisibility();                that._topLabel.pointPosition = notInverted ? "top" : "bottom";                that._bottomLabel.pointPosition = notInverted ? "bottom" : "top";                if ((that.series.getLabelVisibility() || customVisibility !== null) && that.hasValue()) {                    that.visibleTopMarker !== false && labels.push(that._topLabel);                    that.visibleBottomMarker !== false && labels.push(that._bottomLabel);                    $.each(labels, function(_, label) {                        var pointPosition = label.pointPosition;                        label.draw(renderer, group, customVisibility);                        coord = that._addLabelAlignmentAndOffset(label, that._getLabelCoords(label, pointPosition));                        coord = that._checkLabelPosition(label, coord, pointPosition);                        that._labelLocation = label.pointPosition;                        label.setFigureToDrawConnector(that._getLabelConnector());                        that._labelLocation = null;                        label.shift(_round(coord.x), _round(coord.y))                    });                    that._checkLabelsOverlay(that._topLabel.pointPosition)                }                else {                    that._topLabel.hide();                    that._bottomLabel.hide()                }            },            _getImage: function(imageOption) {                var image = {};                if (_isDefined(imageOption))                    if (typeof imageOption === "string")                        image.top = image.bottom = imageOption;                    else {                        image.top = {                            url: typeof imageOption.url === "string" ? imageOption.url : imageOption.url && imageOption.url.rangeMaxPoint,                            width: typeof imageOption.width === "number" ? imageOption.width : imageOption.width && imageOption.width.rangeMaxPoint,                            height: typeof imageOption.height === "number" ? imageOption.height : imageOption.height && imageOption.height.rangeMaxPoint                        };                        image.bottom = {                            url: typeof imageOption.url === "string" ? imageOption.url : imageOption.url && imageOption.url.rangeMinPoint,                            width: typeof imageOption.width === "number" ? imageOption.width : imageOption.width && imageOption.width.rangeMinPoint,                            height: typeof imageOption.height === "number" ? imageOption.height : imageOption.height && imageOption.height.rangeMinPoint                        }                    }                return image            },            _checkSymbol: function(oldOptions, newOptions) {                var that = this,                    oldSymbol = oldOptions.symbol,                    newSymbol = newOptions.symbol,                    symbolChanged = oldSymbol === "circle" && newSymbol !== "circle" || oldSymbol !== "circle" && newSymbol === "circle",                    oldImages = that._getImage(oldOptions.image),                    newImages = that._getImage(newOptions.image),                    topImageChanged = that._checkImage(oldImages.top) !== that._checkImage(newImages.top),                    bottomImageChanged = that._checkImage(oldImages.bottom) !== that._checkImage(newImages.bottom);                return symbolChanged || topImageChanged || bottomImageChanged            },            _getSettingsForTwoMarkers: function(style) {                var that = this,                    options = that._options,                    settings = {},                    x = options.rotated ? _min(that.x, that.minX) : that.x,                    y = options.rotated ? that.y : _min(that.y, that.minY),                    radius = style.r,                    points = that._populatePointShape(options.symbol, radius);                settings.top = _extend({                    translateX: x + that.width,                    translateY: y,                    r: radius                }, style);                settings.bottom = _extend({                    translateX: x,                    translateY: y + that.height,                    r: radius                }, style);                if (points)                    settings.top.points = settings.bottom.points = points;                return settings            },            _hasGraphic: function() {                return this.graphic && this.graphic.topMarker && this.graphic.bottomMarker            },            _drawOneMarker: function(renderer, markerType, imageSettings, settings) {                var that = this,                    graphic = that.graphic;                if (graphic[markerType])                    that._updateOneMarker(markerType, settings);                else                    graphic[markerType] = that._createMarker(renderer, graphic, imageSettings, settings)            },            _drawMarker: function(renderer, group, animationEnabled, firstDrawing, style) {                var that = this,                    settings = that._getSettingsForTwoMarkers(style || that._getStyle()),                    image = that._getImage(that._options.image);                if (that._checkImage(image.top))                    settings.top = that._getImageSettings(settings.top, image.top);                if (that._checkImage(image.bottom))                    settings.bottom = that._getImageSettings(settings.bottom, image.bottom);                that.graphic = that.graphic || renderer.g().append(group);                that.visibleTopMarker && that._drawOneMarker(renderer, 'topMarker', image.top, settings.top);                that.visibleBottomMarker && that._drawOneMarker(renderer, 'bottomMarker', image.bottom, settings.bottom)            },            _getSettingsForTracker: function(radius) {                var that = this,                    rotated = that._options.rotated;                return {                        translateX: rotated ? _min(that.x, that.minX) - radius : that.x - radius,                        translateY: rotated ? that.y - radius : _min(that.y, that.minY) - radius,                        width: that.width + 2 * radius,                        height: that.height + 2 * radius                    }            },            isInVisibleArea: function() {                var that = this,                    rotated = that._options.rotated,                    argument = !rotated ? that.x : that.y,                    maxValue = !rotated ? _max(that.minY, that.y) : _max(that.minX, that.x),                    minValue = !rotated ? _min(that.minY, that.y) : _min(that.minX, that.x),                    translators = that.translators,                    notVisibleByArg,                    notVisibleByVal,                    tmp,                    visibleTopMarker = true,                    visibleBottomMarker = true,                    visibleRangeArea = true,                    visibleArgArea,                    visibleValArea;                if (translators) {                    visibleArgArea = translators[!rotated ? "x" : "y"].getCanvasVisibleArea();                    visibleValArea = translators[!rotated ? "y" : "x"].getCanvasVisibleArea();                    notVisibleByArg = visibleArgArea.max < argument || visibleArgArea.min > argument;                    notVisibleByVal = visibleValArea.min > minValue && visibleValArea.min > maxValue || visibleValArea.max < minValue && visibleValArea.max < maxValue;                    if (notVisibleByArg || notVisibleByVal)                        visibleTopMarker = visibleBottomMarker = visibleRangeArea = false;                    else {                        visibleTopMarker = visibleValArea.min <= minValue && visibleValArea.max > minValue;                        visibleBottomMarker = visibleValArea.min < maxValue && visibleValArea.max >= maxValue;                        if (rotated) {                            tmp = visibleTopMarker;                            visibleTopMarker = visibleBottomMarker;                            visibleBottomMarker = tmp                        }                    }                }                that.visibleTopMarker = visibleTopMarker;                that.visibleBottomMarker = visibleBottomMarker;                return visibleRangeArea            },            getTooltipParams: function() {                var that = this,                    x,                    y,                    min,                    max,                    minValue,                    translators = that.translators,                    visibleAreaX = translators.x.getCanvasVisibleArea(),                    visibleAreaY = translators.y.getCanvasVisibleArea();                if (!that._options.rotated) {                    minValue = _min(that.y, that.minY);                    x = that.x;                    min = visibleAreaY.min > minValue ? visibleAreaY.min : minValue;                    max = visibleAreaY.max < minValue + that.height ? visibleAreaY.max : minValue + that.height;                    y = min + (max - min) / 2                }                else {                    minValue = _min(that.x, that.minX);                    y = that.y;                    min = visibleAreaX.min > minValue ? visibleAreaX.min : minValue;                    max = visibleAreaX.max < minValue + that.width ? visibleAreaX.max : minValue + that.width;                    x = min + (max - min) / 2                }                return {                        x: x,                        y: y,                        offset: 0                    }            },            _translate: function(translators) {                var that = this,                    rotated = that._options.rotated;                that.minX = that.minY = translators.y.translate(that.minValue);                points.symbolPoint._translate.call(that, translators);                that.height = rotated ? 0 : _abs(that.minY - that.y);                that.width = rotated ? _abs(that.x - that.minX) : 0            },            _updateData: function(data) {                var that = this;                points.symbolPoint._updateData.call(that, data);                that.minValue = that.initialMinValue = that.originalMinValue = data.minValue            },            _getImageSettings: function(settings, image) {                return {                        href: image.url || image.toString(),                        width: image.width || DEFAULT_IMAGE_WIDTH,                        height: image.height || DEFAULT_IMAGE_HEIGHT,                        translateX: settings.translateX,                        translateY: settings.translateY                    }            },            getCrosshairCoords: function(x, y) {                var coords;                if (this._options.rotated)                    coords = {                        y: this.vy,                        x: Math.abs(this.vx - x) < Math.abs(this.minX - x) ? this.vx : this.minX                    };                else                    coords = {                        x: this.vx,                        y: Math.abs(this.vy - y) < Math.abs(this.minY - y) ? this.vy : this.minY                    };                return coords            },            _updateOneMarker: function(markerType, settings) {                this.graphic && this.graphic[markerType] && this.graphic[markerType].attr(settings)            },            _updateMarker: function(animationEnabled, style) {                this._drawMarker(undefined, undefined, false, false, style)            },            _getFormatObject: function(tooltip) {                var that = this,                    initialMinValue = that.initialMinValue,                    initialValue = that.initialValue,                    initialArgument = that.initialArgument,                    minValue = tooltip.formatValue(initialMinValue),                    value = tooltip.formatValue(initialValue);                return {                        argument: initialArgument,                        argumentText: tooltip.formatValue(initialArgument, "argument"),                        valueText: minValue + " - " + value,                        rangeValue1Text: minValue,                        rangeValue2Text: value,                        rangeValue1: initialMinValue,                        rangeValue2: initialValue,                        seriesName: that.series.name,                        point: that,                        originalMinValue: that.originalMinValue,                        originalValue: that.originalValue,                        originalArgument: that.originalArgument                    }            },            getLabel: function() {                return [this._topLabel, this._bottomLabel]            },            getBoundingRect: $.noop,            coordsIn: function(x, y) {                var trackerRadius = this._storeTrackerR(),                    xCond = x >= this.x - trackerRadius && x <= this.x + trackerRadius,                    yCond = y >= this.y - trackerRadius && y <= this.y + trackerRadius;                if (this._options.rotated)                    return yCond && (xCond || x >= this.minX - trackerRadius && x <= this.minX + trackerRadius);                else                    return xCond && (yCond || y >= this.minY - trackerRadius && y <= this.minY + trackerRadius)            }        })    })(jQuery, DevExpress);    /*! Module viz-core, file rangeBarPoint.js */    (function($, DX) {        var points = DX.viz.core.series.points.mixins,            rangeSymbolPointMethods = points.rangeSymbolPoint,            _extend = $.extend;        points.rangeBarPoint = _extend({}, points.barPoint, {            deleteLabel: rangeSymbolPointMethods.deleteLabel,            _getFormatObject: rangeSymbolPointMethods._getFormatObject,            clearVisibility: function() {                var graphic = this.graphic;                if (graphic && graphic.attr("visibility"))                    graphic.attr({visibility: null});                this._topLabel.clearVisibility();                this._bottomLabel.clearVisibility()            },            setInvisibility: function() {                var graphic = this.graphic;                if (graphic && graphic.attr("visibility") !== "hidden")                    graphic.attr({visibility: "hidden"});                this._topLabel.hide();                this._bottomLabel.hide()            },            getTooltipParams: function(location) {                var edgeLocation = location === 'edge',                    x,                    y;                if (this._options.rotated) {                    x = edgeLocation ? this.x + this.width : this.x + this.width / 2;                    y = this.y + this.height / 2                }                else {                    x = this.x + this.width / 2;                    y = edgeLocation ? this.y : this.y + this.height / 2                }                return {                        x: x,                        y: y,                        offset: 0                    }            },            _translate: function(translator) {                var that = this,                    barMethods = points.barPoint;                barMethods._translate.call(that, translator);                if (that._options.rotated)                    that.width = that.width || 1;                else                    that.height = that.height || 1            },            _updateData: rangeSymbolPointMethods._updateData,            _getLabelPosition: rangeSymbolPointMethods._getLabelPosition,            _getLabelMinFormatObject: rangeSymbolPointMethods._getLabelMinFormatObject,            _updateLabelData: rangeSymbolPointMethods._updateLabelData,            _updateLabelOptions: rangeSymbolPointMethods._updateLabelOptions,            getCrosshairCoords: rangeSymbolPointMethods.getCrosshairCoords,            _createLabel: rangeSymbolPointMethods._createLabel,            _checkOverlay: rangeSymbolPointMethods._checkOverlay,            _checkLabelsOverlay: rangeSymbolPointMethods._checkLabelsOverlay,            _getOverlayCorrections: rangeSymbolPointMethods._getOverlayCorrections,            _drawLabel: rangeSymbolPointMethods._drawLabel,            _getLabelCoords: rangeSymbolPointMethods._getLabelCoords,            _getGraphicBbox: function(location) {                location = location || this._labelLocation;                var isTop = location === "top",                    bbox = points.barPoint._getGraphicBbox.call(this);                if (!this._options.rotated) {                    bbox.y = isTop ? bbox.y : bbox.y + bbox.height;                    bbox.height = 0                }                else {                    bbox.x = isTop ? bbox.x + bbox.width : bbox.x;                    bbox.width = 0                }                return bbox            },            getLabel: rangeSymbolPointMethods.getLabel,            getBoundingRect: $.noop        })    })(jQuery, DevExpress);    /*! Module viz-core, file candlestickPoint.js */    (function($, DX) {        var viz = DX.viz,            points = viz.core.series.points.mixins,            _isNumeric = $.isNumeric,            _extend = $.extend,            _math = Math,            _abs = _math.abs,            _min = _math.min,            _max = _math.max,            _round = _math.round,            DEFAULT_FINANCIAL_TRACKER_MARGIN = 2;        points.candlestickPoint = _extend({}, points.barPoint, {            _getContinuousPoints: function(minValueName, maxValueName) {                var that = this,                    x = that.x,                    createPoint = that._options.rotated ? function(x, y) {                        return [y, x]                    } : function(x, y) {                        return [x, y]                    },                    width = that.width,                    min = that[minValueName],                    max = that[maxValueName],                    points;                if (min === max)                    points = [].concat(createPoint(x, that.highY)).concat(createPoint(x, that.lowY)).concat(createPoint(x, that.closeY)).concat(createPoint(x - width / 2, that.closeY)).concat(createPoint(x + width / 2, that.closeY)).concat(createPoint(x, that.closeY));                else                    points = [].concat(createPoint(x, that.highY)).concat(createPoint(x, max)).concat(createPoint(x + width / 2, max)).concat(createPoint(x + width / 2, min)).concat(createPoint(x, min)).concat(createPoint(x, that.lowY)).concat(createPoint(x, min)).concat(createPoint(x - width / 2, min)).concat(createPoint(x - width / 2, max)).concat(createPoint(x, max));                return points            },            _getCategoryPoints: function(y) {                var that = this,                    x = that.x,                    createPoint = that._options.rotated ? function(x, y) {                        return [y, x]                    } : function(x, y) {                        return [x, y]                    };                return [].concat(createPoint(x, that.highY)).concat(createPoint(x, that.lowY)).concat(createPoint(x, y)).concat(createPoint(x - that.width / 2, y)).concat(createPoint(x + that.width / 2, y)).concat(createPoint(x, y))            },            _getPoints: function() {                var that = this,                    points,                    minValueName,                    maxValueName,                    openValue = that.openValue,                    closeValue = that.closeValue;                if (_isNumeric(openValue) && _isNumeric(closeValue)) {                    minValueName = openValue > closeValue ? "closeY" : "openY";                    maxValueName = openValue > closeValue ? "openY" : "closeY";                    points = that._getContinuousPoints(minValueName, maxValueName)                }                else if (openValue === closeValue)                    points = [that.x, that.highY, that.x, that.lowY];                else                    points = that._getCategoryPoints(_isNumeric(openValue) ? that.openY : that.closeY);                return points            },            getColor: function() {                var that = this;                return that._isReduction ? that._options.reduction.color : that._styles.normal.stroke || that.series.getColor()            },            _drawMarkerInGroup: function(group, attributes, renderer) {                var that = this;                that.graphic = renderer.path(that._getPoints(), "area").attr({"stroke-linecap": "square"}).attr(attributes).data({point: that}).sharp().append(group)            },            _fillStyle: function() {                var that = this,                    styles = that._options.styles;                if (that._isReduction && that._isPositive)                    that._styles = styles.reductionPositive;                else if (that._isReduction)                    that._styles = styles.reduction;                else if (that._isPositive)                    that._styles = styles.positive;                else                    that._styles = styles            },            _getMinTrackerWidth: function() {                return 2 + 2 * this._styles.normal['stroke-width']            },            correctCoordinates: function(correctOptions) {                var minWidth = this._getMinTrackerWidth(),                    maxWidth = 10,                    width = correctOptions.width;                width = width < minWidth ? minWidth : width > maxWidth ? maxWidth : width;                this.width = width + width % 2;                this.xCorrection = correctOptions.offset            },            _getMarkerGroup: function(group) {                var that = this,                    markerGroup;                if (that._isReduction && that._isPositive)                    markerGroup = group.reductionPositiveMarkersGroup;                else if (that._isReduction)                    markerGroup = group.reductionMarkersGroup;                else if (that._isPositive)                    markerGroup = group.defaultPositiveMarkersGroup;                else                    markerGroup = group.defaultMarkersGroup;                return markerGroup            },            _drawMarker: function(renderer, group) {                this._drawMarkerInGroup(this._getMarkerGroup(group), this._getStyle(), renderer)            },            _getSettingsForTracker: function() {                var that = this,                    highY = that.highY,                    lowY = that.lowY,                    rotated = that._options.rotated,                    x,                    y,                    width,                    height;                if (highY === lowY) {                    highY = rotated ? highY + DEFAULT_FINANCIAL_TRACKER_MARGIN : highY - DEFAULT_FINANCIAL_TRACKER_MARGIN;                    lowY = rotated ? lowY - DEFAULT_FINANCIAL_TRACKER_MARGIN : lowY + DEFAULT_FINANCIAL_TRACKER_MARGIN                }                if (rotated) {                    x = _min(lowY, highY);                    y = that.x - that.width / 2;                    width = _abs(lowY - highY);                    height = that.width                }                else {                    x = that.x - that.width / 2;                    y = _min(lowY, highY);                    width = that.width;                    height = _abs(lowY - highY)                }                return {                        x: x,                        y: y,                        width: width,                        height: height                    }            },            _getGraphicBbox: function() {                var that = this,                    rotated = that._options.rotated,                    x = that.x,                    width = that.width,                    lowY = that.lowY,                    highY = that.highY;                return {                        x: !rotated ? x - _round(width / 2) : lowY,                        y: !rotated ? highY : x - _round(width / 2),                        width: !rotated ? width : highY - lowY,                        height: !rotated ? lowY - highY : width                    }            },            getTooltipParams: function(location) {                var that = this;                if (that.graphic) {                    var x,                        y,                        min,                        max,                        minValue = _min(that.lowY, that.highY),                        maxValue = _max(that.lowY, that.highY),                        visibleAreaX = that.translators.x.getCanvasVisibleArea(),                        visibleAreaY = that.translators.y.getCanvasVisibleArea(),                        edgeLocation = location === 'edge';                    if (!that._options.rotated) {                        min = _max(visibleAreaY.min, minValue);                        max = _min(visibleAreaY.max, maxValue);                        x = that.x;                        y = edgeLocation ? min : min + (max - min) / 2                    }                    else {                        min = _max(visibleAreaX.min, minValue);                        max = _min(visibleAreaX.max, maxValue);                        y = that.x;                        x = edgeLocation ? max : min + (max - min) / 2                    }                    return {                            x: x,                            y: y,                            offset: 0                        }                }            },            hasValue: function() {                return this.highValue !== null && this.lowValue !== null            },            _translate: function() {                var that = this,                    rotated = that._options.rotated,                    translators = that.translators,                    argTranslator = rotated ? translators.y : translators.x,                    valTranslator = rotated ? translators.x : translators.y,                    centerValue,                    height;                that.vx = that.vy = that.x = argTranslator.translate(that.argument) + (that.xCorrection || 0);                that.openY = that.openValue !== null ? valTranslator.translate(that.openValue) : null;                that.highY = valTranslator.translate(that.highValue);                that.lowY = valTranslator.translate(that.lowValue);                that.closeY = that.closeValue !== null ? valTranslator.translate(that.closeValue) : null;                height = _abs(that.lowY - that.highY);                centerValue = _min(that.lowY, that.highY) + _abs(that.lowY - that.highY) / 2;                that._calculateVisibility(!rotated ? that.x : centerValue, !rotated ? centerValue : that.x)            },            getCrosshairCoords: function(x, y) {                var coords,                    valueCoord = this._options.rotated ? x : y,                    value = Math.abs(this.lowY - valueCoord) < Math.abs(this.closeY - valueCoord) ? this.lowY : this.closeY;                value = Math.abs(value - valueCoord) < Math.abs(this.openY - valueCoord) ? value : this.openY;                value = Math.abs(value - valueCoord) < Math.abs(this.highY - valueCoord) ? value : this.highY;                if (this._options.rotated)                    coords = {                        y: this.vy,                        x: value                    };                else                    coords = {                        x: this.vx,                        y: value                    };                return coords            },            _updateData: function(data) {                var that = this,                    label = that._label,                    reductionColor = this._options.reduction.color;                that.value = that.initialValue = data.reductionValue;                that.originalValue = data.value;                that.lowValue = that.originalLowValue = data.lowValue;                that.highValue = that.originalHighValue = data.highValue;                that.openValue = that.originalOpenValue = data.openValue;                that.closeValue = that.originalCloseValue = data.closeValue;                that._isPositive = data.openValue < data.closeValue;                that._isReduction = data.isReduction;                if (that._isReduction)                    label.setColor(reductionColor)            },            _updateMarker: function(animationEnabled, style, group) {                var that = this,                    graphic = that.graphic;                graphic.attr({points: that._getPoints()}).attr(style || that._getStyle()).sharp();                group && graphic.append(that._getMarkerGroup(group))            },            _getLabelFormatObject: function() {                var that = this;                return {                        openValue: that.openValue,                        highValue: that.highValue,                        lowValue: that.lowValue,                        closeValue: that.closeValue,                        reductionValue: that.initialValue,                        argument: that.initialArgument,                        value: that.initialValue,                        seriesName: that.series.name,                        originalOpenValue: that.originalOpenValue,                        originalCloseValue: that.originalCloseValue,                        originalLowValue: that.originalLowValue,                        originalHighValue: that.originalHighValue,                        originalArgument: that.originalArgument,                        point: that                    }            },            _getFormatObject: function(tooltip) {                var that = this,                    highValue = tooltip.formatValue(that.highValue),                    openValue = tooltip.formatValue(that.openValue),                    closeValue = tooltip.formatValue(that.closeValue),                    lowValue = tooltip.formatValue(that.lowValue),                    symbolMethods = points.symbolPoint,                    formatObject = symbolMethods._getFormatObject.call(that, tooltip);                return _extend({}, formatObject, {                        valueText: "h: " + highValue + (openValue !== "" ? " o: " + openValue : "") + (closeValue !== "" ? " c: " + closeValue : "") + " l: " + lowValue,                        highValueText: highValue,                        openValueText: openValue,                        closeValueText: closeValue,                        lowValueText: lowValue                    })            }        })    })(jQuery, DevExpress);    /*! Module viz-core, file stockPoint.js */    (function($, DX) {        var points = DX.viz.core.series.points.mixins,            _extend = $.extend,            _isNumeric = $.isNumeric;        points.stockPoint = _extend({}, points.candlestickPoint, {            _getPoints: function() {                var that = this,                    createPoint = that._options.rotated ? function(x, y) {                        return [y, x]                    } : function(x, y) {                        return [x, y]                    },                    openYExist = _isNumeric(that.openY),                    closeYExist = _isNumeric(that.closeY),                    x = that.x,                    width = that.width,                    points;                points = [].concat(createPoint(x, that.highY));                openYExist && (points = points.concat(createPoint(x, that.openY)));                openYExist && (points = points.concat(createPoint(x - width / 2, that.openY)));                openYExist && (points = points.concat(createPoint(x, that.openY)));                closeYExist && (points = points.concat(createPoint(x, that.closeY)));                closeYExist && (points = points.concat(createPoint(x + width / 2, that.closeY)));                closeYExist && (points = points.concat(createPoint(x, that.closeY)));                points = points.concat(createPoint(x, that.lowY));                return points            },            _drawMarkerInGroup: function(group, attributes, renderer) {                this.graphic = renderer.path(this._getPoints(), "line").attr({"stroke-linecap": "square"}).attr(attributes).data({point: this}).sharp().append(group)            },            _getMinTrackerWidth: function() {                var width = 2 + this._styles.normal['stroke-width'];                return width + width % 2            }        })    })(jQuery, DevExpress);    /*! Module viz-core, file polarPoint.js */    (function($, DX, undefined) {        var _extend = $.extend,            viz = DX.viz,            points = viz.core.series.points.mixins,            utils = DX.utils,            isDefined = utils.isDefined,            normalizeAngle = utils.normalizeAngle,            _math = Math,            _max = _math.max,            ERROR_BARS_ANGLE_OFFSET = 90,            CANVAS_POSITION_START = "canvas_position_start",            CANVAS_POSITION_TOP = "canvas_position_top",            CANVAS_POSITION_END = "canvas_position_end",            CANVAS_POSITION_DEFAULT = "canvas_position_default";        points.polarSymbolPoint = _extend({}, points.symbolPoint, {            _getLabelCoords: points.piePoint._getLabelCoords,            _moveLabelOnCanvas: points.barPoint._moveLabelOnCanvas,            _getLabelPosition: function() {                return "outside"            },            _translate: function(translator) {                var that = this,                    coord = translator.translate(that.argument, that.value),                    center = translator.translate(CANVAS_POSITION_START, CANVAS_POSITION_TOP);                that.vx = normalizeAngle(coord.angle);                that.vy = that.radiusOuter = coord.radius;                that.radius = coord.radius;                that.middleAngle = -coord.angle;                that.angle = -coord.angle;                that.x = coord.x;                that.y = coord.y;                that.defaultX = that.centerX = center.x;                that.defaultY = that.centerY = center.y;                that._translateErrorBars(translator);                that.inVisibleArea = true            },            _translateErrorBars: function(translator) {                var that = this;                isDefined(that.lowError) && (that._lowErrorCoord = that.centerY - translator.translate(that.argument, that.lowError).radius);                isDefined(that.highError) && (that._highErrorCoord = that.centerY - translator.translate(that.argument, that.highError).radius);                that._errorBarPos = that.centerX;                that._baseErrorBarPos = (that._options.errorBars || {}).type === "stdDeviation" ? that._lowErrorCoord + (that._highErrorCoord - that._lowErrorCoord) / 2 : that.centerY - that.radius            },            _getTranslates: function(animationEnabled) {                return animationEnabled ? this.getDefaultCoords() : {                        x: this.x,                        y: this.y                    }            },            getDefaultCoords: function() {                var cossin = utils.getCosAndSin(-this.angle),                    radius = this.translators.translate(CANVAS_POSITION_START, CANVAS_POSITION_DEFAULT).radius,                    x = this.defaultX + radius * cossin.cos,                    y = this.defaultY + radius * cossin.sin;                return {                        x: x,                        y: y                    }            },            _addLabelAlignmentAndOffset: function(label, coord) {                return coord            },            _getVisibleArea: function() {                var canvas = this.translators.canvas;                return {                        minX: canvas.left,                        maxX: canvas.width - canvas.right,                        minY: canvas.top,                        maxY: canvas.height - canvas.bottom                    }            },            _checkLabelPosition: function(label, coord) {                var that = this,                    visibleArea = that._getVisibleArea(),                    graphicBbox = that._getGraphicBbox();                if (that._isPointInVisibleArea(visibleArea, graphicBbox))                    coord = that._moveLabelOnCanvas(coord, visibleArea, label.getBoundingRect(), true, true);                return coord            },            _getErrorBarSettings: function(errorBarOptions, animationEnabled) {                var settings = points.symbolPoint._getErrorBarSettings.call(this, errorBarOptions, animationEnabled);                settings.rotate = ERROR_BARS_ANGLE_OFFSET - this.angle;                settings.rotateX = this.centerX;                settings.rotateY = this.centerY;                return settings            },            getCoords: function(min) {                return min ? this.getDefaultCoords() : {                        x: this.x,                        y: this.y                    }            }        });        points.polarBarPoint = _extend({}, points.barPoint, {            _translateErrorBars: points.polarSymbolPoint._translateErrorBars,            _getErrorBarSettings: points.polarSymbolPoint._getErrorBarSettings,            _getVisibleArea: points.polarSymbolPoint._getVisibleArea,            _moveLabelOnCanvas: points.barPoint._moveLabelOnCanvas,            _getLabelCoords: points.piePoint._getLabelCoords,            _getLabelConnector: points.piePoint._getLabelConnector,            getBoundaryCoords: points.piePoint.getBoundaryCoords,            getTooltipParams: points.piePoint.getTooltipParams,            _getLabelPosition: points.piePoint._getLabelPosition,            _translate: function(translator) {                var that = this,                    maxRadius = translator.translate(CANVAS_POSITION_TOP, CANVAS_POSITION_END).radius;                that.radiusInner = translator.translate(that.argument, that.minValue).radius;                points.polarSymbolPoint._translate.call(that, translator);                if (that.radiusInner === null)                    that.radiusInner = that.radius = maxRadius;                else if (that.radius === null)                    this.radius = this.value >= 0 ? maxRadius : 0;                that.radiusOuter = _max(that.radiusInner, that.radius);                that.radiusInner = that.defaultRadius = _math.min(that.radiusInner, that.radius);                that.middleAngle = that.angle = -utils.normalizeAngle(that.middleAngleCorrection - that.angle)            },            _checkVisibility: function(translator) {                return translator.checkVisibility(this.radius, this.radiusInner)            },            getMarkerCoords: function() {                return {                        x: this.centerX,                        y: this.centerY,                        outerRadius: this.radiusOuter,                        innerRadius: this.defaultRadius,                        startAngle: this.middleAngle - this.interval / 2,                        endAngle: this.middleAngle + this.interval / 2                    }            },            _drawMarker: function(renderer, group, animationEnabled) {                var that = this,                    styles = that._getStyle(),                    coords = that.getMarkerCoords(),                    innerRadius = coords.innerRadius,                    outerRadius = coords.outerRadius,                    start = that.translators.translate(that.argument, CANVAS_POSITION_DEFAULT),                    x = coords.x,                    y = coords.y;                if (animationEnabled) {                    innerRadius = 0;                    outerRadius = 0;                    x = start.x;                    y = start.y                }                that.graphic = renderer.arc(x, y, innerRadius, outerRadius, coords.startAngle, coords.endAngle).attr(styles).data({point: that}).append(group)            },            _checkLabelPosition: function(label, coord) {                var that = this,                    visibleArea = that._getVisibleArea(),                    angleFunctions = utils.getCosAndSin(that.middleAngle),                    x = that.centerX + that.defaultRadius * angleFunctions.cos,                    y = that.centerY - that.defaultRadius * angleFunctions.sin;                if (x > visibleArea.minX && x < visibleArea.maxX && y > visibleArea.minY && y < visibleArea.maxY)                    coord = that._moveLabelOnCanvas(coord, visibleArea, label.getBoundingRect(), true, true);                return coord            },            _addLabelAlignmentAndOffset: function(label, coord) {                return coord            },            correctCoordinates: function(correctOptions) {                this.middleAngleCorrection = correctOptions.offset;                this.interval = correctOptions.width            },            coordsIn: function(x, y) {                var val = this.translators.untranslate(x, y),                    coords = this.getMarkerCoords(),                    isBetweenAngles = coords.startAngle < coords.endAngle ? -val.phi >= coords.startAngle && -val.phi <= coords.endAngle : -val.phi <= coords.startAngle && -val.phi >= coords.endAngle;                return val.r >= coords.innerRadius && val.r <= coords.outerRadius && isBetweenAngles            }        })    })(jQuery, DevExpress);    /*! Module viz-core, file dataValidator.js */    (function($, DX, undefined) {        var viz = DX.viz,            parseUtils = new viz.core.ParseUtils,            STRING = "string",            NUMERIC = "numeric",            DATETIME = "datetime",            DISCRETE = "discrete",            CONTINUOUS = "continuous",            LOGARITHMIC = "logarithmic",            VALUE_TYPE = "valueType",            ARGUMENT_TYPE = "argumentType",            axisTypeParser = viz.core.utils.enumParser([STRING, NUMERIC, DATETIME]),            utils = DX.utils,            _each = $.each,            _isDefined = utils.isDefined;        function groupingValues(data, others, valueField, index) {            if (!_isDefined(index) || index < 0)                return;            _each(data.slice(index), function(_, cell) {                if (!_isDefined(cell[valueField]))                    return;                others[valueField] += cell[valueField];                cell[valueField] = undefined;                cell["original" + valueField] = undefined            })        }        function mergeSort(data, field) {            function merge_sort(array, low, high, field) {                if (low < high) {                    var mid = Math.floor((low + high) / 2);                    merge_sort(array, low, mid, field);                    merge_sort(array, mid + 1, high, field);                    merge(array, low, mid, high, field)                }            }            var n = data.length;            merge_sort(data, 0, n - 1, field);            return data        }        function merge(array, low, mid, high, field) {            var newArray = new Array(high - low + 1),                countL = low,                countR = mid + 1,                k,                i = 0;            while (countL <= mid && countR <= high) {                if (array[countL][field] <= array[countR][field] || !_isDefined(array[countR][field])) {                    newArray[i] = array[countL];                    countL++                }                else {                    newArray[i] = array[countR];                    countR++                }                i++            }            if (countL > mid)                for (k = countR; k <= high; k++, i++)                    newArray[i] = array[k];            else                for (k = countL; k <= mid; k++, i++)                    newArray[i] = array[k];            for (k = 0; k <= high - low; k++)                array[k + low] = newArray[k];            return array        }        function DataValidator(data, groups, incidentOccured, dataPrepareOptions) {            var that = this;            groups = groups || [[]];            that._nullData = !data;            that.groups = groups;            that.data = data || [];            that._parsers = {};            that._errorShowList = {};            that._skipFields = {};            that.options = dataPrepareOptions || {};            that.incidentOccured = incidentOccured;            that.userArgumentCategories = that.groups.argumentOptions && that.groups.argumentOptions.categories || [];            if (!incidentOccured)                that.incidentOccured = $.noop        }        viz.core.DataValidator = DataValidator;        DataValidator.prototype = {            ctor: DataValidator,            validate: function validate() {                var that = this,                    dataLength;                that._data = that.data;                that.groups.argumentType = null;                that.groups.argumentAxisType = null;                _each(that.groups, function(_, group) {                    group.valueType = null;                    group.valueAxisType = null;                    _each(group, function(_, series) {                        series.updateDataType({})                    });                    group.valueAxis && group.valueAxis.resetTypes(VALUE_TYPE)                });                if (that.groups.argumentAxes)                    _each(that.groups.argumentAxes, function(_, axis) {                        axis.resetTypes(ARGUMENT_TYPE)                    });                that._checkType();                that._checkAxisType();                if (!utils.isArray(that.data) || that._nullData)                    that._incorrectDataMessage();                if (that.options.convertToAxisDataType) {                    that._createParser();                    that._parse()                }                that._groupData();                that._sort();                dataLength = that._data.length;                _each(that._skipFields, function(field, fieldValue) {                    if (fieldValue === dataLength)                        that.incidentOccured("W2002", [field])                });                return that._data            },            _checkValueTypeOfGroup: function(group, cell) {                var that = this;                _each(group, function(_, series) {                    _each(series.getValueFields(), function(_, field) {                        group.valueType = that._getType(cell[field], group.valueType)                    })                });                return group.valueType            },            _checkArgumentTypeOfGroup: function(group, cell) {                var that = this;                _each(group, function(_, series) {                    that.groups.argumentType = that._getType(cell[series.getArgumentField()], that.groups.argumentType)                });                return that.groups.argumentType            },            _checkType: function _checkType() {                var that = this,                    groupsWithUndefinedValueType = [],                    groupsWithUndefinedArgumentType = [],                    groups = that.groups,                    argumentTypeGroup = groups.argumentOptions && axisTypeParser(groups.argumentOptions.argumentType);                _each(groups, function(_, group) {                    if (!group.length)                        return null;                    var valueTypeGroup = group.valueOptions && axisTypeParser(group.valueOptions.valueType);                    group.valueType = valueTypeGroup;                    groups.argumentType = argumentTypeGroup;                    !valueTypeGroup && groupsWithUndefinedValueType.push(group);                    !argumentTypeGroup && groupsWithUndefinedArgumentType.push(group)                });                if (groupsWithUndefinedValueType.length || groupsWithUndefinedArgumentType.length)                    _each(that.data, function(_, cell) {                        var defineVal,                            defineArg;                        if (!utils.isObject(cell))                            return;                        _each(groupsWithUndefinedValueType, function(_, group) {                            defineVal = that._checkValueTypeOfGroup(group, cell)                        });                        _each(groupsWithUndefinedArgumentType, function(_, group) {                            defineArg = that._checkArgumentTypeOfGroup(group, cell)                        });                        if (!that.options.checkTypeForAllData && defineVal && defineArg)                            return false                    })            },            _checkAxisType: function _checkAxisType() {                var that = this,                    groups = that.groups,                    argumentOptions = groups.argumentOptions || {};                _each(groups, function(_, group) {                    _each(group, function(_, series) {                        var optionsSeries = {},                            valueOptions = group.valueOptions || {},                            valueCategories = valueOptions.categories || [];                        optionsSeries.argumentAxisType = that._correctAxisType(groups.argumentType, argumentOptions.type, !!that.userArgumentCategories.length);                        optionsSeries.valueAxisType = that._correctAxisType(group.valueType, valueOptions.type, !!valueCategories.length);                        groups.argumentAxisType = groups.argumentAxisType || optionsSeries.argumentAxisType;                        group.valueAxisType = group.valueAxisType || optionsSeries.valueAxisType;                        optionsSeries.argumentType = groups.argumentType;                        optionsSeries.valueType = group.valueType;                        optionsSeries.showZero = valueOptions.showZero;                        series.updateDataType(optionsSeries)                    });                    if (group.valueAxis) {                        group.valueAxis.setTypes(group.valueAxisType, group.valueType, VALUE_TYPE);                        group.valueAxis.validate(false)                    }                });                if (that.groups.argumentAxes)                    _each(that.groups.argumentAxes, function(_, axis) {                        axis.setTypes(that.groups.argumentAxisType, that.groups.argumentType, ARGUMENT_TYPE);                        axis.validate(true)                    })            },            _createParser: function _createParser() {                var that = this,                    groups = that.groups;                _each(groups, function(_, group) {                    _each(group, function(_, series) {                        that._parsers[series.getArgumentField()] = that._createParserUnit(groups.argumentType, groups.argumentAxisType === LOGARITHMIC ? that._filterForLogAxis : null);                        _each(series.getValueFields(), function(_, field) {                            that._parsers[field] = that._createParserUnit(group.valueType, group.valueAxisType === LOGARITHMIC ? that._filterForLogAxis : null, series.getOptions().ignoreEmptyPoints)                        });                        if (series.getTagField())                            that._parsers[series.getTagField()] = null                    })                })            },            _parse: function _parse() {                var that = this,                    parsedData = [];                _each(that.data, function(_, cell) {                    var parserObject = {};                    if (!utils.isObject(cell)) {                        cell && that._incorrectDataMessage();                        return                    }                    _each(that._parsers, function(field, parser) {                        parserObject[field] = parser ? parser(cell[field], field) : cell[field];                        parserObject["original" + field] = cell[field]                    });                    parsedData.push(parserObject)                });                this._data = parsedData            },            _groupMinSlices: function(argumentField, valueField, smallValuesGrouping) {                smallValuesGrouping = smallValuesGrouping || {};                var that = this,                    mode = smallValuesGrouping.mode,                    count = smallValuesGrouping.topCount,                    threshold = smallValuesGrouping.threshold,                    name = smallValuesGrouping.groupName || "others",                    others = {},                    data = that._data.slice(),                    index;                if (!mode || mode === "none")                    return;                others[argumentField] = name + "";                others[valueField] = 0;                data.sort(function(a, b) {                    if (_isDefined(b[valueField]) && _isDefined(a[valueField]))                        return b[valueField] - a[valueField];                    else if (!_isDefined(b[valueField]) && a[valueField])                        return -1;                    else if (!_isDefined(a[valueField]) && b[valueField])                        return 1                });                if (mode === "smallValueThreshold") {                    _each(data, function(i, cell) {                        if (_isDefined(index) || !_isDefined(cell[valueField]))                            return;                        if (threshold > cell[valueField])                            index = i                    });                    groupingValues(data, others, valueField, index)                }                else if (mode === "topN")                    groupingValues(data, others, valueField, count);                others[valueField] && that._data.push(others)            },            _groupData: function() {                var that = this,                    groups = that.groups,                    isPie = groups.length && groups[0].length && (groups[0][0].type === "pie" || groups[0][0].type === "doughnut" || groups[0][0].type === "donut"),                    argumentField,                    valueFields;                if (!isPie)                    return;                _each(groups, function(_, group) {                    _each(group, function(_, series) {                        argumentField = series.getArgumentField();                        valueFields = series.getValueFields();                        if (groups.argumentAxisType === DISCRETE)                            that._groupSameArguments(argumentField, valueFields);                        that._groupMinSlices(argumentField, valueFields[0], series.getOptions().smallValuesGrouping)                    })                })            },            _groupSameArguments: function(argumentField, valueFields) {                var that = this,                    argument,                    dataOfArguments = {},                    parsedData = that._data;                _each(parsedData, function(i, cell) {                    if (!_isDefined(cell[argumentField]) || !_isDefined(cell[valueFields[0]]))                        return;                    argument = cell[argumentField];                    if (_isDefined(dataOfArguments[argument])) {                        var data = parsedData[dataOfArguments[argument]];                        _each(valueFields, function(_, field) {                            data[field] += cell[field];                            cell[field] = undefined;                            cell["original" + field] = undefined                        })                    }                    else                        dataOfArguments[argument] = i                })            },            _getType: function _getType(unit, type) {                if (type === STRING || utils.isString(unit))                    return STRING;                if (type === DATETIME || utils.isDate(unit))                    return DATETIME;                if (utils.isNumber(unit))                    return NUMERIC;                return type            },            _correctAxisType: function _correctAxisType(type, axisType, hasCategories) {                if (type === STRING && (axisType === CONTINUOUS || axisType === LOGARITHMIC))                    this.incidentOccured("E2002");                if (axisType === LOGARITHMIC)                    return LOGARITHMIC;                axisType = (hasCategories || axisType === DISCRETE || type === STRING) && DISCRETE;                return axisType || CONTINUOUS            },            _filterForLogAxis: function(val, field) {                if (val <= 0) {                    this.incidentOccured("E2004", [field]);                    return null                }                return val            },            _createParserUnit: function _createParserUnit(type, filter, ignoreEmptyPoints) {                var that = this,                    parser = type ? parseUtils.getParser(type, undefined, true) : function(unit) {                        return unit                    };                return function(unit, field) {                        var parseUnit = parser(unit);                        if (filter)                            parseUnit = filter.call(that, parseUnit, field);                        parseUnit === null && ignoreEmptyPoints && (parseUnit = undefined);                        if (parseUnit === undefined) {                            that._addSkipFields(field);                            that._validUnit(unit, field, type)                        }                        return parseUnit                    }            },            _validUnit: function _validUnit(unit, field) {                if (!unit)                    return;                if (!utils.isNumber(unit) && !utils.isDate(unit) && !utils.isString(unit)) {                    this.incidentOccured("E2003", [field]);                    return                }                this.incidentOccured("E2004", [field])            },            _sort: function _sort() {                var that = this,                    sortingMethod = that.options.sortingMethod,                    data = that._data,                    groups = that.groups,                    hash = {},                    argumentField = groups.length && groups[0].length && groups[0][0].getArgumentField();                if (utils.isFunction(sortingMethod))                    data.sort(sortingMethod);                else if (that.userArgumentCategories.length) {                    _each(that.userArgumentCategories, function(index, value) {                        hash[value] = index                    });                    data.sort(function sortCat(a, b) {                        a = a[argumentField];                        b = b[argumentField];                        return hash[a] - hash[b]                    })                }                else if (sortingMethod === true && groups.argumentType !== STRING)                    mergeSort(data, argumentField)            },            _addSkipFields: function _addSkipFields(field) {                this._skipFields[field] = (this._skipFields[field] || 0) + 1            },            _incorrectDataMessage: function() {                if (this._erorrDataSource !== true) {                    this._erorrDataSource = true;                    this.incidentOccured("E2001")                }            }        }    })(jQuery, DevExpress);    /*! Module viz-core, file default.js */    (function(DX, undefined) {        var WHITE = "#ffffff",            BLACK = "#000000",            LIGHT_GREY = "#d3d3d3",            GREY_GREEN = "#303030",            RED = "#ff0000";        DX.viz.core.registerTheme({            name: "generic.light",            font: {                color: '#767676',                family: "'Segoe UI', 'Helvetica Neue', 'Trebuchet MS', Verdana",                weight: 400,                size: 12,                cursor: 'default'            },            redrawOnResize: true,            backgroundColor: WHITE,            primaryTitleColor: "#232323",            secondaryTitleColor: "#767676",            axisColor: LIGHT_GREY,            axisLabelColor: "#a8a8a8",            title: {font: {                    family: "'Segoe UI Light', 'Helvetica Neue Light', 'Segoe UI', 'Helvetica Neue', 'Trebuchet MS', Verdana",                    weight: 200                }},            loadingIndicator: {text: "Loading..."},            tooltip: {                enabled: false,                border: {                    width: 1,                    color: LIGHT_GREY,                    dashStyle: 'solid',                    visible: true                },                font: {color: '#232323'},                color: WHITE,                arrowLength: 10,                paddingLeftRight: 18,                paddingTopBottom: 15,                shared: false,                location: 'center',                format: '',                argumentFormat: '',                precision: 0,                argumentPrecision: 0,                percentPrecision: 0,                shadow: {                    opacity: 0.4,                    offsetX: 0,                    offsetY: 4,                    blur: 2,                    color: BLACK                }            },            legend: {                hoverMode: 'includePoints',                verticalAlignment: 'top',                horizontalAlignment: 'right',                position: 'outside',                visible: true,                margin: 10,                markerSize: 12,                border: {                    visible: false,                    width: 1,                    cornerRadius: 0,                    dashStyle: 'solid'                },                paddingLeftRight: 20,                paddingTopBottom: 15,                columnCount: 0,                rowCount: 0,                columnItemSpacing: 20,                rowItemSpacing: 8            },            "chart:common": {                animation: {                    enabled: true,                    duration: 1000,                    easing: 'easeOutCubic',                    maxPointCountSupported: 300                },                commonSeriesSettings: {                    border: {                        visible: false,                        width: 2                    },                    showInLegend: true,                    visible: true,                    hoverMode: 'nearestPoint',                    selectionMode: 'includePoints',                    hoverStyle: {                        hatching: {                            direction: 'right',                            width: 2,                            step: 6,                            opacity: 0.75                        },                        border: {                            visible: false,                            width: 3                        }                    },                    selectionStyle: {                        hatching: {                            direction: 'right',                            width: 2,                            step: 6,                            opacity: 0.5                        },                        border: {                            visible: false,                            width: 3                        }                    },                    valueErrorBar: {                        displayMode: "auto",                        value: 1,                        color: BLACK,                        lineWidth: 2,                        edgeLength: 8                    },                    label: {                        visible: false,                        alignment: 'center',                        rotationAngle: 0,                        horizontalOffset: 0,                        verticalOffset: 0,                        radialOffset: 0,                        format: '',                        argumentFormat: '',                        precision: 0,                        argumentPrecision: 0,                        percentPrecision: 0,                        showForZeroValues: true,                        customizeText: undefined,                        maxLabelCount: undefined,                        position: 'outside',                        font: {color: WHITE},                        border: {                            visible: false,                            width: 1,                            color: LIGHT_GREY,                            dashStyle: 'solid'                        },                        connector: {                            visible: false,                            width: 1                        }                    }                },                seriesSelectionMode: 'single',                pointSelectionMode: 'single',                equalRowHeight: true,                dataPrepareSettings: {                    checkTypeForAllData: false,                    convertToAxisDataType: true,                    sortingMethod: true                },                title: {                    font: {size: 28},                    margin: 10                },                adaptiveLayout: {                    width: 80,                    height: 80,                    keepLabels: true                },                _rtl: {legend: {itemTextPosition: 'left'}},                resolveLabelOverlapping: "none"            },            "chart:common:axis": {                visible: false,                setTicksAtUnitBeginning: true,                valueMarginsEnabled: true,                placeholderSize: null,                logarithmBase: 10,                discreteAxisDivisionMode: 'betweenLabels',                width: 1,                label: {                    visible: true,                    precision: 0,                    format: ""                },                grid: {                    visible: false,                    width: 1                },                minorGrid: {                    visible: false,                    width: 1,                    opacity: 0.3                },                tick: {visible: false},                minorTick: {                    visible: false,                    opacity: 0.3                },                stripStyle: {                    paddingLeftRight: 10,                    paddingTopBottom: 5                },                constantLineStyle: {                    width: 1,                    color: BLACK,                    dashStyle: "solid",                    label: {                        visible: true,                        position: "inside"                    }                }            },            chart: {                commonSeriesSettings: {                    type: 'line',                    stack: 'default',                    point: {                        visible: true,                        symbol: 'circle',                        size: 12,                        border: {                            visible: false,                            width: 1                        },                        hoverMode: 'onlyPoint',                        selectionMode: 'onlyPoint',                        hoverStyle: {                            border: {                                visible: true,                                width: 4                            },                            size: 12                        },                        selectionStyle: {                            border: {                                visible: true,                                width: 4                            },                            size: 12                        }                    },                    scatter: {},                    line: {                        width: 2,                        dashStyle: 'solid',                        hoverStyle: {                            width: 3,                            hatching: {direction: 'none'}                        },                        selectionStyle: {width: 3}                    },                    stackedline: {                        width: 2,                        dashStyle: 'solid',                        hoverStyle: {                            width: 3,                            hatching: {direction: 'none'}                        },                        selectionStyle: {width: 3}                    },                    stackedspline: {                        width: 2,                        dashStyle: 'solid',                        hoverStyle: {                            width: 3,                            hatching: {direction: 'none'}                        },                        selectionStyle: {width: 3}                    },                    fullstackedline: {                        width: 2,                        dashStyle: 'solid',                        hoverStyle: {                            width: 3,                            hatching: {direction: 'none'}                        },                        selectionStyle: {width: 3}                    },                    fullstackedspline: {                        width: 2,                        dashStyle: 'solid',                        hoverStyle: {                            width: 3,                            hatching: {direction: 'none'}                        },                        selectionStyle: {width: 3}                    },                    stepline: {                        width: 2,                        dashStyle: 'solid',                        hoverStyle: {                            width: 3,                            hatching: {direction: 'none'}                        },                        selectionStyle: {width: 3}                    },                    area: {                        point: {visible: false},                        opacity: 0.5                    },                    stackedarea: {                        point: {visible: false},                        opacity: 0.5                    },                    fullstackedarea: {                        point: {visible: false},                        opacity: 0.5                    },                    fullstackedsplinearea: {                        point: {visible: false},                        opacity: 0.5                    },                    steparea: {                        border: {                            visible: true,                            width: 2                        },                        point: {visible: false},                        hoverStyle: {border: {                                visible: true,                                width: 3                            }},                        selectionStyle: {border: {                                visible: true,                                width: 3                            }},                        opacity: 0.5                    },                    spline: {                        width: 2,                        hoverStyle: {                            width: 3,                            hatching: {direction: 'none'}                        },                        selectionStyle: {width: 3}                    },                    splinearea: {                        point: {visible: false},                        opacity: 0.5                    },                    stackedsplinearea: {                        point: {visible: false},                        opacity: 0.5                    },                    bar: {                        cornerRadius: 0,                        point: {                            hoverStyle: {border: {visible: false}},                            selectionStyle: {border: {visible: false}}                        }                    },                    stackedbar: {                        cornerRadius: 0,                        point: {                            hoverStyle: {border: {visible: false}},                            selectionStyle: {border: {visible: false}}                        },                        label: {position: "inside"}                    },                    fullstackedbar: {                        cornerRadius: 0,                        point: {                            hoverStyle: {border: {visible: false}},                            selectionStyle: {border: {visible: false}}                        },                        label: {position: "inside"}                    },                    rangebar: {                        cornerRadius: 0,                        point: {                            hoverStyle: {border: {visible: false}},                            selectionStyle: {border: {visible: false}}                        }                    },                    rangearea: {                        point: {visible: false},                        opacity: 0.5                    },                    rangesplinearea: {                        point: {visible: false},                        opacity: 0.5                    },                    bubble: {                        opacity: 0.5,                        point: {                            hoverStyle: {border: {visible: false}},                            selectionStyle: {border: {visible: false}}                        }                    },                    candlestick: {                        width: 1,                        reduction: {color: RED},                        hoverStyle: {                            width: 3,                            hatching: {direction: 'none'}                        },                        selectionStyle: {width: 3},                        point: {border: {visible: true}}                    },                    stock: {                        width: 1,                        reduction: {color: RED},                        hoverStyle: {                            width: 3,                            hatching: {direction: 'none'}                        },                        selectionStyle: {width: 3},                        point: {border: {visible: true}}                    }                },                crosshair: {                    enabled: false,                    color: '#f78119',                    width: 1,                    dashStyle: 'solid',                    label: {                        visible: false,                        font: {                            color: WHITE,                            size: 12                        }                    },                    verticalLine: {visible: true},                    horizontalLine: {visible: true}                },                commonAxisSettings: {                    multipleAxesSpacing: 5,                    label: {                        overlappingBehavior: {                            mode: 'auto',                            rotationAngle: 90,                            staggeringSpacing: 5                        },                        indentFromAxis: 10                    },                    title: {                        font: {size: 16},                        margin: 6                    },                    constantLineStyle: {                        paddingLeftRight: 10,                        paddingTopBottom: 10                    }                },                horizontalAxis: {                    position: 'bottom',                    axisDivisionFactor: 50,                    label: {alignment: "center"},                    stripStyle: {label: {                            horizontalAlignment: 'center',                            verticalAlignment: 'top'                        }},                    constantLineStyle: {label: {                            horizontalAlignment: 'right',                            verticalAlignment: 'top'                        }},                    constantLines: {}                },                verticalAxis: {                    position: 'left',                    axisDivisionFactor: 30,                    label: {                        alignment: 'right',                        overlappingBehavior: {mode: 'enlargeTickInterval'}                    },                    stripStyle: {label: {                            horizontalAlignment: 'left',                            verticalAlignment: 'center'                        }},                    constantLineStyle: {label: {                            horizontalAlignment: 'left',                            verticalAlignment: 'top'                        }},                    constantLines: {}                },                argumentAxis: {},                valueAxis: {grid: {visible: true}},                commonPaneSettings: {                    backgroundColor: 'none',                    border: {                        color: LIGHT_GREY,                        width: 1,                        visible: false,                        top: true,                        bottom: true,                        left: true,                        right: true,                        dashStyle: 'solid'                    }                },                scrollBar: {                    visible: false,                    offset: 5,                    color: "gray",                    width: 10                },                useAggregation: false,                adjustOnZoom: true,                rotated: false,                zoomingMode: 'none',                scrollingMode: 'none',                synchronizeMultiAxes: true,                equalBarWidth: true,                minBubbleSize: 12,                maxBubbleSize: 0.2            },            pie: {                commonSeriesSettings: {                    type: 'pie',                    pie: {                        border: {                            visible: false,                            width: 2,                            color: WHITE                        },                        hoverStyle: {                            hatching: {                                direction: 'right',                                width: 4,                                step: 10,                                opacity: 0.75                            },                            border: {                                visible: false,                                width: 2                            }                        },                        selectionStyle: {                            hatching: {                                direction: 'right',                                width: 4,                                step: 10,                                opacity: 0.5                            },                            border: {                                visible: false,                                width: 2                            }                        }                    },                    doughnut: {                        innerRadius: 0.5,                        border: {                            visible: false,                            width: 2,                            color: WHITE                        },                        hoverStyle: {                            hatching: {                                direction: 'right',                                width: 4,                                step: 10,                                opacity: 0.75                            },                            border: {                                visible: false,                                width: 2                            }                        },                        selectionStyle: {                            hatching: {                                direction: 'right',                                width: 4,                                step: 10,                                opacity: 0.5                            },                            border: {                                visible: false,                                width: 2                            }                        }                    },                    donut: {                        innerRadius: 0.5,                        border: {                            visible: false,                            width: 2,                            color: WHITE                        },                        hoverStyle: {                            hatching: {                                direction: 'right',                                width: 4,                                step: 10,                                opacity: 0.75                            },                            border: {                                visible: false,                                width: 2                            }                        },                        selectionStyle: {                            hatching: {                                direction: 'right',                                width: 4,                                step: 10,                                opacity: 0.5                            },                            border: {                                visible: false,                                width: 2                            }                        }                    }                },                legend: {                    hoverMode: 'markPoint',                    backgroundColor: "none"                },                adaptiveLayout: {keepLabels: false}            },            pieIE8: {commonSeriesSettings: {                    pie: {                        hoverStyle: {border: {                                visible: true,                                color: WHITE                            }},                        selectionStyle: {border: {                                visible: true,                                color: WHITE                            }}                    },                    donut: {                        hoverStyle: {border: {                                visible: true,                                color: WHITE                            }},                        selectionStyle: {border: {                                visible: true,                                color: WHITE                            }}                    },                    doughnut: {                        hoverStyle: {border: {                                visible: true,                                color: WHITE                            }},                        selectionStyle: {border: {                                visible: true,                                color: WHITE                            }}                    }                }},            gauge: {                scale: {                    majorTick: {                        visible: true,                        length: 5,                        width: 2,                        showCalculatedTicks: true,                        useTicksAutoArrangement: true                    },                    minorTick: {                        visible: false,                        length: 3,                        width: 1,                        showCalculatedTicks: true                    },                    label: {visible: true}                },                rangeContainer: {                    offset: 0,                    width: 5,                    backgroundColor: '#808080'                },                valueIndicators: {                    _default: {color: '#c2c2c2'},                    rangebar: {                        space: 2,                        size: 10,                        color: '#cbc5cf',                        backgroundColor: 'none',                        text: {                            indent: 0,                            font: {                                size: 14,                                color: null                            }                        }                    },                    twocolorneedle: {secondColor: '#e18e92'},                    trianglemarker: {                        space: 2,                        length: 14,                        width: 13,                        color: '#8798a5'                    },                    textcloud: {                        arrowLength: 5,                        horizontalOffset: 6,                        verticalOffset: 3,                        color: '#679ec5',                        text: {font: {                                color: WHITE,                                size: 18                            }}                    }                },                title: {                    layout: {                        horizontalAlignment: 'center',                        verticalAlignment: 'top',                        overlay: 0                    },                    font: {size: 16}                },                subtitle: {font: {size: 14}},                indicator: {                    hasPositiveMeaning: true,                    layout: {                        horizontalAlignment: 'center',                        verticalAlignment: 'bottom',                        overlay: 0                    },                    text: {font: {size: 18}}                },                _circular: {                    scale: {                        orientation: 'outside',                        label: {indentFromTick: 10}                    },                    rangeContainer: {orientation: 'outside'},                    valueIndicatorType: 'rectangleneedle',                    subvalueIndicatorType: 'trianglemarker',                    valueIndicators: {                        _type: 'rectangleneedle',                        _default: {                            offset: 20,                            indentFromCenter: 0,                            width: 2,                            spindleSize: 14,                            spindleGapSize: 10                        },                        triangleneedle: {width: 4},                        twocolorneedle: {                            space: 2,                            secondFraction: 0.4                        },                        rangebar: {offset: 30},                        trianglemarker: {offset: 6},                        textcloud: {offset: -6}                    }                },                _linear: {                    scale: {                        horizontalOrientation: 'right',                        verticalOrientation: 'bottom',                        label: {indentFromTick: -10}                    },                    rangeContainer: {                        horizontalOrientation: 'right',                        verticalOrientation: 'bottom'                    },                    valueIndicatorType: 'rangebar',                    subvalueIndicatorType: 'trianglemarker',                    valueIndicators: {                        _type: 'rectangle',                        _default: {                            offset: 2.5,                            length: 15,                            width: 15                        },                        rectangle: {width: 10},                        rangebar: {                            offset: 10,                            horizontalOrientation: 'right',                            verticalOrientation: 'bottom'                        },                        trianglemarker: {                            offset: -1,                            horizontalOrientation: 'left',                            verticalOrientation: 'top'                        },                        textcloud: {                            offset: -1,                            horizontalOrientation: 'left',                            verticalOrientation: 'top'                        }                    }                }            },            barGauge: {                backgroundColor: '#e0e0e0',                relativeInnerRadius: 0.3,                barSpacing: 4,                label: {                    indent: 20,                    connectorWidth: 2,                    font: {size: 16}                },                title: {                    layout: {                        horizontalAlignment: 'center',                        verticalAlignment: 'top',                        overlay: 0                    },                    font: {size: 16}                },                subtitle: {font: {size: 14}},                indicator: {                    hasPositiveMeaning: true,                    layout: {                        horizontalAlignment: 'center',                        verticalAlignment: 'bottom',                        overlay: 0                    },                    text: {font: {size: 18}}                }            },            rangeSelector: {                scale: {                    showCustomBoundaryTicks: true,                    showMinorTicks: true,                    useTicksAutoArrangement: true,                    setTicksAtUnitBeginning: true,                    label: {                        visible: true,                        topIndent: 7,                        font: {size: 11}                    },                    tick: {                        width: 1,                        color: BLACK,                        opacity: 0.1                    },                    marker: {                        visible: true,                        separatorHeight: 33,                        topIndent: 10,                        textLeftIndent: 7,                        textTopIndent: 11,                        label: {}                    },                    logarithmBase: 10                },                selectedRangeColor: "#606060",                sliderMarker: {                    visible: true,                    paddingTopBottom: 2,                    paddingLeftRight: 4,                    color: '#606060',                    invalidRangeColor: RED,                    font: {                        color: WHITE,                        size: 11                    }                },                sliderHandle: {                    width: 1,                    color: BLACK,                    opacity: 0.2                },                shutter: {opacity: 0.75},                background: {                    color: "#c0bae1",                    visible: true,                    image: {location: 'full'}                },                behavior: {                    snapToTicks: true,                    animationEnabled: true,                    moveSelectedRangeByClick: true,                    manualRangeSelectionEnabled: true,                    allowSlidersSwap: true,                    callSelectedRangeChanged: "onMovingComplete"                },                redrawOnResize: true,                chart: {                    useAggregation: false,                    equalBarWidth: true,                    minBubbleSize: 12,                    maxBubbleSize: 0.2,                    topIndent: 0.1,                    bottomIndent: 0,                    valueAxis: {                        inverted: false,                        logarithmBase: 10                    },                    commonSeriesSettings: {                        type: "area",                        point: {visible: false}                    }                }            },            map: {                background: {                    borderWidth: 1,                    borderColor: '#cacaca'                },                areaSettings: {                    borderWidth: 1,                    borderColor: WHITE,                    color: '#d2d2d2',                    hoveredBorderColor: GREY_GREEN,                    selectedBorderWidth: 2,                    selectedBorderColor: GREY_GREEN,                    label: {                        enabled: false,                        stroke: WHITE,                        'stroke-width': 2,                        'stroke-opacity': 0.5,                        font: {                            color: '#2b2b2b',                            size: 16,                            opacity: 0.5                        }                    }                },                markerSettings: {                    label: {                        enabled: true,                        stroke: WHITE,                        'stroke-width': 1,                        'stroke-opacity': 0.5,                        font: {                            color: '#2b2b2b',                            size: 12                        }                    },                    _dot: {                        borderWidth: 2,                        borderColor: WHITE,                        color: '#ba4d51',                        size: 8,                        selectedStep: 2,                        backStep: 18,                        backColor: WHITE,                        backOpacity: 0.32,                        shadow: true                    },                    _bubble: {                        minSize: 20,                        maxSize: 50,                        color: '#ba4d51',                        hoveredBorderWidth: 1,                        hoveredBorderColor: GREY_GREEN,                        selectedBorderWidth: 2,                        selectedBorderColor: GREY_GREEN                    },                    _pie: {                        size: 50,                        hoveredBorderWidth: 1,                        hoveredBorderColor: GREY_GREEN,                        selectedBorderWidth: 2,                        selectedBorderColor: GREY_GREEN                    },                    _image: {size: 20}                },                legend: {                    verticalAlignment: 'bottom',                    horizontalAlignment: 'right',                    position: 'inside',                    backgroundOpacity: 0.65,                    border: {                        visible: true,                        color: '#cacaca'                    },                    paddingLeftRight: 16,                    paddingTopBottom: 12,                    markerColor: '#ba4d51'                },                controlBar: {                    borderColor: '#5d5d5d',                    borderWidth: 3,                    color: WHITE,                    margin: 20,                    opacity: 0.3                },                _rtl: {legend: {itemTextPosition: 'left'}}            },            sparkline: {                lineColor: '#666666',                lineWidth: 2,                areaOpacity: 0.2,                minColor: '#e8c267',                maxColor: '#e55253',                barPositiveColor: '#a9a9a9',                barNegativeColor: '#d7d7d7',                winColor: '#a9a9a9',                lossColor: '#d7d7d7',                firstLastColor: '#666666',                pointSymbol: 'circle',                pointColor: WHITE,                pointSize: 4,                type: "line",                argumentField: "arg",                valueField: "val",                winlossThreshold: 0,                showFirstLast: true,                showMinMax: false,                tooltip: {enabled: true}            },            bullet: {                color: '#e8c267',                targetColor: '#666666',                targetWidth: 4,                showTarget: true,                showZeroLevel: true,                tooltip: {enabled: true}            },            polar: {                commonSeriesSettings: {                    type: 'scatter',                    closed: true,                    point: {                        visible: true,                        symbol: 'circle',                        size: 12,                        border: {                            visible: false,                            width: 1                        },                        hoverMode: 'onlyPoint',                        selectionMode: 'onlyPoint',                        hoverStyle: {                            border: {                                visible: true,                                width: 4                            },                            size: 12                        },                        selectionStyle: {                            border: {                                visible: true,                                width: 4                            },                            size: 12                        }                    },                    scatter: {},                    line: {                        width: 2,                        dashStyle: 'solid',                        hoverStyle: {                            width: 3,                            hatching: {direction: 'none'}                        },                        selectionStyle: {width: 3}                    },                    area: {                        point: {visible: false},                        opacity: 0.5                    },                    stackedline: {width: 2},                    bar: {opacity: 0.8},                    stackedbar: {opacity: 0.8}                },                adaptiveLayout: {                    width: 170,                    height: 170,                    keepLabels: true                },                equalBarWidth: true,                commonAxisSettings: {                    visible: true,                    label: {                        overlappingBehavior: {mode: 'enlargeTickInterval'},                        indentFromAxis: 5                    },                    grid: {visible: true},                    minorGrid: {visible: true},                    tick: {visible: true},                    title: {                        font: {size: 16},                        margin: 10                    }                },                argumentAxis: {                    startAngle: 0,                    firstPointOnStartAngle: false,                    period: undefined                },                valueAxis: {tick: {visible: false}},                horizontalAxis: {                    position: 'top',                    axisDivisionFactor: 50,                    label: {alignment: "center"}                },                verticalAxis: {                    position: 'top',                    axisDivisionFactor: 30,                    label: {alignment: "right"}                }            }        });        DX.viz.core.registerTheme({            name: "generic.dark",            font: {color: '#808080'},            backgroundColor: GREY_GREEN,            primaryTitleColor: "#dbdbdb",            secondaryTitleColor: "#a3a3a3",            axisColor: "#555555",            axisLabelColor: "#707070",            tooltip: {                color: '#2b2b2b',                border: {color: '#494949'},                font: {color: '#929292'}            },            "chart:common": {commonSeriesSettings: {                    label: {border: {color: '#494949'}},                    valueErrorBar: {color: WHITE}                }},            "chart:common:axis": {constantLineStyle: {color: WHITE}},            chart: {                crosshair: {color: '#515151'},                commonPaneSettings: {border: {color: '#494949'}}            },            pieIE8: {commonSeriesSettings: {                    pie: {                        hoverStyle: {border: {color: '#2b2b2b'}},                        selectionStyle: {border: {color: '#2b2b2b'}}                    },                    donut: {                        hoverStyle: {border: {color: '#2b2b2b'}},                        selectionStyle: {border: {color: '#2b2b2b'}}                    },                    doughnut: {                        hoverStyle: {border: {color: '#2b2b2b'}},                        selectionStyle: {border: {color: '#2b2b2b'}}                    }                }},            gauge: {                rangeContainer: {backgroundColor: '#b5b5b5'},                valueIndicators: {                    _default: {color: '#b5b5b5'},                    rangebar: {color: '#84788b'},                    twocolorneedle: {secondColor: '#ba544d'},                    trianglemarker: {color: '#b7918f'},                    textcloud: {color: '#ba544d'}                }            },            barGauge: {backgroundColor: "#3c3c3c"},            rangeSelector: {                selectedRangeColor: '#b5b5b5',                scale: {tick: {                        color: WHITE,                        opacity: 0.05                    }},                sliderMarker: {                    color: '#b5b5b5',                    font: {color: GREY_GREEN}                },                sliderHandle: {                    color: WHITE,                    opacity: 0.2                },                shutter: {                    color: '#2b2b2b',                    opacity: 0.9                }            },            map: {                background: {borderColor: '#3f3f3f'},                areaSettings: {                    borderColor: GREY_GREEN,                    color: '#686868',                    hoveredBorderColor: WHITE,                    selectedBorderColor: WHITE,                    label: {                        stroke: BLACK,                        font: {color: WHITE}                    }                },                markerSettings: {                    label: {                        stroke: BLACK,                        font: {color: WHITE}                    },                    _bubble: {                        hoveredBorderColor: WHITE,                        selectedBorderColor: WHITE                    },                    _pie: {                        hoveredBorderColor: WHITE,                        selectedBorderColor: WHITE                    }                },                legend: {                    border: {color: '#3f3f3f'},                    font: {color: WHITE}                },                controlBar: {                    borderColor: '#c7c7c7',                    color: GREY_GREEN                }            },            sparkline: {                lineColor: '#c7c7c7',                firstLastColor: '#c7c7c7',                barPositiveColor: '#b8b8b8',                barNegativeColor: '#8e8e8e',                winColor: '#b8b8b8',                lossColor: '#8e8e8e',                pointColor: GREY_GREEN            },            bullet: {targetColor: '#8e8e8e'}        }, "generic.light");        DX.viz.core.currentTheme("generic.light");        DX.viz.core.registerThemeAlias("desktop.light", "generic.light");        DX.viz.core.registerThemeAlias("desktop.dark", "generic.dark")    })(DevExpress);    /*! Module viz-core, file android.js */    (function(DX) {        var ANDROID5_LIGHT = "android5.light",            registerThemeAlias = DX.viz.core.registerThemeAlias;        DX.viz.core.registerTheme({            name: ANDROID5_LIGHT,            backgroundColor: "#ffffff",            primaryTitleColor: "#232323",            secondaryTitleColor: "#767676",            axisColor: "#d3d3d3",            axisLabelColor: "#a8a8a8",            tooltip: {                color: "#e8e8e8",                font: {color: "#808080"}            },            legend: {font: {color: "#000000"}},            pieIE8: {commonSeriesSettings: {                    pie: {                        hoverStyle: {border: {color: '#e8e8e8'}},                        selectionStyle: {border: {color: '#e8e8e8'}}                    },                    donut: {                        hoverStyle: {border: {color: '#e8e8e8'}},                        selectionStyle: {border: {color: '#e8e8e8'}}                    },                    doughnut: {                        hoverStyle: {border: {color: '#e8e8e8'}},                        selectionStyle: {border: {color: '#e8e8e8'}}                    }                }}        }, "generic.light");        registerThemeAlias("android", ANDROID5_LIGHT);        registerThemeAlias("android.holo-dark", ANDROID5_LIGHT);        registerThemeAlias("android.holo-light", ANDROID5_LIGHT);        registerThemeAlias("android.dark", ANDROID5_LIGHT);        registerThemeAlias("android.light", ANDROID5_LIGHT)    })(DevExpress);    /*! Module viz-core, file ios.js */    (function(DX) {        var IOS7_DEFAULT = "ios7.default",            core = DX.viz.core;        core.registerTheme({            name: IOS7_DEFAULT,            backgroundColor: "#ffffff",            primaryTitleColor: "#000000",            secondaryTitleColor: "#767676",            axisColor: "#ececec",            axisLabelColor: "#b8b8b8",            legend: {font: {color: '#000000'}},            tooltip: {font: {color: '#808080'}},            "chart:common": {commonSeriesSettings: {label: {border: {color: '#d3d3d3'}}}},            chart: {commonPaneSettings: {border: {color: '#d3d3d3'}}}        }, "generic.light");        core.registerThemeAlias("ios", IOS7_DEFAULT)    })(DevExpress);    /*! Module viz-core, file win8.js */    (function(DX) {        var core = DX.viz.core,            registerTheme = core.registerTheme,            registerThemeSchemeAlias = core.registerThemeSchemeAlias,            BLACK = "#000000",            WHITE = "#ffffff";        registerTheme({            name: "win8.black",            backgroundColor: BLACK,            primaryTitleColor: WHITE,            secondaryTitleColor: "#d8d8d8",            axisColor: "#4c4c4c",            axisLabelColor: "#a0a0a0",            title: {font: {color: WHITE}},            legend: {font: {color: WHITE}},            tooltip: {                color: BLACK,                font: {color: WHITE}            },            "chart:common": {commonSeriesSettings: {label: {border: {color: '#454545'}}}},            chart: {commonPaneSettings: {border: {color: '#454545'}}},            pieIE8: {commonSeriesSettings: {                    pie: {                        hoverStyle: {border: {color: BLACK}},                        selectionStyle: {border: {color: BLACK}}                    },                    donut: {                        hoverStyle: {border: {color: BLACK}},                        selectionStyle: {border: {color: BLACK}}                    },                    doughnut: {                        hoverStyle: {border: {color: BLACK}},                        selectionStyle: {border: {color: BLACK}}                    }                }},            barGauge: {backgroundColor: "#2b3036"},            rangeSelector: {scale: {tick: {opacity: 0.15}}}        }, "generic.dark");        registerTheme({            name: "win8.white",            backgroundColor: WHITE,            primaryTitleColor: BLACK,            secondaryTitleColor: "#767676",            axisColor: "#ececec",            axisLabelColor: "#b8b8b8",            title: {font: {color: '#808080'}},            legend: {font: {color: BLACK}},            tooltip: {font: {color: '#808080'}}        }, "generic.light");        registerThemeSchemeAlias("win8.dark", "win8.black");        registerThemeSchemeAlias("win8.light", "win8.white")    })(DevExpress);    /*! Module viz-core, file themeManager.js */    (function($, DX, undefined) {        var viz = DX.viz,            Palette = viz.core.Palette,            utils = DX.utils,            _findTheme = DX.viz.core.findTheme,            _isString = utils.isString,            _isDefined = utils.isDefined,            HOVER_COLOR_HIGHLIGHTING = 20,            HIGHLIGHTING_STEP = 50,            FONT = "font",            COMMON_AXIS_SETTINGS = "commonAxisSettings",            PIE_FONT_FIELDS = ["legend." + FONT, "title." + FONT, "tooltip." + FONT, "loadingIndicator." + FONT, "commonSeriesSettings.label." + FONT],            POLAR_FONT_FIELDS = PIE_FONT_FIELDS.concat([COMMON_AXIS_SETTINGS + ".label." + FONT, COMMON_AXIS_SETTINGS + ".title." + FONT]),            CHART_FONT_FIELDS = POLAR_FONT_FIELDS.concat(["crosshair.label." + FONT]),            chartToFontFieldsMap = {                pie: PIE_FONT_FIELDS,                chart: CHART_FONT_FIELDS,                polar: POLAR_FONT_FIELDS            };        viz.charts = viz.charts || {};        viz.charts.ThemeManager = viz.core.BaseThemeManager.inherit(function() {            var ctor = function(options, themeGroupName) {                    var that = this,                        themeObj;                    that.callBase.apply(that, arguments);                    options = options || {};                    that._userOptions = options;                    that._mergeAxisTitleOptions = [];                    that._themeSection = themeGroupName;                    that._fontFields = chartToFontFieldsMap[themeGroupName];                    that._IE8 = DX.browser.msie && DX.browser.version < 9;                    themeObj = options.theme && _findTheme(_isString(options.theme) ? options.theme : options.theme.name) || {};                    that.palette = new Palette(options.palette, {                        stepHighlight: HIGHLIGHTING_STEP,                        theme: themeObj.name                    });                    that._callback = $.noop                };            var dispose = function() {                    var that = this;                    that.palette.dispose();                    that.palette = that._userOptions = that._mergedSettings = null;                    return that.callBase.apply(that, arguments)                };            var resetPalette = function() {                    this.palette.reset()                };            var updatePalette = function(palette) {                    this.palette = new Palette(palette || this._theme.defaultPalette, {                        stepHighlight: HIGHLIGHTING_STEP,                        theme: this.themeName                    })                };            var processTitleOptions = function(options) {                    return _isString(options) ? {text: options} : options                };            var processAxisOptions = function(axisOptions) {                    if (!axisOptions)                        return;                    axisOptions = $.extend(true, {}, axisOptions);                    axisOptions.title = processTitleOptions(axisOptions.title);                    if (axisOptions.type === "logarithmic" && axisOptions.logarithmBase <= 0 || axisOptions.logarithmBase && !$.isNumeric(axisOptions.logarithmBase)) {                        axisOptions.logarithmBase = undefined;                        axisOptions.logarithmBaseError = true                    }                    if (axisOptions.label) {                        if (axisOptions.label.alignment)                            axisOptions.label["userAlignment"] = true;                        if (_isString(axisOptions.label.overlappingBehavior))                            axisOptions.label.overlappingBehavior = {mode: axisOptions.label.overlappingBehavior};                        if (!axisOptions.label.overlappingBehavior || !axisOptions.label.overlappingBehavior.mode)                            axisOptions.label.overlappingBehavior = axisOptions.label.overlappingBehavior || {}                    }                    return axisOptions                };            var applyParticularAxisOptions = function(name, userOptions, rotated) {                    var theme = this._theme,                        position = !(rotated ^ name === "valueAxis") ? "horizontalAxis" : "verticalAxis",                        commonAxisSettings = processAxisOptions(this._userOptions["commonAxisSettings"], name);                    return $.extend(true, {}, theme.commonAxisSettings, theme[position], theme[name], commonAxisSettings, processAxisOptions(userOptions, name))                };            var mergeOptions = function(name, userOptions) {                    userOptions = userOptions || this._userOptions[name];                    var theme = this._theme[name],                        result = this._mergedSettings[name];                    if (result)                        return result;                    if ($.isPlainObject(theme) && $.isPlainObject(userOptions))                        result = $.extend(true, {}, theme, userOptions);                    else                        result = _isDefined(userOptions) ? userOptions : theme;                    this._mergedSettings[name] = result;                    return result                };            var applyParticularTheme = {                    base: mergeOptions,                    argumentAxis: applyParticularAxisOptions,                    valueAxisRangeSelector: function() {                        return mergeOptions.call(this, "valueAxis")                    },                    valueAxis: applyParticularAxisOptions,                    title: function(name) {                        var userOptions = processTitleOptions(this._userOptions[name]);                        return mergeOptions.call(this, name, userOptions)                    },                    series: function(name, userOptions) {                        var theme = this._theme,                            userCommonSettings = this._userOptions.commonSeriesSettings || {},                            themeCommonSettings = theme.commonSeriesSettings,                            type = ((userOptions.type || userCommonSettings.type || themeCommonSettings.type) + "").toLowerCase(),                            settings,                            palette = this.palette,                            isBar = ~type.indexOf("bar"),                            isLine = ~type.indexOf("line"),                            isArea = ~type.indexOf("area"),                            isBubble = type === "bubble",                            mainSeriesColor,                            resolveLabelsOverlapping = this.getOptions("resolveLabelsOverlapping"),                            resolveLabelOverlapping = this.getOptions("resolveLabelOverlapping"),                            containerBackgroundColor = this.getOptions("containerBackgroundColor"),                            seriesVisibility;                        if (isBar || isBubble) {                            userOptions = $.extend(true, {}, userCommonSettings, userCommonSettings[type], userOptions);                            seriesVisibility = userOptions.visible;                            userCommonSettings = {type: {}};                            $.extend(true, userOptions, userOptions.point);                            userOptions.visible = seriesVisibility                        }                        settings = $.extend(true, {}, themeCommonSettings, themeCommonSettings[type], userCommonSettings, userCommonSettings[type], userOptions);                        settings.type = type;                        settings.widgetType = this._themeSection.split(".").slice(-1)[0];                        settings.containerBackgroundColor = containerBackgroundColor;                        if (settings.widgetType !== "pie")                            mainSeriesColor = settings.color || palette.getNextColor();                        else                            mainSeriesColor = function() {                                return palette.getNextColor()                            };                        settings.mainSeriesColor = mainSeriesColor;                        settings._IE8 = this._IE8;                        settings.resolveLabelOverlapping = resolveLabelOverlapping;                        settings.resolveLabelsOverlapping = resolveLabelsOverlapping;                        if (settings.label && (isLine || isArea && type !== "rangearea" || type === "scatter"))                            settings.label.position = "outside";                        return settings                    },                    pieSegment: function(name, seriesSettings, segmentSettings) {                        var settings = $.extend(true, {}, seriesSettings, segmentSettings),                            mainColor = new DX.Color(settings.color || this.palette.getNextColor());                        settings.color = mainColor.toHex();                        settings.border.color = settings.border.color || mainColor.toHex();                        settings.hoverStyle.color = settings.hoverStyle.color || this._IE8 && mainColor.highlight(HOVER_COLOR_HIGHLIGHTING) || mainColor.toHex();                        settings.hoverStyle.border.color = settings.hoverStyle.border.color || mainColor.toHex();                        settings.selectionStyle.color = settings.selectionStyle.color || this._IE8 && mainColor.highlight(HOVER_COLOR_HIGHLIGHTING) || mainColor.toHex();                        settings.selectionStyle.border.color = settings.selectionStyle.border.color || mainColor.toHex();                        return settings                    },                    animation: function(name) {                        var userOptions = this._userOptions[name];                        userOptions = $.isPlainObject(userOptions) ? userOptions : _isDefined(userOptions) ? {enabled: !!userOptions} : {};                        return mergeOptions.call(this, name, userOptions)                    }                };            return {                    _themeSection: "chart",                    ctor: ctor,                    dispose: dispose,                    resetPalette: resetPalette,                    getOptions: function(name) {                        return (applyParticularTheme[name] || applyParticularTheme.base).apply(this, arguments)                    },                    refresh: function() {                        this._mergedSettings = {};                        return this.callBase.apply(this, arguments)                    },                    resetOptions: function(name) {                        this._mergedSettings[name] = null                    },                    update: function(options) {                        this._userOptions = options                    },                    updatePalette: updatePalette                }        }())    })(jQuery, DevExpress);    /*! Module viz-core, file factory.js */    (function($, DX) {        var viz = DX.viz,            charts = viz.charts,            series = charts.series;        charts.factory = function() {            var createSeriesFamily = function(options) {                    return new series.SeriesFamily(options)                };            var createThemeManager = function(options, groupName) {                    return new charts.ThemeManager(options, groupName)                };            var createTracker = function(options, name) {                    return name === "dxPieChart" ? new charts.PieTracker(options) : new charts.ChartTracker(options)                };            var createTitle = function(renderer, options, group) {                    return new charts.ChartTitle(renderer, options, group)                };            var createChartLayoutManager = function(options) {                    return new charts.LayoutManager(options)                };            var createCrosshair = function(renderer, options, params, group) {                    return new charts.Crosshair(renderer, options, params, group)                };            return {                    createSeriesFamily: createSeriesFamily,                    createThemeManager: createThemeManager,                    createTracker: createTracker,                    createChartLayoutManager: createChartLayoutManager,                    createTitle: createTitle,                    createCrosshair: createCrosshair,                    createScrollBar: function(renderer, group) {                        return new DevExpress.viz.charts.ScrollBar(renderer, group)                    }                }        }()    })(jQuery, DevExpress);    /*! Module viz-core, file baseWidget.js */    (function(DX, $, undefined) {        var core = DX.viz.core,            _windowResizeCallbacks = DX.utils.windowResizeCallbacks,            _Number = Number,            _stringFormat = DX.utils.stringFormat,            _isFunction = DX.utils.isFunction,            _parseScalar = core.utils.parseScalar,            OPTION_RTL_ENABLED = "rtlEnabled",            OPTION_LOADING_INDICATOR = "loadingIndicator";        function defaultIncidentOccured(options) {            var args = [options.id];            args.push.apply(args, options.args || []);            DX.log.apply(null, args)        }        function getTrue() {            return true        }        function getFalse() {            return false        }        function areCanvasesDifferent(canvas1, canvas2) {            return !(canvas1.width === canvas2.width && canvas1.height === canvas2.height && canvas1.left === canvas2.left && canvas1.top === canvas2.top && canvas1.right === canvas2.right && canvas1.bottom === canvas2.bottom)        }        function createResizeHandler(callback) {            var $window = $(window),                width,                height,                timeout;            handler.dispose = function() {                clearTimeout(timeout);                return this            };            return handler;            function handler() {                width = $window.width();                height = $window.height();                clearTimeout(timeout);                timeout = setTimeout(trigger, 100)            }            function trigger() {                $window.width() === width && $window.height() === height && callback()            }        }        core.DEBUG_createResizeHandler = createResizeHandler;        core.BaseWidget = DX.DOMComponent.inherit({            _eventsMap: {                onIncidentOccurred: {                    name: 'incidentOccured',                    deprecated: 'incidentOccured',                    deprecatedContext: $.noop,                    deprecatedArgs: function(arg) {                        return [arg.target]                    }                },                onDrawn: {                    name: 'drawn',                    deprecated: 'drawn',                    deprecatedContext: $.noop,                    deprecatedArgs: function(arg) {                        return [arg.component]                    }                },                incidentOccured: {newName: 'onIncidentOccurred'},                drawn: {newName: 'onDrawn'},                onTooltipShown: {name: 'tooltipShown'},                onTooltipHidden: {name: 'tooltipHidden'},                onLoadingIndicatorReady: {name: "loadingIndicatorReady"}            },            _setDeprecatedOptions: function() {                this.callBase.apply(this, arguments);                $.extend(this._deprecatedOptions, {                    incidentOccured: {                        since: '14.2',                        message: "Use the 'onIncidentOccurred' option instead"                    },                    drawn: {                        since: '14.2',                        message: "Use the 'onDrawn' option instead"                    }                })            },            _setDefaultOptions: function() {                this.callBase.apply(this, arguments);                this.option({incidentOccured: defaultIncidentOccured})            },            _init: function() {                var that = this;                that.callBase.apply(that, arguments);                that._themeManager = that._createThemeManager();                that._themeManager.setCallback(function() {                    that._handleThemeOptions()                });                that._renderer = new DX.viz.renderers.Renderer({cssClass: that._rootClassPrefix + " " + that._rootClass});                that._initIncidentOccured();                that._renderVisibilityChange();                that._initEventTrigger();                that._initTooltip();                that._initCore();                that._setThemeAndRtl();                that._initSize();                that._setupResizeHandler();                that._initLoadingIndicator()            },            _initTooltip: function() {                this._tooltip = new core.Tooltip({                    cssClass: this._rootClassPrefix + "-tooltip",                    eventTrigger: this._eventTrigger                })            },            _getAnimationOptions: $.noop,            _initSize: function() {                var canvas = null;                if (this._isContainerVisible()) {                    canvas = this._calculateCanvas();                    if (canvas)                        this._updateSize(canvas, true)                }                if (!canvas)                    this._setHiddenState()            },            _setHiddenState: function() {                var that = this;                that._clean = that._render = $.noop;                that._canvas = null;                that._incidentOccured('W2001', [that.NAME])            },            _setVisibleState: function() {                delete this._clean;                delete this._render            },            _updateSize: function(canvas, isDrawRequired) {                var that = this;                that._renderer.resize(canvas.width, canvas.height);                isDrawRequired && that._renderer.draw(that._$element[0]);                that._canvas = canvas;                that._applySize();                that._updateLoadingIndicatorCanvas()            },            _updateCanvasAndResize: function() {                var that = this,                    canvas = that._calculateCanvas();                if (canvas)                    if (areCanvasesDifferent(canvas, that._canvas) || that.__forceRender) {                        that._updateSize(canvas);                        that._resize()                    }                return canvas            },            render: function() {                var that = this,                    canvas,                    visible = that._isContainerVisible();                if (that._canvas) {                    if (visible)                        canvas = that._updateCanvasAndResize();                    if (!canvas) {                        that._clean();                        that._renderer.clear();                        that._setHiddenState()                    }                }                else {                    if (visible) {                        canvas = that._calculateCanvas();                        if (canvas) {                            that._setVisibleState();                            that._updateSize(canvas, true);                            that._render()                        }                    }                    if (!canvas)                        that._setHiddenState()                }            },            _handleResize: function() {                if (this._canvas)                    this._updateCanvasAndResize()            },            _dispose: function() {                var that = this;                that.callBase.apply(that, arguments);                that._removeResizeHandler();                that._eventTrigger.dispose();                that._disposeCore();                that._disposeLoadingIndicator();                that._renderer.dispose();                that._tooltip && that._tooltip.dispose();                that._themeManager.dispose();                that._themeManager = that._renderer = that._eventTrigger = that._tooltip = null            },            _initEventTrigger: function() {                var that = this;                that._eventTrigger = createEventTrigger(that._eventsMap, function(name, deprecatedName) {                    var data = {callback: that._createActionByOption(name)};                    that._suppressDeprecatedWarnings();                    if (that.option(name) === undefined)                        data.deprecatedCallback = that.option(deprecatedName);                    that._resumeDeprecatedWarnings();                    return data                })            },            _isContainerVisible: function() {                return this._$element.is(':visible')            },            _calculateCanvas: function() {                var that = this,                    size = that.option('size') || {},                    margin = that.option('margin') || {},                    defaultCanvas = that._getDefaultSize() || {},                    canvas = {};                if (size.width <= 0 || size.height <= 0)                    canvas = null;                else {                    canvas.width = size.width > 0 ? _Number(size.width) : that._$element.width() || defaultCanvas.width;                    canvas.height = size.height > 0 ? _Number(size.height) : that._$element.height() || defaultCanvas.height;                    canvas.left = margin.left > 0 ? _Number(margin.left) : defaultCanvas.left || 0;                    canvas.top = margin.top > 0 ? _Number(margin.top) : defaultCanvas.top || 0;                    canvas.right = margin.right > 0 ? _Number(margin.right) : defaultCanvas.right || 0;                    canvas.bottom = margin.bottom > 0 ? _Number(margin.bottom) : defaultCanvas.bottom || 0;                    canvas = canvas.width - canvas.left - canvas.right > 0 && canvas.height - canvas.top - canvas.bottom > 0 ? canvas : null                }                return canvas            },            DEBUG_getCanvas: function() {                return this._canvas            },            DEBUG_getEventTrigger: function() {                return this._eventTrigger            },            _getOption: function(name, isScalar) {                var theme = this._themeManager.theme(name),                    option = this.option(name);                return isScalar ? option !== undefined ? option : theme : $.extend(true, {}, theme, option)            },            _setupResizeHandler: function() {                if (_parseScalar(this._getOption('redrawOnResize', true), true))                    this._addResizeHandler();                else                    this._removeResizeHandler()            },            _addResizeHandler: function() {                var that = this;                if (!that._resizeHandler) {                    that._resizeHandler = createResizeHandler(function() {                        that._handleResize()                    });                    _windowResizeCallbacks.add(that._resizeHandler)                }            },            _removeResizeHandler: function() {                if (this._resizeHandler) {                    _windowResizeCallbacks.remove(this._resizeHandler);                    this._resizeHandler.dispose();                    this._resizeHandler = null                }            },            _optionChanged: function(args) {                var that = this;                if (!that._eventTrigger.update(args.name))                    switch (args.name) {                        case'size':                        case'margin':                            that.render();                            break;                        case'redrawOnResize':                            that._setupResizeHandler();                            break;                        case OPTION_LOADING_INDICATOR:                            that._handleLoadingIndicatorOptionChanged();                            break;                        case"theme":                        case OPTION_RTL_ENABLED:                            that._setThemeAndRtl();                            break;                        case"encodeHtml":                        case"pathModified":                            that._handleThemeOptions();                            break;                        case"tooltip":                            that._setTooltipOptions();                            break;                        default:                            that._invalidate();                            that.callBase.apply(that, arguments)                    }            },            _handleThemeOptions: function() {                var that = this,                    options = {                        rtl: that.option(OPTION_RTL_ENABLED),                        encodeHtml: that.option("encodeHtml"),                        pathModified: that.option("pathModified"),                        animation: that._getAnimationOptions()                    };                that._renderer.setOptions(options);                that._setTooltipRendererOptions(options);                that._setTooltipOptions();                that._updateLoadingIndicatorOptions();                that._handleThemeOptionsCore()            },            _handleThemeOptionsCore: function() {                this._initialized && this._refresh()            },            _visibilityChanged: function() {                this.render()            },            _initIncidentOccured: function() {                var that = this;                that._incidentOccured = function(errorOrWarningId, options) {                    that._eventTrigger('incidentOccured', {target: {                            id: errorOrWarningId,                            type: errorOrWarningId[0] === 'E' ? 'error' : 'warning',                            args: options,                            text: _stringFormat.apply(null, [DX.ERROR_MESSAGES[errorOrWarningId]].concat(options ? options.slice(0) : [])),                            widget: that.NAME,                            version: DX.VERSION                        }})                }            },            _setThemeAndRtl: function() {                this._themeManager.setTheme(this.option("theme"), this.option(OPTION_RTL_ENABLED))            },            _setTooltipRendererOptions: function(options) {                this._tooltip.setRendererOptions(options)            },            _setTooltipOptions: function() {                this._tooltip.update(this._getOption("tooltip"))            },            _initLoadingIndicator: function() {                if (this._getOption(OPTION_LOADING_INDICATOR).show) {                    this.showLoadingIndicator();                    this._loadIndicator.forceShow()                }            },            _handleLoadingIndicatorOptionChanged: function() {                var that = this;                if (!that._skipOptionChanged) {                    that._updateLoadingIndicatorOptions();                    if (that._getOption(OPTION_LOADING_INDICATOR).show)                        that.showLoadingIndicator();                    else                        that.hideLoadingIndicator()                }            },            _updateLoadingIndicatorCanvas: function() {                this._loadIndicator && this._canvas && this._loadIndicator.applyCanvas(this._canvas)            },            _updateLoadingIndicatorOptions: function() {                this._loadIndicator && this._loadIndicator.applyOptions(this._getOption(OPTION_LOADING_INDICATOR))            },            _endLoading: function(complete) {                if (this._loadIndicator) {                    this._resetIsReady();                    this._loadIndicator.endLoading(complete)                }                else                    complete && complete()            },            _reappendLoadingIndicator: function() {                this._loadIndicator && this._loadIndicator.toForeground()            },            _disposeLoadingIndicator: function() {                if (this._loadIndicator) {                    this._loadIndicator.dispose();                    this._loadIndicator = null                }            },            _scheduleLoadingIndicatorHiding: function() {                this._loadIndicator && this._loadIndicator.scheduleHiding()            },            _fulfillLoadingIndicatorHiding: function() {                this._loadIndicator && this._loadIndicator.fulfillHiding() && this._toggleLoadingIndicatorState(false)            },            _normalizeHtml: function(html) {                var re = /xmlns="[\s\S]*?"/gi,                    first = true;                html = html.replace(re, function(match) {                    if (!first)                        return "";                    first = false;                    return match                });                return html.replace(/xmlns:NS1="[\s\S]*?"/gi, "").replace(/NS1:xmlns:xlink="([\s\S]*?)"/gi, 'xmlns:xlink="$1"')            },            _dataIsReady: getTrue,            _resetIsReady: function() {                this.isReady = getFalse            },            _drawn: function() {                var that = this;                that.isReady = getFalse;                that._dataIsReady() && that._renderer.onEndAnimation(function() {                    that.isReady = getTrue                });                that._eventTrigger('drawn', {})            },            _toggleLoadingIndicatorState: function(state) {                if (Boolean(this._getOption(OPTION_LOADING_INDICATOR).show) !== state) {                    this._skipOptionChanged = true;                    this.option(OPTION_LOADING_INDICATOR, {show: state});                    this._skipOptionChanged = false                }            },            _handleLoadingIndicatorShown: function() {                this._tooltip.hide()            },            showLoadingIndicator: function() {                var that = this;                if (!that._loadIndicator) {                    that._loadIndicator = new core.LoadIndicator({                        container: that._$element,                        eventTrigger: that._eventTrigger                    });                    that._updateLoadingIndicatorCanvas();                    that._updateLoadingIndicatorOptions()                }                that._toggleLoadingIndicatorState(true);                that._loadIndicator.show();                that._handleLoadingIndicatorShown()            },            hideLoadingIndicator: function() {                var that = this;                if (that._loadIndicator) {                    that._toggleLoadingIndicatorState(false);                    that._loadIndicator.hide()                }            },            svg: function() {                return this._normalizeHtml(this._renderer.svg())            },            isReady: getFalse        });        function createEventTrigger(eventsMap, callbackGetter) {            var triggers = {},                timers = {};            $.each(eventsMap, function(name, info) {                if (info.name)                    createItem(name)            });            trigger.update = function(name) {                var eventInfo = eventsMap[name];                if (eventInfo)                    createItem(eventInfo.newName || name);                return !!eventInfo            };            trigger.dispose = function() {                $.each(timers, function(timer) {                    clearTimeout(timer)                });                eventsMap = callbackGetter = triggers = timers = null            };            return trigger;            function trigger(eventName, arg, complete) {                triggers[eventName](arg, complete)            }            function createItem(name) {                var eventInfo = eventsMap[name],                    data = callbackGetter(name, eventInfo.deprecated);                triggers[eventInfo.name] = createCallback(data.callback, _isFunction(data.deprecatedCallback) && data.deprecatedCallback, eventInfo.deprecatedContext, eventInfo.deprecatedArgs)            }            function createCallback(callback, deprectatedCallback, deprecatedContext, deprecatedArgs) {                return function(arg, complete) {                        var timer = setTimeout(function() {                                callback(arg);                                deprectatedCallback && deprectatedCallback.apply(deprecatedContext(arg), deprecatedArgs(arg));                                complete && complete();                                delete timers[timer]                            });                        timers[timer] = 1                    }            }        }        core.DEBUG_createEventTrigger = createEventTrigger    })(DevExpress, jQuery);    /*! Module viz-core, file CoreFactory.js */    (function(DX, undefined) {        var viz = DX.viz,            core = viz.core,            seriesNS = core.series;        core.CoreFactory = {            createSeries: function(renderSettings, options) {                return new seriesNS.Series(renderSettings, options)            },            createPoint: function(series, data, options) {                return new seriesNS.points.Point(series, data, options)            },            createLabel: function() {                return new core.series.points.Label            },            createTranslator1D: function(fromValue, toValue, fromAngle, toAngle) {                return (new core.Translator1D).setDomain(fromValue, toValue).setCodomain(fromAngle, toAngle)            },            createTranslator2D: function(range, canvas, options) {                return new core.Translator2D(range, canvas, options)            },            createTickManager: function(types, data, options) {                return new core.tickManager.TickManager(types, data, options)            },            createLegend: function(settings) {                return new core.Legend(settings)            },            createSeriesFamily: function(options) {                return new seriesNS.helpers.SeriesFamily(options)            },            createDataValidator: function(data, groups, incidentOccured, dataPrepareOptions) {                return new core.DataValidator(data, groups, incidentOccured, dataPrepareOptions)            }        }    })(DevExpress);    DevExpress.MOD_VIZ_CORE = true}if (!DevExpress.MOD_VIZ_CHARTS) {    if (!DevExpress.MOD_VIZ_CORE)        throw Error('Required module is not referenced: viz-core');    /*! Module viz-charts, file chartTitle.js */    (function($, DX, undefined) {        var viz = DX.viz,            vizUtils = viz.core.utils,            isDefined = DX.utils.isDefined,            DEFAULT_MARGIN = 10;        function parseMargins(options) {            options.margin = isDefined(options.margin) ? options.margin : {};            if (typeof options.margin === 'number') {                options.margin = options.margin >= 0 ? options.margin : DEFAULT_MARGIN;                options.margin = {                    top: options.margin,                    bottom: options.margin,                    left: options.margin,                    right: options.margin                }            }            else {                options.margin.top = options.margin.top >= 0 ? options.margin.top : DEFAULT_MARGIN;                options.margin.bottom = options.margin.bottom >= 0 ? options.margin.bottom : DEFAULT_MARGIN;                options.margin.left = options.margin.left >= 0 ? options.margin.left : DEFAULT_MARGIN;                options.margin.right = options.margin.right >= 0 ? options.margin.right : DEFAULT_MARGIN            }        }        function parseAlignments(options) {            options.verticalAlignment = (options.verticalAlignment || '').toLowerCase();            options.horizontalAlignment = (options.horizontalAlignment || '').toLowerCase();            if (options.verticalAlignment !== 'top' && options.verticalAlignment !== 'bottom')                options.verticalAlignment = 'top';            if (options.horizontalAlignment !== 'left' && options.horizontalAlignment !== 'center' && options.horizontalAlignment !== 'right')                options.horizontalAlignment = 'center'        }        function ChartTitle(renderer, options, group) {            var that = this;            that.update(options);            that.renderer = renderer;            that.titleGroup = group        }        viz.charts.ChartTitle = ChartTitle;        ChartTitle.prototype = {            dispose: function() {                var that = this;                that.renderer = null;                that.clipRect = null;                that.title = null;                that.innerTitleGroup = null;                that.titleGroup = null;                that.options = null            },            update: function(options) {                var that = this;                if (options) {                    parseAlignments(options);                    that.horizontalAlignment = options.horizontalAlignment;                    that.verticalAlignment = options.verticalAlignment;                    parseMargins(options);                    that.margin = options.margin;                    that.options = options                }            },            _setBoundingRect: function() {                var that = this,                    options = that.options,                    margin = that.changedMargin || that.margin,                    box;                if (!that.innerTitleGroup)                    return;                box = that.innerTitleGroup.getBBox();                box.height += margin.top + margin.bottom;                box.width += margin.left + margin.right;                box.x -= margin.left;                box.y -= margin.top;                if (isDefined(options.placeholderSize))                    box.height = options.placeholderSize;                that.boundingRect = box            },            draw: function(size) {                var that = this,                    titleOptions = that.options,                    renderer = that.renderer;                if (!titleOptions.text)                    return that;                size && that.setSize(size);                that.changedMargin = null;                if (!that.innerTitleGroup) {                    that.innerTitleGroup = renderer.g();                    that.clipRect = that.createClipRect();                    that.titleGroup && that.clipRect && that.titleGroup.attr({clipId: that.clipRect.id})                }                else                    that.innerTitleGroup.clear();                that.innerTitleGroup.append(that.titleGroup);                that.title = renderer.text(titleOptions.text, 0, 0).css(vizUtils.patchFontOptions(titleOptions.font)).attr({align: that.horizontalAlignment}).append(that.innerTitleGroup);                that.title.text = titleOptions.text;                that._correctTitleLength();                that._setClipRectSettings();                return that            },            _correctTitleLength: function() {                var that = this,                    text = that.title.text,                    lineLength,                    box;                that.title.attr({text: text});                that._setBoundingRect();                box = that.getLayoutOptions();                if (that._width > box.width || text.indexOf("<br/>") !== -1)                    return;                lineLength = text.length * that._width / box.width;                that.title.attr({text: text.substr(0, ~~lineLength - 1 - 3) + "..."});                that.title.setTitle(text);                that._setBoundingRect()            },            changeSize: function(size) {                var that = this,                    margin = $.extend(true, {}, that.margin);                if (margin.top + margin.bottom < size.height) {                    if (that.innerTitleGroup) {                        that.options._incidentOccured("W2103");                        that.innerTitleGroup.dispose();                        that.innerTitleGroup = null                    }                    if (that.clipRect) {                        that.clipRect.dispose();                        that.clipRect = null                    }                }                else if (size.height > 0) {                    vizUtils.decreaseGaps(margin, ["top", "bottom"], size.height);                    size.height && (that.changedMargin = margin)                }                that._correctTitleLength();                that._setBoundingRect();                that._setClipRectSettings();                return that            },            getLayoutOptions: function() {                var options = this.options,                    boundingRect = this.innerTitleGroup ? this.boundingRect : {                        width: 0,                        height: 0,                        x: 0,                        y: 0                    };                boundingRect.verticalAlignment = options.verticalAlignment;                boundingRect.horizontalAlignment = options.horizontalAlignment;                boundingRect.cutLayoutSide = options.verticalAlignment;                return boundingRect            },            getBBox: function() {                var bbox = $.extend({}, this.getLayoutOptions());                bbox.x = this._x;                bbox.y = this._y;                return bbox            },            setSize: function(size) {                this._width = size.width || this._width;                return this            },            shift: function(x, y) {                var that = this,                    box = that.getLayoutOptions();                that._x = x;                that._y = y;                x -= box.x;                y -= box.y;                that.innerTitleGroup && that.innerTitleGroup.move(x, y);                that.clipRect && that.clipRect.attr({                    translateX: x,                    translateY: y                });                return that            },            createClipRect: function() {                if (isDefined(this.options.placeholderSize))                    return this.renderer.clipRect(0, 0, 0, 0)            },            _setClipRectSettings: function() {                var bbox = this.getLayoutOptions(),                    clipRect = this.clipRect;                if (clipRect)                    clipRect.attr({                        x: bbox.x,                        y: bbox.y,                        width: bbox.width,                        height: bbox.height                    })            }        };        DX.viz.charts.ChartTitle.__DEFAULT_MARGIN = DEFAULT_MARGIN    })(jQuery, DevExpress);    /*! Module viz-charts, file axesConstants.js */    (function($, DX, undefined) {        var _map = $.map;        function getFormatObject(value, options, axisMinMax) {            var formatObject = {                    value: value,                    valueText: DX.formatHelper.format(value, options.format, options.precision) || ""                };            if (axisMinMax) {                formatObject.min = axisMinMax.min;                formatObject.max = axisMinMax.max            }            return formatObject        }        DX.viz.charts.axes = {};        DX.viz.charts.axes.constants = {            logarithmic: "logarithmic",            discrete: "discrete",            numeric: "numeric",            left: "left",            right: "right",            top: "top",            bottom: "bottom",            center: "center",            canvasPositionPrefix: "canvas_position_",            canvasPositionTop: "canvas_position_top",            canvasPositionBottom: "canvas_position_bottom",            canvasPositionLeft: "canvas_position_left",            canvasPositionRight: "canvas_position_right",            canvasPositionStart: "canvas_position_start",            canvasPositionEnd: "canvas_position_end",            horizontal: "horizontal",            vertical: "vertical",            halfTickLength: 4,            convertTicksToValues: function(ticks) {                return _map(ticks || [], function(item) {                        return item.value                    })            },            convertValuesToTicks: function(values) {                return _map(values || [], function(item) {                        return {value: item}                    })            },            validateOverlappingMode: function(mode) {                return mode !== "ignore" ? "enlargeTickInterval" : "ignore"            },            formatLabel: function(value, options, axisMinMax) {                var formatObject = getFormatObject(value, options, axisMinMax);                return $.isFunction(options.customizeText) ? options.customizeText.call(formatObject, formatObject) : formatObject.valueText            },            formatHint: function(value, options, axisMinMax) {                var formatObject = getFormatObject(value, options, axisMinMax);                return $.isFunction(options.customizeHint) ? options.customizeHint.call(formatObject, formatObject) : undefined            }        }    })(jQuery, DevExpress);    /*! Module viz-charts, file xyAxes.js */    (function($, DX, undefined) {        var viz = DX.viz,            core = viz.core,            axes = viz.charts.axes,            constants = axes.constants,            _abs = Math.abs,            _extend = $.extend,            CANVAS_POSITION_PREFIX = constants.canvasPositionPrefix,            TOP = constants.top,            BOTTOM = constants.bottom,            LEFT = constants.left,            RIGHT = constants.right,            CENTER = constants.center;        axes.xyAxes = {};        axes.xyAxes.linear = {            _getSharpParam: function(oposite) {                return this._isHorizontal ^ oposite ? "h" : "v"            },            _createAxisElement: function() {                var axisCoord = this._axisPosition,                    canvas = this._getCanvasStartEnd(),                    points = this._isHorizontal ? [canvas.start, axisCoord, canvas.end, axisCoord] : [axisCoord, canvas.start, axisCoord, canvas.end];                return this._renderer.path(points, "line")            },            _getTranslatedCoord: function(value, offset) {                return this._translator.translate(value, offset)            },            _getCanvasStartEnd: function() {                return {                        start: this._translator.translateSpecialCase(constants.canvasPositionStart),                        end: this._translator.translateSpecialCase(constants.canvasPositionEnd)                    }            },            _getScreenDelta: function() {                return _abs(this._translator.translateSpecialCase(constants.canvasPositionStart) - this._translator.translateSpecialCase(constants.canvasPositionEnd))            },            _initAxisPositions: function() {                var that = this,                    position = that._options.position,                    delta = 0;                if (that.delta)                    delta = that.delta[position] || 0;                that._axisPosition = that._additionalTranslator.translateSpecialCase(CANVAS_POSITION_PREFIX + position) + delta            },            _drawTitle: function() {                var that = this,                    options = that._options,                    titleOptions = options.title,                    attr = {                        opacity: titleOptions.opacity,                        align: CENTER                    };                if (!titleOptions.text || !that._axisTitleGroup)                    return;                that._title = that._renderer.text(titleOptions.text, 0, 0).css(core.utils.patchFontOptions(titleOptions.font)).attr(attr).append(that._axisTitleGroup)            },            _adjustConstantLineLabels: function() {                var that = this,                    options = that._options,                    isHorizontal = that._isHorizontal,                    lines = that._constantLines,                    labels = that._constantLineLabels,                    label,                    line,                    lineBox,                    linesOptions,                    labelOptions,                    box,                    x,                    y,                    i,                    padding = isHorizontal ? {                        top: 0,                        bottom: 0                    } : {                        left: 0,                        right: 0                    },                    paddingTopBottom,                    paddingLeftRight,                    labelVerticalAlignment,                    labelHorizontalAlignment,                    labelIsInside,                    labelHeight,                    labelWidth,                    delta = 0;                if (labels === undefined && lines === undefined)                    return;                for (i = 0; i < labels.length; i++) {                    x = y = 0;                    linesOptions = options.constantLines[i];                    paddingTopBottom = linesOptions.paddingTopBottom;                    paddingLeftRight = linesOptions.paddingLeftRight;                    labelOptions = linesOptions.label;                    labelVerticalAlignment = labelOptions.verticalAlignment;                    labelHorizontalAlignment = labelOptions.horizontalAlignment;                    labelIsInside = labelOptions.position === "inside";                    label = labels[i];                    if (label !== null) {                        line = lines[i];                        box = label.getBBox();                        lineBox = line.getBBox();                        labelHeight = box.height;                        labelWidth = box.width;                        if (isHorizontal)                            if (labelIsInside) {                                if (labelHorizontalAlignment === LEFT)                                    x -= paddingLeftRight;                                else                                    x += paddingLeftRight;                                switch (labelVerticalAlignment) {                                    case CENTER:                                        y += lineBox.y + lineBox.height / 2 - box.y - labelHeight / 2;                                        break;                                    case BOTTOM:                                        y += lineBox.y + lineBox.height - box.y - labelHeight - paddingTopBottom;                                        break;                                    default:                                        y += lineBox.y - box.y + paddingTopBottom;                                        break                                }                            }                            else if (labelVerticalAlignment === BOTTOM) {                                delta = that.delta && that.delta[BOTTOM] || 0;                                y += paddingTopBottom - box.y + that._additionalTranslator.translateSpecialCase(CANVAS_POSITION_PREFIX + BOTTOM) + delta;                                if (padding[BOTTOM] < labelHeight + paddingTopBottom)                                    padding[BOTTOM] = labelHeight + paddingTopBottom                            }                            else {                                delta = that.delta && that.delta[TOP] || 0;                                y -= paddingTopBottom + box.y + labelHeight - that._additionalTranslator.translateSpecialCase(CANVAS_POSITION_PREFIX + TOP) - delta;                                if (padding[TOP] < paddingTopBottom + labelHeight)                                    padding[TOP] = paddingTopBottom + labelHeight                            }                        else if (labelIsInside) {                            switch (labelHorizontalAlignment) {                                case CENTER:                                    x += lineBox.x + labelWidth / 2 - box.x - labelWidth / 2;                                    break;                                case RIGHT:                                    x -= paddingLeftRight;                                    break;                                default:                                    x += paddingLeftRight;                                    break                            }                            if (labelVerticalAlignment === BOTTOM)                                y += lineBox.y - box.y + paddingTopBottom;                            else                                y += lineBox.y - box.y - labelHeight - paddingTopBottom                        }                        else {                            y += lineBox.y + lineBox.height / 2 - box.y - labelHeight / 2;                            if (labelHorizontalAlignment === RIGHT) {                                x += paddingLeftRight;                                if (padding[RIGHT] < paddingLeftRight + labelWidth)                                    padding[RIGHT] = paddingLeftRight + labelWidth                            }                            else {                                x -= paddingLeftRight;                                if (padding[LEFT] < paddingLeftRight + labelWidth)                                    padding[LEFT] = paddingLeftRight + labelWidth                            }                        }                        label.move(x, y)                    }                }                that.padding = padding            },            _checkAlignmentConstantLineLabels: function(labelOptions) {                var position = labelOptions.position,                    verticalAlignment = (labelOptions.verticalAlignment || "").toLowerCase(),                    horizontalAlignment = (labelOptions.horizontalAlignment || "").toLowerCase();                if (this._isHorizontal)                    if (position === "outside") {                        verticalAlignment = verticalAlignment === BOTTOM ? BOTTOM : TOP;                        horizontalAlignment = CENTER                    }                    else {                        verticalAlignment = verticalAlignment === CENTER ? CENTER : verticalAlignment === BOTTOM ? BOTTOM : TOP;                        horizontalAlignment = horizontalAlignment === LEFT ? LEFT : RIGHT                    }                else if (position === "outside") {                    verticalAlignment = CENTER;                    horizontalAlignment = horizontalAlignment === LEFT ? LEFT : RIGHT                }                else {                    verticalAlignment = verticalAlignment === BOTTOM ? BOTTOM : TOP;                    horizontalAlignment = horizontalAlignment === RIGHT ? RIGHT : horizontalAlignment === CENTER ? CENTER : LEFT                }                labelOptions.verticalAlignment = verticalAlignment;                labelOptions.horizontalAlignment = horizontalAlignment            },            _getConstantLineLabelsCoords: function(value, lineLabelOptions) {                var that = this,                    additionalTranslator = that._additionalTranslator,                    align = CENTER,                    x = value,                    y = value;                if (that._isHorizontal)                    y = additionalTranslator.translateSpecialCase(CANVAS_POSITION_PREFIX + lineLabelOptions.verticalAlignment);                else                    x = additionalTranslator.translateSpecialCase(CANVAS_POSITION_PREFIX + lineLabelOptions.horizontalAlignment);                switch (lineLabelOptions.horizontalAlignment) {                    case LEFT:                        align = !that._isHorizontal && lineLabelOptions.position === "inside" ? LEFT : RIGHT;                        break;                    case CENTER:                        align = CENTER;                        break;                    case RIGHT:                        align = !that._isHorizontal && lineLabelOptions.position === "inside" ? RIGHT : LEFT;                        break                }                return {                        x: x,                        y: y,                        align: align                    }            },            _getAdjustedStripLabelCoords: function(stripOptions, label, rect) {                var x = 0,                    y = 0,                    horizontalAlignment = stripOptions.label.horizontalAlignment,                    verticalAlignment = stripOptions.label.verticalAlignment,                    box = label.getBBox(),                    rectBox = rect.getBBox();                if (horizontalAlignment === LEFT)                    x += stripOptions.paddingLeftRight;                else if (horizontalAlignment === RIGHT)                    x -= stripOptions.paddingLeftRight;                if (verticalAlignment === TOP)                    y += rectBox.y - box.y + stripOptions.paddingTopBottom;                else if (verticalAlignment === CENTER)                    y += rectBox.y + rectBox.height / 2 - box.y - box.height / 2;                else if (verticalAlignment === BOTTOM)                    y -= stripOptions.paddingTopBottom;                return {                        x: x,                        y: y                    }            },            _adjustTitle: function() {                var that = this,                    options = that._options,                    position = options.position,                    title = that._title,                    margin = options.title.margin,                    boxGroup,                    boxTitle,                    params,                    centerPosition = that._translator.translateSpecialCase(CANVAS_POSITION_PREFIX + CENTER),                    axisElementsGroup = that._axisElementsGroup,                    heightTitle,                    axisPosition = that._axisPosition,                    noLabels;                if (!title || !axisElementsGroup)                    return;                boxTitle = title.getBBox();                boxGroup = axisElementsGroup.getBBox();                noLabels = boxGroup.isEmpty;                heightTitle = boxTitle.height;                if (that._isHorizontal)                    if (position === BOTTOM)                        params = {                            y: (noLabels ? axisPosition : boxGroup.y + boxGroup.height) - boxTitle.y + margin,                            x: centerPosition                        };                    else                        params = {                            y: (noLabels ? axisPosition : boxGroup.y) - heightTitle - boxTitle.y - margin,                            x: centerPosition                        };                else {                    if (position === LEFT)                        params = {                            x: (noLabels ? axisPosition : boxGroup.x) - heightTitle - boxTitle.y - margin,                            y: centerPosition                        };                    else                        params = {                            x: (noLabels ? axisPosition : boxGroup.x + boxGroup.width) + heightTitle + boxTitle.y + margin,                            y: centerPosition                        };                    params.rotate = options.position === LEFT ? 270 : 90                }                title.attr(params)            },            coordsIn: function(x, y) {                var rect = this.getBoundingRect();                return x >= rect.x && x <= rect.x + rect.width && y >= rect.y && y <= rect.y + rect.height            },            _getTicksOptions: function() {                var options = this._options;                return {                        base: options.type === constants.logarithmic ? options.logarithmBase : undefined,                        tickInterval: this._translator.getBusinessRange().stubData ? null : options.tickInterval,                        gridSpacingFactor: options.axisDivisionFactor,                        incidentOccured: options.incidentOccured,                        setTicksAtUnitBeginning: options.setTicksAtUnitBeginning,                        showMinorTicks: options.minorTick.visible || options.minorGrid.visible,                        minorTickInterval: options.minorTickInterval,                        minorTickCount: options.minorTickCount                    }            },            _getOverlappingBehaviorOptions: function() {                var that = this,                    options = that._options,                    getText = function() {                        return ""                    },                    overlappingBehavior = options.label.overlappingBehavior ? _extend({}, options.label.overlappingBehavior) : null;                if (overlappingBehavior) {                    if (!that._isHorizontal)                        overlappingBehavior.mode = constants.validateOverlappingMode(overlappingBehavior.mode);                    if (overlappingBehavior.mode !== "rotate")                        overlappingBehavior.rotationAngle = 0                }                if (!that._translator.getBusinessRange().stubData)                    getText = function(value, labelOptions) {                        return constants.formatLabel(value, labelOptions, {                                min: options.min,                                max: options.max                            })                    };                return {                        hasLabelFormat: that._hasLabelFormat,                        labelOptions: options.label,                        overlappingBehavior: overlappingBehavior,                        isHorizontal: that._isHorizontal,                        textOptions: that._textOptions,                        textFontStyles: that._textFontStyles,                        textSpacing: options.label.minSpacing,                        getText: getText,                        renderText: function(text, x, y, options) {                            return that._renderer.text(text, x, y, options).append(that._renderer.root)                        },                        translate: function(value, useAdditionalTranslator) {                            return useAdditionalTranslator ? that._additionalTranslator.translate(value) : that._translator.translate(value)                        },                        isInverted: that._translator.getBusinessRange().invert                    }            },            _getSpiderCategoryOption: $.noop,            _getMinMax: function() {                return {                        min: this._options.min,                        max: this._options.max                    }            },            _getStick: function() {                return !this._options.valueMarginsEnabled            },            _getStripLabelCoords: function(stripLabelOptions, stripFrom, stripTo) {                var that = this,                    additionalTranslator = that._additionalTranslator,                    isHorizontal = that._isHorizontal,                    align = isHorizontal ? CENTER : LEFT,                    x,                    y;                if (isHorizontal) {                    if (stripLabelOptions.horizontalAlignment === CENTER) {                        x = stripFrom + (stripTo - stripFrom) / 2;                        align = CENTER                    }                    else if (stripLabelOptions.horizontalAlignment === LEFT) {                        x = stripFrom;                        align = LEFT                    }                    else if (stripLabelOptions.horizontalAlignment === RIGHT) {                        x = stripTo;                        align = RIGHT                    }                    y = additionalTranslator.translateSpecialCase(CANVAS_POSITION_PREFIX + stripLabelOptions.verticalAlignment)                }                else {                    x = additionalTranslator.translateSpecialCase(CANVAS_POSITION_PREFIX + stripLabelOptions.horizontalAlignment);                    align = stripLabelOptions.horizontalAlignment;                    if (stripLabelOptions.verticalAlignment === TOP)                        y = stripFrom;                    else if (stripLabelOptions.verticalAlignment === CENTER)                        y = stripTo + (stripFrom - stripTo) / 2;                    else if (stripLabelOptions.verticalAlignment === BOTTOM)                        y = stripTo                }                return {                        x: x,                        y: y,                        align: align                    }            },            _getTranslatedValue: function(value, y, offset) {                return {                        x: this._translator.translate(value, offset),                        y: y                    }            },            _getSkippedCategory: function() {                var that = this,                    options = that._options,                    categories = that._translator.getVisibleCategories() || that._translator.getBusinessRange().categories,                    categoryToSkip;                if (categories && !!that._tickOffset && !options.valueMarginsEnabled)                    categoryToSkip = options.inverted ? categories[0] : categories[categories.length - 1];                return categoryToSkip            }        }    })(jQuery, DevExpress);    /*! Module viz-charts, file polarAxes.js */    (function($, DX, undefined) {        var viz = DX.viz,            core = viz.core,            utils = DX.utils,            constants = viz.charts.axes.constants,            _math = Math,            _abs = _math.abs,            _round = _math.round,            _extend = $.extend,            _noop = $.noop,            _map = $.map,            HALF_PI_ANGLE = 90;        viz.charts.axes.polarAxes = {};        function getPolarQuarter(angle) {            var quarter;            angle = utils.normalizeAngle(angle);            if (angle >= 315 && angle <= 360 || angle < 45 && angle >= 0)                quarter = 1;            else if (angle >= 45 && angle < 135)                quarter = 2;            else if (angle >= 135 && angle < 225)                quarter = 3;            else if (angle >= 225 && angle < 315)                quarter = 4;            return quarter        }        viz.charts.axes.polarAxes.circular = {            _overlappingBehaviorType: "circular",            _createAxisElement: function() {                var additionalTranslator = this._additionalTranslator;                return this._renderer.circle(additionalTranslator.getCenter().x, additionalTranslator.getCenter().y, additionalTranslator.getRadius())            },            _setBoundingRect: function() {                this.boundingRect = {                    width: 0,                    height: 0                }            },            _getTicksOptions: viz.charts.axes.xyAxes.linear._getTicksOptions,            _getOverlappingBehaviorOptions: function() {                var that = this,                    additionalTranslator = that._additionalTranslator,                    startAngle = additionalTranslator.getStartAngle(),                    options = viz.charts.axes.xyAxes.linear._getOverlappingBehaviorOptions.call(that),                    translator = that._translator,                    indentFromAxis = that._options.label.indentFromAxis || 0;                if (options.overlappingBehavior)                    options.overlappingBehavior = {mode: constants.validateOverlappingMode(options.overlappingBehavior.mode)};                options.translate = function(value) {                    return core.utils.convertPolarToXY(additionalTranslator.getCenter(), startAngle, translator.translate(value), additionalTranslator.translate(constants.canvasPositionBottom))                };                options.addMinMax = {min: true};                options.isInverted = translator.getBusinessRange().invert;                options.circularRadius = additionalTranslator.getRadius() + indentFromAxis;                options.circularStartAngle = options.circularEndAngle = startAngle;                options.isHorizontal = false;                return options            },            _getSpiderCategoryOption: function() {                return this._options.firstPointOnStartAngle            },            _getMinMax: function() {                var options = this._options;                return {                        min: undefined,                        max: utils.isNumber(options.period) && options.argumentType === constants.numeric ? options.period : undefined                    }            },            _getStick: function() {                return this._options.firstPointOnStartAngle || this._options.type !== constants.discrete            },            measureLabels: function() {                var that = this,                    options = that._options,                    indentFromAxis = options.label.indentFromAxis || 0,                    widthAxis = options.visible ? options.width : 0,                    maxLabelParams;                if (!that._axisElementsGroup || !that._options.label.visible)                    return {                            height: widthAxis,                            width: widthAxis                        };                that._updateTickManager();                maxLabelParams = that._tickManager.getMaxLabelParams();                return {                        height: maxLabelParams.height + indentFromAxis + constants.halfTickLength,                        width: maxLabelParams.width + indentFromAxis + constants.halfTickLength                    }            },            _getTranslatedCoord: function(value, offset) {                return this._translator.translate(value, offset) - HALF_PI_ANGLE            },            _getCanvasStartEnd: function() {                return {                        start: 0 - HALF_PI_ANGLE,                        end: 360 - HALF_PI_ANGLE                    }            },            _createStrip: function(fromAngle, toAngle, attr) {                var center = this._additionalTranslator.getCenter(),                    r = this._additionalTranslator.getRadius();                return this._renderer.arc(center.x, center.y, 0, r, -toAngle, -fromAngle).attr(attr)            },            _getStripLabelCoords: function(_, stripFrom, stripTo) {                var that = this,                    angle = stripFrom + (stripTo - stripFrom) / 2,                    cossin = utils.getCosAndSin(-angle),                    halfRad = that._additionalTranslator.getRadius() / 2,                    center = that._additionalTranslator.getCenter(),                    x = _round(center.x + halfRad * cossin.cos),                    y = _round(center.y - halfRad * cossin.sin);                return {                        x: x,                        y: y,                        align: constants.center                    }            },            _createConstantLine: function(value, attr) {                var center = this._additionalTranslator.getCenter(),                    r = this._additionalTranslator.getRadius();                return this._createPathElement([center.x, center.y, center.x + r, center.y], attr).rotate(value, center.x, center.y)            },            _getConstantLineLabelsCoords: function(value) {                var that = this,                    cossin = utils.getCosAndSin(-value),                    halfRad = that._additionalTranslator.getRadius() / 2,                    center = that._additionalTranslator.getCenter(),                    x = _round(center.x + halfRad * cossin.cos),                    y = _round(center.y - halfRad * cossin.sin);                return {                        x: x,                        y: y,                        align: constants.center                    }            },            _checkAlignmentConstantLineLabels: _noop,            _getScreenDelta: function() {                return 2 * Math.PI * this._additionalTranslator.getRadius()            },            _getTickCoord: function(tick) {                var center = this._additionalTranslator.getCenter(),                    r = this._additionalTranslator.getRadius();                return {                        x1: center.x + r - constants.halfTickLength,                        y1: center.y,                        x2: center.x + r + constants.halfTickLength,                        y2: center.y,                        angle: tick.angle                    }            },            _getLabelAdjustedCoord: function(tick) {                var that = this,                    pos = tick.labelPos,                    cossin = utils.getCosAndSin(pos.angle),                    cos = cossin.cos,                    sin = cossin.sin,                    box = tick.label.getBBox(),                    halfWidth = box.width / 2,                    halfHeight = box.height / 2,                    indentFromAxis = that._options.label.indentFromAxis || 0,                    x = pos.x + indentFromAxis * cos,                    y = pos.y + (pos.y - box.y - halfHeight) + indentFromAxis * sin;                switch (getPolarQuarter(pos.angle)) {                    case 1:                        x += halfWidth;                        y += halfHeight * sin;                        break;                    case 2:                        x += halfWidth * cos;                        y += halfHeight;                        break;                    case 3:                        x += -halfWidth;                        y += halfHeight * sin;                        break;                    case 4:                        x += halfWidth * cos;                        y += -halfHeight;                        break                }                return {                        x: x,                        y: y                    }            },            _getGridLineDrawer: function() {                var that = this,                    r = that._additionalTranslator.getRadius(),                    center = that._additionalTranslator.getCenter();                return function(tick) {                        return that._createPathElement([center.x, center.y, center.x + r, center.y], tick.gridStyle).rotate(tick.angle, center.x, center.y)                    }            },            _getTranslatedValue: function(value, _, offset) {                var additionalTranslator = this._additionalTranslator,                    startAngle = additionalTranslator.getStartAngle(),                    angle = this._translator.translate(value, -offset),                    coords = core.utils.convertPolarToXY(additionalTranslator.getCenter(), startAngle, angle, additionalTranslator.translate(constants.canvasPositionBottom));                return {                        x: coords.x,                        y: coords.y,                        angle: angle + startAngle - HALF_PI_ANGLE                    }            },            _getAdjustedStripLabelCoords: function(_, label) {                var y,                    box = label.getBBox();                y = label.attr("y") - box.y - box.height / 2;                return {                        x: 0,                        y: y                    }            },            coordsIn: function(x, y) {                return core.utils.convertXYToPolar(this._additionalTranslator.getCenter(), x, y).r > this._additionalTranslator.getRadius()            },            _rotateTick: function(tick, angle) {                var center = this._additionalTranslator.getCenter();                tick.graphic.rotate(angle, center.x, center.y)            }        };        viz.charts.axes.polarAxes.circularSpider = _extend({}, viz.charts.axes.polarAxes.circular, {            _createAxisElement: function() {                var points = _map(this.getSpiderTicks(), function(tick) {                        return {                                x: tick.posX,                                y: tick.posY                            }                    });                return this._renderer.path(points, "area")            },            _getStick: function() {                return true            },            _getSpiderCategoryOption: function() {                return true            },            getSpiderTicks: function() {                var that = this;                that._spiderTicks = constants.convertValuesToTicks(that._tickManager.getFullTicks());                that._initTicks(that._spiderTicks, {}, {});                return that._spiderTicks            },            _createStrip: function(fromAngle, toAngle, attr) {                var center = this._additionalTranslator.getCenter(),                    spiderTicks = this.getSpiderTicks(),                    firstTick,                    lastTick,                    points = _map(spiderTicks, function(tick, i) {                        var result = [],                            nextTick;                        if (tick.angle >= fromAngle && tick.angle <= toAngle) {                            if (!firstTick) {                                firstTick = spiderTicks[i - 1] || spiderTicks[spiderTicks.length - 1];                                result.push((tick.posX + firstTick.posX) / 2, (tick.posY + firstTick.posY) / 2)                            }                            result.push(tick.posX, tick.posY);                            nextTick = spiderTicks[i + 1] || spiderTicks[0];                            lastTick = {                                x: (tick.posX + nextTick.posX) / 2,                                y: (tick.posY + nextTick.posY) / 2                            }                        }                        else                            result = null;                        return result                    });                points.push(lastTick.x, lastTick.y);                points.push(center.x, center.y);                return this._renderer.path(points, "area").attr(attr)            },            _getTranslatedCoord: function(value, offset) {                return this._translator.translate(value, offset) - HALF_PI_ANGLE            },            _setTickOffset: function() {                this._tickOffset = false            }        });        viz.charts.axes.polarAxes.linear = {            _overlappingBehaviorType: "linear",            _getMinMax: viz.charts.axes.polarAxes.circular._getMinMax,            _getStick: viz.charts.axes.xyAxes.linear._getStick,            _getTicksOptions: viz.charts.axes.xyAxes.linear._getTicksOptions,            _getSpiderCategoryOption: $.noop,            _createAxisElement: function() {                var additionalTranslator = this._additionalTranslator,                    centerCoord = additionalTranslator.getCenter(),                    points = [centerCoord.x, centerCoord.y, centerCoord.x + additionalTranslator.getRadius(), centerCoord.y];                return this._renderer.path(points, "line").rotate(additionalTranslator.getStartAngle() - HALF_PI_ANGLE, centerCoord.x, centerCoord.y)            },            _setBoundingRect: viz.charts.axes.polarAxes.circular._setBoundingRect,            _getScreenDelta: function() {                return this._additionalTranslator.getRadius()            },            _getTickCoord: function(tick) {                return {                        x1: tick.posX - constants.halfTickLength,                        y1: tick.posY,                        x2: tick.posX + constants.halfTickLength,                        y2: tick.posY,                        angle: tick.angle + HALF_PI_ANGLE                    }            },            _getOverlappingBehaviorOptions: function() {                var that = this,                    translator = that._translator,                    orthTranslator = that._additionalTranslator,                    options = viz.charts.axes.xyAxes.linear._getOverlappingBehaviorOptions.call(this),                    startAngle = utils.normalizeAngle(that._additionalTranslator.getStartAngle());                if (options.overlappingBehavior)                    options.overlappingBehavior = {mode: constants.validateOverlappingMode(options.overlappingBehavior.mode)};                options.isHorizontal = startAngle > 45 && startAngle < 135 || startAngle > 225 && startAngle < 315 ? true : false;                options.isInverted = translator.getBusinessRange().invert;                options.translate = function(value) {                    return core.utils.convertPolarToXY(orthTranslator.getCenter(), that._options.startAngle, orthTranslator.translate(constants.canvasPositionTop), translator.translate(value)).x                };                return options            },            _getLabelAdjustedCoord: function(tick) {                var that = this,                    pos = tick.labelPos,                    cossin = utils.getCosAndSin(pos.angle),                    indentFromAxis = that._options.label.indentFromAxis || 0,                    box = tick.label.getBBox(),                    x,                    y;                x = pos.x - _abs(indentFromAxis * cossin.sin) + _abs(box.width / 2 * cossin.cos);                y = pos.y + (pos.y - box.y) - _abs(box.height / 2 * cossin.sin) + _abs(indentFromAxis * cossin.cos);                return {                        x: x,                        y: y                    }            },            _getGridLineDrawer: function() {                var that = this,                    pos = that._additionalTranslator.getCenter();                return function(tick) {                        return that._renderer.circle(pos.x, pos.y, utils.getDistance(pos.x, pos.y, tick.posX, tick.posY)).attr(tick.gridStyle).sharp()                    }            },            _getTranslatedValue: function(value, _, offset) {                var additionalTranslator = this._additionalTranslator,                    startAngle = additionalTranslator.getStartAngle(),                    angle = additionalTranslator.translate(constants.canvasPositionStart),                    xy = core.utils.convertPolarToXY(additionalTranslator.getCenter(), startAngle, angle, this._translator.translate(value, offset));                return {                        x: xy.x,                        y: xy.y,                        angle: angle + startAngle - HALF_PI_ANGLE                    }            },            _getTranslatedCoord: function(value, offset) {                return this._translator.translate(value, offset)            },            _getCanvasStartEnd: function() {                return {                        start: 0,                        end: this._additionalTranslator.getRadius()                    }            },            _createStrip: function(fromPoint, toPoint, attr) {                var center = this._additionalTranslator.getCenter();                return this._renderer.arc(center.x, center.y, fromPoint, toPoint, 0, 360).attr(attr)            },            _getAdjustedStripLabelCoords: viz.charts.axes.polarAxes.circular._getAdjustedStripLabelCoords,            _getStripLabelCoords: function(_, stripFrom, stripTo) {                var that = this,                    labelPos = stripFrom + (stripTo - stripFrom) / 2,                    center = that._additionalTranslator.getCenter(),                    y = _round(center.y - labelPos);                return {                        x: center.x,                        y: y,                        align: constants.center                    }            },            _createConstantLine: function(value, attr) {                var center = this._additionalTranslator.getCenter();                return this._renderer.circle(center.x, center.y, value).attr(attr).sharp()            },            _getConstantLineLabelsCoords: function(value) {                var that = this,                    center = that._additionalTranslator.getCenter(),                    y = _round(center.y - value);                return {                        x: center.x,                        y: y,                        align: constants.center                    }            },            _checkAlignmentConstantLineLabels: _noop,            _rotateTick: function(tick, angle) {                tick.graphic.rotate(angle, tick.posX, tick.posY)            }        };        viz.charts.axes.polarAxes.linearSpider = _extend({}, viz.charts.axes.polarAxes.linear, {            _createPathElement: function(points, attr) {                return this._renderer.path(points, "area").attr(attr).sharp()            },            setSpiderTicks: function(ticks) {                this._spiderTicks = ticks            },            _getGridLineDrawer: function() {                var that = this,                    pos = that._additionalTranslator.getCenter();                return function(tick) {                        var radius = utils.getDistance(pos.x, pos.y, tick.posX, tick.posY);                        return that._createPathElement(that._getGridPoints(pos, radius), tick.gridStyle)                    }            },            _getGridPoints: function(pos, radius) {                return _map(this._spiderTicks, function(tick) {                        var cossin = utils.getCosAndSin(tick.angle);                        return {                                x: _round(pos.x + radius * cossin.cos),                                y: _round(pos.y + radius * cossin.sin)                            }                    })            },            _createStrip: function(fromPoint, toPoint, attr) {                var center = this._additionalTranslator.getCenter(),                    innerPoints = this._getGridPoints(center, toPoint),                    outerPoints = this._getGridPoints(center, fromPoint);                return this._renderer.path([outerPoints, innerPoints.reverse()], "area").attr(attr)            },            _createConstantLine: function(value, attr) {                var center = this._additionalTranslator.getCenter(),                    points = this._getGridPoints(center, value);                return this._createPathElement(points, attr)            }        })    })(jQuery, DevExpress);    /*! Module viz-charts, file baseAxis.js */    (function($, DX, undefined) {        var viz = DX.viz,            core = viz.core,            utils = DX.utils,            constants = viz.charts.axes.constants,            _isDefined = utils.isDefined,            _isNumber = utils.isNumber,            _getSignificantDigitPosition = utils.getSignificantDigitPosition,            _roundValue = utils.roundValue,            _math = Math,            _abs = _math.abs,            _round = _math.round,            _extend = $.extend,            _each = $.each,            _noop = $.noop,            WIDGET_CLASS = "dxc",            DEFAULT_AXIS_LABEL_SPACING = 5,            MAX_GRID_BORDER_ADHENSION = 4,            LABEL_BACKGROUND_PADDING_X = 8,            LABEL_BACKGROUND_PADDING_Y = 4,            Axis;        function validateAxisOptions(options, isHorizontal) {            var labelOptions = options.label,                position = options.position,                defaultPosition = isHorizontal ? constants.bottom : constants.left,                secondaryPosition = isHorizontal ? constants.top : constants.right;            if (position !== defaultPosition && position !== secondaryPosition)                position = defaultPosition;            if (position === constants.right && !labelOptions.userAlignment)                labelOptions.alignment = constants.left;            options.position = position;            options.hoverMode = options.hoverMode ? options.hoverMode.toLowerCase() : "none";            labelOptions.minSpacing = _isDefined(labelOptions.minSpacing) ? labelOptions.minSpacing : DEFAULT_AXIS_LABEL_SPACING        }        Axis = DX.viz.charts.axes.Axis = function(renderSettings) {            var that = this;            that._renderer = renderSettings.renderer;            that._isHorizontal = renderSettings.isHorizontal;            that._incidentOccured = renderSettings.incidentOccured;            that._stripsGroup = renderSettings.stripsGroup;            that._labelAxesGroup = renderSettings.labelAxesGroup;            that._constantLinesGroup = renderSettings.constantLinesGroup;            that._axesContainerGroup = renderSettings.axesContainerGroup;            that._gridContainerGroup = renderSettings.gridGroup;            that._axisClass = renderSettings.axisClass;            that._setType(renderSettings.axesType, renderSettings.drawingType);            that._createAxisGroups();            that._tickManager = that._createTickManager()        };        Axis.prototype = {            constructor: Axis,            dispose: function() {                var that = this;                that._axisElementsGroup && that._axisElementsGroup.dispose();                that._stripLabels = that._strips = null;                that._title = null;                that._axisStripGroup = that._axisConstantLineGroup = that._axisLabelGroup = null;                that._axisLineGroup = that._axisElementsGroup = that._axisGridGroup = null;                that._axisGroup = that._axisTitleGroup = null;                that._axesContainerGroup = that._stripsGroup = that._constantLinesGroup = null;                that._renderer = that._options = that._textOptions = that._textFontStyles = null;                that._translator = that._additionalTranslator = null;                that._majorTicks = that._minorTicks = null;                that._tickManager = null            },            getOptions: function() {                return this._options            },            setPane: function(pane) {                this.pane = pane;                this._options.pane = pane            },            setTypes: function(type, axisType, typeSelector) {                this._options.type = type || this._options.type;                this._options[typeSelector] = axisType || this._options[typeSelector]            },            resetTypes: function(typeSelector) {                this._options.type = this._initTypes.type;                this._options[typeSelector] = this._initTypes[typeSelector]            },            getTranslator: function() {                return this._translator            },            updateOptions: function(options) {                var that = this,                    labelOpt = options.label;                that._options = options;                that._initTypes = {                    type: options.type,                    argumentType: options.argumentType,                    valueType: options.valueType                };                validateAxisOptions(options, that._isHorizontal);                that._setTickOffset();                that.pane = options.pane;                that.name = options.name;                that.priority = options.priority;                that._virtual = options.virtual;                that._hasLabelFormat = labelOpt.format !== "" && _isDefined(labelOpt.format);                that._textOptions = {                    align: labelOpt.alignment,                    opacity: labelOpt.opacity                };                that._textFontStyles = core.utils.patchFontOptions(labelOpt.font);                if (options.type === constants.logarithmic) {                    if (options.logarithmBaseError) {                        that._incidentOccured("E2104");                        delete options.logarithmBaseError                    }                    that.calcInterval = function(value, prevValue) {                        return utils.getLog(value / prevValue, options.logarithmBase)                    }                }            },            updateSize: function(clearAxis) {                var that = this,                    options = that._options,                    direction = that._isHorizontal ? "horizontal" : "vertical";                if (options.title.text && that._axisTitleGroup) {                    that._incidentOccured("W2105", [direction]);                    that._axisTitleGroup.dispose();                    that._axisTitleGroup = null                }                if (clearAxis && that._axisElementsGroup && options.label.visible && !that._translator.getBusinessRange().stubData) {                    that._incidentOccured("W2106", [direction]);                    that._axisElementsGroup.dispose();                    that._axisElementsGroup = null                }                that._setBoundingRect()            },            _updateTranslatorInterval: function() {                var that = this,                    i,                    majorTicks,                    majorTicksLength,                    translator = that._translator,                    businessRange = translator.getBusinessRange();                if (!businessRange.categories && !businessRange.isSynchronized) {                    that.getMajorTicks(true);                    businessRange.addRange(that._tickManager.getTickBounds());                    translator.reinit()                }                that._majorTicks = majorTicks = that.getMajorTicks();                if (!businessRange.categories) {                    majorTicksLength = majorTicks.length;                    for (i = 0; i < majorTicksLength - 1; i++)                        businessRange.addRange({interval: _abs(majorTicks[i].value - majorTicks[i + 1].value)})                }                that._decimatedTicks = businessRange.categories ? that.getDecimatedTicks() : [];                that._minorTicks = that.getMinorTicks()            },            setTranslator: function(translator, additionalTranslator) {                var that = this,                    range = translator.getBusinessRange();                this._minBound = range.minVisible;                this._maxBound = range.maxVisible;                that._translator = translator;                that._additionalTranslator = additionalTranslator;                that.resetTicks();                that._updateTranslatorInterval()            },            resetTicks: function() {                this._deleteLabels();                this._majorTicks = this._minorTicks = null            },            getCurrentLabelPos: function() {                var that = this,                    options = that._options,                    position = options.position,                    labelOffset = options.label.indentFromAxis,                    axisPosition = that._axisPosition;                return position === constants.top || position === constants.left ? axisPosition - labelOffset : axisPosition + labelOffset            },            getUntranslatedValue: function(pos) {                var that = this,                    translator = that._translator,                    value = translator.untranslate(pos);                if (_isDefined(value))                    return constants.formatLabel(_isNumber(value) ? _roundValue(value, _getSignificantDigitPosition(translator.getBusinessRange().interval)) : value, that._options.label);                return null            },            _drawAxis: function() {                var that = this,                    options = that._options,                    axis = that._createAxis({                        "stroke-width": options.width,                        stroke: options.color,                        "stroke-opacity": options.opacity                    });                axis.append(that._axisLineGroup)            },            _correctMinForTicks: function(min, max, screenDelta) {                var digitPosition = _getSignificantDigitPosition(_abs(max - min) / screenDelta),                    newMin = _roundValue(Number(min), digitPosition),                    correctingValue;                if (newMin < min) {                    correctingValue = _math.pow(10, -digitPosition);                    newMin = utils.applyPrecisionByMinDelta(newMin, correctingValue, newMin + correctingValue)                }                if (newMin > max)                    newMin = min;                return newMin            },            _getTickManagerData: function() {                var that = this,                    options = that._options,                    screenDelta = that._getScreenDelta(),                    min = that._minBound,                    max = that._maxBound,                    categories = that._translator.getVisibleCategories() || that._translator.getBusinessRange().categories,                    customTicks = $.isArray(categories) ? categories : that._majorTicks && constants.convertTicksToValues(that._majorTicks),                    customMinorTicks = that._minorTicks && constants.convertTicksToValues(that._minorTicks);                if (_isNumber(min) && options.type !== constants.logarithmic)                    min = that._correctMinForTicks(min, max, screenDelta);                return {                        min: min,                        max: max,                        customTicks: customTicks,                        customMinorTicks: customMinorTicks,                        screenDelta: screenDelta                    }            },            _getTickManagerTypes: function() {                return {                        axisType: this._options.type,                        dataType: this._options.dataType                    }            },            _createTickManager: function() {                return DX.viz.core.CoreFactory.createTickManager({}, {}, {overlappingBehaviorType: this._overlappingBehaviorType})            },            _getMarginsOptions: function() {                var range = this._translator.getBusinessRange();                return {                        stick: range.stick,                        minStickValue: range.minStickValue,                        maxStickValue: range.maxStickValue,                        percentStick: range.percentStick,                        minValueMargin: this._options.minValueMargin,                        maxValueMargin: this._options.maxValueMargin,                        minSpaceCorrection: range.minSpaceCorrection,                        maxSpaceCorrection: range.maxSpaceCorrection                    }            },            _updateTickManager: function() {                var overlappingOptions = this._getOverlappingBehaviorOptions(),                    options;                options = _extend(true, {}, this._getMarginsOptions(), overlappingOptions, this._getTicksOptions());                this._tickManager.update(this._getTickManagerTypes(), this._getTickManagerData(), options)            },            _correctLabelAlignment: function() {                var that = this,                    labelOptions = that._options.label,                    overlappingBehavior = that._tickManager.getOverlappingBehavior();                if (overlappingBehavior && overlappingBehavior.mode === "rotate") {                    that._textOptions.rotate = overlappingBehavior.rotationAngle;                    if (!labelOptions.userAlignment)                        that._textOptions.align = constants.left                }                else if (!labelOptions.userAlignment)                    that._textOptions.align = labelOptions.alignment            },            _correctLabelFormat: function() {                this._options.label = this._tickManager.getOptions().labelOptions            },            getTicksValues: function() {                return {                        majorTicksValues: constants.convertTicksToValues(this._majorTicks || this.getMajorTicks()),                        minorTicksValues: constants.convertTicksToValues(this._minorTicks || this.getMinorTicks())                    }            },            getMajorTicks: function(withoutOverlappingBehavior) {                var that = this,                    majorTicks;                that._updateTickManager();                that._textOptions.rotate = 0;                majorTicks = constants.convertValuesToTicks(that._tickManager.getTicks(withoutOverlappingBehavior));                that._correctLabelAlignment();                that._correctLabelFormat();                return majorTicks            },            getMinorTicks: function() {                return constants.convertValuesToTicks(this._tickManager.getMinorTicks())            },            getDecimatedTicks: function() {                return constants.convertValuesToTicks(this._tickManager.getDecimatedTicks())            },            setTicks: function(ticks) {                this.resetTicks();                this._majorTicks = constants.convertValuesToTicks(ticks.majorTicks);                this._minorTicks = constants.convertValuesToTicks(ticks.minorTicks)            },            _deleteLabels: function() {                this._axisElementsGroup && this._axisElementsGroup.clear()            },            _drawTicks: function(ticks) {                var that = this,                    group = that._axisLineGroup;                _each(ticks || [], function(_, tick) {                    var coord = that._getTickCoord(tick),                        points;                    if (coord) {                        points = that._isHorizontal ? [coord.x1, coord.y1, coord.x2, coord.y2] : [coord.y1, coord.x1, coord.y2, coord.x2];                        tick.graphic = that._createPathElement(points, tick.tickStyle).append(group);                        coord.angle && that._rotateTick(tick, coord.angle)                    }                })            },            _createPathElement: function(points, attr, oposite) {                return this._renderer.path(points, "line").attr(attr).sharp(this._getSharpParam(oposite))            },            _createAxis: function(options) {                return this._createAxisElement().attr(options).sharp(this._getSharpParam(true))            },            _getTickCoord: function(tick) {                var coords;                if (_isDefined(tick.posX) && _isDefined(tick.posY))                    coords = {                        x1: tick.posX,                        y1: tick.posY - constants.halfTickLength,                        x2: tick.posX,                        y2: tick.posY + constants.halfTickLength                    };                else                    coords = null;                return coords            },            setPercentLabelFormat: function() {                if (!this._hasLabelFormat)                    this._options.label.format = "percent"            },            resetAutoLabelFormat: function() {                if (!this._hasLabelFormat)                    delete this._options.label.format            },            _drawLabels: function() {                var that = this,                    renderer = that._renderer,                    group = that._axisElementsGroup,                    emptyStrRegExp = /^\s+$/;                _each(that._majorTicks, function(_, tick) {                    var text = tick.labelText,                        xCoord,                        yCoord;                    if (_isDefined(text) && text !== "" && !emptyStrRegExp.test(text)) {                        xCoord = that._isHorizontal ? tick.labelPos.x : tick.labelPos.y;                        yCoord = that._isHorizontal ? tick.labelPos.y : tick.labelPos.x;                        if (!tick.label)                            tick.label = renderer.text(text, xCoord, yCoord).css(tick.labelFontStyle).attr(tick.labelStyle).append(group);                        else                            tick.label.css(tick.labelFontStyle).attr(tick.labelStyle).attr({                                text: text,                                x: xCoord,                                y: yCoord                            });                        tick.label.data({argument: tick.value})                    }                })            },            getMultipleAxesSpacing: function() {                return this._options.multipleAxesSpacing || 0            },            _drawTitle: _noop,            _getGridLineDrawer: function(borderOptions) {                var that = this,                    translator = that._translator,                    additionalTranslator = that._additionalTranslator,                    isHorizontal = that._isHorizontal,                    canvasStart = isHorizontal ? constants.left : constants.top,                    canvasEnd = isHorizontal ? constants.right : constants.bottom,                    positionFrom = additionalTranslator.translateSpecialCase(constants.canvasPositionStart),                    positionTo = additionalTranslator.translateSpecialCase(constants.canvasPositionEnd),                    firstBorderLinePosition = borderOptions.visible && borderOptions[canvasStart] ? translator.translateSpecialCase(constants.canvasPositionPrefix + canvasStart) : undefined,                    lastBorderLinePosition = borderOptions.visible && borderOptions[canvasEnd] ? translator.translateSpecialCase(constants.canvasPositionPrefix + canvasEnd) : undefined,                    getPoints = isHorizontal ? function(tick) {                        return tick.posX !== null ? [tick.posX, positionFrom, tick.posX, positionTo] : null                    } : function(tick) {                        return tick.posX !== null ? [positionFrom, tick.posX, positionTo, tick.posX] : null                    };                return function(tick) {                        var points;                        if (_abs(tick.posX - firstBorderLinePosition) < MAX_GRID_BORDER_ADHENSION || _abs(tick.posX - lastBorderLinePosition) < MAX_GRID_BORDER_ADHENSION)                            return;                        points = getPoints(tick);                        return points && that._createPathElement(points, tick.gridStyle)                    }            },            _drawGrids: function(ticks, borderOptions) {                var that = this,                    group = that._axisGridGroup,                    drawLine = that._getGridLineDrawer(borderOptions || {visible: false});                _each(ticks || [], function(_, tick) {                    tick.grid = drawLine(tick);                    tick.grid && tick.grid.append(group)                })            },            _getConstantLinePos: function(lineValue, canvasStart, canvasEnd) {                var parsedValue = this._validateUnit(lineValue, "E2105", "constantLine"),                    value = this._getTranslatedCoord(parsedValue);                if (!_isDefined(value) || value < _math.min(canvasStart, canvasEnd) || value > _math.max(canvasStart, canvasEnd))                    return {};                return {                        value: value,                        parsedValue: parsedValue                    }            },            _createConstantLine: function(value, attr) {                var that = this,                    additionalTranslator = this._additionalTranslator,                    positionFrom = additionalTranslator.translateSpecialCase(constants.canvasPositionStart),                    positionTo = additionalTranslator.translateSpecialCase(constants.canvasPositionEnd),                    points = this._isHorizontal ? [value, positionTo, value, positionFrom] : [positionFrom, value, positionTo, value];                return that._createPathElement(points, attr)            },            _drawConstantLinesAndLabels: function(lineOptions, canvasStart, canvasEnd) {                if (!_isDefined(lineOptions.value))                    return;                var that = this,                    pos = that._getConstantLinePos(lineOptions.value, canvasStart, canvasEnd),                    labelOptions = lineOptions.label || {},                    value = pos.value,                    attr = {                        stroke: lineOptions.color,                        "stroke-width": lineOptions.width,                        dashStyle: lineOptions.dashStyle                    };                if (!_isDefined(value)) {                    that._constantLines.push(null);                    if (labelOptions.visible)                        that._constantLineLabels.push(null);                    return                }                that._constantLines.push(that._createConstantLine(value, attr).append(that._axisConstantLineGroup));                that._constantLineLabels.push(labelOptions.visible ? that._drawConstantLineLabels(pos.parsedValue, labelOptions, value) : null)            },            _drawConstantLine: function() {                var that = this,                    options = that._options,                    data = options.constantLines,                    canvas = that._getCanvasStartEnd();                if (that._translator.getBusinessRange().stubData)                    return;                that._constantLines = [];                that._constantLineLabels = [];                _each(data, function(_, dataItem) {                    that._drawConstantLinesAndLabels(dataItem, canvas.start, canvas.end)                })            },            _drawConstantLineLabels: function(parsedValue, lineLabelOptions, value) {                var that = this,                    text = lineLabelOptions.text,                    options = that._options,                    labelOptions = options.label,                    coords;                that._checkAlignmentConstantLineLabels(lineLabelOptions);                text = _isDefined(text) ? text : constants.formatLabel(parsedValue, labelOptions);                coords = that._getConstantLineLabelsCoords(value, lineLabelOptions);                return that._renderer.text(text, coords.x, coords.y).css(core.utils.patchFontOptions(_extend({}, labelOptions.font, lineLabelOptions.font))).attr({align: coords.align}).append(that._axisConstantLineGroup)            },            _adjustConstantLineLabels: _noop,            _getStripPos: function(startValue, endValue, canvasStart, canvasEnd, range) {                var isContinous = !!(range.minVisible || range.maxVisible),                    categories = range.categories || [],                    start,                    end,                    firstValue = startValue,                    lastValue = endValue,                    startCategoryIndex,                    endCategoryIndex,                    min = range.minVisible;                if (!isContinous) {                    startCategoryIndex = $.inArray(startValue, categories);                    endCategoryIndex = $.inArray(endValue, categories);                    if (startCategoryIndex === -1 || endCategoryIndex === -1)                        return {                                stripFrom: 0,                                stripTo: 0                            };                    if (startCategoryIndex > endCategoryIndex) {                        firstValue = endValue;                        lastValue = startValue                    }                }                start = this._getTranslatedCoord(this._validateUnit(firstValue, "E2105", "strip"), -1);                end = this._getTranslatedCoord(this._validateUnit(lastValue, "E2105", "strip"), 1);                if (!_isDefined(start) && isContinous)                    start = startValue < min ? canvasStart : canvasEnd;                if (!_isDefined(end) && isContinous)                    end = endValue < min ? canvasStart : canvasEnd;                return start < end ? {                        stripFrom: start,                        stripTo: end                    } : {                        stripFrom: end,                        stripTo: start                    }            },            _createStrip: function(fromPoint, toPoint, attr) {                var x,                    y,                    width,                    height,                    additionalTranslator = this._additionalTranslator,                    positionFrom = additionalTranslator.translateSpecialCase(constants.canvasPositionStart),                    positionTo = additionalTranslator.translateSpecialCase(constants.canvasPositionEnd);                if (this._isHorizontal) {                    x = fromPoint;                    y = _math.min(positionFrom, positionTo);                    width = toPoint - fromPoint;                    height = _abs(positionFrom - positionTo)                }                else {                    x = _math.min(positionFrom, positionTo);                    y = fromPoint;                    width = _abs(positionFrom - positionTo);                    height = _abs(fromPoint - toPoint)                }                return this._renderer.rect(x, y, width, height).attr(attr)            },            _drawStrip: function() {                var that = this,                    options = that._options,                    stripData = options.strips,                    canvas = this._getCanvasStartEnd(),                    i,                    stripOptions,                    stripPos,                    stripLabelOptions,                    attr,                    range = that._translator.getBusinessRange();                if (range.stubData)                    return;                that._strips = [];                that._stripLabels = [];                for (i = 0; i < stripData.length; i++) {                    stripOptions = stripData[i];                    stripLabelOptions = stripOptions.label || {};                    attr = {fill: stripOptions.color};                    if (_isDefined(stripOptions.startValue) && _isDefined(stripOptions.endValue) && _isDefined(stripOptions.color)) {                        stripPos = that._getStripPos(stripOptions.startValue, stripOptions.endValue, canvas.start, canvas.end, range);                        if (stripPos.stripTo - stripPos.stripFrom === 0 || !_isDefined(stripPos.stripTo) || !_isDefined(stripPos.stripFrom)) {                            that._strips.push(null);                            if (stripLabelOptions.text)                                that._stripLabels.push(null);                            continue                        }                        that._strips.push(that._createStrip(stripPos.stripFrom, stripPos.stripTo, attr).append(that._axisStripGroup));                        that._stripLabels.push(stripLabelOptions.text ? that._drawStripLabel(stripLabelOptions, stripPos.stripFrom, stripPos.stripTo) : null)                    }                }            },            _drawStripLabel: function(stripLabelOptions, stripFrom, stripTo) {                var that = this,                    options = that._options,                    coords = that._getStripLabelCoords(stripLabelOptions, stripFrom, stripTo);                return that._renderer.text(stripLabelOptions.text, coords.x, coords.y).css(core.utils.patchFontOptions(_extend({}, options.label.font, stripLabelOptions.font))).attr({align: coords.align}).append(that._axisLabelGroup)            },            _adjustStripLabels: function() {                var that = this,                    labels = that._stripLabels,                    rects = that._strips,                    i,                    coords;                if (labels === undefined && rects === undefined)                    return;                for (i = 0; i < labels.length; i++)                    if (labels[i] !== null) {                        coords = that._getAdjustedStripLabelCoords(that._options.strips[i], labels[i], rects[i]);                        labels[i].move(coords.x, coords.y)                    }            },            _initAxisPositions: _noop,            _adjustLabels: function() {                var that = this,                    options = that._options,                    majorTicks = that._majorTicks,                    majorTicksLength = majorTicks.length,                    isHorizontal = that._isHorizontal,                    overlappingBehavior = that._tickManager ? that._tickManager.getOverlappingBehavior() : options.label.overlappingBehavior,                    position = options.position,                    label,                    labelHeight,                    isNeedLabelAdjustment,                    staggeringSpacing,                    i,                    box,                    hasLabels = false,                    boxAxis = that._axisElementsGroup && that._axisElementsGroup.getBBox() || {};                _each(majorTicks, function(_, tick) {                    if (tick.label) {                        tick.label.attr(that._getLabelAdjustedCoord(tick, boxAxis));                        hasLabels = true                    }                });                isNeedLabelAdjustment = hasLabels && isHorizontal && overlappingBehavior && overlappingBehavior.mode === "stagger";                if (isNeedLabelAdjustment) {                    labelHeight = 0;                    for (i = 0; i < majorTicksLength; i = i + 2) {                        label = majorTicks[i].label;                        box = label && label.getBBox() || {};                        if (box.height > labelHeight)                            labelHeight = box.height                    }                    staggeringSpacing = overlappingBehavior.staggeringSpacing;                    labelHeight = _round(labelHeight) + staggeringSpacing;                    for (i = 1; i < majorTicksLength; i = i + 2) {                        label = majorTicks[i].label;                        if (label)                            if (position === constants.bottom)                                label.move(0, labelHeight);                            else if (position === constants.top)                                label.move(0, -labelHeight)                    }                    for (i = 0; i < majorTicksLength; i++)                        majorTicks[i].label && majorTicks[i].label.rotate(0)                }            },            _getLabelAdjustedCoord: function(tick, boxAxis) {                var that = this,                    options = that._options,                    box = tick.label.getBBox(),                    x,                    y,                    isHorizontal = that._isHorizontal,                    position = options.position,                    shift = that.padding && that.padding[position] || 0,                    textOptions = that._textOptions,                    labelSettingsY = tick.label.attr("y");                if (isHorizontal && position === constants.bottom)                    y = 2 * labelSettingsY - box.y + shift;                else if (!isHorizontal) {                    if (position === constants.left)                        if (textOptions.align === constants.right)                            x = box.x + box.width - shift;                        else if (textOptions.align === constants.center)                            x = box.x + box.width / 2 - shift - (boxAxis.width / 2 || 0);                        else                            x = box.x - shift - (boxAxis.width || 0);                    else if (textOptions.align === constants.center)                        x = box.x + box.width / 2 + (boxAxis.width / 2 || 0) + shift;                    else if (textOptions.align === constants.right)                        x = box.x + box.width + (boxAxis.width || 0) + shift;                    else                        x = box.x + shift;                    y = labelSettingsY + ~~(labelSettingsY - box.y - box.height / 2)                }                else if (isHorizontal && position === constants.top)                    y = 2 * labelSettingsY - box.y - box.height - shift;                return {                        x: x,                        y: y                    }            },            _adjustTitle: _noop,            _createAxisGroups: function() {                var that = this,                    renderer = that._renderer,                    classSelector = WIDGET_CLASS + "-" + that._axisClass + "-";                that._axisGroup = renderer.g().attr({"class": classSelector + "axis"});                that._axisStripGroup = renderer.g().attr({"class": classSelector + "strips"});                that._axisGridGroup = renderer.g().attr({"class": classSelector + "grid"});                that._axisElementsGroup = renderer.g().attr({"class": classSelector + "elements"}).append(that._axisGroup);                that._axisLineGroup = renderer.g().attr({"class": classSelector + "line"}).append(that._axisGroup);                that._axisTitleGroup = renderer.g().attr({"class": classSelector + "title"}).append(that._axisGroup);                that._axisConstantLineGroup = renderer.g().attr({"class": classSelector + "constant-lines"});                that._axisLabelGroup = renderer.g().attr({"class": classSelector + "axis-labels"})            },            _clearAxisGroups: function(adjustAxis) {                var that = this,                    classSelector = WIDGET_CLASS + "-" + that._axisClass + "-";                that._axisGroup.remove();                that._axisStripGroup.remove();                that._axisLabelGroup.remove();                that._axisConstantLineGroup.remove();                that._axisGridGroup.remove();                if (that._axisTitleGroup)                    that._axisTitleGroup.clear();                else if (!adjustAxis)                    that._axisTitleGroup = that._renderer.g().attr({"class": classSelector + "title"}).append(that._axisGroup);                if (that._axisElementsGroup)                    that._axisElementsGroup.clear();                else if (!adjustAxis)                    that._axisElementsGroup = that._renderer.g().attr({"class": classSelector + "elements"}).append(that._axisGroup);                that._axisLineGroup.clear();                that._axisStripGroup.clear();                that._axisGridGroup.clear();                that._axisConstantLineGroup.clear();                that._axisLabelGroup.clear()            },            _initTicks: function(ticks, tickOptions, gridOptions, withLabels) {                var that = this,                    options = that._options,                    tickStyle = {                        stroke: tickOptions.color,                        "stroke-width": 1,                        "stroke-opacity": tickOptions.opacity                    },                    gridStyle = {                        stroke: gridOptions.color,                        "stroke-width": gridOptions.width,                        "stroke-opacity": gridOptions.opacity                    },                    currentLabelConst = that.getCurrentLabelPos(),                    categoryToSkip = that._getSkippedCategory();                _each(ticks || [], function(_, tick) {                    var coord;                    if (!(categoryToSkip && categoryToSkip === tick.value)) {                        coord = that._getTranslatedValue(tick.value, that._axisPosition, that._tickOffset);                        tick.posX = coord.x;                        tick.posY = coord.y;                        tick.angle = coord.angle                    }                    tick.tickStyle = tickStyle;                    tick.gridStyle = gridStyle;                    if (withLabels) {                        tick.labelText = constants.formatLabel(tick.value, options.label, {                            min: that._minBound,                            max: that._maxBound                        });                        tick.labelPos = that._getTranslatedValue(tick.value, currentLabelConst);                        tick.labelStyle = that._textOptions;                        tick.labelFontStyle = that._textFontStyles;                        tick.labelHint = constants.formatHint(tick.value, options.label, {                            min: that._minBound,                            max: that._maxBound                        })                    }                })            },            _setTickOffset: function() {                var options = this._options,                    discreteAxisDivisionMode = options.discreteAxisDivisionMode;                this._tickOffset = +(discreteAxisDivisionMode !== "crossLabels" || !discreteAxisDivisionMode)            },            drawGrids: function(borderOptions) {                var that = this,                    options = that._options;                borderOptions = borderOptions || {};                that._axisGridGroup.append(that._gridContainerGroup);                if (options.grid.visible)                    that._drawGrids(that._majorTicks.concat(that._decimatedTicks), borderOptions);                options.minorGrid.visible && that._drawGrids(that._minorTicks, borderOptions)            },            draw: function(adjustAxis) {                var that = this,                    options = that._options,                    areLabelsVisible;                if (that._axisGroup)                    that._clearAxisGroups(adjustAxis);                areLabelsVisible = options.label.visible && that._axisElementsGroup && !that._translator.getBusinessRange().stubData;                that._updateTranslatorInterval();                that._initAxisPositions();                that._initTicks(that._majorTicks, options.tick, options.grid, areLabelsVisible);                that._initTicks(that._decimatedTicks, options.tick, options.grid, false);                that._initTicks(that._minorTicks, options.minorTick, options.minorGrid);                if (!that._virtual) {                    options.visible && that._drawAxis();                    if (options.tick.visible) {                        that._drawTicks(that._majorTicks);                        that._drawTicks(that._decimatedTicks)                    }                    options.minorTick.visible && that._drawTicks(that._minorTicks);                    areLabelsVisible && that._drawLabels();                    that._drawTitle()                }                options.strips && that._drawStrip();                options.constantLines && that._drawConstantLine();                that._axisStripGroup.append(that._stripsGroup);                that._axisConstantLineGroup.append(that._constantLinesGroup);                that._axisGroup.append(that._axesContainerGroup);                that._axisLabelGroup.append(that._labelAxesGroup);                that._adjustConstantLineLabels();                areLabelsVisible && that._adjustLabels();                that._createHints();                that._adjustStripLabels();                that._adjustTitle();                that._setBoundingRect()            },            _createHints: function() {                var that = this;                _each(that._majorTicks || [], function(_, tick) {                    var labelHint = tick.labelHint;                    if (_isDefined(labelHint) && labelHint !== "")                        tick.label.setTitle(labelHint)                })            },            _setBoundingRect: function() {                var that = this,                    options = that._options,                    axisBox = that._axisElementsGroup ? that._axisElementsGroup.getBBox() : {                        x: 0,                        y: 0,                        width: 0,                        height: 0,                        isEmpty: true                    },                    lineBox = that._axisLineGroup.getBBox(),                    placeholderSize = options.placeholderSize,                    start,                    isHorizontal = that._isHorizontal,                    coord = isHorizontal ? "y" : "x",                    side = isHorizontal ? "height" : "width",                    shiftCoords = options.crosshairEnabled ? isHorizontal ? LABEL_BACKGROUND_PADDING_Y : LABEL_BACKGROUND_PADDING_X : 0,                    axisTitleBox = that._title && that._axisTitleGroup ? that._axisTitleGroup.getBBox() : axisBox;                if (axisBox.isEmpty && axisTitleBox.isEmpty && !placeholderSize) {                    that.boundingRect = axisBox;                    return                }                start = lineBox[coord] || that._axisPosition;                if (options.position === (isHorizontal && constants.bottom || constants.right)) {                    axisBox[side] = placeholderSize || axisTitleBox[coord] + axisTitleBox[side] - start + shiftCoords;                    axisBox[coord] = start                }                else {                    axisBox[side] = placeholderSize || lineBox[side] + start - axisTitleBox[coord] + shiftCoords;                    axisBox[coord] = axisTitleBox.isEmpty ? start : axisTitleBox[coord] - shiftCoords                }                that.boundingRect = axisBox            },            getBoundingRect: function() {                return this._axisElementsGroup ? this.boundingRect : {                        x: 0,                        y: 0,                        width: 0,                        height: 0                    }            },            shift: function(x, y) {                var settings = {};                if (x)                    settings.translateX = x;                if (y)                    settings.translateY = y;                this._axisGroup.attr(settings)            },            applyClipRects: function(elementsClipID, canvasClipID) {                this._axisGroup.attr({clipId: canvasClipID});                this._axisStripGroup.attr({clipId: elementsClipID})            },            validate: function(isArgumentAxis) {                var that = this,                    options = that._options,                    parseUtils = new core.ParseUtils,                    dataType = isArgumentAxis ? options.argumentType : options.valueType,                    parser = dataType ? parseUtils.getParser(dataType, "axis") : function(unit) {                        return unit                    };                that.parser = parser;                options.dataType = dataType;                if (options.min !== undefined)                    options.min = that._validateUnit(options.min, "E2106");                if (options.max !== undefined)                    options.max = that._validateUnit(options.max, "E2106");                if (that._minBound !== undefined)                    that._minBound = that._validateUnit(that._minBound);                if (that._maxBound !== undefined)                    that._maxBound = that._validateUnit(that._maxBound)            },            _validateUnit: function(unit, idError, parameters) {                var that = this;                unit = that.parser(unit);                if (unit === undefined && idError)                    that._incidentOccured(idError, [parameters]);                return unit            },            zoom: function(min, max, skipAdjusting) {                var that = this,                    minOpt = that._options.min,                    maxOpt = that._options.max;                skipAdjusting = skipAdjusting || that._options.type === constants.discrete;                min = that._validateUnit(min);                max = that._validateUnit(max);                if (!skipAdjusting) {                    if (minOpt !== undefined) {                        min = minOpt > min ? minOpt : min;                        max = minOpt > max ? minOpt : max                    }                    if (maxOpt !== undefined) {                        max = maxOpt < max ? maxOpt : max;                        min = maxOpt < min ? maxOpt : min                    }                }                that._zoomArgs = {                    min: min,                    max: max                };                return that._zoomArgs            },            resetZoom: function() {                this._zoomArgs = null            },            getRangeData: function() {                var that = this,                    options = that._options,                    minMax = that._getMinMax(),                    min = minMax.min,                    max = minMax.max,                    zoomArgs = that._zoomArgs || {},                    type = options.type,                    rangeMin,                    rangeMax,                    rangeMinVisible,                    rangeMaxVisible;                if (type === constants.logarithmic) {                    min = min <= 0 ? undefined : min;                    max = max <= 0 ? undefined : max                }                if (type !== constants.discrete) {                    rangeMin = min;                    rangeMax = max;                    if (_isDefined(min) && _isDefined(max)) {                        rangeMin = min < max ? min : max;                        rangeMax = max > min ? max : min                    }                    rangeMinVisible = _isDefined(zoomArgs.min) ? zoomArgs.min : rangeMin;                    rangeMaxVisible = _isDefined(zoomArgs.max) ? zoomArgs.max : rangeMax                }                else {                    rangeMinVisible = _isDefined(zoomArgs.min) ? zoomArgs.min : min;                    rangeMaxVisible = _isDefined(zoomArgs.max) ? zoomArgs.max : max                }                return {                        min: rangeMin,                        max: rangeMax,                        stick: that._getStick(),                        categories: options.categories,                        dataType: options.dataType,                        axisType: type,                        base: options.logarithmBase,                        invert: options.inverted,                        addSpiderCategory: that._getSpiderCategoryOption(),                        minVisible: rangeMinVisible,                        maxVisible: rangeMaxVisible                    }            },            _setType: function(axesType, drawingType) {                var that = this;                _each(DX.viz.charts.axes[axesType][drawingType], function(methodName, method) {                    that[methodName] = method                })            },            _getSharpParam: function() {                return true            },            getSpiderTicks: _noop,            setSpiderTicks: _noop,            measureLabels: _noop,            coordsIn: _noop,            _getSkippedCategory: _noop        }    })(jQuery, DevExpress);    /*! Module viz-charts, file scrollBar.js */    (function($, DX, math) {        var MIN_SCROLL_BAR_SIZE = 2,            isDefined = DX.utils.isDefined,            _min = math.min,            _max = math.max;        DX.viz.charts.ScrollBar = function(renderer, group) {            this._translator = DX.viz.core.CoreFactory.createTranslator2D({}, {}, {});            this._scroll = renderer.rect().append(group);            this._addEvents()        };        function _getXCoord(canvas, pos, offset, width) {            var x = 0;            if (pos === "right")                x = canvas.width - canvas.right + offset;            else if (pos === "left")                x = canvas.left - offset - width;            return x        }        function _getYCoord(canvas, pos, offset, width) {            var y = 0;            if (pos === "top")                y = canvas.top - offset;            else if (pos === "bottom")                y = canvas.height - canvas.bottom + width + offset;            return y        }        DX.viz.charts.ScrollBar.prototype = {            _addEvents: function() {                var that = this,                    $scroll = $(that._scroll.element),                    startPosX = 0,                    startPosY = 0,                    scrollChangeHandler = function(e) {                        var dX = (startPosX - e.pageX) * that._scale,                            dY = (startPosY - e.pageY) * that._scale;                        $scroll.trigger(new $.Event("dxc-scroll-move", $.extend(e, {                            type: "dxc-scroll-move",                            pointers: [{                                    pageX: startPosX + dX,                                    pageY: startPosY + dY                                }]                        })))                    };                $scroll.on("dxpointerdown", function(e) {                    startPosX = e.pageX;                    startPosY = e.pageY;                    $scroll.trigger(new $.Event("dxc-scroll-start", {pointers: [{                                pageX: startPosX,                                pageY: startPosY                            }]}));                    $(document).on("dxpointermove", scrollChangeHandler)                });                $(document).on("dxpointerup", function() {                    $(document).off("dxpointermove", scrollChangeHandler)                })            },            update: function(options) {                var that = this,                    position = options.position,                    isVertical = options.rotated,                    defaultPosition = isVertical ? "right" : "top",                    secondaryPosition = isVertical ? "left" : "bottom";                if (position !== defaultPosition && position !== secondaryPosition)                    position = defaultPosition;                that._scroll.attr({                    rotate: !options.rotated ? -90 : 0,                    rotateX: 0,                    rotateY: 0,                    fill: options.color,                    width: options.width,                    opacity: options.opacity                });                that._layoutOptions = {                    width: options.width,                    offset: options.offset,                    vertical: isVertical,                    position: position                };                return that            },            init: function(range, canvas) {                var that = this;                that._translateWithOffset = range.axisType === "discrete" && !range.stick && 1 || 0;                that._translator.update($.extend({}, range, {                    minVisible: null,                    maxVisible: null,                    visibleCategories: null                }), $.extend({}, canvas), {direction: that._layoutOptions.vertical ? "vertical" : "horizontal"});                return that            },            getOptions: function() {                return this._layoutOptions            },            shift: function(x, y) {                this._scroll.attr({                    translateX: x,                    translateY: y                })            },            setPane: function(panes) {                var position = this._layoutOptions.position,                    pane;                if (position === "left" || position === "top")                    pane = panes[0];                else                    pane = panes[panes.length - 1];                this.pane = pane.name;                this._canvas = pane.canvas;                return this            },            getMultipleAxesSpacing: function() {                return 0            },            getBoundingRect: function() {                var options = this._layoutOptions,                    isVertical = options.vertical,                    offset = options.offset,                    width = options.width,                    pos = options.position,                    size = width + offset,                    canvas = this._canvas;                return isVertical ? {                        x: _getXCoord(canvas, pos, offset, width),                        y: canvas.top,                        width: size,                        height: canvas.height - canvas.top - canvas.bottom                    } : {                        x: canvas.left,                        y: _getYCoord(canvas, pos, offset, width),                        width: canvas.width - canvas.left - canvas.right,                        height: size                    }            },            applyLayout: function() {                var canvas = this._canvas,                    options = this._layoutOptions,                    pos = options.position,                    offset = options.offset,                    width = options.width;                this.shift(_getXCoord(canvas, pos, offset, width), _getYCoord(canvas, pos, offset, width))            },            setPosition: function(min, max) {                var that = this,                    translator = that._translator,                    minPoint = isDefined(min) ? translator.translate(min, -that._translateWithOffset) : translator.translate("canvas_position_start"),                    maxPoint = isDefined(max) ? translator.translate(max, that._translateWithOffset) : translator.translate("canvas_position_end");                that._offset = _min(minPoint, maxPoint);                that._scale = translator.getScale(min, max);                that._applyPosition(_min(minPoint, maxPoint), _max(minPoint, maxPoint))            },            transform: function(translate, scale) {                var x = this._translator.getCanvasVisibleArea().min,                    dx = x - (x * scale - translate),                    lx = this._offset + dx / (this._scale * scale);                this._applyPosition(lx, lx + this._translator.canvasLength / (this._scale * scale))            },            dispose: function() {                this._scroll.dispose();                this._scroll = this._translator = null            },            _applyPosition: function(x1, x2) {                var that = this,                    visibleArea = that._translator.getCanvasVisibleArea(),                    height;                x1 = _max(x1, visibleArea.min);                x1 = _min(x1, visibleArea.max);                x2 = _min(x2, visibleArea.max);                x2 = _max(x2, visibleArea.min);                height = math.abs(x2 - x1);                that._scroll.attr({                    y: x1,                    height: height < MIN_SCROLL_BAR_SIZE ? MIN_SCROLL_BAR_SIZE : height                })            }        }    })(jQuery, DevExpress, Math);    /*! Module viz-charts, file baseChart.js */    (function($, DX, undefined) {        var ui = DX.ui,            charts = DX.viz.charts,            utils = DX.utils,            ACTIONS_BY_PRIORITY = ['reinit', '_reinitDataSource', '_dataInit', 'force_render', "_resize"],            core = DX.viz.core,            _each = $.each,            _map = $.map,            _extend = $.extend,            DEFAULT_ANIMATION_OPTIONS = {asyncSeriesRendering: true},            _isDefined = utils.isDefined,            DEFAULT_OPACITY = 0.3;        function createEventMapObject(name, deprecatedArgs) {            return {                    name: name,                    deprecated: name,                    deprecatedContext: function(arg) {                        return arg.target                    },                    deprecatedArgs: deprecatedArgs || function(arg) {                        return [arg.target, arg.jQueryEvent]                    }                }        }        function checkHeightLabelsInCanvas(points, canvas, isRotated) {            var commonLabelSize = 0,                canvasSize = canvas.end - canvas.start,                label,                bbox;            for (var i = 0; i < points.length; i++) {                label = points[i].getLabel();                if (label.isVisible()) {                    bbox = label.getBoundingRect();                    commonLabelSize += isRotated ? bbox.width : bbox.height                }                else                    points[i] = null            }            if (canvasSize > 0)                while (commonLabelSize > canvasSize)                    commonLabelSize -= killSmallValues(points, isRotated)        }        function killSmallValues(points, isRotated) {            var smallestValuePoint = {originalValue: Infinity},                label,                bbox,                indexOfPoint;            _each(points, function(index, point) {                if (point && smallestValuePoint.originalValue >= point.originalValue) {                    smallestValuePoint = point;                    indexOfPoint = index                }            });            if (indexOfPoint !== null) {                label = points[indexOfPoint].getLabel();                bbox = label.getBoundingRect();                label.hide();                points[indexOfPoint] = null;                return isRotated ? bbox.width : bbox.height            }            return 0        }        function resolveLabelOverlappingInOneDirection(points, canvas, isRotated, shiftFunction) {            var stubCanvas = {                    start: isRotated ? canvas.left : canvas.top,                    end: isRotated ? canvas.width - canvas.right : canvas.height - canvas.bottom                };            checkHeightLabelsInCanvas(points, stubCanvas, isRotated);            var rollingStocks = $.map(points, function(point) {                    return point && new RollingStock(point, isRotated, shiftFunction)                });            rollingStocks.sort(function(a, b) {                return a.getPointPosition() - b.getPointPosition()            });            if (!checkStackOverlap(rollingStocks))                return;            rollingStocks.reverse();            moveRollingStock(rollingStocks, stubCanvas)        }        function overlapRollingStock(firstRolling, secondRolling) {            if (!firstRolling || !secondRolling)                return;            return firstRolling.getBoundingRect().end > secondRolling.getBoundingRect().start        }        function checkStackOverlap(rollingStocks) {            var i,                j,                currentRollingStock,                nextRollingStock,                overlap;            for (i = 0; i < rollingStocks.length; i++) {                currentRollingStock = rollingStocks[i];                for (j = i + 1; j < rollingStocks.length; j++) {                    nextRollingStock = rollingStocks[j];                    if (overlapRollingStock(currentRollingStock, nextRollingStock)) {                        currentRollingStock.toChain(nextRollingStock);                        overlap = true;                        rollingStocks[j] = null                    }                }            }            return overlap        }        function moveRollingStock(rollingStocks, canvas) {            var i,                j,                currentRollingStock,                nextRollingStock,                currentBBox,                nextBBox;            for (i = 0; i < rollingStocks.length; i++) {                currentRollingStock = rollingStocks[i];                if (rollingStocksIsOut(currentRollingStock, canvas)) {                    currentBBox = currentRollingStock.getBoundingRect();                    for (j = i + 1; j < rollingStocks.length; j++) {                        nextRollingStock = rollingStocks[j];                        if (!nextRollingStock)                            continue;                        nextBBox = nextRollingStock.getBoundingRect();                        if (nextBBox.end > currentBBox.start - (currentBBox.end - canvas.end)) {                            nextRollingStock.toChain(currentRollingStock);                            rollingStocks[i] = currentRollingStock = null;                            break                        }                    }                }                currentRollingStock && currentRollingStock.setRollingStockInCanvas(canvas)            }        }        function rollingStocksIsOut(rollingStock, canvas) {            return rollingStock && rollingStock.getBoundingRect().end > canvas.end        }        function RollingStock(point, isRotated, shiftFunction) {            var label = point.getLabel(),                bbox = label.getBoundingRect();            this.labels = [label];            this.points = [point];            this.shiftFunction = shiftFunction;            this._bbox = {                start: isRotated ? bbox.x : bbox.y,                width: isRotated ? bbox.width : bbox.height,                end: isRotated ? bbox.x + bbox.width : bbox.y + bbox.height            };            this._pointPositionInitialize = isRotated ? point.getBoundaryCoords().x : point.getBoundaryCoords().y;            return this        }        RollingStock.prototype = {            toChain: function(nextRollingStock) {                var nextRollingStockBBox = nextRollingStock.getBoundingRect();                nextRollingStock.shift(nextRollingStockBBox.start - this._bbox.end);                this._changeBoxWidth(nextRollingStockBBox.width);                this.labels = this.labels.concat(nextRollingStock.labels);                this.points = this.points.concat(nextRollingStock.points)            },            getBoundingRect: function() {                return this._bbox            },            shift: function(shiftLength) {                var shiftFunction = this.shiftFunction;                _each(this.labels, function(index, label) {                    var bbox = label.getBoundingRect(),                        coords = shiftFunction(bbox, shiftLength, label);                    label.shift(coords.x, coords.y)                });                this._bbox.end -= shiftLength;                this._bbox.start -= shiftLength            },            setRollingStockInCanvas: function(canvas) {                if (this._bbox.end > canvas.end)                    this.shift(this._bbox.end - canvas.end)            },            getPointPosition: function() {                return this._pointPositionInitialize            },            _changeBoxWidth: function(width) {                this._bbox.end += width;                this._bbox.width += width            }        };        function getLegendFields(name) {            return {                    nameField: name + 'Name',                    colorField: name + 'Color',                    indexField: name + 'Index'                }        }        function getLegendSettings(legendDataField) {            var formatObjectFields = getLegendFields(legendDataField);            return {                    getFormatObject: function(data) {                        var res = {};                        res[formatObjectFields.indexField] = data.id;                        res[formatObjectFields.colorField] = data.states.normal.fill;                        res[formatObjectFields.nameField] = data.text;                        return res                    },                    textField: formatObjectFields.nameField                }        }        function checkOverlapping(firstRect, secondRect) {            return (firstRect.x <= secondRect.x && secondRect.x <= firstRect.x + firstRect.width || firstRect.x >= secondRect.x && firstRect.x <= secondRect.x + secondRect.width) && (firstRect.y <= secondRect.y && secondRect.y <= firstRect.y + firstRect.height || firstRect.y >= secondRect.y && firstRect.y <= secondRect.y + secondRect.height)        }        charts.overlapping = {resolveLabelOverlappingInOneDirection: resolveLabelOverlappingInOneDirection};        charts.BaseChart = core.BaseWidget.inherit({            _eventsMap: $.extend({}, core.BaseWidget.prototype._eventsMap, {                onSeriesClick: createEventMapObject("seriesClick"),                onPointClick: createEventMapObject("pointClick"),                onArgumentAxisClick: createEventMapObject("argumentAxisClick", function(arg) {                    return [arg.target, arg.argument, arg.jQueryEvent]                }),                onLegendClick: createEventMapObject("legendClick"),                onSeriesSelectionChanged: createEventMapObject('seriesSelectionChanged'),                onPointSelectionChanged: createEventMapObject('pointSelectionChanged'),                onSeriesHoverChanged: createEventMapObject('seriesHoverChanged'),                onPointHoverChanged: createEventMapObject('pointHoverChanged'),                onTooltipShown: createEventMapObject('tooltipShown'),                onTooltipHidden: createEventMapObject('tooltipHidden'),                onDone: createEventMapObject("done"),                seriesClick: {newName: 'onSeriesClick'},                pointClick: {newName: 'onPointClick'},                argumentAxisClick: {newName: 'onArgumentAxisClick'},                legendClick: {newName: 'onLegendClick'},                pointHoverChanged: {newName: 'onPointHoverChanged'},                seriesSelectionChanged: {newName: 'onSeriesSelectionChanged'},                pointSelectionChanged: {newName: 'onPointSelectionChanged'},                seriesHoverChanged: {newName: 'onSeriesHoverChanged'},                tooltipShown: {newName: 'onTooltipShown'},                tooltipHidden: {newName: 'onTooltipHidden'},                done: {newName: 'onDone'}            }),            _setDeprecatedOptions: function() {                this.callBase();                $.extend(this._deprecatedOptions, {                    seriesClick: {                        since: '14.2',                        message: "Use the 'onSeriesClick' option instead"                    },                    pointClick: {                        since: '14.2',                        message: "Use the 'onPointClick' option instead"                    },                    argumentAxisClick: {                        since: '14.2',                        message: "Use the 'onArgumentAxisClick' option instead"                    },                    legendClick: {                        since: '14.2',                        message: "Use the 'onLegendClick' option instead"                    },                    seriesSelectionChanged: {                        since: '14.2',                        message: "Use the 'onSeriesSelectionChanged' option instead"                    },                    pointSelectionChanged: {                        since: '14.2',                        message: "Use the 'onPointSelectionChanged' option instead"                    },                    seriesHoverChanged: {                        since: '14.2',                        message: "Use the 'onSeriesHoverChanged' option instead"                    },                    pointHoverChanged: {                        since: '14.2',                        message: "Use the 'onPointHoverChanged' option instead"                    },                    tooltipShown: {                        since: '14.2',                        message: "Use the 'onTooltipShown' option instead"                    },                    tooltipHidden: {                        since: '14.2',                        message: "Use the 'onTooltipHidden' option instead"                    },                    done: {                        since: '14.2',                        message: "Use the 'onDone' option instead"                    }                })            },            _rootClassPrefix: "dxc",            _rootClass: "dxc-chart",            _init: function() {                var that = this;                that.callBase.apply(that, arguments);                that._reinit()            },            _createThemeManager: function() {                var option = this.option(),                    themeManager = charts.factory.createThemeManager(option, this._chartType);                themeManager.setTheme(option.theme, option.rtlEnabled);                return themeManager            },            _initCore: function() {                var that = this;                that._canvasClipRect = that._renderer.clipRect();                that._createHtmlStructure();                that._createLegend();                that._needHandleRenderComplete = true;                that.layoutManager = charts.factory.createChartLayoutManager(that._layoutManagerOptions());                that._createScrollBar();                that._$element.on('contextmenu', function(event) {                    that.eventType = 'contextmenu';                    if (ui.events.isTouchEvent(event) || ui.events.isPointerEvent(event))                        event.preventDefault()                }).on('MSHoldVisual', function(event) {                    that.eventType = 'MSHoldVisual';                    event.preventDefault()                })            },            _layoutManagerOptions: function() {                return this._themeManager.getOptions("adaptiveLayout")            },            _reinit: function(needRedraw) {                var that = this;                charts._setCanvasValues(that._canvas);                that._createTracker();                that._reinitAxes();                that._reinitDataSource();                if (!that.series)                    that._dataSpecificInit();                that._correctAxes();                needRedraw && that._endLoading(function() {                    that._render({force: true})                })            },            _createHtmlStructure: function() {                var that = this,                    renderer = that._renderer;                that._backgroundRect = renderer.rect(0, 0, 0, 0).attr({                    fill: "gray",                    opacity: 0.0001                });                that._panesBackgroundGroup = renderer.g().attr({'class': 'dxc-background'});                that._titleGroup = renderer.g().attr({'class': 'dxc-title'});                that._legendGroup = renderer.g().attr({                    'class': 'dxc-legend',                    clipId: that._getCanvasClipRectID()                });                that._stripsGroup = renderer.g().attr({'class': 'dxc-strips-group'});                that._constantLinesGroup = renderer.g().attr({'class': 'dxc-constant-lines-group'});                that._axesGroup = renderer.g().attr({'class': 'dxc-axes-group'});                that._gridGroup = renderer.g().attr({'class': 'dxc-grids-group'});                that._panesBorderGroup = renderer.g().attr({'class': 'dxc-border'});                that._labelAxesGroup = renderer.g().attr({'class': 'dxc-strips-labels-group'});                that._scrollBarGroup = renderer.g().attr({'class': 'dxc-scroll-bar'});                that._seriesGroup = renderer.g().attr({'class': 'dxc-series-group'});                that._labelsGroup = renderer.g().attr({'class': 'dxc-labels-group'});                that._crosshairCursorGroup = renderer.g().attr({'class': 'dxc-crosshair-cursor'})            },            _disposeObjectsInArray: function(propName, fieldNames) {                $.each(this[propName] || [], function(_, item) {                    if (fieldNames && item)                        $.each(fieldNames, function(_, field) {                            item[field] && item[field].dispose()                        });                    else                        item && item.dispose()                });                this[propName] = null            },            _disposeCore: function() {                var that = this,                    disposeObject = function(propName) {                        if (that[propName]) {                            that[propName].dispose();                            that[propName] = null                        }                    },                    disposeObjectsInArray = this._disposeObjectsInArray;                clearTimeout(that._delayedRedraw);                that._renderer.stopAllAnimations();                disposeObjectsInArray.call(that, "businessRanges", ["arg", "val"]);                that.translators = null;                disposeObjectsInArray.call(that, "series");                disposeObject("layoutManager");                disposeObject("tracker");                disposeObject("chartTitle");                disposeObject("_crosshair");                that.paneAxis = null;                that._userOptions = null;                that._canvas = null;                disposeObject("_canvasClipRect");                disposeObject("_panesBackgroundGroup");                disposeObject("_titleGroup");                disposeObject("_scrollBarGroup");                disposeObject("_legendGroup");                disposeObject("_stripsGroup");                disposeObject("_constantLinesGroup");                disposeObject("_axesGroup");                disposeObject("_gridGroup");                disposeObject("_labelAxesGroup");                disposeObject("_panesBorderGroup");                disposeObject("_seriesGroup");                disposeObject("_labelsGroup");                disposeObject("_crosshairCursorGroup")            },            _getAnimationOptions: function() {                return $.extend({}, DEFAULT_ANIMATION_OPTIONS, this._themeManager.getOptions("animation"))            },            _getDefaultSize: function() {                return {                        width: 400,                        height: 400                    }            },            _getOption: function(name) {                return this._themeManager.getOptions(name)            },            _reinitDataSource: function() {                this._refreshDataSource()            },            _applySize: $.noop,            _resize: function() {                if (this._updateLockCount)                    this._processRefreshData("_resize");                else                    this._render(this.__renderOptions || {                        animate: false,                        isResize: true,                        updateTracker: false                    })            },            _createTracker: function() {                var that = this,                    themeManager = that._themeManager;                if (that.tracker)                    that.tracker.dispose();                that.tracker = charts.factory.createTracker({                    seriesSelectionMode: themeManager.getOptions('seriesSelectionMode'),                    pointSelectionMode: themeManager.getOptions('pointSelectionMode'),                    seriesGroup: that._seriesGroup,                    renderer: that._renderer,                    tooltip: that._tooltip,                    eventTrigger: that._eventTrigger                }, that.NAME)            },            _getTrackerSettings: function() {                var that = this;                return {                        series: that.series,                        legend: that.legend,                        legendCallback: $.proxy(that.legend.getActionCallback, that.legend)                    }            },            _updateTracker: function() {                this.tracker.update(this._getTrackerSettings())            },            _render: function(_options) {                var that = this,                    drawOptions,                    originalCanvas;                if (!that._initialized)                    return;                if (!that._canvas)                    return;                that._resetIsReady();                drawOptions = that._prepareDrawOptions(_options);                clearTimeout(that._delayedRedraw);                originalCanvas = that._canvas;                that._canvas = $.extend({}, that._canvas);                if (drawOptions.recreateCanvas)                    that.__currentCanvas = that._canvas;                else                    that._canvas = that.__currentCanvas;                that.DEBUG_canvas = that._canvas;                if (drawOptions.recreateCanvas) {                    that._reappendLoadingIndicator();                    that._updateCanvasClipRect()                }                that._renderer.stopAllAnimations(true);                charts._setCanvasValues(that._canvas);                that._cleanGroups(drawOptions);                that._renderElements(drawOptions);                that._canvas = originalCanvas            },            _renderElements: function(drawOptions) {                var that = this,                    preparedOptions = that._prepareToRender(drawOptions),                    isRotated = that._isRotated(),                    isLegendInside = that._isLegendInside(),                    trackerCanvases = [],                    layoutTargets = that._getLayoutTargets(),                    dirtyCanvas = $.extend({}, that._canvas),                    argBusinessRange,                    zoomMinArg,                    zoomMaxArg;                !drawOptions.isResize && that._scheduleLoadingIndicatorHiding();                that.DEBUG_dirtyCanvas = dirtyCanvas;                that._renderTitleAndLegend(drawOptions, isLegendInside);                that._renderAxes(drawOptions, preparedOptions, isRotated);                if (drawOptions.drawTitle && drawOptions.drawLegend && drawOptions.adjustAxes && that.layoutManager.needMoreSpaceForPanesCanvas(that._getLayoutTargets(), isRotated)) {                    that.layoutManager.updateDrawnElements(that._getAxesForTransform(isRotated), that._canvas, dirtyCanvas, that._getLayoutTargets(), isRotated);                    if (that.chartTitle)                        that.layoutManager.correctSizeElement(that.chartTitle, that._canvas);                    that._updateCanvasClipRect(dirtyCanvas);                    that._updateAxesLayout(drawOptions, preparedOptions, isRotated)                }                drawOptions.drawTitle && drawOptions.drawLegend && drawOptions.adjustAxes && that.layoutManager.placeDrawnElements(that._canvas);                that._applyClipRects(preparedOptions);                that._appendSeriesGroups();                that._createCrosshairCursor();                $.each(layoutTargets, function() {                    var canvas = this.canvas;                    trackerCanvases.push({                        left: canvas.left,                        right: canvas.width - canvas.right,                        top: canvas.top,                        bottom: canvas.height - canvas.bottom                    })                });                if (that._scrollBar) {                    argBusinessRange = that.businessRanges[0].arg;                    if (argBusinessRange.categories && argBusinessRange.categories.length <= 1)                        zoomMinArg = zoomMaxArg = undefined;                    else {                        zoomMinArg = argBusinessRange.minVisible;                        zoomMaxArg = argBusinessRange.maxVisible                    }                    that._scrollBar.init(argBusinessRange, layoutTargets[0].canvas).setPosition(zoomMinArg, zoomMaxArg)                }                drawOptions.updateTracker && that._updateTracker();                that.tracker.setCanvases({                    left: 0,                    right: that._canvas.width,                    top: 0,                    bottom: that._canvas.height                }, trackerCanvases);                that._updateLegendPosition(drawOptions, isLegendInside);                var timeout = that._getSeriesRenderTimeout(drawOptions);                if (timeout >= 0)                    that._delayedRedraw = setTimeout(renderSeries, timeout);                else                    renderSeries();                function renderSeries() {                    that._renderSeries(drawOptions, isRotated, isLegendInside)                }            },            _createCrosshairCursor: $.noop,            _appendSeriesGroups: function() {                var that = this,                    root = that._renderer.root;                that._seriesGroup.append(root);                that._labelsGroup.append(root);                that._appendAdditionalSeriesGroups()            },            _renderSeries: function(drawOptions, isRotated, isLegendInside) {                var that = this,                    themeManager = that._themeManager,                    resolveLabelOverlapping = themeManager.getOptions("resolveLabelOverlapping");                drawOptions.hideLayoutLabels = that.layoutManager.needMoreSpaceForPanesCanvas(that._getLayoutTargets(), that._isRotated()) && !themeManager.getOptions("adaptiveLayout").keepLabels;                that._drawSeries(drawOptions, isRotated);                resolveLabelOverlapping !== "none" && that._resolveLabelOverlapping(resolveLabelOverlapping);                that._adjustSeries();                that._renderTrackers(isLegendInside);                if (that._dataSource && that._dataSource.isLoaded())                    that._fulfillLoadingIndicatorHiding();                that.tracker.repairTooltip();                that._drawn();                that._renderCompleteHandler()            },            _getAnimateOption: function(series, drawOptions) {                return drawOptions.animate && series.getPoints().length <= drawOptions.animationPointsLimit && this._renderer.animationEnabled()            },            _resolveLabelOverlapping: function(resolveLabelOverlapping) {                var func;                switch (resolveLabelOverlapping) {                    case"stack":                        func = this._resolveLabelOverlappingStack;                        break;                    case"hide":                        func = this._resolveLabelOverlappingHide;                        break;                    case"shift":                        func = this._resolveLabelOverlappingShift;                        break                }                $.isFunction(func) && func.call(this)            },            _getVisibleSeries: function() {                return $.grep(this.getAllSeries(), function(series) {                        return series.isVisible()                    })            },            _resolveLabelOverlappingHide: function() {                var labels = $.map(this._getVisibleSeries(), function(series) {                        return $.map(series.getVisiblePoints(), function(point) {                                return point.getLabel()                            })                    }),                    currenctLabel,                    nextLabel,                    currenctLabelRect,                    nextLabelRect,                    i,                    j;                for (i = 0; i < labels.length; i++) {                    currenctLabel = labels[i];                    currenctLabelRect = currenctLabel.getBoundingRect();                    if (!currenctLabel.isVisible())                        continue;                    for (j = i + 1; j < labels.length; j++) {                        nextLabel = labels[j];                        nextLabelRect = nextLabel.getBoundingRect();                        if (checkOverlapping(currenctLabelRect, nextLabelRect))                            nextLabel.hide()                    }                }            },            _cleanGroups: function(drawOptions) {                var that = this;                that._stripsGroup.remove();                that._constantLinesGroup.remove();                that._axesGroup.remove();                that._gridGroup.remove();                that._labelAxesGroup.remove();                that._labelsGroup.remove();                that._crosshairCursorGroup.remove();                if (!drawOptions || drawOptions.drawLegend)                    that._legendGroup.remove().clear();                if (!drawOptions || drawOptions.drawTitle)                    that._titleGroup.remove().clear();                that._stripsGroup.clear();                that._constantLinesGroup.clear();                that._axesGroup.clear();                that._gridGroup.clear();                that._labelAxesGroup.clear();                that._labelsGroup.clear();                that._crosshairCursorGroup.clear()            },            _drawTitle: function() {                var that = this,                    options = that._themeManager.getOptions("title"),                    width = that._canvas.width - that._canvas.left - that._canvas.right;                options._incidentOccured = that._incidentOccured;                if (that.chartTitle)                    that.chartTitle.update(options, width);                else                    that.chartTitle = charts.factory.createTitle(that._renderer, options, that._titleGroup)            },            _createLegend: function() {                var legendSettings = getLegendSettings(this._legendDataField);                this.legend = core.CoreFactory.createLegend({                    renderer: this._renderer,                    group: this._legendGroup,                    backgroundClass: 'dxc-border',                    itemGroupClass: 'dxc-item',                    textField: legendSettings.textField,                    getFormatObject: legendSettings.getFormatObject                })            },            _updateLegend: function() {                var that = this,                    themeManager = that._themeManager,                    legendOptions = themeManager.getOptions('legend'),                    legendData = that._getLegendData();                legendOptions.containerBackgroundColor = themeManager.getOptions("containerBackgroundColor");                legendOptions._incidentOccured = that._incidentOccured;                that.legend.update(legendData, legendOptions)            },            _prepareDrawOptions: function(drawOptions) {                var animationOptions = this._getAnimationOptions(),                    options;                options = $.extend({}, {                    force: false,                    adjustAxes: true,                    drawLegend: true,                    drawTitle: true,                    adjustSeriesLabels: true,                    animate: animationOptions.enabled,                    animationPointsLimit: animationOptions.maxPointCountSupported,                    asyncSeriesRendering: animationOptions.asyncSeriesRendering,                    updateTracker: true                }, drawOptions, this.__renderOptions);                if (!_isDefined(options.recreateCanvas))                    options.recreateCanvas = options.adjustAxes && options.drawLegend && options.drawTitle;                return options            },            _processRefreshData: function(newRefreshAction) {                var currentRefreshActionPosition = $.inArray(this._currentRefreshData, ACTIONS_BY_PRIORITY),                    newRefreshActionPosition = $.inArray(newRefreshAction, ACTIONS_BY_PRIORITY);                if (!this._currentRefreshData || currentRefreshActionPosition >= 0 && newRefreshActionPosition < currentRefreshActionPosition)                    this._currentRefreshData = newRefreshAction            },            _getLegendData: function() {                var that = this;                return _map(this._getLegendTargets(), function(item) {                        var style = item.getLegendStyles(),                            textOpacity,                            opacity = style.normal.opacity;                        if (!item.isVisible()) {                            if (!_isDefined(opacity) || opacity > DEFAULT_OPACITY)                                opacity = DEFAULT_OPACITY;                            textOpacity = DEFAULT_OPACITY                        }                        return {                                text: item[that._legendItemTextField],                                id: item.index,                                textOpacity: textOpacity,                                states: {                                    hover: style.hover,                                    selection: style.selection,                                    normal: _extend({}, style.normal, {opacity: opacity})                                }                            }                    })            },            _seriesVisibilityChanged: function() {                this._specialProcessSeries();                this._populateBusinessRange();                this._renderer.stopAllAnimations(true);                this._updateLegend();                this._render({                    force: true,                    asyncSeriesRendering: false,                    updateTracker: false                })            },            _disposeSeries: function() {                var that = this;                $.each(that.series || [], function(_, series) {                    series.dispose()                });                that.series = null;                $.each(that.seriesFamilies || [], function(_, family) {                    family.dispose()                });                that.seriesFamilies = null;                that._needHandleRenderComplete = true            },            _optionChanged: function(args) {                var that = this,                    themeManager = that._themeManager,                    name = args.name;                themeManager.resetOptions(name);                themeManager.update(that._options);                that._scheduleLoadingIndicatorHiding();                if (name === 'animation') {                    that._renderer.updateAnimationOptions(that._getAnimationOptions());                    return                }                switch (name) {                    case'size':                    case'margin':                        that._invalidate();                        break;                    case'dataSource':                        that._needHandleRenderComplete = true;                        that._processRefreshData('_reinitDataSource');                        break;                    case'palette':                        themeManager.updatePalette(that.option(name));                        that._refreshSeries('_dataInit');                        break;                    case'series':                    case'commonSeriesSettings':                    case'containerBackgroundColor':                    case'dataPrepareSettings':                        that._refreshSeries('_dataInit');                        break;                    case'legend':                    case'seriesTemplate':                        that._processRefreshData('_dataInit');                        break;                    case'title':                        that._processRefreshData('force_render');                        break;                    case'valueAxis':                    case'argumentAxis':                    case'commonAxisSettings':                    case'panes':                    case'defaultPane':                        that._refreshSeries('reinit');                        that.paneAxis = {};                        break;                    case'rotated':                        that._createScrollBar();                        that._refreshSeries('reinit');                        break;                    case'customizePoint':                    case'customizeLabel':                        that._refreshSeries('reinit');                        break;                    case'scrollBar':                        that._createScrollBar();                        that._processRefreshData('force_render');                        break;                    case'tooltip':                        that._organizeStackPoints();                        break;                    default:                        that._processRefreshData('reinit')                }                that.callBase.apply(that, arguments)            },            _handleThemeOptionsCore: function() {                var that = this;                if (that._initialized) {                    that._scheduleLoadingIndicatorHiding();                    that._refreshSeries('reinit');                    that.beginUpdate();                    that._invalidate();                    that.endUpdate()                }            },            _refreshSeries: function(actionName) {                this._disposeSeries();                this._processRefreshData(actionName)            },            _refresh: function() {                var that = this;                that._renderer.stopAllAnimations(true);                if (that._currentRefreshData) {                    switch (that._currentRefreshData) {                        case'force_render':                            that._render({force: true});                            break;                        case'reinit':                            that._reinit(true);                            break;                        default:                            that[that._currentRefreshData] && that[that._currentRefreshData]()                    }                    delete that._currentRefreshData                }                else                    that._render({force: true})            },            _dataSourceOptions: function() {                return {paginate: false}            },            _updateCanvasClipRect: function(canvas) {                var that = this,                    width,                    height;                canvas = canvas || that._canvas;                width = Math.max(canvas.width - canvas.left - canvas.right, 0);                height = Math.max(canvas.height - canvas.top - canvas.bottom, 0);                that._canvasClipRect.attr({                    x: canvas.left,                    y: canvas.top,                    width: width,                    height: height                });                that._backgroundRect.attr({                    x: canvas.left,                    y: canvas.top,                    width: width,                    height: height                }).append(that._renderer.root).toBackground()            },            _getCanvasClipRectID: function() {                return this._canvasClipRect.id            },            _dataSourceChangedHandler: function() {                this._resetZoom();                this._scheduleLoadingIndicatorHiding();                this._dataInit()            },            _dataInit: function() {                clearTimeout(this._delayedRedraw);                this._dataSpecificInit(true)            },            _dataSpecificInit: function(needRedraw) {                this.series = this.series || this._populateSeries();                this._repopulateSeries();                this._seriesPopulatedHandler(needRedraw)            },            _seriesPopulatedHandler: function(needRedraw) {                var that = this;                that._seriesPopulatedHandlerCore();                that._populateBusinessRange();                that._updateLegend();                needRedraw && that._endLoading(function() {                    that._render({force: true})                })            },            _repopulateSeries: function() {                var that = this,                    parsedData,                    themeManager = that._themeManager,                    data = that._dataSource && that._dataSource.items(),                    dataValidatorOptions = themeManager.getOptions('dataPrepareSettings'),                    seriesTemplate = themeManager.getOptions('seriesTemplate');                if (that._dataSource && seriesTemplate) {                    that._templatedSeries = utils.processSeriesTemplate(seriesTemplate, that._dataSource.items());                    that._populateSeries();                    delete that._templatedSeries;                    data = that.teamplateData || data                }                that._groupSeries();                that._dataValidator = DX.viz.core.CoreFactory.createDataValidator(data, that._groupedSeries, that._incidentOccured, dataValidatorOptions);                parsedData = that._dataValidator.validate();                themeManager.resetPalette();                $.each(that.series, function(_, singleSeries) {                    singleSeries.updateData(parsedData);                    that._processSingleSeries(singleSeries)                });                that._organizeStackPoints()            },            _organizeStackPoints: function() {                var that = this,                    themeManager = that._themeManager,                    sharedTooltip = themeManager.getOptions("tooltip").shared,                    stackPoints = {};                $.each(that.series || [], function(_, singleSeries) {                    that._resetStackPoints(singleSeries);                    sharedTooltip && that._prepareStackPoints(singleSeries, stackPoints, true)                })            },            _renderCompleteHandler: function() {                var that = this,                    allSeriesInited = true;                if (that._needHandleRenderComplete) {                    $.each(that.series, function(_, s) {                        allSeriesInited = allSeriesInited && s.canRenderCompleteHandle()                    });                    if (allSeriesInited) {                        that._needHandleRenderComplete = false;                        that._eventTrigger("done", {target: that})                    }                }            },            _renderTitleAndLegend: function(drawOptions, legendHasInsidePosition) {                var that = this,                    titleOptions = that._themeManager.getOptions("title"),                    drawTitle = titleOptions.text && drawOptions.drawTitle,                    drawLegend = drawOptions.drawLegend && that.legend && !legendHasInsidePosition,                    drawElements = [];                if (drawTitle) {                    that._titleGroup.append(that._renderer.root);                    that._drawTitle();                    drawElements.push(that.chartTitle)                }                if (drawLegend) {                    that._legendGroup.append(that._renderer.root);                    drawElements.push(that.legend)                }                drawElements.length && that.layoutManager.drawElements(drawElements, that._canvas);                if (drawTitle)                    that.layoutManager.correctSizeElement(that.chartTitle, that._canvas)            },            _prepareStackPoints: $.noop,            _resetStackPoints: $.noop,            _resetZoom: $.noop,            _dataIsReady: function() {                return this._isDataSourceReady()            },            getAllSeries: function getAllSeries() {                return this.series.slice()            },            getSeriesByName: function getSeriesByName(name) {                var found = null;                $.each(this.series, function(i, singleSeries) {                    if (singleSeries.name === name) {                        found = singleSeries;                        return false                    }                });                return found            },            getSeriesByPos: function getSeriesByPos(pos) {                return this.series[pos]            },            clearSelection: function clearSelection() {                this.tracker.clearSelection()            },            hideTooltip: function() {                this.tracker._hideTooltip()            },            render: function(renderOptions) {                var that = this;                that.__renderOptions = renderOptions;                that.__forceRender = renderOptions && renderOptions.force;                that.callBase.apply(that, arguments);                that.__renderOptions = that.__forceRender = null;                return that            },            getSize: function() {                var canvas = this._canvas || {};                return {                        width: canvas.width,                        height: canvas.height                    }            }        }).include(ui.DataHelperMixin)    })(jQuery, DevExpress);    /*! Module viz-charts, file advancedChart.js */    (function($, DX, undefined) {        var charts = DX.viz.charts,            utils = DX.utils,            core = DX.viz.core,            DEFAULT_AXIS_NAME = "defaultAxisName",            _isArray = utils.isArray,            _isDefined = utils.isDefined,            _each = $.each,            _extend = $.extend,            _map = $.map,            MIN = 'min',            MAX = 'max';        function prepareAxis(axisOptions) {            return _isArray(axisOptions) ? axisOptions.length === 0 ? [{}] : axisOptions : [axisOptions]        }        function unique(array) {            var values = {},                i,                len = array.length;            for (i = 0; i < len; i++)                values[array[i]] = true;            return _map(values, function(_, key) {                    return key                })        }        function prepareVisibleArea(visibleArea, axisRange, useAggregation, aggregationRange) {            visibleArea.minVal = axisRange.min;            visibleArea.maxVal = axisRange.max;            if (useAggregation && !visibleArea.adjustOnZoom) {                visibleArea.minVal = _isDefined(visibleArea.minVal) ? visibleArea.minVal : aggregationRange.val.min;                visibleArea.maxVal = _isDefined(visibleArea.maxVal) ? visibleArea.maxVal : aggregationRange.val.max            }        }        function setTemplateFields(data, templateData, series) {            _each(data, function(_, data) {                _each(series.getTeamplatedFields(), function(_, field) {                    data[field.teamplateField] = data[field.originalField]                });                templateData.push(data)            });            series.updateTeamplateFieldNames()        }        charts.AdvancedChart = charts.BaseChart.inherit({            _dispose: function() {                var that = this,                    disposeObjectsInArray = this._disposeObjectsInArray;                that.callBase();                that.panes = null;                if (that.legend) {                    that.legend.dispose();                    that.legend = null                }                disposeObjectsInArray.call(that, "panesBackground");                disposeObjectsInArray.call(that, "seriesFamilies");                that._disposeAxes()            },            _reinitAxes: function() {                this.translators = {};                this.panes = this._createPanes();                this._populateAxes()            },            _populateSeries: function() {                var that = this,                    themeManager = that._themeManager,                    hasSeriesTemplate = !!themeManager.getOptions("seriesTemplate"),                    series = hasSeriesTemplate ? that._templatedSeries : that.option("series"),                    allSeriesOptions = _isArray(series) ? series : series ? [series] : [],                    data,                    extraOptions = that._getExtraOptions(),                    particularSeriesOptions,                    particularSeries,                    rotated = that._isRotated(),                    i;                that.teamplateData = [];                that._disposeSeries();                that.series = [];                themeManager.resetPalette();                for (i = 0; i < allSeriesOptions.length; i++) {                    particularSeriesOptions = _extend(true, {}, allSeriesOptions[i], extraOptions);                    data = particularSeriesOptions.data;                    particularSeriesOptions.data = null;                    particularSeriesOptions.rotated = rotated;                    particularSeriesOptions.customizePoint = themeManager.getOptions("customizePoint");                    particularSeriesOptions.customizeLabel = themeManager.getOptions("customizeLabel");                    particularSeriesOptions.visibilityChanged = $.proxy(that._seriesVisibilityChanged, that);                    particularSeriesOptions.resolveLabelsOverlapping = themeManager.getOptions("resolveLabelsOverlapping");                    particularSeriesOptions.incidentOccured = that._incidentOccured;                    if (!particularSeriesOptions.name)                        particularSeriesOptions.name = "Series " + (i + 1).toString();                    var seriesTheme = themeManager.getOptions("series", particularSeriesOptions);                    if (!that._checkPaneName(seriesTheme))                        continue;                    particularSeries = core.CoreFactory.createSeries({                        renderer: that._renderer,                        seriesGroup: that._seriesGroup,                        labelsGroup: that._labelsGroup                    }, seriesTheme);                    if (!particularSeries.isUpdated)                        that._incidentOccured("E2101", [seriesTheme.type]);                    else {                        particularSeries.index = that.series.length;                        that.series.push(particularSeries);                        if (hasSeriesTemplate)                            setTemplateFields(data, that.teamplateData, particularSeries)                    }                }                return that.series            },            _populateAxes: function() {                var that = this,                    valueAxes = [],                    argumentAxes,                    panes = that.panes,                    rotated = that._isRotated(),                    valueAxisOptions = that.option("valueAxis") || {},                    argumentOption = that.option("argumentAxis") || {},                    argumentAxesOptions = prepareAxis(argumentOption)[0],                    valueAxesOptions = prepareAxis(valueAxisOptions),                    axisNames = [],                    valueAxesCounter = 0,                    paneWithNonVirtualAxis,                    crosshairOptions = that._getOption("crosshair") || {},                    crosshairEnabled = crosshairOptions.enabled,                    horCrosshairEnabled = crosshairEnabled && crosshairOptions.horizontalLine.visible,                    verCrosshairEnabled = crosshairEnabled && crosshairOptions.verticalLine.visible;                function getNextAxisName() {                    return DEFAULT_AXIS_NAME + valueAxesCounter++                }                that._disposeAxes();                if (rotated)                    paneWithNonVirtualAxis = argumentAxesOptions.position === "right" ? panes[panes.length - 1].name : panes[0].name;                else                    paneWithNonVirtualAxis = argumentAxesOptions.position === "top" ? panes[0].name : panes[panes.length - 1].name;                argumentAxes = _map(panes, function(pane) {                    return that._createAxis("argumentAxis", argumentAxesOptions, {                            virtual: pane.name !== paneWithNonVirtualAxis,                            pane: pane.name,                            crosshairEnabled: rotated ? horCrosshairEnabled : verCrosshairEnabled                        }, rotated)                });                _each(valueAxesOptions, function(priority, axisOptions) {                    var axisPanes = [],                        name = axisOptions.name;                    if (name && $.inArray(name, axisNames) !== -1) {                        that._incidentOccured("E2102");                        return                    }                    name && axisNames.push(name);                    if (axisOptions.pane)                        axisPanes.push(axisOptions.pane);                    if (axisOptions.panes && axisOptions.panes.length)                        axisPanes = axisPanes.concat(axisOptions.panes.slice(0));                    axisPanes = unique(axisPanes);                    if (!axisPanes.length)                        axisPanes.push(undefined);                    _each(axisPanes, function(_, pane) {                        valueAxes.push(that._createAxis("valueAxis", axisOptions, {                            name: name || getNextAxisName(),                            pane: pane,                            priority: priority,                            crosshairEnabled: rotated ? verCrosshairEnabled : horCrosshairEnabled                        }, rotated))                    })                });                that._valueAxes = valueAxes;                that._argumentAxes = argumentAxes            },            _prepareStackPoints: function(singleSeries, stackPoints, isSharedTooltip) {                var points = singleSeries.getPoints(),                    stackName = singleSeries.getStackName();                _each(points, function(_, point) {                    var argument = point.argument;                    if (!stackPoints[argument]) {                        stackPoints[argument] = {};                        stackPoints[argument][null] = []                    }                    if (stackName && !_isArray(stackPoints[argument][stackName])) {                        stackPoints[argument][stackName] = [];                        _each(stackPoints[argument][null], function(_, point) {                            if (!point.stackName)                                stackPoints[argument][stackName].push(point)                        })                    }                    if (stackName) {                        stackPoints[argument][stackName].push(point);                        stackPoints[argument][null].push(point)                    }                    else                        _each(stackPoints[argument], function(_, stack) {                            stack.push(point)                        });                    if (isSharedTooltip) {                        point.stackPoints = stackPoints[argument][stackName];                        point.stackName = stackName                    }                })            },            _resetStackPoints: function(singleSeries) {                _each(singleSeries.getPoints(), function(_, point) {                    point.stackPoints = null;                    point.stackName = null                })            },            _disposeAxes: function() {                var disposeObjectsInArray = this._disposeObjectsInArray;                disposeObjectsInArray.call(this, "_argumentAxes");                disposeObjectsInArray.call(this, "_valueAxes")            },            _drawAxes: function(panesBorderOptions, drawOptions, adjustUnits) {                var that = this,                    drawAxes = function(axes) {                        _each(axes, function(_, axis) {                            axis.draw(adjustUnits)                        })                    },                    drawStaticAxisElements = function(axes) {                        _each(axes, function(_i, axis) {                            axis.drawGrids(panesBorderOptions[axis.pane])                        })                    };                that._reinitTranslators();                that._prepareAxesAndDraw(drawAxes, drawStaticAxisElements, drawOptions)            },            _appendAdditionalSeriesGroups: function() {                var that = this,                    root = that._renderer.root;                that._crosshairCursorGroup.append(root);                that._legendGroup.append(root);                that._scrollBar && that._scrollBarGroup.append(root)            },            _getLegendTargets: function() {                return _map(this.series, function(item) {                        if (item.getOptions().showInLegend)                            return item                    })            },            _legendItemTextField: "name",            _seriesPopulatedHandlerCore: function() {                this._processSeriesFamilies();                this._processValueAxisFormat()            },            _renderTrackers: function() {                var that = this,                    i;                for (i = 0; i < that.series.length; ++i)                    that.series[i].drawTrackers()            },            _specialProcessSeries: function() {                this._processSeriesFamilies()            },            _processSeriesFamilies: function() {                var that = this,                    types = [],                    families = [],                    paneSeries,                    themeManager = that._themeManager,                    familyOptions = {                        equalBarWidth: that._getEqualBarWidth(),                        minBubbleSize: themeManager.getOptions("minBubbleSize"),                        maxBubbleSize: themeManager.getOptions("maxBubbleSize")                    };                if (that.seriesFamilies && that.seriesFamilies.length) {                    _each(that.seriesFamilies, function(_, family) {                        family.updateOptions(familyOptions);                        family.adjustSeriesValues()                    });                    return                }                _each(that.series, function(_, item) {                    if ($.inArray(item.type, types) === -1)                        types.push(item.type)                });                _each(that._getLayoutTargets(), function(_, pane) {                    paneSeries = that._getSeriesForPane(pane.name);                    _each(types, function(_, type) {                        var family = core.CoreFactory.createSeriesFamily({                                type: type,                                pane: pane.name,                                equalBarWidth: familyOptions.equalBarWidth,                                minBubbleSize: familyOptions.minBubbleSize,                                maxBubbleSize: familyOptions.maxBubbleSize                            });                        family.add(paneSeries);                        family.adjustSeriesValues();                        families.push(family)                    })                });                that.seriesFamilies = families            },            _appendAxesGroups: function() {                var that = this,                    root = that._renderer.root;                that._stripsGroup.append(root);                that._gridGroup.append(root);                that._axesGroup.append(root);                that._constantLinesGroup.append(root);                that._labelAxesGroup.append(root)            },            _updateAxesLayout: function(drawOptions, panesBorderOptions, rotated) {                this.layoutManager.updatePanesCanvases(this._getLayoutTargets(), this._canvas, rotated);                this._drawAxes(panesBorderOptions, drawOptions, true)            },            _populateBusinessRange: function(visibleArea) {                var that = this,                    businessRanges = [],                    themeManager = that._themeManager,                    rotated = that._isRotated(),                    useAggregation = themeManager.getOptions('useAggregation'),                    argAxes = that._argumentAxes,                    lastArgAxis = argAxes[argAxes.length - 1],                    calcInterval = lastArgAxis.calcInterval,                    argRange = new core.Range({rotated: !!rotated}),                    argBusinessRange;                that._disposeObjectsInArray("businessRanges", ["arg", "val"]);                _each(argAxes, function(_, axis) {                    argRange.addRange(axis.getRangeData())                });                _each(that._groupedSeries, function(_, group) {                    var groupRange = new core.Range({                            rotated: !!rotated,                            isValueRange: true,                            pane: group.valueAxis.pane,                            axis: group.valueAxis.name                        }),                        groupAxisRange = group.valueAxis.getRangeData();                    groupRange.addRange(groupAxisRange);                    _each(group, function(_, series) {                        visibleArea && prepareVisibleArea(visibleArea, groupAxisRange, useAggregation, series._originalBusinessRange);                        var seriesRange = series.getRangeData(visibleArea, calcInterval);                        groupRange.addRange(seriesRange.val);                        argRange.addRange(seriesRange.arg)                    });                    if (!groupRange.isDefined())                        groupRange.setStubData(group.valueAxis.getOptions().valueType === 'datetime' ? 'datetime' : undefined);                    if (group.valueAxis.getOptions().showZero)                        groupRange.correctValueZeroLevel();                    groupRange.checkZeroStick();                    businessRanges.push({                        val: groupRange,                        arg: argRange                    })                });                if (!argRange.isDefined())                    argRange.setStubData(argAxes[0].getOptions().argumentType);                if (visibleArea && visibleArea.notApplyMargins && argRange.axisType !== "discrete") {                    argBusinessRange = argAxes[0].getTranslator().getBusinessRange();                    argRange.addRange({                        min: argBusinessRange.min,                        max: argBusinessRange.max,                        stick: true                    })                }                that._correctBusinessRange(argRange, lastArgAxis);                that.businessRanges = businessRanges            },            _correctBusinessRange: function(range, lastArgAxis) {                var setTicksAtUnitBeginning = lastArgAxis.getOptions().setTicksAtUnitBeginning,                    tickIntervalRange = {},                    tickInterval = lastArgAxis.getOptions().tickInterval,                    originInterval = tickInterval;                tickInterval = $.isNumeric(tickInterval) ? tickInterval : utils.dateToMilliseconds(tickInterval);                if (tickInterval && _isDefined(range[MIN]) && _isDefined(range[MAX]) && tickInterval >= Math.abs(range[MAX] - range[MIN])) {                    if (utils.isDate(range[MIN])) {                        if (!$.isNumeric(originInterval)) {                            tickIntervalRange[MIN] = utils.addInterval(range[MIN], originInterval, true);                            tickIntervalRange[MAX] = utils.addInterval(range[MAX], originInterval, false)                        }                        else {                            tickIntervalRange[MIN] = new Date(range[MIN].valueOf() - tickInterval);                            tickIntervalRange[MAX] = new Date(range[MAX].valueOf() + tickInterval)                        }                        if (setTicksAtUnitBeginning) {                            utils.correctDateWithUnitBeginning(tickIntervalRange[MAX], originInterval);                            utils.correctDateWithUnitBeginning(tickIntervalRange[MIN], originInterval)                        }                    }                    else {                        tickIntervalRange[MIN] = range[MIN] - tickInterval;                        tickIntervalRange[MAX] = range[MAX] + tickInterval                    }                    range.addRange(tickIntervalRange)                }            },            _getArgumentAxes: function() {                return this._argumentAxes            },            _getValueAxes: function() {                return this._valueAxes            },            _processValueAxisFormat: function() {                var that = this,                    valueAxes = that._valueAxes,                    axesWithFullStackedFormat = [];                _each(that.series, function() {                    if (this.isFullStackedSeries() && $.inArray(this.axis, axesWithFullStackedFormat) === -1)                        axesWithFullStackedFormat.push(this.axis)                });                _each(valueAxes, function() {                    if ($.inArray(this.name, axesWithFullStackedFormat) !== -1)                        this.setPercentLabelFormat();                    else                        this.resetAutoLabelFormat()                })            },            _createAxis: function(typeSelector, userOptions, axisOptions, rotated) {                var that = this,                    renderingSettings = _extend({                        renderer: that._renderer,                        incidentOccured: that._incidentOccured,                        axisClass: typeSelector === "argumentAxis" ? "arg" : "val",                        stripsGroup: that._stripsGroup,                        labelAxesGroup: that._labelAxesGroup,                        constantLinesGroup: that._constantLinesGroup,                        axesContainerGroup: that._axesGroup,                        gridGroup: that._gridGroup                    }, that._getAxisRenderingOptions(typeSelector, userOptions, rotated)),                    axis;                userOptions = that._prepareStripsAndConstantLines(typeSelector, userOptions, rotated);                axis = new charts.axes.Axis(renderingSettings);                axis.updateOptions(_extend(true, {}, userOptions, axisOptions, that._prepareAxisOptions(typeSelector, userOptions)));                return axis            },            _getTrackerSettings: function() {                return _extend(this.callBase(), {argumentAxis: this._argumentAxes})            },            _prepareStripsAndConstantLines: function(typeSelector, userOptions, rotated) {                userOptions = this._themeManager.getOptions(typeSelector, userOptions, rotated);                if (userOptions.strips)                    _each(userOptions.strips, function(i) {                        userOptions.strips[i] = _extend(true, {}, userOptions.stripStyle, userOptions.strips[i])                    });                if (userOptions.constantLines)                    _each(userOptions.constantLines, function(i, line) {                        userOptions.constantLines[i] = _extend(true, {}, userOptions.constantLineStyle, line)                    });                return userOptions            },            _legendDataField: 'series',            _adjustSeries: $.noop        })    })(jQuery, DevExpress);    /*! Module viz-charts, file chart.js */    (function($, DX, undefined) {        var viz = DX.viz,            core = viz.core,            charts = viz.charts,            utils = DX.utils,            MAX_ADJUSTMENT_ATTEMPTS = 5,            DEFAULT_PANE_NAME = "default",            ASYNC_SERIES_RENDERING_DELAY = 25,            DEFAULT_PANES = [{                    name: DEFAULT_PANE_NAME,                    border: {}                }],            _map = $.map,            _each = $.each,            _extend = $.extend,            _isArray = utils.isArray,            _isDefined = utils.isDefined;        function getFirstAxisNameForPane(axes, paneName) {            var result;            for (var i = 0; i < axes.length; i++)                if (axes[i].pane === paneName) {                    result = axes[i].name;                    break                }            if (!result)                result = axes[0].name;            return result        }        function hideGridsOnNonFirstValueAxisForPane(valAxes, paneName, synchronizeMultiAxes) {            var axesForPane = [],                firstShownAxis;            _each(valAxes, function(_, axis) {                if (axis.pane === paneName)                    axesForPane.push(axis)            });            if (axesForPane.length > 1 && synchronizeMultiAxes)                _each(axesForPane, function(_, axis) {                    var gridOpt = axis.getOptions().grid,                        minorGridOpt = axis.getOptions().minorGrid;                    if (firstShownAxis && gridOpt && gridOpt.visible) {                        gridOpt.visible = false;                        minorGridOpt && (minorGridOpt.visible = false)                    }                    else                        firstShownAxis = firstShownAxis ? firstShownAxis : gridOpt && gridOpt.visible                })        }        function getPaneForAxis(paneAxis, axisNameWithoutPane) {            var result;            _each(paneAxis, function(paneName, pane) {                _each(pane, function(axisName) {                    if (axisNameWithoutPane === axisName) {                        result = paneName;                        return false                    }                })            });            return result        }        function findAxisOptions(valueAxes, valueAxesOptions, axisName) {            var result,                axInd;            for (axInd = 0; axInd < valueAxesOptions.length; axInd++)                if (valueAxesOptions[axInd].name === axisName) {                    result = valueAxesOptions[axInd];                    result.priority = axInd;                    break                }            if (!result)                for (axInd = 0; axInd < valueAxes.length; axInd++)                    if (valueAxes[axInd].name === axisName) {                        result = valueAxes[axInd].getOptions();                        result.priority = valueAxes[axInd].priority;                        break                    }            return result        }        function findAxis(paneName, axisName, axes) {            var axis,                i;            for (i = 0; i < axes.length; i++) {                axis = axes[i];                if (axis.name === axisName && axis.pane === paneName)                    return axis            }        }        function prepareSegmentRectPoints(left, top, width, height, borderOptions) {            var maxSW = ~~((width < height ? width : height) / 2),                sw = borderOptions.width || 0,                newSW = sw < maxSW ? sw : maxSW;            left = left + newSW / 2;            top = top + newSW / 2;            width = width - newSW;            height = height - newSW;            var right = left + width,                bottom = top + height,                points = [],                segments = [],                segmentSequence,                visiblyOpt = 0,                prevSegmentVisibility = 0;            var allSegment = {                    top: [[left, top], [right, top]],                    right: [[right, top], [right, bottom]],                    bottom: [[right, bottom], [left, bottom]],                    left: [[left, bottom], [left, top]]                };            _each(allSegment, function(seg) {                var visibility = !!borderOptions[seg];                visiblyOpt = visiblyOpt * 2 + ~~visibility            });            switch (visiblyOpt) {                case 13:                case 9:                    segmentSequence = ['left', 'top', 'right', 'bottom'];                    break;                case 11:                    segmentSequence = ['bottom', 'left', 'top', 'right'];                    break;                default:                    segmentSequence = ['top', 'right', 'bottom', 'left']            }            _each(segmentSequence, function(_, seg) {                var segmentVisibility = !!borderOptions[seg];                if (!prevSegmentVisibility && segments.length) {                    points.push(segments);                    segments = []                }                if (segmentVisibility)                    _each(allSegment[seg].slice(prevSegmentVisibility), function(_, segment) {                        segments = segments.concat(segment)                    });                prevSegmentVisibility = ~~segmentVisibility            });            segments.length && points.push(segments);            points.length === 1 && (points = points[0]);            return {                    points: points,                    pathType: visiblyOpt === 15 ? "area" : "line"                }        }        function applyClipSettings(clipRects, settings) {            _each(clipRects || [], function(_, c) {                c && c.attr(settings)            })        }        function reinitTranslators(translators) {            _each(translators, function(_, axisTrans) {                _each(axisTrans, function(_, translator) {                    translator.arg.reinit();                    translator.val.reinit()                })            })        }        charts._test_prepareSegmentRectPoints = function() {            var original = prepareSegmentRectPoints.original || prepareSegmentRectPoints;            if (arguments[0])                prepareSegmentRectPoints = arguments[0];            prepareSegmentRectPoints.original = original;            prepareSegmentRectPoints.restore = function() {                prepareSegmentRectPoints = original            };            return prepareSegmentRectPoints        };        DX.registerComponent("dxChart", viz.charts, charts.AdvancedChart.inherit({            _chartType: "chart",            _setDefaultOptions: function() {                this.callBase();                this.option({defaultPane: DEFAULT_PANE_NAME})            },            _initCore: function() {                this.__ASYNC_SERIES_RENDERING_DELAY = ASYNC_SERIES_RENDERING_DELAY;                this.paneAxis = {};                this._panesClipRects = {};                this.callBase()            },            _disposeCore: function() {                var that = this,                    disposeObjectsInArray = this._disposeObjectsInArray,                    panesClipRects = that._panesClipRects;                that.callBase();                disposeObjectsInArray.call(panesClipRects, "fixed");                disposeObjectsInArray.call(panesClipRects, "base");                disposeObjectsInArray.call(panesClipRects, "wide");                that._panesClipRects = null            },            _correctAxes: function() {                this.series && this._correctValueAxes()            },            _getExtraOptions: $.noop,            _processSingleSeries: $.noop,            _groupSeries: function() {                var that = this,                    panes = that.panes,                    valAxes = that._valueAxes,                    paneList = _map(panes, function(pane) {                        return pane.name                    }),                    series = that.series,                    paneAxis = that.paneAxis,                    synchronizeMultiAxes = that._themeManager.getOptions("synchronizeMultiAxes"),                    groupedSeries = that._groupedSeries = [];                _each(series, function(i, particularSeries) {                    particularSeries.axis = particularSeries.axis || getFirstAxisNameForPane(valAxes, particularSeries.pane);                    if (particularSeries.axis) {                        paneAxis[particularSeries.pane] = paneAxis[particularSeries.pane] || {};                        paneAxis[particularSeries.pane][particularSeries.axis] = true                    }                });                _each(valAxes, function(_, axis) {                    if (axis.name && axis.pane && $.inArray(axis.pane, paneList) !== -1) {                        paneAxis[axis.pane] = paneAxis[axis.pane] || {};                        paneAxis[axis.pane][axis.name] = true                    }                });                that._correctValueAxes();                _each(paneAxis, function(paneName, pane) {                    hideGridsOnNonFirstValueAxisForPane(valAxes, paneName, synchronizeMultiAxes);                    _each(pane, function(axisName) {                        var group = [];                        _each(series, function(_, particularSeries) {                            if (particularSeries.pane === paneName && particularSeries.axis === axisName)                                group.push(particularSeries)                        });                        groupedSeries.push(group);                        group.valueAxis = findAxis(paneName, axisName, valAxes);                        group.valueOptions = group.valueAxis.getOptions()                    })                });                groupedSeries.argumentAxes = that._argumentAxes;                groupedSeries.argumentOptions = groupedSeries.argumentAxes[0].getOptions()            },            _cleanPanesClipRects: function(clipArrayName) {                var that = this,                    clipArray = that._panesClipRects[clipArrayName];                _each(clipArray || [], function(_, clipRect) {                    clipRect && clipRect.dispose()                });                that._panesClipRects[clipArrayName] = []            },            _createPanes: function() {                var that = this,                    panes = that.option("panes"),                    panesNameCounter = 0,                    bottomPaneName;                if (panes && _isArray(panes) && !panes.length || $.isEmptyObject(panes))                    panes = DEFAULT_PANES;                that._cleanPanesClipRects("fixed");                that._cleanPanesClipRects("base");                that._cleanPanesClipRects("wide");                that.defaultPane = that.option("defaultPane");                panes = _extend(true, [], _isArray(panes) ? panes : panes ? [panes] : []);                _each(panes, function(_, pane) {                    pane.name = !_isDefined(pane.name) ? DEFAULT_PANE_NAME + panesNameCounter++ : pane.name                });                if (!that._doesPaneExists(panes, that.defaultPane) && panes.length > 0) {                    bottomPaneName = panes[panes.length - 1].name;                    that._incidentOccured("W2101", [that.defaultPane, bottomPaneName]);                    that.defaultPane = bottomPaneName                }                panes = that._isRotated() ? panes.reverse() : panes;                return panes            },            _doesPaneExists: function(panes, paneName) {                var found = false;                _each(panes, function(_, pane) {                    if (pane.name === paneName) {                        found = true;                        return false                    }                });                return found            },            _getAxisRenderingOptions: function(typeSelector, axisOptions, rotated) {                return {                        axesType: "xyAxes",                        drawingType: "linear",                        isHorizontal: typeSelector === "argumentAxis" ? !rotated : rotated                    }            },            _prepareAxisOptions: $.noop,            _checkPaneName: function(seriesTheme) {                var paneList = _map(this.panes, function(pane) {                        return pane.name                    });                seriesTheme.pane = seriesTheme.pane || this.defaultPane;                return $.inArray(seriesTheme.pane, paneList) !== -1            },            _correctValueAxes: function() {                var that = this,                    rotated = that._isRotated(),                    valueAxisOptions = that.option("valueAxis") || {},                    valueAxesOptions = _isArray(valueAxisOptions) ? valueAxisOptions : [valueAxisOptions],                    valueAxes = that._valueAxes || [],                    defaultAxisName = valueAxes[0].name,                    paneAxis = that.paneAxis || {},                    panes = that.panes,                    i,                    neededAxis = {};                _each(valueAxes, function(_, axis) {                    if (axis.pane)                        return;                    var pane = getPaneForAxis(that.paneAxis, axis.name);                    if (!pane) {                        pane = that.defaultPane;                        paneAxis[pane] = paneAxis[pane] || {};                        paneAxis[pane][axis.name] = true                    }                    axis.setPane(pane)                });                for (i = 0; i < panes.length; i++)                    if (!paneAxis[panes[i].name]) {                        paneAxis[panes[i].name] = {};                        paneAxis[panes[i].name][defaultAxisName] = true                    }                _each(that.paneAxis, function(paneName, axisNames) {                    _each(axisNames, function(axisName) {                        neededAxis[axisName + "-" + paneName] = true;                        if (!findAxis(paneName, axisName, valueAxes)) {                            var axisOptions = findAxisOptions(valueAxes, valueAxesOptions, axisName);                            if (!axisOptions) {                                that._incidentOccured("W2102", [axisName]);                                axisOptions = {                                    name: axisName,                                    priority: valueAxes.length                                }                            }                            valueAxes.push(that._createAxis("valueAxis", axisOptions, {                                pane: paneName,                                name: axisName                            }, rotated))                        }                    })                });                valueAxes = $.grep(valueAxes, function(elem) {                    return !!neededAxis[elem.name + "-" + elem.pane]                });                valueAxes.sort(function(a, b) {                    return a.priority - b.priority                });                that._valueAxes = valueAxes            },            _getSeriesForPane: function(paneName) {                var paneSeries = [];                _each(this.series, function(_, oneSeries) {                    if (oneSeries.pane === paneName)                        paneSeries.push(oneSeries)                });                return paneSeries            },            _createTranslator: function(range, canvas, options) {                return core.CoreFactory.createTranslator2D(range, canvas, options)            },            _createPanesBorderOptions: function() {                var commonBorderOptions = this._themeManager.getOptions("commonPaneSettings").border,                    panesBorderOptions = {};                _each(this.panes, function(_, pane) {                    panesBorderOptions[pane.name] = _extend(true, {}, commonBorderOptions, pane.border)                });                return panesBorderOptions            },            _createScrollBar: function() {                var that = this,                    scrollBarOptions = that._themeManager.getOptions("scrollBar") || {},                    scrollBarGroup = that._scrollBarGroup;                if (scrollBarOptions.visible) {                    scrollBarOptions.rotated = that._isRotated();                    that._scrollBar = (that._scrollBar || charts.factory.createScrollBar(that._renderer, scrollBarGroup)).update(scrollBarOptions)                }                else {                    scrollBarGroup.remove();                    that._scrollBar && that._scrollBar.dispose();                    that._scrollBar = null                }            },            _prepareToRender: function(drawOptions) {                var that = this,                    panesBorderOptions = that._createPanesBorderOptions();                that._createPanesBackground();                that._appendAxesGroups();                that._transformed && that._resetTransform();                that._createTranslators(drawOptions);                that._options.useAggregation && _each(that.series, function(_, series) {                    series._originalBusinessRange = series._originalBusinessRange || series.getRangeData();                    series.resamplePoints(that._getTranslator(series.pane, series.axis).arg, that._zoomMinArg, that._zoomMaxArg)                });                if (_isDefined(that._zoomMinArg) || _isDefined(that._zoomMaxArg))                    that._populateBusinessRange({                        adjustOnZoom: that._themeManager.getOptions("adjustOnZoom"),                        minArg: that._zoomMinArg,                        maxArg: that._zoomMaxArg,                        notApplyMargins: that._notApplyMargins                    });                if (that._options.useAggregation || _isDefined(that._zoomMinArg) || _isDefined(that._zoomMaxArg))                    that._updateTranslators();                return panesBorderOptions            },            _isLegendInside: function() {                return this.legend && this.legend.getPosition() === "inside"            },            _renderAxes: function(drawOptions, panesBorderOptions, rotated) {                if (drawOptions && drawOptions.recreateCanvas)                    this.layoutManager.updatePanesCanvases(this.panes, this._canvas, rotated);                this._drawAxes(panesBorderOptions, drawOptions)            },            _isRotated: function() {                return this._themeManager.getOptions("rotated")            },            _getLayoutTargets: function() {                return this.panes            },            _applyClipRects: function(panesBorderOptions) {                var that = this,                    canvasClipRectID = that._getCanvasClipRectID(),                    i;                that._drawPanesBorders(panesBorderOptions);                that._createClipRectsForPanes();                for (i = 0; i < that._argumentAxes.length; i++)                    that._argumentAxes[i].applyClipRects(that._getElementsClipRectID(that._argumentAxes[i].pane), canvasClipRectID);                for (i = 0; i < that._valueAxes.length; i++)                    that._valueAxes[i].applyClipRects(that._getElementsClipRectID(that._valueAxes[i].pane), canvasClipRectID);                that._fillPanesBackground()            },            _getSeriesRenderTimeout: function(drawOptions) {                return drawOptions.asyncSeriesRendering ? ASYNC_SERIES_RENDERING_DELAY : undefined            },            _updateLegendPosition: function(drawOptions, legendHasInsidePosition) {                var that = this;                if (drawOptions.drawLegend && that.legend && legendHasInsidePosition) {                    var panes = that.panes,                        newCanvas = _extend({}, panes[0].canvas),                        layoutManager = charts.factory.createChartLayoutManager();                    newCanvas.right = panes[panes.length - 1].canvas.right;                    newCanvas.bottom = panes[panes.length - 1].canvas.bottom;                    that._legendGroup.append(that._renderer.root);                    layoutManager.drawElements([that.legend], newCanvas);                    layoutManager.placeDrawnElements(newCanvas)                }            },            _drawSeries: function(drawOptions, rotated) {                var that = this;                _each(that.seriesFamilies || [], function(_, seriesFamily) {                    var translators = that._getTranslator(seriesFamily.pane) || {};                    seriesFamily.updateSeriesValues(translators);                    seriesFamily.adjustSeriesDimensions(translators)                });                _each(that.series, function(_, particularSeries) {                    that._applyPaneClipRect(particularSeries);                    particularSeries.setAdjustSeriesLabels(drawOptions.adjustSeriesLabels);                    var tr = that._getTranslator(particularSeries.pane, particularSeries.axis),                        translators = {};                    translators[rotated ? "x" : "y"] = tr.val;                    translators[rotated ? "y" : "x"] = tr.arg;                    particularSeries.draw(translators, that._getAnimateOption(particularSeries, drawOptions), drawOptions.hideLayoutLabels, that.legend && that.legend.getActionCallback(particularSeries))                })            },            _applyPaneClipRect: function(seriesOptions) {                var that = this,                    paneIndex = that._getPaneIndex(seriesOptions.pane),                    panesClipRects = that._panesClipRects,                    wideClipRect = panesClipRects.wide[paneIndex];                seriesOptions.setClippingParams(panesClipRects.base[paneIndex].id, wideClipRect && wideClipRect.id, that._getPaneBorderVisibility(paneIndex))            },            _createTranslators: function(drawOptions) {                var that = this,                    rotated = that._isRotated(),                    translators;                if (!drawOptions.recreateCanvas)                    return;                that.translators = translators = {};                that.layoutManager.updatePanesCanvases(that.panes, that._canvas, rotated);                _each(that.paneAxis, function(paneName, pane) {                    translators[paneName] = translators[paneName] || {};                    _each(pane, function(axisName) {                        var translator = that._createTranslator(new core.Range(that._getBusinessRange(paneName, axisName).val), that._getCanvasForPane(paneName), rotated ? {direction: "horizontal"} : {});                        translator.pane = paneName;                        translator.axis = axisName;                        translators[paneName][axisName] = {val: translator}                    })                });                _each(that._argumentAxes, function(_, axis) {                    var translator = that._createTranslator(new core.Range(that._getBusinessRange(axis.pane).arg), that._getCanvasForPane(axis.pane), !rotated ? {direction: "horizontal"} : {});                    _each(translators[axis.pane], function(valAxis, paneAxisTran) {                        paneAxisTran.arg = translator                    })                })            },            _updateTranslators: function() {                var that = this;                _each(that.translators, function(pane, axisTrans) {                    _each(axisTrans, function(axis, translator) {                        translator.arg.updateBusinessRange(new core.Range(that._getBusinessRange(pane).arg));                        delete translator.arg._originalBusinessRange;                        translator.val.updateBusinessRange(new core.Range(that._getBusinessRange(pane, axis).val));                        delete translator.val._originalBusinessRange                    })                })            },            _getAxesForTransform: function(rotated) {                return {                        verticalAxes: !rotated ? this._getValueAxes() : this._getArgumentAxes(),                        horizontalAxes: !rotated ? this._getArgumentAxes() : this._getValueAxes()                    }            },            _reinitTranslators: function() {                var that = this;                _each(that._argumentAxes, function(_, axis) {                    var translator = that._getTranslator(axis.pane);                    if (translator) {                        translator.arg.reinit();                        axis.setTranslator(translator.arg, translator.val)                    }                });                _each(that._valueAxes, function(_, axis) {                    var translator = that._getTranslator(axis.pane, axis.name);                    if (translator) {                        translator.val.reinit();                        axis.setTranslator(translator.val, translator.arg)                    }                })            },            _prepareAxesAndDraw: function(drawAxes, drawStaticAxisElements, drawOptions) {                var that = this,                    i = 0,                    layoutManager = that.layoutManager,                    rotated = that._isRotated(),                    adjustmentCounter = 0,                    synchronizeMultiAxes = that._themeManager.getOptions('synchronizeMultiAxes'),                    layoutTargets = that._getLayoutTargets(),                    verticalAxes = rotated ? that._argumentAxes : that._valueAxes,                    horizontalAxes = rotated ? that._valueAxes : that._argumentAxes,                    hElements = horizontalAxes,                    vElements = verticalAxes;                if (that._scrollBar) {                    that._scrollBar.setPane(layoutTargets);                    if (rotated)                        vElements = [that._scrollBar].concat(vElements);                    else                        hElements = hElements.concat([that._scrollBar])                }                do {                    for (i = 0; i < that._argumentAxes.length; i++)                        that._argumentAxes[i].resetTicks();                    for (i = 0; i < that._valueAxes.length; i++)                        that._valueAxes[i].resetTicks();                    if (synchronizeMultiAxes)                        charts.multiAxesSynchronizer.synchronize(that._valueAxes);                    drawAxes(horizontalAxes);                    layoutManager.requireAxesRedraw = false;                    if (drawOptions.adjustAxes) {                        layoutManager.applyHorizontalAxesLayout(hElements, layoutTargets, rotated);                        !layoutManager.stopDrawAxes && reinitTranslators(that.translators)                    }                    drawAxes(verticalAxes);                    if (drawOptions.adjustAxes && !layoutManager.stopDrawAxes) {                        layoutManager.applyVerticalAxesLayout(vElements, layoutTargets, rotated);                        !layoutManager.stopDrawAxes && reinitTranslators(that.translators)                    }                    adjustmentCounter = adjustmentCounter + 1                } while (!layoutManager.stopDrawAxes && layoutManager.requireAxesRedraw && adjustmentCounter < MAX_ADJUSTMENT_ATTEMPTS);                drawStaticAxisElements(verticalAxes);                drawStaticAxisElements(horizontalAxes);                that._scrollBar && that._scrollBar.applyLayout();                that.__axisAdjustmentsCount = adjustmentCounter            },            _getPanesParameters: function() {                var that = this,                    panes = that.panes,                    i,                    params = [];                for (i = 0; i < panes.length; i++)                    if (that._getPaneBorderVisibility(i))                        params.push({                            coords: panes[i].borderCoords,                            clipRect: that._panesClipRects.fixed[i]                        });                return params            },            _createCrosshairCursor: function() {                var that = this,                    options = that._themeManager.getOptions("crosshair") || {},                    axes = !that._isRotated() ? [that._argumentAxes, that._valueAxes] : [that._valueAxes, that._argumentAxes],                    parameters = {                        canvas: that._getCommonCanvas(),                        panes: that._getPanesParameters(),                        axes: axes                    };                if (!options || !options.enabled)                    return;                if (!that._crosshair)                    that._crosshair = charts.factory.createCrosshair(that._renderer, options, parameters, that._crosshairCursorGroup);                else                    that._crosshair.update(options, parameters);                that._crosshair.render()            },            _getCommonCanvas: function() {                var i,                    canvas,                    commonCanvas,                    panes = this.panes;                for (i = 0; i < panes.length; i++) {                    canvas = panes[i].canvas;                    if (!commonCanvas)                        commonCanvas = _extend({}, canvas);                    else {                        commonCanvas.right = canvas.right;                        commonCanvas.bottom = canvas.bottom                    }                }                return commonCanvas            },            _createPanesBackground: function() {                var that = this,                    defaultBackgroundColor = that._themeManager.getOptions("commonPaneSettings").backgroundColor,                    backgroundColor,                    renderer = that._renderer,                    rect,                    i,                    rects = [];                that._panesBackgroundGroup && that._panesBackgroundGroup.clear();                for (i = 0; i < that.panes.length; i++) {                    backgroundColor = that.panes[i].backgroundColor || defaultBackgroundColor;                    if (!backgroundColor || backgroundColor === "none") {                        rects.push(null);                        continue                    }                    rect = renderer.rect(0, 0, 0, 0).attr({                        fill: backgroundColor,                        "stroke-width": 0                    }).append(that._panesBackgroundGroup);                    rects.push(rect)                }                that.panesBackground = rects;                that._panesBackgroundGroup.append(renderer.root)            },            _fillPanesBackground: function() {                var that = this,                    bc;                _each(that.panes, function(i, pane) {                    bc = pane.borderCoords;                    if (that.panesBackground[i] !== null)                        that.panesBackground[i].attr({                            x: bc.left,                            y: bc.top,                            width: bc.width,                            height: bc.height                        })                })            },            _calcPaneBorderCoords: function(pane) {                var canvas = pane.canvas,                    bc = pane.borderCoords = pane.borderCoords || {};                bc.left = canvas.left;                bc.top = canvas.top;                bc.right = canvas.width - canvas.right;                bc.bottom = canvas.height - canvas.bottom;                bc.width = Math.max(bc.right - bc.left, 0);                bc.height = Math.max(bc.bottom - bc.top, 0)            },            _drawPanesBorders: function(panesBorderOptions) {                var that = this,                    rotated = that._isRotated();                that._panesBorderGroup && that._panesBorderGroup.remove().clear();                _each(that.panes, function(i, pane) {                    var bc,                        borderOptions = panesBorderOptions[pane.name],                        segmentRectParams,                        attr = {                            fill: "none",                            stroke: borderOptions.color,                            "stroke-opacity": borderOptions.opacity,                            "stroke-width": borderOptions.width,                            dashStyle: borderOptions.dashStyle,                            "stroke-linecap": "square"                        };                    that._calcPaneBorderCoords(pane, rotated);                    if (!borderOptions.visible)                        return;                    bc = pane.borderCoords;                    segmentRectParams = prepareSegmentRectPoints(bc.left, bc.top, bc.width, bc.height, borderOptions);                    that._renderer.path(segmentRectParams.points, segmentRectParams.pathType).attr(attr).append(that._panesBorderGroup)                });                that._panesBorderGroup.append(that._renderer.root)            },            _createClipRect: function(clipArray, index, left, top, width, height) {                var that = this,                    clipRect = clipArray[index];                if (!clipRect) {                    clipRect = that._renderer.clipRect(left, top, width, height);                    clipArray[index] = clipRect                }                else                    clipRect.attr({                        x: left,                        y: top,                        width: width,                        height: height                    })            },            _createClipRectsForPanes: function() {                var that = this,                    canvas = that._canvas;                _each(that.panes, function(i, pane) {                    var needWideClipRect = false,                        bc = pane.borderCoords,                        left = bc.left,                        top = bc.top,                        width = bc.width,                        height = bc.height,                        panesClipRects = that._panesClipRects;                    that._createClipRect(panesClipRects.fixed, i, left, top, width, height);                    that._createClipRect(panesClipRects.base, i, left, top, width, height);                    _each(that.series, function(_, series) {                        if (series.pane === pane.name && (series.isFinancialSeries() || series.areErrorBarsVisible()))                            needWideClipRect = true                    });                    if (needWideClipRect) {                        if (that._isRotated()) {                            top = 0;                            height = canvas.height                        }                        else {                            left = 0;                            width = canvas.width                        }                        that._createClipRect(panesClipRects.wide, i, left, top, width, height)                    }                    else                        panesClipRects.wide.push(null)                })            },            _getPaneIndex: function(paneName) {                var paneIndex;                _each(this.panes, function(index, pane) {                    if (pane.name === paneName) {                        paneIndex = index;                        return false                    }                });                return paneIndex            },            _getPaneBorderVisibility: function(paneIndex) {                var commonPaneBorderVisible = this._themeManager.getOptions("commonPaneSettings").border.visible,                    pane = this.panes[paneIndex] || {},                    paneBorder = pane.border || {};                return "visible" in paneBorder ? paneBorder.visible : commonPaneBorderVisible            },            _getElementsClipRectID: function(paneName) {                return this._panesClipRects.fixed[this._getPaneIndex(paneName)].id            },            _getTranslator: function(paneName, axisName) {                var paneTrans = this.translators[paneName],                    foundTranslator = null;                if (!paneTrans)                    return foundTranslator;                foundTranslator = paneTrans[axisName];                if (!foundTranslator)                    _each(paneTrans, function(axis, trans) {                        foundTranslator = trans;                        return false                    });                return foundTranslator            },            _getCanvasForPane: function(paneName) {                var panes = this.panes,                    panesNumber = panes.length,                    i;                for (i = 0; i < panesNumber; i++)                    if (panes[i].name === paneName)                        return panes[i].canvas            },            _getBusinessRange: function(paneName, axisName) {                var ranges = this.businessRanges || [],                    rangesNumber = ranges.length,                    foundRange,                    i;                for (i = 0; i < rangesNumber; i++)                    if (ranges[i].val.pane === paneName && ranges[i].val.axis === axisName) {                        foundRange = ranges[i];                        break                    }                if (!foundRange)                    for (i = 0; i < rangesNumber; i++)                        if (ranges[i].val.pane === paneName) {                            foundRange = ranges[i];                            break                        }                return foundRange            },            _transformArgument: function(translate, scale) {                var that = this,                    rotated = that._isRotated(),                    settings,                    clipSettings,                    panesClipRects = that._panesClipRects;                if (!that._transformed) {                    that._transformed = true;                    that._labelsGroup.remove();                    that._resetIsReady();                    _each(that.series || [], function(i, s) {                        s.applyClip()                    })                }                if (rotated) {                    settings = {                        translateY: translate,                        scaleY: scale                    };                    clipSettings = {                        translateY: -translate / scale,                        scaleY: 1 / scale                    }                }                else {                    settings = {                        translateX: translate,                        scaleX: scale                    };                    clipSettings = {                        translateX: -translate / scale,                        scaleX: 1 / scale                    }                }                applyClipSettings(panesClipRects.base, clipSettings);                applyClipSettings(panesClipRects.wide, clipSettings);                that._seriesGroup.attr(settings);                that._scrollBar && that._scrollBar.transform(-translate, scale)            },            _resetTransform: function() {                var that = this,                    settings = {                        translateX: 0,                        translateY: 0,                        scaleX: null,                        scaleY: null                    },                    panesClipRects = that._panesClipRects;                applyClipSettings(panesClipRects.base, settings);                applyClipSettings(panesClipRects.wide, settings);                that._seriesGroup.attr(settings);                _each(that.series || [], function(i, s) {                    s.resetClip()                });                that._transformed = false            },            _getTrackerSettings: function() {                var that = this,                    themeManager = that._themeManager;                return _extend(this.callBase(), {                        chart: that,                        zoomingMode: themeManager.getOptions("zoomingMode"),                        scrollingMode: themeManager.getOptions("scrollingMode"),                        rotated: that._isRotated(),                        crosshair: that._crosshair                    })            },            _resolveLabelOverlappingStack: function() {                var that = this,                    stackPoints = {},                    isRotated = that._isRotated(),                    shiftDirection = isRotated ? function(box, length) {                        return {                                x: box.x - length,                                y: box.y                            }                    } : function(box, length) {                        return {                                x: box.x,                                y: box.y - length                            }                    };                _each(this._getVisibleSeries(), function(_, particularSeries) {                    that._prepareStackPoints(particularSeries, stackPoints)                });                _each(stackPoints, function(_, stacks) {                    _each(stacks, function(_, points) {                        charts.overlapping.resolveLabelOverlappingInOneDirection(points, that._getCommonCanvas(), isRotated, shiftDirection)                    })                })            },            _getEqualBarWidth: function() {                return this._themeManager.getOptions("equalBarWidth")            },            zoomArgument: function(min, max, gesturesUsed) {                var that = this,                    zoomArg;                if (!_isDefined(min) && !_isDefined(max))                    return;                zoomArg = that._argumentAxes[0].zoom(min, max, gesturesUsed);                that._zoomMinArg = zoomArg.min;                that._zoomMaxArg = zoomArg.max;                that._notApplyMargins = gesturesUsed;                that._render({                    force: true,                    drawTitle: false,                    drawLegend: false,                    adjustAxes: false,                    animate: false,                    adjustSeriesLabels: false,                    asyncSeriesRendering: false,                    updateTracker: false                })            },            _resetZoom: function() {                var that = this;                that._zoomMinArg = that._zoomMaxArg = undefined;                that._argumentAxes[0] && that._argumentAxes[0].resetZoom()            },            getVisibleArgumentBounds: function() {                var range = this._argumentAxes[0].getTranslator().getBusinessRange(),                    isDiscrete = range.axisType === "discrete",                    categories = range.categories;                return {                        minVisible: isDiscrete ? range.minVisible || categories[0] : range.minVisible,                        maxVisible: isDiscrete ? range.maxVisible || categories[categories.length - 1] : range.maxVisible                    }            }        }))    })(jQuery, DevExpress);    /*! Module viz-charts, file pieChart.js */    (function($, DX, undefined) {        var viz = DX.viz,            core = viz.core,            charts = viz.charts,            utils = DX.utils,            _extend = $.extend,            _noop = $.noop,            _getVerticallyShiftedAngularCoords = DX.viz.core.utils.getVerticallyShiftedAngularCoords;        DX.registerComponent("dxPieChart", viz.charts, charts.BaseChart.inherit({            _chartType: 'pie',            _reinitAxes: _noop,            _correctAxes: _noop,            _layoutManagerOptions: function() {                var diameter = this._themeManager.getOptions('diameter');                if (utils.isNumber(diameter)) {                    if (diameter > 1)                        diameter = 1;                    else if (diameter < 0)                        diameter = 0                }                else                    diameter = undefined;                return _extend(true, {}, this.callBase(), {piePercentage: diameter})            },            _groupSeries: function() {                this.series.valueOptions = {valueType: "numeric"};                this._groupedSeries = [this.series];                this._groupedSeries.argumentOptions = this.series[0] && this.series[0].getOptions()            },            _populateBusinessRange: function() {                var businessRanges = [],                    series = this.series,                    singleSeries = series[0],                    range = new core.Range,                    singleSeriesRange;                this._disposeObjectsInArray("businessRanges");                if (singleSeries) {                    singleSeriesRange = singleSeries.getRangeData();                    range.addRange(singleSeriesRange.val);                    if (!range.isDefined())                        range.setStubData();                    businessRanges.push(range)                }                this.businessRanges = businessRanges            },            _specialProcessSeries: function() {                this.series[0].arrangePoints()            },            _createTranslator: function(range) {                return core.CoreFactory.createTranslator1D(range.min, range.max, 360, 0)            },            _populateSeries: function() {                var that = this,                    themeManager = that._themeManager,                    hasSeriesTemplate = !!themeManager.getOptions("seriesTemplate"),                    seriesOptions = hasSeriesTemplate ? that._templatedSeries : that.option("series"),                    allSeriesOptions = $.isArray(seriesOptions) ? seriesOptions : seriesOptions ? [seriesOptions] : [],                    data,                    particularSeriesOptions,                    particularSeries,                    seriesTheme;                that._disposeSeries();                that.series = [];                themeManager.resetPalette();                if (allSeriesOptions.length) {                    particularSeriesOptions = _extend(true, {}, allSeriesOptions[0]);                    if (particularSeriesOptions.type && !utils.isString(particularSeriesOptions.type))                        particularSeriesOptions.type = "";                    data = particularSeriesOptions.data;                    particularSeriesOptions.data = null;                    particularSeriesOptions.incidentOccured = that._incidentOccured;                    seriesTheme = themeManager.getOptions("series", particularSeriesOptions, true);                    seriesTheme.visibilityChanged = $.proxy(that._seriesVisibilityChanged, that);                    seriesTheme.customizePoint = themeManager.getOptions("customizePoint");                    seriesTheme.customizeLabel = themeManager.getOptions("customizeLabel");                    particularSeries = core.CoreFactory.createSeries({                        renderer: that._renderer,                        seriesGroup: that._seriesGroup,                        labelsGroup: that._labelsGroup                    }, seriesTheme);                    if (!particularSeries.isUpdated)                        that._incidentOccured("E2101", [seriesTheme.type]);                    else {                        that._processSingleSeries(particularSeries);                        that.series.push(particularSeries)                    }                    particularSeriesOptions.data = data                }                return that.series            },            _processSingleSeries: function(singleSeries) {                singleSeries.arrangePoints()            },            _seriesPopulatedHandlerCore: _noop,            _getLegendTargets: function() {                return this.series[0] ? this.series[0].getPoints() : []            },            _legendItemTextField: "argument",            _prepareToRender: _noop,            _isLegendInside: _noop,            _renderAxes: _noop,            _isRotated: _noop,            _getLayoutTargets: function() {                return [{canvas: this._canvas}]            },            _getAxesForTransform: function() {                return {                        verticalAxes: [],                        horizontalAxes: []                    }            },            _updateAxesLayout: _noop,            _applyClipRects: _noop,            _appendAdditionalSeriesGroups: _noop,            _getSeriesRenderTimeout: _noop,            _drawSeries: function(drawOptions) {                var that = this,                    singleSeries = that.getSeries(),                    legend = that.legend,                    getActionCallbackProxy = $.proxy(legend.getActionCallback, legend);                if (singleSeries) {                    that.layoutManager.applyPieChartSeriesLayout(that._canvas, singleSeries, true);                    singleSeries.canvas = that._canvas;                    singleSeries.resetLabelSetups();                    if (singleSeries.drawLabelsWOPoints(that._createTranslator(that.businessRanges[0], that._canvas)))                        that.layoutManager.applyPieChartSeriesLayout(that._canvas, singleSeries, drawOptions.hideLayoutLabels);                    singleSeries.draw(that._createTranslator(that.businessRanges[0], that._canvas), that._getAnimateOption(singleSeries, drawOptions), drawOptions.hideLayoutLabels, getActionCallbackProxy)                }            },            _adjustSeries: function() {                var singleSeries = this.getSeries();                singleSeries && singleSeries.adjustLabels()            },            _updateLegendPosition: _noop,            _renderTrackers: _noop,            _createScrollBar: _noop,            _resolveLabelOverlappingShift: function() {                var series = this.series[0],                    center = series.getCenter(),                    lPoints = [],                    rPoints = [];                $.each(series.getVisiblePoints(), function(_, point) {                    var angle = utils.normalizeAngle(point.middleAngle);                    (angle <= 90 || angle >= 270 ? rPoints : lPoints).push(point)                });                charts.overlapping.resolveLabelOverlappingInOneDirection(lPoints, this._canvas, false, shiftFunction);                charts.overlapping.resolveLabelOverlappingInOneDirection(rPoints, this._canvas, false, shiftFunction);                function shiftFunction(box, length) {                    return _getVerticallyShiftedAngularCoords(box, -length, center)                }            },            getSeries: function getSeries() {                return this.series && this.series[0]            },            _legendDataField: 'point'        }))    })(jQuery, DevExpress);    /*! Module viz-charts, file polarChart.js */    (function($, DX, undefined) {        var charts = DX.viz.charts,            core = DX.viz.core,            DEFAULT_PANE_NAME = 'default';        var PolarChart = charts.AdvancedChart.inherit({                _chartType: 'polar',                _createPanes: function() {                    return [{name: DEFAULT_PANE_NAME}]                },                _checkPaneName: function() {                    return true                },                _getAxisRenderingOptions: function(typeSelector) {                    var isArgumentAxis = typeSelector === "argumentAxis",                        type = isArgumentAxis ? "circular" : "linear",                        useSpiderWeb = this.option("useSpiderWeb");                    if (useSpiderWeb)                        type += "Spider";                    return {                            axesType: "polarAxes",                            drawingType: type,                            isHorizontal: true                        }                },                _prepareAxisOptions: function(typeSelector, axisOptions) {                    return {type: this.option("useSpiderWeb") && typeSelector === "argumentAxis" ? "discrete" : axisOptions.type}                },                _getExtraOptions: function() {                    return {spiderWidget: this.option("useSpiderWeb")}                },                _correctAxes: $.noop,                _groupSeries: function() {                    this._groupedSeries = [this.series];                    this._groupedSeries[0].valueAxis = this._valueAxes[0];                    this._groupedSeries[0].valueOptions = this._valueAxes[0].getOptions();                    this._groupedSeries.argumentAxes = this._argumentAxes;                    this._groupedSeries.argumentOptions = this._argumentAxes[0].getOptions()                },                _processSingleSeries: $.noop,                _prepareToRender: function() {                    this._appendAxesGroups();                    return {}                },                _isLegendInside: $.noop,                _renderAxes: function(drawOptions) {                    this._drawAxes({}, drawOptions)                },                _reinitTranslators: function() {                    var that = this,                        valueAxes = that._valueAxes,                        argumentAxes = that._argumentAxes,                        translator = that._createTranslator({                            arg: new core.Range(that.businessRanges[0].arg),                            val: new core.Range(that.businessRanges[0].val)                        }),                        argTranslator = translator.getComponent("arg"),                        valTranslator = translator.getComponent("val"),                        i = 0;                    that.translator = translator;                    argumentAxes[0].setTranslator(argTranslator, valTranslator);                    for (i; i < valueAxes.length; i++)                        valueAxes[i].setTranslator(valTranslator, argTranslator)                },                _prepareAxesAndDraw: function(drawAxes, drawStaticAxisElements) {                    var that = this,                        valueAxes = that._valueAxes,                        argAxes = that._argumentAxes,                        argumentAxis = argAxes[0];                    that._calcCanvas(argumentAxis.measureLabels());                    that.translator.reinit();                    drawAxes(argAxes);                    $.each(valueAxes, function(_, valAxis) {                        valAxis.setSpiderTicks(argumentAxis.getSpiderTicks())                    });                    drawAxes(valueAxes);                    drawStaticAxisElements(argAxes);                    drawStaticAxisElements(valueAxes)                },                _calcCanvas: function(measure) {                    var canvas = this.translator.canvas;                    canvas.left += measure.width;                    canvas.right += measure.width;                    canvas.top += measure.height;                    canvas.bottom += measure.height                },                _isRotated: $.noop,                _getLayoutTargets: function() {                    return [{canvas: this._canvas}]                },                _getAxesForTransform: function() {                    var argAxes = this._getArgumentAxes();                    return {                            verticalAxes: argAxes,                            horizontalAxes: argAxes                        }                },                _applyClipRects: $.noop,                _getSeriesRenderTimeout: $.noop,                _drawSeries: function(drawOptions) {                    var that = this,                        i,                        seriesFamilies = that.seriesFamilies || [],                        series = that.series;                    if (!series.length)                        return;                    for (i = 0; i < seriesFamilies.length; i++) {                        var translators = {};                        translators.val = that.translator;                        translators.arg = that.translator;                        seriesFamilies[i].updateSeriesValues(translators);                        seriesFamilies[i].adjustSeriesDimensions(translators)                    }                    for (i = 0; i < series.length; i++)                        series[i].draw(that.translator, that._getAnimateOption(series[i], drawOptions), drawOptions.hideLayoutLabels, that.legend && that.legend.getActionCallback(series[i]))                },                _updateLegendPosition: $.noop,                _createScrollBar: $.noop,                _createTranslator: function(br) {                    var themeManager = this._themeManager,                        axisUserOptions = this.option("argumentAxis"),                        axisOptions = themeManager.getOptions("argumentAxis", axisUserOptions) || {};                    return new core.PolarTranslator(br, $.extend(true, {}, this._canvas), {startAngle: axisOptions.startAngle})                },                _getSeriesForPane: function() {                    return this.series                },                _getEqualBarWidth: function() {                    return !!this._themeManager.getOptions("equalBarWidth")                }            });        DX.registerComponent('dxPolarChart', charts, PolarChart)    })(jQuery, DevExpress);    /*! Module viz-charts, file layoutManager.js */    (function($, DX, undefined) {        var _isNumber = DX.utils.isNumber,            _decreaseGaps = DX.viz.core.utils.decreaseGaps,            _round = Math.round,            _min = Math.min,            _max = Math.max,            _floor = Math.floor,            _sqrt = Math.sqrt,            _each = $.each,            _extend = $.extend;        function correctElementsPosition(elements, direction, canvas) {            _each(elements, function(_, element) {                var options = element.getLayoutOptions(),                    side = options.cutLayoutSide;                canvas[side] -= options[direction]            })        }        function placeElementAndCutCanvas(elements, canvas) {            _each(elements, function(_, element) {                var shiftX,                    shiftY,                    options = element.getLayoutOptions(),                    length = getLength(options.cutLayoutSide);                if (!options.width)                    return;                switch (options.horizontalAlignment) {                    case"left":                        shiftX = canvas.left;                        break;                    case"center":                        shiftX = (canvas.width - canvas.left - canvas.right - options.width) / 2 + canvas.left;                        break;                    case"right":                        shiftX = canvas.width - canvas.right - options.width;                        break                }                switch (options.verticalAlignment) {                    case"top":                        shiftY = canvas.top;                        break;                    case"bottom":                        shiftY = canvas.height - canvas.bottom - options.height;                        break                }                element.shift(_round(shiftX), _round(shiftY));                canvas[options.cutLayoutSide] += options[length];                setCanvasValues(canvas)            })        }        function getLength(side) {            return side === 'left' || side === 'right' ? 'width' : 'height'        }        function setCanvasValues(canvas) {            if (canvas) {                canvas.originalTop = canvas.top;                canvas.originalBottom = canvas.bottom;                canvas.originalLeft = canvas.left;                canvas.originalRight = canvas.right            }        }        function updateElements(elements, length, otherLength, dirtyCanvas, canvas, needRemoveSpace) {            _each(elements, function(_, element) {                var options = element.getLayoutOptions(),                    side = options.cutLayoutSide,                    freeSpaceWidth = dirtyCanvas.width - dirtyCanvas.left - dirtyCanvas.right,                    freeSpaceHeight = dirtyCanvas.height - dirtyCanvas.top - dirtyCanvas.bottom,                    updateObject = {};                element.setSize({                    width: freeSpaceWidth,                    height: freeSpaceHeight                });                updateObject[otherLength] = 0;                updateObject[length] = needRemoveSpace[length];                element.changeSize(updateObject);                canvas[side] -= options[length] - element.getLayoutOptions()[length];                needRemoveSpace[length] -= options[length] - element.getLayoutOptions()[length]            })        }        function updateAxis(axes, side, needRemoveSpace) {            if (axes && needRemoveSpace[side] > 0) {                _each(axes, function(i, axis) {                    var bbox = axis.getBoundingRect();                    axis.updateSize();                    needRemoveSpace[side] -= bbox[side] - axis.getBoundingRect()[side]                });                if (needRemoveSpace[side] > 0)                    _each(axes, function(_, axis) {                        axis.updateSize(true)                    })            }        }        function getNearestCoord(firstCoord, secondCoord, pointCenterCoord) {            var nearestCoord;            if (pointCenterCoord < firstCoord)                nearestCoord = firstCoord;            else if (secondCoord < pointCenterCoord)                nearestCoord = secondCoord;            else                nearestCoord = pointCenterCoord;            return nearestCoord        }        function getLengthFromCenter(x, y, paneCenterX, paneCenterY) {            return _sqrt((x - paneCenterX) * (x - paneCenterX) + (y - paneCenterY) * (y - paneCenterY))        }        function getInnerRadius(series) {            var innerRadius;            if (series.type === "pie")                innerRadius = 0;            else {                innerRadius = _isNumber(series.innerRadius) ? Number(series.innerRadius) : 0.5;                innerRadius = innerRadius < 0.2 ? 0.2 : innerRadius;                innerRadius = innerRadius > 0.8 ? 0.8 : innerRadius            }            return innerRadius        }        function isValidBox(box) {            return !!(box.x || box.y || box.width || box.height)        }        function correctDeltaMarginValue(panes, marginSides) {            var canvas,                deltaSide,                requireAxesRedraw = false;            _each(panes, function(_, pane) {                canvas = pane.canvas;                _each(marginSides, function(_, side) {                    deltaSide = "delta" + side;                    canvas[deltaSide] = _max(canvas[deltaSide] - (canvas[side.toLowerCase()] - canvas["original" + side]), 0);                    if (canvas[deltaSide] > 0)                        requireAxesRedraw = true                })            });            return requireAxesRedraw        }        function getPane(name, panes) {            var findPane = panes[0];            _each(panes, function(_, pane) {                if (name === pane.name)                    findPane = pane            });            return findPane        }        function applyFoundExceedings(panes, rotated) {            var stopDrawAxes = false,                maxLeft = 0,                maxRight = 0,                maxTop = 0,                maxBottom = 0;            _each(panes, function(_, pane) {                maxLeft = _max(maxLeft, pane.canvas.deltaLeft);                maxRight = _max(maxRight, pane.canvas.deltaRight);                maxTop = _max(maxTop, pane.canvas.deltaTop);                maxBottom = _max(maxBottom, pane.canvas.deltaBottom)            });            if (rotated)                _each(panes, function(_, pane) {                    pane.canvas.top += maxTop;                    pane.canvas.bottom += maxBottom;                    pane.canvas.right += pane.canvas.deltaRight;                    pane.canvas.left += pane.canvas.deltaLeft                });            else                _each(panes, function(_, pane) {                    pane.canvas.top += pane.canvas.deltaTop;                    pane.canvas.bottom += pane.canvas.deltaBottom;                    pane.canvas.right += maxRight;                    pane.canvas.left += maxLeft                });            _each(panes, function(_, pane) {                if (pane.canvas.top + pane.canvas.bottom > pane.canvas.height)                    stopDrawAxes = true;                if (pane.canvas.left + pane.canvas.right > pane.canvas.width)                    stopDrawAxes = true            });            return stopDrawAxes        }        function LayoutManager(options) {            this._verticalElements = [];            this._horizontalElements = [];            this._options = options        }        LayoutManager.prototype = {            constructor: LayoutManager,            dispose: function() {                this._verticalElements = this._horizontalElements = this._options = null            },            drawElements: function(elements, canvas) {                var horizontalElements = [],                    verticalElements = [];                _each(elements, function(_, element) {                    var options,                        length;                    element.setSize({                        width: canvas.width - canvas.left - canvas.right,                        height: canvas.height - canvas.top - canvas.bottom                    });                    element.draw();                    options = element.getLayoutOptions();                    if (options) {                        length = getLength(options.cutLayoutSide);                        (length === 'width' ? horizontalElements : verticalElements).push(element);                        canvas[options.cutLayoutSide] += options[length];                        setCanvasValues(canvas)                    }                });                this._horizontalElements = horizontalElements;                this._verticalElements = verticalElements;                return this            },            placeDrawnElements: function(canvas) {                correctElementsPosition(this._horizontalElements, 'width', canvas);                placeElementAndCutCanvas(this._horizontalElements, canvas);                correctElementsPosition(this._verticalElements, 'height', canvas);                placeElementAndCutCanvas(this._verticalElements, canvas);                return this            },            updatePanesCanvases: function(panes, canvas, rotated) {                var weightSum = 0;                _each(panes, function(_, pane) {                    pane.weight = pane.weight || 1;                    weightSum += pane.weight                });                var distributedSpace = 0,                    padding = panes.padding || 10,                    paneSpace = rotated ? canvas.width - canvas.left - canvas.right : canvas.height - canvas.top - canvas.bottom,                    oneWeight = (paneSpace - padding * (panes.length - 1)) / weightSum,                    startName = rotated ? "left" : "top",                    endName = rotated ? "right" : "bottom";                _each(panes, function(_, pane) {                    var calcLength = _round(pane.weight * oneWeight);                    pane.canvas = pane.canvas || {};                    _extend(pane.canvas, {                        deltaLeft: 0,                        deltaRight: 0,                        deltaTop: 0,                        deltaBottom: 0                    }, canvas);                    pane.canvas[startName] = canvas[startName] + distributedSpace;                    pane.canvas[endName] = canvas[endName] + (paneSpace - calcLength - distributedSpace);                    distributedSpace = distributedSpace + calcLength + padding;                    setCanvasValues(pane.canvas)                })            },            applyVerticalAxesLayout: function(axes, panes, rotated) {                this._applyAxesLayout(axes, panes, rotated)            },            applyHorizontalAxesLayout: function(axes, panes, rotated) {                axes.reverse();                this._applyAxesLayout(axes, panes, rotated);                axes.reverse()            },            _applyAxesLayout: function(axes, panes, rotated) {                var that = this,                    canvas,                    axisPosition,                    box,                    delta,                    axis,                    axisLength,                    direction,                    directionMultiplier,                    someDirection = [],                    pane,                    i;                _each(panes, function(_, pane) {                    _extend(pane.canvas, {                        deltaLeft: 0,                        deltaRight: 0,                        deltaTop: 0,                        deltaBottom: 0                    })                });                for (i = 0; i < axes.length; i++) {                    axis = axes[i];                    axisPosition = axis.getOptions().position || "left";                    axis.delta = {};                    box = axis.getBoundingRect();                    pane = getPane(axis.pane, panes);                    canvas = pane.canvas;                    if (!isValidBox(box))                        continue;                    direction = "delta" + axisPosition.slice(0, 1).toUpperCase() + axisPosition.slice(1);                    switch (axisPosition) {                        case"right":                            directionMultiplier = 1;                            canvas.deltaLeft += axis.padding ? axis.padding.left : 0;                            break;                        case"left":                            directionMultiplier = -1;                            canvas.deltaRight += axis.padding ? axis.padding.right : 0;                            break;                        case"top":                            directionMultiplier = -1;                            canvas.deltaBottom += axis.padding ? axis.padding.bottom : 0;                            break;                        case"bottom":                            directionMultiplier = 1;                            canvas.deltaTop += axis.padding ? axis.padding.top : 0;                            break                    }                    switch (axisPosition) {                        case"right":                        case"left":                            if (!box.isEmpty) {                                delta = box.y + box.height - (canvas.height - canvas.originalBottom);                                if (delta > 0) {                                    that.requireAxesRedraw = true;                                    canvas.deltaBottom += delta                                }                                delta = canvas.originalTop - box.y;                                if (delta > 0) {                                    that.requireAxesRedraw = true;                                    canvas.deltaTop += delta                                }                            }                            axisLength = box.width;                            someDirection = ["Left", "Right"];                            break;                        case"top":                        case"bottom":                            if (!box.isEmpty) {                                delta = box.x + box.width - (canvas.width - canvas.originalRight);                                if (delta > 0) {                                    that.requireAxesRedraw = true;                                    canvas.deltaRight += delta                                }                                delta = canvas.originalLeft - box.x;                                if (delta > 0) {                                    that.requireAxesRedraw = true;                                    canvas.deltaLeft += delta                                }                            }                            someDirection = ["Bottom", "Top"];                            axisLength = box.height;                            break                    }                    if (!axis.delta[axisPosition] && canvas[direction] > 0)                        canvas[direction] += axis.getMultipleAxesSpacing();                    axis.delta[axisPosition] = axis.delta[axisPosition] || 0;                    axis.delta[axisPosition] += canvas[direction] * directionMultiplier;                    canvas[direction] += axisLength                }                that.requireAxesRedraw = correctDeltaMarginValue(panes, someDirection) || that.requireAxesRedraw;                that.stopDrawAxes = applyFoundExceedings(panes, rotated)            },            applyPieChartSeriesLayout: function(canvas, singleSeries, hideLayoutLabels) {                var paneSpaceHeight = canvas.height - canvas.top - canvas.bottom,                    paneSpaceWidth = canvas.width - canvas.left - canvas.right,                    paneCenterX = paneSpaceWidth / 2 + canvas.left,                    paneCenterY = paneSpaceHeight / 2 + canvas.top,                    piePercentage = this._options.piePercentage,                    accessibleRadius = _isNumber(piePercentage) ? piePercentage * _min(canvas.height, canvas.width) / 2 : _min(paneSpaceWidth, paneSpaceHeight) / 2,                    minR = 0.7 * accessibleRadius,                    innerRadius = getInnerRadius(singleSeries);                if (!hideLayoutLabels && !_isNumber(piePercentage))                    _each(singleSeries.getPoints(), function(_, point) {                        if (point._label.isVisible() && point.isVisible()) {                            var labelBBox = point._label.getBoundingRect(),                                nearestX = getNearestCoord(labelBBox.x, labelBBox.x + labelBBox.width, paneCenterX),                                nearestY = getNearestCoord(labelBBox.y, labelBBox.y + labelBBox.height, paneCenterY),                                minRadiusWithLabels = _max(getLengthFromCenter(nearestX, nearestY, paneCenterX, paneCenterY) - DX.viz.core.series.helpers.consts.pieLabelIndent, minR);                            accessibleRadius = _min(accessibleRadius, minRadiusWithLabels)                        }                    });                singleSeries.correctPosition({                    centerX: _floor(paneCenterX),                    centerY: _floor(paneCenterY),                    radiusInner: _floor(accessibleRadius * innerRadius),                    radiusOuter: _floor(accessibleRadius)                })            },            updateDrawnElements: function(axes, canvas, dirtyCanvas, panes, rotated) {                var needRemoveSpace,                    saveDirtyCanvas = _extend({}, dirtyCanvas);                needRemoveSpace = this.needMoreSpaceForPanesCanvas(panes, rotated);                if (!needRemoveSpace)                    return;                needRemoveSpace.height = _decreaseGaps(dirtyCanvas, ["top", "bottom"], needRemoveSpace.height);                needRemoveSpace.width = _decreaseGaps(dirtyCanvas, ["left", "right"], needRemoveSpace.width);                canvas.top -= saveDirtyCanvas.top - dirtyCanvas.top;                canvas.bottom -= saveDirtyCanvas.bottom - dirtyCanvas.bottom;                canvas.left -= saveDirtyCanvas.left - dirtyCanvas.left;                canvas.right -= saveDirtyCanvas.right - dirtyCanvas.right;                updateElements(this._horizontalElements, "width", "height", dirtyCanvas, canvas, needRemoveSpace);                updateElements(this._verticalElements, "height", "width", dirtyCanvas, canvas, needRemoveSpace);                updateAxis(axes.verticalAxes, "width", needRemoveSpace);                updateAxis(axes.horizontalAxes, "height", needRemoveSpace)            },            needMoreSpaceForPanesCanvas: function(panes, rotated) {                var options = this._options,                    width = options.width,                    height = options.height,                    piePercentage = options.piePercentage,                    percentageIsValid = _isNumber(piePercentage),                    needHorizontalSpace = 0,                    needVerticalSpace = 0;                _each(panes, function(_, pane) {                    var paneCanvas = pane.canvas,                        minSize = percentageIsValid ? _min(paneCanvas.width, paneCanvas.height) * piePercentage : undefined,                        needPaneHorizonralSpace = (percentageIsValid ? minSize : width) - (paneCanvas.width - paneCanvas.left - paneCanvas.right),                        needPaneVerticalSpace = (percentageIsValid ? minSize : height) - (paneCanvas.height - paneCanvas.top - paneCanvas.bottom);                    if (rotated) {                        needHorizontalSpace += needPaneHorizonralSpace > 0 ? needPaneHorizonralSpace : 0;                        needVerticalSpace = _max(needPaneVerticalSpace > 0 ? needPaneVerticalSpace : 0, needVerticalSpace)                    }                    else {                        needHorizontalSpace = _max(needPaneHorizonralSpace > 0 ? needPaneHorizonralSpace : 0, needHorizontalSpace);                        needVerticalSpace += needPaneVerticalSpace > 0 ? needPaneVerticalSpace : 0                    }                });                return needHorizontalSpace > 0 || needVerticalSpace > 0 ? {                        width: needHorizontalSpace,                        height: needVerticalSpace                    } : false            },            correctSizeElement: function(element, canvas) {                element.setSize({                    width: canvas.width - canvas.right - canvas.left,                    height: canvas.width - canvas.right - canvas.left                });                element.changeSize({                    width: 0,                    height: 0                })            }        };        DX.viz.charts._setCanvasValues = setCanvasValues;        DX.viz.charts.LayoutManager = LayoutManager    })(jQuery, DevExpress);    /*! Module viz-charts, file multiAxesSynchronizer.js */    (function($, DX, undefined) {        var Range = DX.viz.core.Range,            utils = DX.utils,            _adjustValue = utils.adjustValue,            _applyPrecisionByMinDelta = utils.applyPrecisionByMinDelta,            _isDefined = utils.isDefined,            _math = Math,            _floor = _math.floor,            _max = _math.max,            _each = $.each,            MIN_RANGE_FOR_ADJUST_BOUNDS = 0.1;        var getValueAxesPerPanes = function(valueAxes) {                var result = {};                _each(valueAxes, function(_, axis) {                    var pane = axis.pane;                    if (!result[pane])                        result[pane] = [];                    result[pane].push(axis)                });                return result            };        var restoreOriginalBusinessRange = function(axis) {                var businessRange,                    translator = axis.getTranslator();                if (!translator._originalBusinessRange)                    translator._originalBusinessRange = new Range(translator.getBusinessRange());                else {                    businessRange = new Range(translator._originalBusinessRange);                    translator.updateBusinessRange(businessRange)                }            };        var linearConvertor = {                transform: function(v, b) {                    return utils.getLog(v, b)                },                addInterval: function(v, i) {                    return v + i                },                getInterval: function(base, tickInterval) {                    return tickInterval                },                adjustValue: _floor            };        var logConvertor = {                transform: function(v, b) {                    return utils.raiseTo(v, b)                },                addInterval: function(v, i) {                    return v * i                },                getInterval: function(base, tickInterval) {                    return _math.pow(base, tickInterval)                },                adjustValue: _adjustValue            };        var convertAxisInfo = function(axisInfo, convertor) {                if (!axisInfo.isLogarithmic)                    return;                var base = axisInfo.logarithmicBase,                    tickValues = axisInfo.tickValues,                    tick,                    ticks = [],                    interval,                    i;                axisInfo.minValue = convertor.transform(axisInfo.minValue, base);                axisInfo.oldMinValue = convertor.transform(axisInfo.oldMinValue, base);                axisInfo.maxValue = convertor.transform(axisInfo.maxValue, base);                axisInfo.oldMaxValue = convertor.transform(axisInfo.oldMaxValue, base);                axisInfo.tickInterval = _math.round(axisInfo.tickInterval);                if (axisInfo.tickInterval < 1)                    axisInfo.tickInterval = 1;                interval = convertor.getInterval(base, axisInfo.tickInterval);                tick = convertor.transform(tickValues[0], base);                for (i = 0; i < tickValues.length; i++) {                    ticks.push(convertor.adjustValue(tick));                    tick = convertor.addInterval(tick, interval)                }                ticks.tickInterval = axisInfo.tickInterval;                axisInfo.tickValues = ticks            };        var populateAxesInfo = function(axes) {                return $.map(axes, function(axis) {                        restoreOriginalBusinessRange(axis);                        var ticksValues = axis.getTicksValues(),                            majorTicks = ticksValues.majorTicksValues,                            options = axis.getOptions(),                            minValue,                            maxValue,                            axisInfo = null,                            businessRange,                            tickInterval,                            synchronizedValue;                        if (majorTicks && majorTicks.length > 0 && utils.isNumber(majorTicks[0]) && options.type !== "discrete") {                            businessRange = axis.getTranslator().getBusinessRange();                            tickInterval = axis._tickManager.getTickInterval();                            minValue = businessRange.minVisible;                            maxValue = businessRange.maxVisible;                            synchronizedValue = options.synchronizedValue;                            if (minValue === maxValue && _isDefined(synchronizedValue)) {                                minValue = majorTicks[0] - 1;                                maxValue = majorTicks[0] + 1;                                tickInterval = 1                            }                            axisInfo = {                                axis: axis,                                isLogarithmic: options.type === "logarithmic",                                logarithmicBase: businessRange.base,                                tickValues: majorTicks,                                minorValues: ticksValues.minorTicksValues,                                minValue: minValue,                                oldMinValue: minValue,                                maxValue: maxValue,                                oldMaxValue: maxValue,                                inverted: businessRange.invert,                                tickInterval: tickInterval,                                synchronizedValue: synchronizedValue                            };                            if (businessRange.stubData) {                                axisInfo.stubData = true;                                axisInfo.tickInterval = axisInfo.tickInterval || options.tickInterval;                                axisInfo.isLogarithmic = false                            }                            convertAxisInfo(axisInfo, linearConvertor);                            DX.utils.debug.assert(axisInfo.tickInterval !== undefined && axisInfo.tickInterval !== null, "tickInterval was not provided")                        }                        return axisInfo                    })            };        var updateTickValues = function(axesInfo) {                var maxTicksCount = 0;                _each(axesInfo, function(_, axisInfo) {                    maxTicksCount = _max(maxTicksCount, axisInfo.tickValues.length)                });                _each(axesInfo, function(_, axisInfo) {                    var ticksMultiplier,                        ticksCount,                        additionalStartTicksCount = 0,                        synchronizedValue = axisInfo.synchronizedValue,                        tickValues = axisInfo.tickValues,                        tickInterval = axisInfo.tickInterval;                    if (_isDefined(synchronizedValue)) {                        axisInfo.baseTickValue = axisInfo.invertedBaseTickValue = synchronizedValue;                        axisInfo.tickValues = [axisInfo.baseTickValue]                    }                    else {                        if (tickValues.length > 1 && tickInterval) {                            ticksMultiplier = _floor((maxTicksCount + 1) / tickValues.length);                            ticksCount = ticksMultiplier > 1 ? _floor((maxTicksCount + 1) / ticksMultiplier) : maxTicksCount;                            additionalStartTicksCount = _floor((ticksCount - tickValues.length) / 2);                            while (additionalStartTicksCount > 0 && tickValues[0] !== 0) {                                tickValues.unshift(_applyPrecisionByMinDelta(tickValues[0], tickInterval, tickValues[0] - tickInterval));                                additionalStartTicksCount--                            }                            while (tickValues.length < ticksCount)                                tickValues.push(_applyPrecisionByMinDelta(tickValues[0], tickInterval, tickValues[tickValues.length - 1] + tickInterval));                            axisInfo.tickInterval = tickInterval / ticksMultiplier                        }                        axisInfo.baseTickValue = tickValues[0];                        axisInfo.invertedBaseTickValue = tickValues[tickValues.length - 1]                    }                })            };        var getAxisRange = function(axisInfo) {                return axisInfo.maxValue - axisInfo.minValue || 1            };        var getMainAxisInfo = function(axesInfo) {                for (var i = 0; i < axesInfo.length; i++)                    if (!axesInfo[i].stubData)                        return axesInfo[i];                return null            };        var correctMinMaxValues = function(axesInfo) {                var mainAxisInfo = getMainAxisInfo(axesInfo),                    mainAxisInfoTickInterval = mainAxisInfo.tickInterval;                _each(axesInfo, function(_, axisInfo) {                    var scale,                        move,                        mainAxisBaseValueOffset,                        valueFromAxisInfo;                    if (axisInfo !== mainAxisInfo) {                        if (mainAxisInfoTickInterval && axisInfo.tickInterval) {                            if (axisInfo.stubData && _isDefined(axisInfo.synchronizedValue)) {                                axisInfo.oldMinValue = axisInfo.minValue = axisInfo.baseTickValue - (mainAxisInfo.baseTickValue - mainAxisInfo.minValue) / mainAxisInfoTickInterval * axisInfo.tickInterval;                                axisInfo.oldMaxValue = axisInfo.maxValue = axisInfo.baseTickValue - (mainAxisInfo.baseTickValue - mainAxisInfo.maxValue) / mainAxisInfoTickInterval * axisInfo.tickInterval                            }                            scale = mainAxisInfoTickInterval / getAxisRange(mainAxisInfo) / axisInfo.tickInterval * getAxisRange(axisInfo);                            axisInfo.maxValue = axisInfo.minValue + getAxisRange(axisInfo) / scale                        }                        if (mainAxisInfo.inverted && !axisInfo.inverted || !mainAxisInfo.inverted && axisInfo.inverted)                            mainAxisBaseValueOffset = mainAxisInfo.maxValue - mainAxisInfo.invertedBaseTickValue;                        else                            mainAxisBaseValueOffset = mainAxisInfo.baseTickValue - mainAxisInfo.minValue;                        valueFromAxisInfo = getAxisRange(axisInfo);                        move = (mainAxisBaseValueOffset / getAxisRange(mainAxisInfo) - (axisInfo.baseTickValue - axisInfo.minValue) / valueFromAxisInfo) * valueFromAxisInfo;                        axisInfo.minValue -= move;                        axisInfo.maxValue -= move                    }                })            };        var calculatePaddings = function(axesInfo) {                var minPadding,                    maxPadding,                    startPadding = 0,                    endPadding = 0;                _each(axesInfo, function(_, axisInfo) {                    var inverted = axisInfo.inverted;                    minPadding = axisInfo.minValue > axisInfo.oldMinValue ? (axisInfo.minValue - axisInfo.oldMinValue) / getAxisRange(axisInfo) : 0;                    maxPadding = axisInfo.maxValue < axisInfo.oldMaxValue ? (axisInfo.oldMaxValue - axisInfo.maxValue) / getAxisRange(axisInfo) : 0;                    startPadding = _max(startPadding, inverted ? maxPadding : minPadding);                    endPadding = _max(endPadding, inverted ? minPadding : maxPadding)                });                return {                        start: startPadding,                        end: endPadding                    }            };        var correctMinMaxValuesByPaddings = function(axesInfo, paddings) {                _each(axesInfo, function(_, info) {                    var range = getAxisRange(info),                        inverted = info.inverted;                    info.minValue -= paddings[inverted ? "end" : "start"] * range;                    info.maxValue += paddings[inverted ? "start" : "end"] * range;                    if (range > MIN_RANGE_FOR_ADJUST_BOUNDS) {                        info.minValue = _math.min(info.minValue, _adjustValue(info.minValue));                        info.maxValue = _max(info.maxValue, _adjustValue(info.maxValue))                    }                })            };        var updateTickValuesIfSyncronizedValueUsed = function(axesInfo) {                var hasSyncronizedValue = false;                _each(axesInfo, function(_, info) {                    hasSyncronizedValue = hasSyncronizedValue || _isDefined(info.synchronizedValue)                });                _each(axesInfo, function(_, info) {                    var lastTickValue,                        tickInterval = info.tickInterval,                        tickValues = info.tickValues,                        maxValue = info.maxValue,                        minValue = info.minValue;                    if (hasSyncronizedValue && tickInterval) {                        while (tickValues[0] - tickInterval >= minValue)                            tickValues.unshift(_adjustValue(tickValues[0] - tickInterval));                        lastTickValue = tickValues[tickValues.length - 1];                        while ((lastTickValue = lastTickValue + tickInterval) <= maxValue)                            tickValues.push(utils.isExponential(lastTickValue) ? _adjustValue(lastTickValue) : _applyPrecisionByMinDelta(minValue, tickInterval, lastTickValue))                    }                    while (tickValues[0] < minValue)                        tickValues.shift();                    while (tickValues[tickValues.length - 1] > maxValue)                        tickValues.pop()                })            };        var applyMinMaxValues = function(axesInfo) {                _each(axesInfo, function(_, info) {                    var axis = info.axis,                        range = axis.getTranslator().getBusinessRange();                    if (range.min === range.minVisible)                        range.min = info.minValue;                    if (range.max === range.maxVisible)                        range.max = info.maxValue;                    range.minVisible = info.minValue;                    range.maxVisible = info.maxValue;                    if (_isDefined(info.stubData))                        range.stubData = info.stubData;                    if (range.min > range.minVisible)                        range.min = range.minVisible;                    if (range.max < range.maxVisible)                        range.max = range.maxVisible;                    range.isSynchronized = true;                    axis.getTranslator().updateBusinessRange(range);                    axis.setTicks({                        majorTicks: info.tickValues,                        minorTicks: info.minorValues                    })                })            };        var correctAfterSynchronize = function(axesInfo) {                var invalidAxisInfo = [],                    correctValue,                    validAxisInfo;                _each(axesInfo, function(i, info) {                    if (info.oldMaxValue - info.oldMinValue === 0)                        invalidAxisInfo.push(info);                    else if (!_isDefined(correctValue) && !_isDefined(info.synchronizedValue)) {                        correctValue = _math.abs((info.maxValue - info.minValue) / (info.tickValues[_floor(info.tickValues.length / 2)] || info.maxValue));                        validAxisInfo = info                    }                });                if (!_isDefined(correctValue))                    return;                _each(invalidAxisInfo, function(i, info) {                    var firstTick = info.tickValues[0],                        correctedTick = firstTick * correctValue,                        tickValues = validAxisInfo.tickValues,                        centralTick = tickValues[_floor(tickValues.length / 2)];                    if (firstTick > 0) {                        info.maxValue = correctedTick;                        info.minValue = 0                    }                    else if (firstTick < 0) {                        info.minValue = correctedTick;                        info.maxValue = 0                    }                    else if (firstTick === 0) {                        info.maxValue = validAxisInfo.maxValue - centralTick;                        info.minValue = validAxisInfo.minValue - centralTick                    }                })            };        DX.viz.charts.multiAxesSynchronizer = {synchronize: function(valueAxes) {                _each(getValueAxesPerPanes(valueAxes), function(_, axes) {                    var axesInfo,                        paddings;                    if (axes.length > 1) {                        axesInfo = populateAxesInfo(axes);                        if (axesInfo.length === 0 || !getMainAxisInfo(axesInfo))                            return;                        updateTickValues(axesInfo);                        correctMinMaxValues(axesInfo);                        paddings = calculatePaddings(axesInfo);                        correctMinMaxValuesByPaddings(axesInfo, paddings);                        correctAfterSynchronize(axesInfo);                        updateTickValuesIfSyncronizedValueUsed(axesInfo);                        _each(axesInfo, function() {                            convertAxisInfo(this, logConvertor)                        });                        applyMinMaxValues(axesInfo)                    }                })            }}    })(jQuery, DevExpress);    /*! Module viz-charts, file tracker.js */    (function($, DX, math) {        var charts = DX.viz.charts,            eventsConsts = DX.viz.core.series.helpers.consts.events,            utils = DX.utils,            isDefined = utils.isDefined,            _floor = math.floor,            _each = $.each,            MULTIPLE_MODE = 'multiple',            ALL_ARGUMENTS_POINTS_MODE = 'allargumentpoints',            ALL_SERIES_POINTS_MODE = 'allseriespoints',            NONE_MODE = 'none',            POINTER_ACTION = "dxpointerdown dxpointermove",            POINT_SELECTION_CHANGED = "pointSelectionChanged",            LEGEND_CLICK = "legendClick",            SERIES_CLICK = "seriesClick",            POINT_CLICK = "pointClick",            RELEASE_POINT_SELECTED_STATE = "releasePointSelectedState",            SET_POINT_SELECTED_STATE = "setPointSelectedState",            DELAY = 100;        function processMode(mode) {            return (mode + "").toLowerCase()        }        function getNonVirtualAxis(axisArray) {            var axis;            _each(axisArray, function(_, a) {                if (!a._virtual) {                    axis = a;                    return false                }            });            return axis        }        function eventCanceled(event, target) {            return event.cancel || !target.getOptions()        }        var baseTrackerPrototype = {                ctor: function(options) {                    var that = this,                        data = {tracker: that};                    if (processMode(options.pointSelectionMode) === MULTIPLE_MODE) {                        that._setSelectedPoint = that._selectPointMultipleMode;                        that._releaseSelectedPoint = that._releaseSelectedPointMultipleMode                    }                    else {                        that._setSelectedPoint = that._selectPointSingleMode;                        that._releaseSelectedPoint = that._releaseSelectedPointSingleMode                    }                    if (processMode(options.seriesSelectionMode) === MULTIPLE_MODE) {                        that._releaseSelectedSeries = that._releaseSelectedSeriesMultipleMode;                        that._setSelectedSeries = that._setSelectedSeriesMultipleMode                    }                    else {                        that._releaseSelectedSeries = that._releaseSelectedSeriesSingleMode;                        that._setSelectedSeries = that._setSelectedSeriesSingleMode                    }                    that._renderer = options.renderer;                    that._tooltip = options.tooltip;                    that._eventTrigger = options.eventTrigger;                    options.seriesGroup.off().on(eventsConsts.selectSeries, data, that._selectSeries).on(eventsConsts.deselectSeries, data, that._deselectSeries).on(eventsConsts.selectPoint, data, that._selectPoint).on(eventsConsts.deselectPoint, data, that._deselectPoint).on(eventsConsts.showPointTooltip, data, that._showPointTooltip).on(eventsConsts.hidePointTooltip, data, that._hidePointTooltip);                    that._renderer.root.off(POINTER_ACTION).off("dxclick dxhold").on(POINTER_ACTION, data, that._pointerHandler).on("dxclick", data, that._clickHandler).on("dxhold", {timeout: 300}, $.noop)                },                update: function(options) {                    var that = this;                    if (that._storedSeries !== options.series) {                        that._storedSeries = options.series || [];                        that._clean()                    }                    else {                        that._hideTooltip(that.pointAtShownTooltip);                        that._clearHover();                        that.clearSelection()                    }                    that._legend = options.legend;                    that.legendCallback = options.legendCallback;                    that._prepare(that._renderer.root)                },                setCanvases: function(mainCanvas, paneCanvases) {                    this._mainCanvas = mainCanvas;                    this._canvases = paneCanvases                },                repairTooltip: function() {                    var point = this.pointAtShownTooltip;                    if (point && !point.isVisible())                        this._hideTooltip(point, true);                    else                        this._showTooltip(point)                },                _prepare: function(root) {                    root.off("dxmousewheel").on("dxmousewheel", {tracker: this}, function(e) {                        e.data.tracker._pointerOut()                    })                },                _selectPointMultipleMode: function(point) {                    var that = this;                    that._selectedPoint = that._selectedPoint || [];                    if ($.inArray(point, that._selectedPoint) < 0) {                        that._selectedPoint.push(point);                        that._setPointState(point, SET_POINT_SELECTED_STATE, processMode(point.getOptions().selectionMode), POINT_SELECTION_CHANGED, that.legendCallback(point))                    }                },                _releaseSelectedPointMultipleMode: function(point) {                    var that = this,                        points = that._selectedPoint || [],                        pointIndex = $.inArray(point, points);                    if (pointIndex >= 0) {                        that._setPointState(point, RELEASE_POINT_SELECTED_STATE, processMode(point.getOptions().selectionMode), POINT_SELECTION_CHANGED, that.legendCallback(point));                        points.splice(pointIndex, 1)                    }                    else if (!point)                        _each(points, function(_, point) {                            that._releaseSelectedPoint(point)                        })                },                _selectPointSingleMode: function(point) {                    var that = this;                    if (that._selectedPoint !== point) {                        that._releaseSelectedPoint();                        that._selectedPoint = point;                        that._setPointState(point, SET_POINT_SELECTED_STATE, processMode(point.getOptions().selectionMode), POINT_SELECTION_CHANGED, that.legendCallback(point))                    }                },                _releaseSelectedPointSingleMode: function() {                    var that = this,                        point = that._selectedPoint;                    if (point) {                        that._setPointState(point, RELEASE_POINT_SELECTED_STATE, processMode(point.getOptions().selectionMode), POINT_SELECTION_CHANGED, that.legendCallback(point));                        that._selectedPoint = null                    }                },                _setPointState: function(point, action, mode, eventName, legendCallback) {                    var that = this;                    switch (mode) {                        case ALL_ARGUMENTS_POINTS_MODE:                            that._toAllArgumentPoints(point.argument, action, eventName);                            break;                        case ALL_SERIES_POINTS_MODE:                            _each(point.series.getPoints(), function(_, point) {                                point.series[action](point);                                that._eventTrigger(eventName, {target: point})                            });                            break;                        case NONE_MODE:                            break;                        default:                            point.series[action](point, legendCallback);                            that._eventTrigger(eventName, {target: point})                    }                },                _toAllArgumentPoints: function(argument, func, eventName) {                    var that = this;                    _each(that._storedSeries, function(_, series) {                        var neighborPoints = series.getPointsByArg(argument);                        _each(neighborPoints || [], function(_, point) {                            series[func](point);                            eventName && that._eventTrigger(eventName, {target: point})                        })                    })                },                _setHoveredPoint: function(point, mode) {                    var that = this;                    var debug = DX.utils.debug;                    debug.assert(point.series, 'series was not assigned to point or empty');                    if (that.hoveredPoint === point || !point.series)                        return;                    that._releaseHoveredPoint();                    if (point && point.getOptions() && mode !== NONE_MODE) {                        that.hoveredPoint = point;                        that._setPointState(point, 'setPointHoverState', mode || processMode(point.getOptions().hoverMode), "pointHoverChanged", that.legendCallback(point))                    }                },                _releaseHoveredPoint: function() {                    var that = this,                        point = that.hoveredPoint,                        mode;                    if (!point || !point.getOptions())                        return;                    mode = processMode(point.getOptions().hoverMode);                    if (mode === ALL_SERIES_POINTS_MODE)                        _each(point.series.getPoints(), function(_, point) {                            point.series.releasePointHoverState(point);                            that._eventTrigger("pointHoverChanged", {target: point})                        });                    else if (mode === ALL_ARGUMENTS_POINTS_MODE)                        that._toAllArgumentPoints(point.argument, 'releasePointHoverState', "pointHoverChanged");                    else {                        point.releaseHoverState(that.legendCallback(point));                        that._eventTrigger("pointHoverChanged", {target: point})                    }                    if (that._tooltip.isEnabled())                        that._hideTooltip(point);                    that.hoveredPoint = null                },                _setSelectedSeriesMultipleMode: function(series, mode) {                    var that = this;                    that._selectedSeries = that._selectedSeries || [];                    if ($.inArray(series, that._selectedSeries) < 0) {                        that._selectedSeries.push(series);                        series.setSelectedState(true, mode, that.legendCallback(series));                        that._eventTrigger("seriesSelectionChanged", {target: series})                    }                },                _setSelectedSeriesSingleMode: function(series, mode) {                    var that = this;                    if (series !== that._selectedSeries || series.lastSelectionMode !== mode) {                        this._releaseSelectedSeries();                        that._selectedSeries = series;                        series.setSelectedState(true, mode, that.legendCallback(series));                        that._eventTrigger("seriesSelectionChanged", {target: series})                    }                },                _releaseSelectedSeriesMultipleMode: function(series) {                    var that = this,                        selectedSeries = that._selectedSeries || [],                        seriesIndex = $.inArray(series, selectedSeries);                    if (seriesIndex >= 0) {                        series.setSelectedState(false, undefined, that.legendCallback(series));                        that._eventTrigger("seriesSelectionChanged", {target: series});                        selectedSeries.splice(seriesIndex, 1)                    }                    else if (!series)                        _each(selectedSeries, function(_, series) {                            that._releaseSelectedSeries(series)                        })                },                _releaseSelectedSeriesSingleMode: function() {                    var that = this,                        series = that._selectedSeries;                    if (series) {                        series.setSelectedState(false, undefined, that.legendCallback(series));                        that._eventTrigger("seriesSelectionChanged", {target: series});                        that._selectedSeries = null                    }                },                _setHoveredSeries: function(series, mode) {                    var that = this;                    if (mode !== NONE_MODE && that.hoveredSeries !== series || series.lastHoverMode !== mode) {                        that._clearHover();                        series.setHoverState(true, mode, that.legendCallback(series));                        that._eventTrigger("seriesHoverChanged", {target: series})                    }                    that.hoveredSeries = series;                    if (mode === NONE_MODE)                        $(series).trigger('NoneMode')                },                _releaseHoveredSeries: function() {                    var that = this;                    if (that.hoveredSeries) {                        that.hoveredSeries.setHoverState(false, undefined, that.legendCallback(that.hoveredSeries));                        that._eventTrigger("seriesHoverChanged", {target: that.hoveredSeries});                        that.hoveredSeries = null                    }                },                _selectSeries: function(event, mode) {                    event.data.tracker._setSelectedSeries(event.target, mode)                },                _deselectSeries: function(event, mode) {                    event.data.tracker._releaseSelectedSeries(event.target, mode)                },                _selectPoint: function(event, point) {                    event.data.tracker._setSelectedPoint(point)                },                _deselectPoint: function(event, point) {                    event.data.tracker._releaseSelectedPoint(point)                },                clearSelection: function() {                    this._releaseSelectedPoint();                    this._releaseSelectedSeries()                },                _clean: function() {                    var that = this;                    that._selectedPoint = that._selectedSeries = that.hoveredPoint = that.hoveredSeries = null;                    that._hideTooltip(that.pointAtShownTooltip)                },                _clearHover: function() {                    this._releaseHoveredSeries();                    this._releaseHoveredPoint()                },                _hideTooltip: function(point, silent) {                    var that = this;                    if (!that._tooltip || point && that.pointAtShownTooltip !== point)                        return;                    if (!silent && that.pointAtShownTooltip)                        that.pointAtShownTooltip = null;                    that._tooltip.hide()                },                _showTooltip: function(point) {                    var that = this,                        tooltipFormatObject,                        eventData;                    if (point && point.getOptions()) {                        tooltipFormatObject = point.getTooltipFormatObject(that._tooltip);                        if (!isDefined(tooltipFormatObject.valueText) && !tooltipFormatObject.points || !point.isVisible())                            return;                        if (!that.pointAtShownTooltip || that.pointAtShownTooltip !== point)                            eventData = {target: point};                        var coords = point.getTooltipParams(that._tooltip.getLocation()),                            rootOffset = that._renderer.getRootOffset();                        coords.x += rootOffset.left;                        coords.y += rootOffset.top;                        if (!that._tooltip.show(tooltipFormatObject, coords, eventData))                            return;                        that.pointAtShownTooltip = point                    }                },                _showPointTooltip: function(event, point) {                    var that = event.data.tracker,                        pointWithTooltip = that.pointAtShownTooltip;                    if (pointWithTooltip && pointWithTooltip !== point)                        that._hideTooltip(pointWithTooltip);                    that._showTooltip(point)                },                _hidePointTooltip: function(event, point) {                    event.data.tracker._hideTooltip(point)                },                _enableOutHandler: function() {                    if (this._outHandler)                        return;                    var that = this,                        handler = function(e) {                            var rootOffset = that._renderer.getRootOffset(),                                x = _floor(e.pageX - rootOffset.left),                                y = _floor(e.pageY - rootOffset.top);                            if (!that._inCanvas(that._mainCanvas, x, y)) {                                that._pointerOut();                                that._disableOutHandler()                            }                        };                    $(document).on(POINTER_ACTION, handler);                    this._outHandler = handler                },                _disableOutHandler: function() {                    this._outHandler && $(document).off(POINTER_ACTION, this._outHandler);                    this._outHandler = null                },                _pointerOut: function() {                    this._clearHover();                    this._tooltip.isEnabled() && this._hideTooltip(this.pointAtShownTooltip)                },                _inCanvas: function(canvas, x, y) {                    return x >= canvas.left && x <= canvas.right && y >= canvas.top && y <= canvas.bottom                },                dispose: function() {                    var that = this;                    that._disableOutHandler();                    _each(that, function(k) {                        that[k] = null                    })                }            };        charts.ChartTracker = function(options) {            this.ctor(options)        };        $.extend(charts.ChartTracker.prototype, baseTrackerPrototype, {            ctor: function(options) {                var that = this;                baseTrackerPrototype.ctor.call(that, options)            },            _pointClick: function(point, event) {                var that = this,                    eventTrigger = that._eventTrigger,                    series = point.series;                eventTrigger(POINT_CLICK, {                    target: point,                    jQueryEvent: event                }, function() {                    !eventCanceled(event, series) && eventTrigger(SERIES_CLICK, {                        target: series,                        jQueryEvent: event                    })                })            },            __trackerDelay: DELAY,            _legendClick: function(series, event) {                var that = this,                    evetArgs = {                        target: series,                        jQueryEvent: event                    },                    eventTrigger = that._eventTrigger;                eventTrigger(LEGEND_CLICK, evetArgs, function() {                    !eventCanceled(event, series) && eventTrigger(SERIES_CLICK, evetArgs)                })            },            update: function(options) {                var that = this;                that._zoomingMode = (options.zoomingMode + '').toLowerCase();                that._scrollingMode = (options.scrollingMode + '').toLowerCase();                baseTrackerPrototype.update.call(this, options);                that._argumentAxis = getNonVirtualAxis(options.argumentAxis || []);                that._axisHoverEnabled = that._argumentAxis && processMode(that._argumentAxis.getOptions().hoverMode) === ALL_ARGUMENTS_POINTS_MODE;                that._chart = options.chart;                that._rotated = options.rotated;                that._crosshair = options.crosshair            },            _getAxisArgument: function(event) {                var $target = $(event.target);                return event.target.tagName === "tspan" ? $target.parent().data('argument') : $target.data('argument')            },            _getCanvas: function(x, y) {                var that = this,                    canvases = that._canvases || [];                for (var i = 0; i < canvases.length; i++) {                    var c = canvases[i];                    if (that._inCanvas(c, x, y))                        return c                }                return null            },            _focusOnCanvas: function(canvas) {                if (!canvas && this._stickedSeries)                    this._pointerOut()            },            _resetHoveredArgument: function() {                if (isDefined(this.hoveredArgument)) {                    this._toAllArgumentPoints(this.hoveredArgument, 'releasePointHoverState');                    this.hoveredArgument = null                }            },            _hideCrosshair: function() {                this._crosshair && this._crosshair.hide()            },            _moveCrosshair: function(point, x, y) {                if (point && this._crosshair && point.isVisible()) {                    var coords = point.getCrosshairCoords(x, y),                        r = point.getPointRadius();                    this._crosshair.shift(coords.x, coords.y, r)                }            },            _prepare: function(root) {                var that = this,                    touchScrollingEnabled = that._scrollingMode === 'all' || that._scrollingMode === 'touch',                    touchZoomingEnabled = that._zoomingMode === 'all' || that._zoomingMode === 'touch',                    cssValue = (!touchScrollingEnabled ? "pan-x pan-y " : '') + (!touchZoomingEnabled ? "pinch-zoom" : '') || "none",                    rootStyles = {                        'touch-action': cssValue,                        '-ms-touch-action': cssValue                    },                    wheelzoomingEnabled = that._zoomingMode === "all" || that._zoomingMode === "mouse";                root.off("dxmousewheel dxc-scroll-start dxc-scroll-move");                baseTrackerPrototype._prepare.call(that, root);                if (!that._gestureEndHandler) {                    that._gestureEndHandler = function() {                        that._gestureEnd && that._gestureEnd()                    };                    $(document).on("dxpointerup", that._gestureEndHandler)                }                wheelzoomingEnabled && root.on("dxmousewheel", function(e) {                    var rootOffset = that._renderer.getRootOffset(),                        x = that._rotated ? e.pageY - rootOffset.top : e.pageX - rootOffset.left,                        scale = that._argumentAxis.getTranslator().getMinScale(e.delta > 0),                        translate = x - x * scale,                        zoom = that._argumentAxis.getTranslator().zoom(-translate, scale);                    that._pointerOut();                    that._chart.zoomArgument(zoom.min, zoom.max, true);                    e.preventDefault();                    e.stopPropagation()                });                root.on("dxc-scroll-start", function(e) {                    that._gestureStart(that._getGestureParams(e, {                        left: 0,                        top: 0                    }))                }).on("dxc-scroll-move", function(e) {                    that._gestureChange(that._getGestureParams(e, {                        left: 0,                        top: 0                    })) && e.preventDefault()                });                root.css(rootStyles)            },            _getGestureParams: function(e, offset) {                var that = this,                    x1,                    x2,                    touches = e.pointers.length,                    left,                    right,                    eventCoordField = that._rotated ? "pageY" : "pageX";                offset = that._rotated ? offset.top : offset.left;                if (touches === 2)                    x1 = e.pointers[0][eventCoordField] - offset,                    x2 = e.pointers[1][eventCoordField] - offset;                else if (touches === 1)                    x1 = x2 = e.pointers[0][eventCoordField] - offset;                left = math.min(x1, x2);                right = math.max(x1, x2);                return {                        center: left + (right - left) / 2,                        distance: right - left,                        touches: touches,                        scale: 1,                        pointerType: e.pointerType                    }            },            _gestureStart: function(gestureParams) {                var that = this;                that._startGesture = that._startGesture || gestureParams;                if (that._startGesture.touches !== gestureParams.touches)                    that._startGesture = gestureParams            },            _gestureChange: function(gestureParams) {                var that = this,                    startGesture = that._startGesture,                    gestureChanged = false,                    scrollingEnabled = that._scrollingMode === 'all' || that._scrollingMode !== 'none' && that._scrollingMode === gestureParams.pointerType,                    zoommingEnabled = that._zoomingMode === 'all' || that._zoomingMode === 'touch';                if (!startGesture)                    return gestureChanged;                if (startGesture.touches === 1 && math.abs(startGesture.center - gestureParams.center) < 3) {                    that._gestureStart(gestureParams);                    return gestureChanged                }                if (startGesture.touches === 2 && zoommingEnabled) {                    gestureChanged = true;                    startGesture.scale = gestureParams.distance / startGesture.distance;                    startGesture.scroll = gestureParams.center - startGesture.center + (startGesture.center - startGesture.center * startGesture.scale)                }                else if (startGesture.touches === 1 && scrollingEnabled) {                    gestureChanged = true;                    startGesture.scroll = gestureParams.center - startGesture.center                }                if (gestureChanged) {                    startGesture.changed = gestureChanged;                    that._chart._transformArgument(startGesture.scroll, startGesture.scale)                }                return gestureChanged            },            _gestureEnd: function() {                var that = this,                    startGesture = that._startGesture,                    zoom,                    renderer = that._renderer;                that._startGesture = null;                function complete() {                    that._chart.zoomArgument(zoom.min, zoom.max, true)                }                if (startGesture && startGesture.changed) {                    zoom = that._argumentAxis._translator.zoom(-startGesture.scroll, startGesture.scale);                    if (renderer.animationEnabled() && (-startGesture.scroll !== zoom.translate || startGesture.scale !== zoom.scale)) {                        var translateDelta = -(startGesture.scroll + zoom.translate),                            scaleDelta = startGesture.scale - zoom.scale;                        renderer.root.animate({_: 0}, {                            step: function(pos) {                                var translateValue = -startGesture.scroll - translateDelta * pos;                                var scaleValue = startGesture.scale - scaleDelta * pos;                                that._chart._transformArgument(-translateValue, scaleValue)                            },                            complete: complete,                            duration: 250                        })                    }                    else                        complete()                }            },            _clean: function() {                var that = this;                baseTrackerPrototype._clean.call(that);                that._resetTimer();                that._stickedSeries = null            },            _getSeriesForShared: function(x, y) {                var that = this,                    points = [],                    point = null,                    distance = Infinity;                if (that._tooltip.isShared() && !that.hoveredSeries) {                    _each(that._storedSeries, function(_, series) {                        var point = series.getNeighborPoint(x, y);                        point && points.push(point)                    });                    _each(points, function(_, p) {                        var coords = p.getCrosshairCoords(x, y),                            d = math.sqrt((x - coords.x) * (x - coords.x) + (y - coords.y) * (y - coords.y));                        if (d < distance) {                            point = p;                            distance = d                        }                    })                }                return point && point.series            },            _setTimeout: function(callback, keeper) {                var that = this;                if (that._timeoutKeeper !== keeper) {                    that._resetTimer();                    that._hoverTimeout = setTimeout(function() {                        callback();                        that._timeoutKeeper = null                    }, DELAY);                    that._timeoutKeeper = keeper                }            },            _resetTimer: function() {                clearTimeout(this._hoverTimeout);                this._timeoutKeeper = this._hoverTimeout = null            },            _pointerHandler: function(e) {                var that = e.data.tracker,                    rootOffset = that._renderer.getRootOffset(),                    x = _floor(e.pageX - rootOffset.left),                    y = _floor(e.pageY - rootOffset.top),                    canvas = that._getCanvas(x, y),                    series = $(e.target).data("series"),                    point = $(e.target).data("point") || series && series.getPointByCoord(x, y);                that._enableOutHandler();                that._x = x;                that._y = y;                if (e.type === "dxpointerdown")                    canvas && that._gestureStart(that._getGestureParams(e, rootOffset));                else if (that._startGesture && canvas)                    if (that._gestureChange(that._getGestureParams(e, rootOffset))) {                        that._pointerOut();                        e.preventDefault();                        return                    }                if (that._legend.coordsIn(x, y)) {                    var item = that._legend.getItemByCoord(x, y);                    if (item) {                        series = that._storedSeries[item.id];                        that._setHoveredSeries(series, that._legend._options.hoverMode);                        that._stickedSeries = series                    }                    else                        that._clearHover();                    that._hideCrosshair();                    return                }                if (that._axisHoverEnabled && that._argumentAxis.coordsIn(x, y)) {                    var argument = that._getAxisArgument(e),                        argumentDefined = isDefined(argument);                    if (argumentDefined && that.hoveredArgument !== argument) {                        that._clearHover();                        that._resetHoveredArgument();                        that._toAllArgumentPoints(argument, "setPointHoverState");                        that.hoveredArgument = argument                    }                    else if (!argumentDefined)                        that._resetHoveredArgument();                    return                }                that._resetHoveredArgument();                that._focusOnCanvas(canvas);                if (!canvas && !point)                    return;                if (!series && !point)                    that._stickedSeries = that._stickedSeries || that._getSeriesForShared(x, y);                if (series && !point) {                    point = series.getNeighborPoint(x, y);                    if (series !== that.hoveredSeries) {                        that._setTimeout(function() {                            that._setHoveredSeries(series, series.getOptions().hoverMode);                            that._stickedSeries = series;                            that._pointerComplete(point)                        }, series);                        return                    }                }                else if (point) {                    if (that.hoveredSeries)                        that._setTimeout(function() {                            that._pointerOnPoint(point)                        }, point);                    else                        that._pointerOnPoint(point);                    return                }                else if (that._stickedSeries) {                    series = that._stickedSeries;                    point = series.getNeighborPoint(x, y);                    that.hoveredSeries && that._releaseHoveredSeries();                    point && that._setHoveredPoint(point)                }                that._pointerComplete(point)            },            _pointerOnPoint: function(point) {                var that = this;                that._stickedSeries = point.series;                that._setHoveredPoint(point);                that.hoveredSeries && that._releaseHoveredSeries();                that._pointerComplete(point)            },            _pointerComplete: function(point) {                var that = this;                that.hoveredSeries && that.hoveredSeries.updateHover(that._x, that._y);                that._resetTimer();                that._moveCrosshair(point, that._x, that._y);                that.pointAtShownTooltip !== point && that._tooltip.isEnabled() && that._showTooltip(point)            },            _pointerOut: function() {                var that = this;                that._stickedSeries = null;                that._hideCrosshair();                that._resetHoveredArgument();                that._resetTimer();                baseTrackerPrototype._pointerOut.call(that)            },            _clickHandler: function(e) {                var that = e.data.tracker,                    rootOffset = that._renderer.getRootOffset(),                    x = _floor(e.pageX - rootOffset.left),                    y = _floor(e.pageY - rootOffset.top),                    point = $(e.target).data("point"),                    series = that._stickedSeries || $(e.target).data("series") || point && point.series,                    axis = that._argumentAxis;                if (that._legend.coordsIn(x, y)) {                    var item = that._legend.getItemByCoord(x, y);                    if (item) {                        series = that._storedSeries[item.id];                        that._legendClick(series, e)                    }                    return                }                if (axis && axis.coordsIn(x, y)) {                    var argument = that._getAxisArgument(e);                    if (isDefined(argument)) {                        that._eventTrigger("argumentAxisClick", {                            argument: argument,                            jQueryEvent: e                        });                        return                    }                }                if (series) {                    point = point || series.getPointByCoord(x, y);                    if (point)                        that._pointClick(point, e);                    else                        $(e.target).data("series") && that._eventTrigger(SERIES_CLICK, {                            target: series,                            jQueryEvent: e                        })                }            },            dispose: function() {                this._gestureEndHandler && $(document).off("dxpointerup", this._gestureEndHandler);                this._resetTimer();                baseTrackerPrototype.dispose.call(this)            }        });        charts.PieTracker = function(options) {            this.ctor(options)        };        $.extend(charts.PieTracker.prototype, baseTrackerPrototype, {            _legendClick: function(point, event) {                var that = this,                    eventArg = {                        target: point,                        jQueryEvent: event                    },                    eventTrigger = that._eventTrigger;                eventTrigger(LEGEND_CLICK, eventArg, function() {                    !eventCanceled(event, point) && eventTrigger(POINT_CLICK, eventArg)                })            },            _pointerHandler: function(e) {                var that = e.data.tracker,                    rootOffset = that._renderer.getRootOffset(),                    x = _floor(e.pageX - rootOffset.left),                    y = _floor(e.pageY - rootOffset.top),                    series = that._storedSeries[0],                    point = $(e.target).data("point") || series && series.getPointByCoord(x, y),                    item,                    mode;                that._enableOutHandler();                if (that._legend.coordsIn(x, y)) {                    item = that._legend.getItemByCoord(x, y);                    if (item) {                        point = series.getPoints()[item.id];                        mode = that._legend._options.hoverMode                    }                }                if (point && point !== that.hoveredPoint) {                    that._tooltip.isEnabled() && that._showTooltip(point);                    that._setHoveredPoint(point, mode)                }                else if (!point)                    that._pointerOut()            },            _clickHandler: function(e) {                var that = e.data.tracker,                    rootOffset = that._renderer.getRootOffset(),                    x = _floor(e.pageX - rootOffset.left),                    y = _floor(e.pageY - rootOffset.top),                    storedSeries = that._storedSeries[0],                    point;                if (that._legend.coordsIn(x, y)) {                    var item = that._legend.getItemByCoord(x, y);                    if (item) {                        point = storedSeries.getPoints()[item.id];                        that._legendClick(point, e)                    }                }                else {                    point = $(e.target).data("point") || storedSeries && storedSeries.getPointByCoord(x, y);                    point && that._eventTrigger(POINT_CLICK, {                        target: point,                        jQueryEvent: e                    })                }            }        })    })(jQuery, DevExpress, Math);    /*! Module viz-charts, file crosshair.js */    (function($, DX, undefined) {        var _math = Math,            mathAbs = _math.abs,            mathMin = _math.min,            mathMax = _math.max,            _round = _math.round,            HORIZONTAL = "horizontal",            VERTICAL = "vertical",            LABEL_BACKGROUND_PADDING_X = 8,            LABEL_BACKGROUND_PADDING_Y = 4,            CENTER = "center",            RIGHT = "right",            LEFT = "left",            TOP = "top",            BOTTOM = "bottom",            _isDefined = DX.utils.isDefined;        function Crosshair() {            this.ctor.apply(this, arguments)        }        DX.viz.charts.Crosshair = Crosshair;        Crosshair.prototype = {            ctor: function(renderer, options, params, group) {                var that = this;                that._renderer = renderer;                that._crosshairGroup = group;                that._options = {};                that._init(options, params)            },            update: function(options, params) {                this._init(options, params)            },            dispose: function() {                var that = this;                that._renderer = null;                that._crosshairGroup = null;                that._options = null;                that._axes = null;                that._canvas = null;                that._horizontalGroup = null;                that._verticalGroup = null;                that._horizontal = null;                that._vertical = null;                that._circle = null;                that._panes = null            },            _init: function(options, params) {                var that = this,                    canvas = params.canvas;                that._canvas = {                    top: canvas.top,                    bottom: canvas.height - canvas.bottom,                    left: canvas.left,                    right: canvas.width - canvas.right,                    width: canvas.width,                    height: canvas.height                };                that._axes = params.axes;                that._panes = params.panes;                that._prepareOptions(options, HORIZONTAL);                that._prepareOptions(options, VERTICAL)            },            _prepareOptions: function(options, direction) {                this._options[direction] = {                    visible: options[direction + "Line"].visible,                    line: {                        stroke: options[direction + "Line"].color || options.color,                        "stroke-width": options[direction + "Line"].width || options.width,                        dashStyle: options[direction + "Line"].dashStyle || options.dashStyle,                        opacity: options[direction + "Line"].opacity || options.opacity,                        "stroke-linecap": "butt"                    },                    label: $.extend(true, {}, options.label, options[direction + "Line"].label)                }            },            _createLines: function(options, sharpParam, group) {                var lines = [],                    canvas = this._canvas,                    points = [canvas.left, canvas.top, canvas.left, canvas.top];                for (var i = 0; i < 2; i++)                    lines.push(this._renderer.path(points, "line").attr(options).sharp(sharpParam).append(group));                return lines            },            render: function() {                var that = this,                    renderer = that._renderer,                    options = that._options,                    verticalOptions = options.vertical,                    horizontalOptions = options.horizontal,                    extraOptions = horizontalOptions.visible ? horizontalOptions.line : verticalOptions.line,                    circleOptions = {                        stroke: extraOptions.stroke,                        "stroke-width": extraOptions["stroke-width"],                        dashStyle: extraOptions.dashStyle,                        opacity: extraOptions.opacity                    },                    canvas = that._canvas;                that._horizontal = {};                that._vertical = {};                that._horizontalGroup = renderer.g().append(that._crosshairGroup);                that._verticalGroup = renderer.g().append(that._crosshairGroup);                if (verticalOptions.visible) {                    that._vertical.lines = that._createLines(verticalOptions.line, "h", that._verticalGroup);                    that._vertical.labels = that._createLabels(that._axes[0], verticalOptions, false, that._verticalGroup)                }                if (horizontalOptions.visible) {                    that._horizontal.lines = that._createLines(horizontalOptions.line, "v", that._horizontalGroup);                    that._horizontal.labels = that._createLabels(that._axes[1], horizontalOptions, true, that._horizontalGroup)                }                that._circle = renderer.circle(canvas.left, canvas.top, 0).attr(circleOptions).append(that._crosshairGroup)            },            _createLabels: function(axes, options, isHorizontal, group) {                var that = this,                    canvas = that._canvas,                    renderer = that._renderer,                    x,                    y,                    text,                    labels = [],                    background,                    curentLabelPos,                    bbox;                if (!options.label || !options.label.visible)                    return;                $.each(axes, function(_, axis) {                    var axisOptions = axis.getOptions(),                        position = axisOptions.position;                    if (axis._virtual || axisOptions.stubData)                        return;                    curentLabelPos = axis.getCurrentLabelPos();                    if (isHorizontal) {                        y = canvas.top;                        x = curentLabelPos                    }                    else {                        x = canvas.left;                        y = curentLabelPos                    }                    text = renderer.text("0", x, y).css(DX.viz.core.utils.patchFontOptions(options.label.font)).attr({align: position === TOP || position === BOTTOM ? CENTER : position === RIGHT ? LEFT : RIGHT}).append(group);                    bbox = text.getBBox();                    text.attr({y: isHorizontal ? 2 * y - bbox.y - bbox.height / 2 : position === BOTTOM ? 2 * y - bbox.y : 2 * y - (bbox.y + bbox.height)});                    background = renderer.rect(0, 0, 0, 0).attr({fill: options.label.backgroundColor || options.line.stroke}).append(group).toBackground();                    labels.push({                        text: text,                        background: background,                        axis: axis,                        pos: {                            coord: curentLabelPos,                            side: position                        }                    })                });                return labels            },            _updateText: function(coord, labels) {                var that = this,                    bbox,                    text,                    textElement,                    backgroundElement;                if (!labels)                    return;                $.each(labels, function(i, label) {                    textElement = label.text;                    backgroundElement = label.background;                    if (!textElement)                        return;                    text = label.axis.getUntranslatedValue(coord);                    if (_isDefined(text)) {                        textElement.attr({text: text});                        bbox = textElement.getBBox();                        that._updateLinesCanvas(label.pos.side, label.pos.coord);                        backgroundElement.attr({                            x: bbox.x - LABEL_BACKGROUND_PADDING_X,                            y: bbox.y - LABEL_BACKGROUND_PADDING_Y,                            width: bbox.width + LABEL_BACKGROUND_PADDING_X * 2,                            height: bbox.height + LABEL_BACKGROUND_PADDING_Y * 2                        })                    }                    else {                        textElement.attr({text: ""});                        backgroundElement.attr({                            x: 0,                            y: 0,                            width: 0,                            height: 0                        })                    }                })            },            show: function() {                this._crosshairGroup.attr({visibility: "visible"})            },            hide: function() {                this._crosshairGroup.attr({visibility: "hidden"})            },            _updateLinesCanvas: function(position, labelPosition) {                var coords = this._linesCanvas,                    canvas = this._canvas;                coords[position] = coords[position] !== canvas[position] && mathAbs(coords[position] - canvas[position]) < mathAbs(labelPosition - canvas[position]) ? coords[position] : labelPosition            },            _updateLines: function(lines, x, y, r, isHorizontal) {                var coords = this._linesCanvas,                    canvas = this._canvas,                    points = isHorizontal ? [[mathMin(x - r, coords.left), canvas.top, x - r, canvas.top], [x + r, canvas.top, mathMax(coords.right, x + r), canvas.top]] : [[canvas.left, mathMin(coords.top, y - r), canvas.left, y - r], [canvas.left, y + r, canvas.left, mathMax(coords.bottom, y + r)]];                for (var i = 0; i < 2; i++)                    lines[i].attr({points: points[i]})            },            _resetLinesCanvas: function() {                var canvas = this._canvas;                this._linesCanvas = {                    left: canvas.left,                    right: canvas.right,                    top: canvas.top,                    bottom: canvas.bottom                }            },            _getClipRectForPane: function(x, y) {                var panes = this._panes,                    i,                    coords;                for (i = 0; i < panes.length; i++) {                    coords = panes[i].coords;                    if (coords.left <= x && coords.right >= x && coords.top <= y && coords.bottom >= y)                        return panes[i].clipRect                }                return {id: null}            },            shift: function(x, y, r) {                var that = this,                    horizontal = that._horizontal,                    vertical = that._vertical,                    clipRect,                    rad = !r ? 0 : r + 3,                    canvas = that._canvas;                x = _round(x);                y = _round(y);                if (x >= canvas.left && x <= canvas.right && y >= canvas.top && y <= canvas.bottom) {                    that.show();                    that._resetLinesCanvas();                    clipRect = that._getClipRectForPane(x, y);                    that._circle.attr({                        cx: x,                        cy: y,                        r: rad,                        clipId: clipRect.id                    });                    if (horizontal.lines) {                        that._updateText(y, horizontal.labels);                        that._updateLines(horizontal.lines, x, y, rad, true);                        that._horizontalGroup.attr({translateY: y - canvas.top})                    }                    if (vertical.lines) {                        that._updateText(x, vertical.labels);                        that._updateLines(vertical.lines, x, y, rad, false);                        that._verticalGroup.attr({translateX: x - canvas.left})                    }                }                else                    that.hide()            }        }    })(jQuery, DevExpress);    DevExpress.MOD_VIZ_CHARTS = true}if (!DevExpress.MOD_VIZ_GAUGES) {    if (!DevExpress.MOD_VIZ_CORE)        throw Error('Required module is not referenced: viz-core');    /*! Module viz-gauges, file namespaces.js */    (function(DX) {        DX.viz.gauges = {__internals: {                circularNeedles: {},                circularMarkers: {},                linearNeedles: {},                linearMarkers: {}            }};        DX.viz.gauges.__tests = {}    })(DevExpress);    /*! Module viz-gauges, file factory.js */    (function(DX, $, undefined) {        var internals = DX.viz.gauges.__internals,            circularNeedles = internals.circularNeedles,            circularMarkers = internals.circularMarkers,            linearNeedles = internals.linearNeedles,            linearMarkers = internals.linearMarkers,            _String = String;        DX.viz.gauges.__factory = {            createCircularIndicator: function(parameters, type, _strict) {                var indicatorType;                switch (_String(type).toLowerCase()) {                    case'rectangleneedle':                        indicatorType = circularNeedles.RectangleNeedle;                        break;                    case'triangleneedle':                        indicatorType = circularNeedles.TriangleNeedle;                        break;                    case'twocolorneedle':                        indicatorType = circularNeedles.TwoColorRectangleNeedle;                        break;                    case'rangebar':                        indicatorType = internals.CircularRangeBar;                        break;                    case'trianglemarker':                        indicatorType = circularMarkers.TriangleMarker;                        break;                    case'textcloud':                        indicatorType = circularMarkers.TextCloudMarker;                        break;                    default:                        indicatorType = _strict ? null : circularNeedles.RectangleNeedle;                        break                }                return indicatorType ? new indicatorType(parameters) : null            },            createLinearIndicator: function(parameters, type, _strict) {                var indicatorType = internals.LinearRangeBar;                switch (_String(type).toLowerCase()) {                    case'rectangle':                        indicatorType = linearNeedles.RectangleNeedle;                        break;                    case'rhombus':                        indicatorType = linearNeedles.RhombusNeedle;                        break;                    case'circle':                        indicatorType = linearNeedles.CircleNeedle;                        break;                    case'rangebar':                        indicatorType = internals.LinearRangeBar;                        break;                    case'trianglemarker':                        indicatorType = linearMarkers.TriangleMarker;                        break;                    case'textcloud':                        indicatorType = linearMarkers.TextCloudMarker;                        break;                    default:                        indicatorType = _strict ? null : internals.LinearRangeBar;                        break                }                return indicatorType ? new indicatorType(parameters) : null            },            createCircularScale: function(parameters) {                return new internals.CircularScale(parameters)            },            createLinearScale: function(parameters) {                return new internals.LinearScale(parameters)            },            createCircularRangeContainer: function(parameters) {                return new internals.CircularRangeContainer(parameters)            },            createLinearRangeContainer: function(parameters) {                return new internals.LinearRangeContainer(parameters)            },            createTitle: function(parameters) {                return new internals.Title(parameters)            },            createIndicator: function() {                return internals.Indicator && new internals.Indicator || null            },            createLayoutManager: function() {                return new internals.LayoutManager            },            createThemeManager: function(options) {                return new internals.ThemeManager(options)            },            createTracker: function(parameters) {                return new internals.Tracker(parameters)            }        };        var _isFunction = DX.utils.isFunction,            _extend = $.extend;        var _formatHelper = DX.formatHelper;        internals.formatValue = function(value, options, extra) {            options = options || {};            var text = _formatHelper.format(value, options.format, options.precision),                context;            if (_isFunction(options.customizeText)) {                context = _extend({                    value: value,                    valueText: text                }, extra);                return _String(options.customizeText.call(context, context))            }            return text        };        internals.getSampleText = function(translator, options) {            var text1 = internals.formatValue(translator.getDomainStart(), options),                text2 = internals.formatValue(translator.getDomainEnd(), options);            return text1.length >= text2.length ? text1 : text2        }    })(DevExpress, jQuery);    /*! Module viz-gauges, file baseIndicator.js */    (function(DX, $, undefined) {        var _isFinite = isFinite,            _Number = Number;        DX.viz.gauges.__internals.BaseElement = DX.Class.inherit({            ctor: function(parameters) {                var that = this;                $.each(parameters, function(name, value) {                    that["_" + name] = value                });                that._init()            },            dispose: function() {                var that = this;                $.each(that, function(name) {                    that[name] = null                });                return that            },            getOffset: function() {                return _Number(this._options.offset) || 0            }        });        DX.viz.gauges.__internals.BaseIndicator = DX.viz.gauges.__internals.BaseElement.inherit({            _init: function() {                this._rootElement = this._createRoot();                this._trackerElement = this._createTracker()            },            _setupAnimation: function() {                var that = this;                if (that._options.animation)                    that._animation = {                        step: function(pos) {                            that._actualValue = that._animation.start + that._animation.delta * pos;                            that._actualPosition = that._translator.translate(that._actualValue);                            that._move()                        },                        duration: that._options.animation.duration > 0 ? _Number(that._options.animation.duration) : 0,                        easing: that._options.animation.easing                    }            },            _runAnimation: function(value, notifyReady) {                var that = this,                    animation = that._animation;                animation.start = that._actualValue;                animation.delta = value - that._actualValue;                that._rootElement.animate({_: 0}, {                    step: animation.step,                    duration: animation.duration,                    easing: animation.easing,                    complete: notifyReady                })            },            _createRoot: function() {                return this._renderer.g().attr({'class': this._className})            },            _createTracker: function() {                return this._renderer.path([], "area")            },            _getTrackerSettings: $.noop,            clean: function() {                var that = this;                that._animation && that._rootElement.stopAnimation();                that._rootElement.remove();                that._rootElement.clear();                that._clear();                that._tracker.detach(that._trackerElement);                that._options = that.enabled = that._animation = null;                return that            },            render: function(options) {                var that = this;                that.type = options.type;                that._options = options;                that._actualValue = that._currentValue = that._translator.adjust(that._options.currentValue);                that.enabled = that._isEnabled();                if (that.enabled) {                    that._setupAnimation();                    that._rootElement.attr({fill: that._options.color}).append(that._owner);                    that._tracker.attach(that._trackerElement, that, that._trackerInfo)                }                return that            },            resize: function(layout) {                var that = this;                that._rootElement.clear();                that._clear();                that.visible = that._isVisible(layout);                if (that.visible) {                    $.extend(that._options, layout);                    that._actualPosition = that._translator.translate(that._actualValue);                    that._render();                    that._trackerElement.attr(that._getTrackerSettings());                    that._move()                }                return that            },            value: function(arg, _noAnimation) {                var that = this,                    immediateReady = true,                    val;                if (arg !== undefined) {                    val = that._translator.adjust(arg);                    that._notifiers.dirty();                    if (that._currentValue !== val && _isFinite(val)) {                        that._currentValue = val;                        if (that.visible)                            if (that._animation && !_noAnimation) {                                immediateReady = false;                                that._runAnimation(val, that._notifiers.ready)                            }                            else {                                that._actualValue = val;                                that._actualPosition = that._translator.translate(val);                                that._move()                            }                    }                    immediateReady && that._notifiers.ready();                    return that                }                return that._currentValue            },            _isEnabled: null,            _isVisible: null,            _render: null,            _clear: null,            _move: null        })    })(DevExpress, jQuery);    /*! Module viz-gauges, file baseMarker.js */    (function(DX, undefined) {        var viz = DX.viz,            core = viz.core,            _min = Math.min,            _round = Math.round,            _formatValue = viz.gauges.__internals.formatValue,            _getSampleText = viz.gauges.__internals.getSampleText,            COEFFICIENTS_MAP = {};        COEFFICIENTS_MAP['right-bottom'] = COEFFICIENTS_MAP['rb'] = [0, -1, -1, 0, 0, 1, 1, 0];        COEFFICIENTS_MAP['bottom-right'] = COEFFICIENTS_MAP['br'] = [-1, 0, 0, -1, 1, 0, 0, 1];        COEFFICIENTS_MAP['left-bottom'] = COEFFICIENTS_MAP['lb'] = [0, -1, 1, 0, 0, 1, -1, 0];        COEFFICIENTS_MAP['bottom-left'] = COEFFICIENTS_MAP['bl'] = [1, 0, 0, -1, -1, 0, 0, 1];        COEFFICIENTS_MAP['left-top'] = COEFFICIENTS_MAP['lt'] = [0, 1, 1, 0, 0, -1, -1, 0];        COEFFICIENTS_MAP['top-left'] = COEFFICIENTS_MAP['tl'] = [1, 0, 0, 1, -1, 0, 0, -1];        COEFFICIENTS_MAP['right-top'] = COEFFICIENTS_MAP['rt'] = [0, 1, -1, 0, 0, -1, 1, 0];        COEFFICIENTS_MAP['top-right'] = COEFFICIENTS_MAP['tr'] = [-1, 0, 0, 1, 1, 0, 0, -1];        function getTextCloudInfo(options) {            var x = options.x,                y = options.y,                type = COEFFICIENTS_MAP[options.type],                cloudWidth = options.textWidth + 2 * options.horMargin,                cloudHeight = options.textHeight + 2 * options.verMargin,                tailWidth,                tailHeight,                cx = x,                cy = y;            tailWidth = tailHeight = options.tailLength;            if (type[0] & 1)                tailHeight = _min(tailHeight, cloudHeight / 3);            else                tailWidth = _min(tailWidth, cloudWidth / 3);            return {                    cx: _round(cx + type[0] * tailWidth + (type[0] + type[2]) * cloudWidth / 2),                    cy: _round(cy + type[1] * tailHeight + (type[1] + type[3]) * cloudHeight / 2),                    points: [_round(x), _round(y), _round(x += type[0] * (cloudWidth + tailWidth)), _round(y += type[1] * (cloudHeight + tailHeight)), _round(x += type[2] * cloudWidth), _round(y += type[3] * cloudHeight), _round(x += type[4] * cloudWidth), _round(y += type[5] * cloudHeight), _round(x += type[6] * (cloudWidth - tailWidth)), _round(y += type[7] * (cloudHeight - tailHeight))]                }        }        viz.gauges.__tests.getTextCloudInfo = getTextCloudInfo;        viz.gauges.__internals.BaseTextCloudMarker = viz.gauges.__internals.BaseIndicator.inherit({            _move: function() {                var that = this,                    bbox,                    info,                    textCloudOptions = that._getTextCloudOptions();                that._text.attr({text: _formatValue(that._actualValue, that._options.text)});                bbox = that._text.getBBox();                info = getTextCloudInfo({                    x: textCloudOptions.x,                    y: textCloudOptions.y,                    textWidth: bbox.width,                    textHeight: bbox.height,                    horMargin: that._options.horizontalOffset,                    verMargin: that._options.verticalOffset,                    tailLength: that._options.arrowLength,                    type: textCloudOptions.type                });                that._text.attr({                    x: info.cx,                    y: info.cy + that._textVerticalOffset                });                that._cloud.attr({points: info.points});                that._trackerElement && that._trackerElement.attr({points: info.points})            },            _measureText: function() {                var that = this,                    root,                    text,                    bbox;                if (!that._textVerticalOffset) {                    root = that._createRoot().append(that._owner);                    text = that._renderer.text(_getSampleText(that._translator, that._options.text), 0, 0).attr({align: "center"}).css(core.utils.patchFontOptions(that._options.text.font)).append(root);                    bbox = text.getBBox();                    root.remove();                    that._textVerticalOffset = -bbox.y - bbox.height / 2;                    that._textWidth = bbox.width;                    that._textHeight = bbox.height;                    that._textFullWidth = that._textWidth + 2 * that._options.horizontalOffset;                    that._textFullHeight = that._textHeight + 2 * that._options.verticalOffset                }            },            _render: function() {                var that = this;                that._measureText();                that._cloud = that._cloud || that._renderer.path([], "area").append(that._rootElement);                that._text = that._text || that._renderer.text().append(that._rootElement);                that._text.attr({align: "center"}).css(core.utils.patchFontOptions(that._options.text.font))            },            _clear: function() {                delete this._cloud;                delete this._text            },            getTooltipParameters: function() {                var position = this._getTextCloudOptions();                return {                        x: position.x,                        y: position.y,                        value: this._currentValue,                        color: this._options.color                    }            }        })    })(DevExpress);    /*! Module viz-gauges, file baseRangeBar.js */    (function(DX, $, undefined) {        var viz = DX.viz,            core = viz.core,            $extend = $.extend,            formatValue = viz.gauges.__internals.formatValue,            getSampleText = viz.gauges.__internals.getSampleText;        viz.gauges.__internals.BaseRangeBar = viz.gauges.__internals.BaseIndicator.inherit({            _measureText: function() {                var that = this,                    root,                    text,                    bbox;                that._hasText = that._isTextVisible();                if (that._hasText && !that._textVerticalOffset) {                    root = that._createRoot().append(that._owner);                    text = that._renderer.text(getSampleText(that._translator, that._options.text), 0, 0).attr({                        'class': 'dxg-text',                        align: 'center'                    }).css(core.utils.patchFontOptions(that._options.text.font)).append(root);                    bbox = text.getBBox();                    root.remove();                    that._textVerticalOffset = -bbox.y - bbox.height / 2;                    that._textWidth = bbox.width;                    that._textHeight = bbox.height                }            },            _move: function() {                var that = this;                that._updateBarItemsPositions();                if (that._hasText) {                    that._text.attr({text: formatValue(that._actualValue, that._options.text)});                    that._updateTextPosition();                    that._updateLinePosition()                }            },            _updateBarItems: function() {                var that = this,                    options = that._options,                    backgroundColor,                    spaceColor,                    translator = that._translator;                that._setBarSides();                that._startPosition = translator.translate(translator.getDomainStart());                that._endPosition = translator.translate(translator.getDomainEnd());                that._basePosition = translator.translate(options.baseValue);                that._space = that._getSpace();                backgroundColor = options.backgroundColor || 'none';                if (backgroundColor !== 'none' && that._space > 0)                    spaceColor = options.containerBackgroundColor || 'none';                else {                    that._space = 0;                    spaceColor = 'none'                }                that._backItem1.attr({fill: backgroundColor});                that._backItem2.attr({fill: backgroundColor});                that._spaceItem1.attr({fill: spaceColor});                that._spaceItem2.attr({fill: spaceColor})            },            _getSpace: function() {                return 0            },            _updateTextItems: function() {                var that = this;                if (that._hasText) {                    that._line = that._line || that._renderer.path([], "line").attr({                        'class': 'dxg-main-bar',                        "stroke-linecap": "square"                    }).append(that._rootElement);                    that._text = that._text || that._renderer.text('', 0, 0).attr({'class': 'dxg-text'}).append(that._rootElement);                    that._text.attr({align: that._getTextAlign()}).css(that._getFontOptions());                    that._setTextItemsSides()                }                else {                    if (that._line) {                        that._line.remove();                        delete that._line                    }                    if (that._text) {                        that._text.remove();                        delete that._text                    }                }            },            _isTextVisible: function() {                return false            },            _getTextAlign: function() {                return 'center'            },            _getFontOptions: function() {                var options = this._options,                    font = options.text.font;                if (!font || !font.color)                    font = $extend({}, font, {color: options.color});                return core.utils.patchFontOptions(font)            },            _updateBarItemsPositions: function() {                var that = this,                    positions = that._getPositions();                that._backItem1.attr(that._buildItemSettings(positions.start, positions.back1));                that._backItem2.attr(that._buildItemSettings(positions.back2, positions.end));                that._spaceItem1.attr(that._buildItemSettings(positions.back1, positions.main1));                that._spaceItem2.attr(that._buildItemSettings(positions.main2, positions.back2));                that._mainItem.attr(that._buildItemSettings(positions.main1, positions.main2));                that._trackerElement && that._trackerElement.attr(that._buildItemSettings(positions.main1, positions.main2))            },            _render: function() {                var that = this;                that._measureText();                if (!that._backItem1) {                    that._backItem1 = that._createBarItem();                    that._backItem1.attr({'class': 'dxg-back-bar'})                }                if (!that._backItem2) {                    that._backItem2 = that._createBarItem();                    that._backItem2.attr({'class': 'dxg-back-bar'})                }                if (!that._spaceItem1) {                    that._spaceItem1 = that._createBarItem();                    that._spaceItem1.attr({'class': 'dxg-space-bar'})                }                if (!that._spaceItem2) {                    that._spaceItem2 = that._createBarItem();                    that._spaceItem2.attr({'class': 'dxg-space-bar'})                }                if (!that._mainItem) {                    that._mainItem = that._createBarItem();                    that._mainItem.attr({'class': 'dxg-main-bar'})                }                that._updateBarItems();                that._updateTextItems()            },            _clear: function() {                var that = this;                delete that._backItem1;                delete that._backItem2;                delete that._spaceItem1;                delete that._spaceItem2;                delete that._mainItem;                delete that._hasText;                delete that._line;                delete that._text            },            getTooltipParameters: function() {                var position = this._getTooltipPosition();                return {                        x: position.x,                        y: position.y,                        value: this._currentValue,                        color: this._options.color,                        offset: 0                    }            }        })    })(DevExpress, jQuery);    /*! Module viz-gauges, file circularNeedle.js */    (function(DX, undefined) {        var circularNeedles = DX.viz.gauges.__internals.circularNeedles,            _Number = Number;        circularNeedles.SimpleIndicator = DX.viz.gauges.__internals.BaseIndicator.inherit({            _move: function() {                var that = this,                    options = that._options,                    angle = DX.utils.convertAngleToRendererSpace(that._actualPosition);                that._rootElement.rotate(angle, options.x, options.y);                that._trackerElement && that._trackerElement.rotate(angle, options.x, options.y)            },            _isEnabled: function() {                return this._options.width > 0            },            _isVisible: function(layout) {                return layout.radius - _Number(this._options.indentFromCenter) > 0            },            _getTrackerSettings: function() {                var options = this._options,                    x = options.x,                    y = options.y - (options.radius + _Number(options.indentFromCenter)) / 2,                    width = options.width / 2,                    length = (options.radius - _Number(options.indentFromCenter)) / 2;                width > 10 || (width = 10);                length > 10 || (length = 10);                return {points: [x - width, y - length, x - width, y + length, x + width, y + length, x + width, y - length]}            },            _renderSpindle: function() {                var that = this,                    options = that._options,                    gapSize;                if (options.spindleSize > 0) {                    gapSize = _Number(options.spindleGapSize) || 0;                    if (gapSize > 0)                        gapSize = gapSize <= options.spindleSize ? gapSize : _Number(options.spindleSize);                    that._spindleOuter = that._spindleOuter || that._renderer.circle().append(that._rootElement);                    that._spindleInner = that._spindleInner || that._renderer.circle().append(that._rootElement);                    that._spindleOuter.attr({                        'class': 'dxg-spindle-border',                        cx: options.x,                        cy: options.y,                        r: options.spindleSize / 2                    });                    that._spindleInner.attr({                        'class': 'dxg-spindle-hole',                        cx: options.x,                        cy: options.y,                        r: gapSize / 2,                        fill: options.containerBackgroundColor                    })                }            },            _render: function() {                var that = this;                that._renderPointer();                that._renderSpindle()            },            _clearSpindle: function() {                delete this._spindleOuter;                delete this._spindleInner            },            _clearPointer: function() {                delete this._element            },            _clear: function() {                this._clearPointer();                this._clearSpindle()            },            measure: function(layout) {                var result = {max: layout.radius};                if (this._options.indentFromCenter < 0)                    result.inverseHorizontalOffset = result.inverseVerticalOffset = -_Number(this._options.indentFromCenter);                return result            },            getTooltipParameters: function() {                var options = this._options,                    cossin = DX.utils.getCosAndSin(this._actualPosition),                    r = (options.radius + _Number(options.indentFromCenter)) / 2;                return {                        x: options.x + cossin.cos * r,                        y: options.y - cossin.sin * r,                        value: this._currentValue,                        color: options.color,                        offset: options.width / 2                    }            }        });        circularNeedles.RectangleNeedle = circularNeedles.SimpleIndicator.inherit({_renderPointer: function() {                var that = this,                    options = that._options,                    y2 = options.y - options.radius,                    y1 = options.y - _Number(options.indentFromCenter),                    x1 = options.x - options.width / 2,                    x2 = x1 + _Number(options.width);                that._element = that._element || that._renderer.path([], "area").append(that._rootElement);                that._element.attr({points: [x1, y1, x1, y2, x2, y2, x2, y1]})            }});        circularNeedles.TriangleNeedle = circularNeedles.SimpleIndicator.inherit({_renderPointer: function() {                var that = this,                    options = that._options,                    y2 = options.y - options.radius,                    y1 = options.y - _Number(options.indentFromCenter),                    x1 = options.x - options.width / 2,                    x2 = options.x + options.width / 2;                that._element = that._element || that._renderer.path([], "area").append(that._rootElement);                that._element.attr({points: [x1, y1, options.x, y2, x2, y1]})            }});        circularNeedles.TwoColorRectangleNeedle = circularNeedles.SimpleIndicator.inherit({            _renderPointer: function() {                var that = this,                    options = that._options,                    x1 = options.x - options.width / 2,                    x2 = options.x + options.width / 2,                    y4 = options.y - options.radius,                    y1 = options.y - _Number(options.indentFromCenter),                    fraction = _Number(options.secondFraction) || 0,                    y2,                    y3;                if (fraction >= 1)                    y2 = y3 = y1;                else if (fraction <= 0)                    y2 = y3 = y4;                else {                    y3 = y4 + (y1 - y4) * fraction;                    y2 = y3 + _Number(options.space)                }                that._firstElement = that._firstElement || that._renderer.path([], "area").append(that._rootElement);                that._spaceElement = that._spaceElement || that._renderer.path([], "area").append(that._rootElement);                that._secondElement = that._secondElement || that._renderer.path([], "area").append(that._rootElement);                that._firstElement.attr({points: [x1, y1, x1, y2, x2, y2, x2, y1]});                that._spaceElement.attr({                    points: [x1, y2, x1, y3, x2, y3, x2, y2],                    'class': 'dxg-hole',                    fill: options.containerBackgroundColor                });                that._secondElement.attr({                    points: [x1, y3, x1, y4, x2, y4, x2, y3],                    'class': 'dxg-part',                    fill: options.secondColor                })            },            _clearPointer: function() {                delete this._firstElement;                delete this._secondElement;                delete this._spaceElement            }        })    })(DevExpress);    /*! Module viz-gauges, file linearNeedle.js */    (function(DX, undefined) {        var linearNeedles = DX.viz.gauges.__internals.linearNeedles;        linearNeedles.SimpleIndicator = DX.viz.gauges.__internals.BaseIndicator.inherit({            _move: function() {                var that = this,                    delta = that._actualPosition - that._zeroPosition;                that._rootElement.move(that.vertical ? 0 : delta, that.vertical ? delta : 0);                that._trackerElement && that._trackerElement.move(that.vertical ? 0 : delta, that.vertical ? delta : 0)            },            _isEnabled: function() {                this.vertical = this._options.vertical;                return this._options.length > 0 && this._options.width > 0            },            _isVisible: function() {                return true            },            _getTrackerSettings: function() {                var options = this._options,                    x1,                    x2,                    y1,                    y2,                    width = options.width / 2,                    length = options.length / 2,                    p = this._zeroPosition;                width > 10 || (width = 10);                length > 10 || (length = 10);                if (this.vertical) {                    x1 = options.x - length;                    x2 = options.x + length;                    y1 = p + width;                    y2 = p - width                }                else {                    x1 = p - width;                    x2 = p + width;                    y1 = options.y + length;                    y2 = options.y - length                }                return {points: [x1, y1, x1, y2, x2, y2, x2, y1]}            },            _render: function() {                var that = this;                that._zeroPosition = that._translator.getCodomainStart()            },            _clear: function() {                delete this._element            },            measure: function(layout) {                var p = this.vertical ? layout.x : layout.y;                return {                        min: p - this._options.length / 2,                        max: p + this._options.length / 2                    }            },            getTooltipParameters: function() {                var that = this,                    options = that._options,                    p = that._actualPosition,                    parameters = {                        x: p,                        y: p,                        value: that._currentValue,                        color: options.color,                        offset: options.width / 2                    };                that.vertical ? parameters.x = options.x : parameters.y = options.y;                return parameters            }        });        linearNeedles.RectangleNeedle = linearNeedles.SimpleIndicator.inherit({_render: function() {                var that = this,                    options = that._options,                    p,                    x1,                    x2,                    y1,                    y2;                that.callBase();                p = that._zeroPosition;                if (that.vertical) {                    x1 = options.x - options.length / 2;                    x2 = options.x + options.length / 2;                    y1 = p + options.width / 2;                    y2 = p - options.width / 2                }                else {                    x1 = p - options.width / 2;                    x2 = p + options.width / 2;                    y1 = options.y + options.length / 2;                    y2 = options.y - options.length / 2                }                that._element = that._element || that._renderer.path([], "area").append(that._rootElement);                that._element.attr({points: [x1, y1, x1, y2, x2, y2, x2, y1]})            }});        linearNeedles.RhombusNeedle = linearNeedles.SimpleIndicator.inherit({_render: function() {                var that = this,                    options = that._options,                    x,                    y,                    dx,                    dy;                that.callBase();                if (that.vertical) {                    x = options.x;                    y = that._zeroPosition;                    dx = options.length / 2 || 0;                    dy = options.width / 2 || 0                }                else {                    x = that._zeroPosition;                    y = options.y;                    dx = options.width / 2 || 0;                    dy = options.length / 2 || 0                }                that._element = that._element || that._renderer.path([], "area").append(that._rootElement);                that._element.attr({points: [x - dx, y, x, y - dy, x + dx, y, x, y + dy]})            }});        linearNeedles.CircleNeedle = linearNeedles.SimpleIndicator.inherit({_render: function() {                var that = this,                    options = that._options,                    x,                    y,                    r;                that.callBase();                if (that.vertical) {                    x = options.x;                    y = that._zeroPosition                }                else {                    x = that._zeroPosition;                    y = options.y                }                r = options.length / 2 || 0;                that._element = that._element || that._renderer.circle().append(that._rootElement);                that._element.attr({                    cx: x,                    cy: y,                    r: r                })            }})    })(DevExpress);    /*! Module viz-gauges, file circularMarker.js */    (function(DX, undefined) {        var circularMarkers = DX.viz.gauges.__internals.circularMarkers,            _Number = Number;        circularMarkers.TriangleMarker = DX.viz.gauges.__internals.circularNeedles.SimpleIndicator.inherit({            _isEnabled: function() {                return this._options.length > 0 && this._options.width > 0            },            _isVisible: function(layout) {                return layout.radius > 0            },            _render: function() {                var that = this,                    options = that._options,                    x = options.x,                    y1 = options.y - options.radius,                    dx = options.width / 2 || 0,                    y2 = y1 - _Number(options.length),                    settings;                that._element = that._element || that._renderer.path([], "area").append(that._rootElement);                settings = {                    points: [x, y1, x - dx, y2, x + dx, y2],                    stroke: "none",                    "stroke-width": 0,                    "stroke-linecap": "square"                };                if (options.space > 0) {                    settings["stroke-width"] = Math.min(options.space, options.width / 4) || 0;                    settings.stroke = settings["stroke-width"] > 0 ? options.containerBackgroundColor || "none" : "none"                }                that._element.attr(settings).sharp()            },            _clear: function() {                delete this._element            },            _getTrackerSettings: function() {                var options = this._options,                    x = options.x,                    y = options.y - options.radius - options.length / 2,                    width = options.width / 2,                    length = options.length / 2;                width > 10 || (width = 10);                length > 10 || (length = 10);                return {points: [x - width, y - length, x - width, y + length, x + width, y + length, x + width, y - length]}            },            measure: function(layout) {                return {                        min: layout.radius,                        max: layout.radius + _Number(this._options.length)                    }            },            getTooltipParameters: function() {                var options = this._options,                    cossin = DX.utils.getCosAndSin(this._actualPosition),                    r = options.radius + options.length / 2,                    parameters = this.callBase();                parameters.x = options.x + cossin.cos * r;                parameters.y = options.y - cossin.sin * r;                parameters.offset = options.length / 2;                return parameters            }        });        circularMarkers.TextCloudMarker = DX.viz.gauges.__internals.BaseTextCloudMarker.inherit({            _isEnabled: function() {                return true            },            _isVisible: function(layout) {                return layout.radius > 0            },            _getTextCloudOptions: function() {                var that = this,                    cossin = DX.utils.getCosAndSin(that._actualPosition),                    nangle = DX.utils.normalizeAngle(that._actualPosition);                return {                        x: that._options.x + cossin.cos * that._options.radius,                        y: that._options.y - cossin.sin * that._options.radius,                        type: nangle > 270 ? "left-top" : nangle > 180 ? "top-right" : nangle > 90 ? "right-bottom" : "bottom-left"                    }            },            measure: function(layout) {                var that = this,                    arrowLength = _Number(that._options.arrowLength) || 0,                    verticalOffset,                    horizontalOffset;                that._measureText();                verticalOffset = that._textFullHeight + arrowLength;                horizontalOffset = that._textFullWidth + arrowLength;                return {                        min: layout.radius,                        max: layout.radius,                        horizontalOffset: horizontalOffset,                        verticalOffset: verticalOffset,                        inverseHorizontalOffset: horizontalOffset,                        inverseVerticalOffset: verticalOffset                    }            }        })    })(DevExpress);    /*! Module viz-gauges, file linearMarker.js */    (function(DX, undefined) {        var linearMarkers = DX.viz.gauges.__internals.linearMarkers,            _Number = Number,            _String = String;        linearMarkers.TriangleMarker = DX.viz.gauges.__internals.linearNeedles.SimpleIndicator.inherit({            _isEnabled: function() {                var that = this;                that.vertical = that._options.vertical;                that._inverted = that.vertical ? _String(that._options.horizontalOrientation).toLowerCase() === 'right' : _String(that._options.verticalOrientation).toLowerCase() === 'bottom';                return that._options.length > 0 && that._options.width > 0            },            _isVisible: function() {                return true            },            _render: function() {                var that = this,                    options = that._options,                    x1,                    x2,                    y1,                    y2,                    settings = {                        stroke: 'none',                        "stroke-width": 0,                        "stroke-linecap": "square"                    };                that.callBase();                if (that.vertical) {                    x1 = options.x;                    y1 = that._zeroPosition;                    x2 = x1 + _Number(that._inverted ? options.length : -options.length);                    settings.points = [x1, y1, x2, y1 - options.width / 2, x2, y1 + options.width / 2]                }                else {                    y1 = options.y;                    x1 = that._zeroPosition;                    y2 = y1 + _Number(that._inverted ? options.length : -options.length);                    settings.points = [x1, y1, x1 - options.width / 2, y2, x1 + options.width / 2, y2]                }                if (options.space > 0) {                    settings["stroke-width"] = Math.min(options.space, options.width / 4) || 0;                    settings.stroke = settings["stroke-width"] > 0 ? options.containerBackgroundColor || 'none' : 'none'                }                that._element = that._element || that._renderer.path([], "area").append(that._rootElement);                that._element.attr(settings).sharp()            },            _getTrackerSettings: function() {                var that = this,                    options = that._options,                    width = options.width / 2,                    length = _Number(options.length),                    x1,                    x2,                    y1,                    y2,                    result;                width > 10 || (width = 10);                length > 20 || (length = 20);                if (that.vertical) {                    x1 = x2 = options.x;                    x2 = x1 + (that._inverted ? length : -length);                    y1 = that._zeroPosition + width;                    y2 = that._zeroPosition - width;                    result = [x1, y1, x2, y1, x2, y2, x1, y2]                }                else {                    y1 = options.y;                    y2 = y1 + (that._inverted ? length : -length);                    x1 = that._zeroPosition - width;                    x2 = that._zeroPosition + width;                    result = [x1, y1, x1, y2, x2, y2, x2, y1]                }                return {points: result}            },            measure: function(layout) {                var that = this,                    length = _Number(that._options.length),                    minbound,                    maxbound;                if (that.vertical) {                    minbound = maxbound = layout.x;                    if (that._inverted)                        maxbound = minbound + length;                    else                        minbound = maxbound - length                }                else {                    minbound = maxbound = layout.y;                    if (that._inverted)                        maxbound = minbound + length;                    else                        minbound = maxbound - length                }                return {                        min: minbound,                        max: maxbound,                        indent: that._options.width / 2                    }            },            getTooltipParameters: function() {                var that = this,                    options = that._options,                    s = (that._inverted ? options.length : -options.length) / 2,                    parameters = that.callBase();                that.vertical ? parameters.x += s : parameters.y += s;                parameters.offset = options.length / 2;                return parameters            }        });        linearMarkers.TextCloudMarker = DX.viz.gauges.__internals.BaseTextCloudMarker.inherit({            _isEnabled: function() {                var that = this;                that.vertical = that._options.vertical;                that._inverted = that.vertical ? _String(that._options.horizontalOrientation).toLowerCase() === 'right' : _String(that._options.verticalOrientation).toLowerCase() === 'bottom';                return true            },            _isVisible: function() {                return true            },            _getTextCloudOptions: function() {                var that = this,                    x = that._actualPosition,                    y = that._actualPosition,                    type;                if (that.vertical) {                    x = that._options.x;                    type = that._inverted ? 'top-left' : 'top-right'                }                else {                    y = that._options.y;                    type = that._inverted ? 'right-top' : 'right-bottom'                }                return {                        x: x,                        y: y,                        type: type                    }            },            measure: function(layout) {                var that = this,                    minbound,                    maxbound,                    arrowLength = _Number(that._options.arrowLength) || 0,                    indent;                that._measureText();                if (that.vertical) {                    indent = that._textFullHeight;                    if (that._inverted) {                        minbound = layout.x;                        maxbound = layout.x + arrowLength + that._textFullWidth                    }                    else {                        minbound = layout.x - arrowLength - that._textFullWidth;                        maxbound = layout.x                    }                }                else {                    indent = that._textFullWidth;                    if (that._inverted) {                        minbound = layout.y;                        maxbound = layout.y + arrowLength + that._textFullHeight                    }                    else {                        minbound = layout.y - arrowLength - that._textFullHeight;                        maxbound = layout.y                    }                }                return {                        min: minbound,                        max: maxbound,                        indent: indent                    }            }        })    })(DevExpress);    /*! Module viz-gauges, file circularRangeBar.js */    (function(DX, undefined) {        var _Number = Number,            getCosAndSin = DX.utils.getCosAndSin,            convertAngleToRendererSpace = DX.utils.convertAngleToRendererSpace,            max = Math.max,            min = Math.min;        DX.viz.gauges.__internals.CircularRangeBar = DX.viz.gauges.__internals.BaseRangeBar.inherit({            _isEnabled: function() {                return this._options.size > 0            },            _isVisible: function(layout) {                return layout.radius - _Number(this._options.size) > 0            },            _createBarItem: function() {                return this._renderer.arc().attr({"stroke-linejoin": "round"}).append(this._rootElement)            },            _createTracker: function() {                return this._renderer.arc().attr({"stroke-linejoin": "round"})            },            _setBarSides: function() {                var that = this;                that._maxSide = that._options.radius;                that._minSide = that._maxSide - _Number(that._options.size)            },            _getSpace: function() {                var options = this._options;                return options.space > 0 ? options.space * 180 / options.radius / Math.PI : 0            },            _isTextVisible: function() {                var options = this._options.text || {};                return options.indent > 0            },            _setTextItemsSides: function() {                var that = this,                    options = that._options,                    indent = _Number(options.text.indent);                that._lineFrom = options.y - options.radius;                that._lineTo = that._lineFrom - indent;                that._textRadius = options.radius + indent            },            _getPositions: function() {                var that = this,                    basePosition = that._basePosition,                    actualPosition = that._actualPosition,                    mainPosition1,                    mainPosition2;                if (basePosition >= actualPosition) {                    mainPosition1 = basePosition;                    mainPosition2 = actualPosition                }                else {                    mainPosition1 = actualPosition;                    mainPosition2 = basePosition                }                return {                        start: that._startPosition,                        end: that._endPosition,                        main1: mainPosition1,                        main2: mainPosition2,                        back1: min(mainPosition1 + that._space, that._startPosition),                        back2: max(mainPosition2 - that._space, that._endPosition)                    }            },            _buildItemSettings: function(from, to) {                var that = this;                return {                        x: that._options.x,                        y: that._options.y,                        innerRadius: that._minSide,                        outerRadius: that._maxSide,                        startAngle: to,                        endAngle: from                    }            },            _updateTextPosition: function() {                var that = this,                    cossin = getCosAndSin(that._actualPosition),                    x = that._options.x + that._textRadius * cossin.cos,                    y = that._options.y - that._textRadius * cossin.sin;                x += cossin.cos * that._textWidth * 0.6;                y -= cossin.sin * that._textHeight * 0.6;                that._text.attr({                    x: x,                    y: y + that._textVerticalOffset                })            },            _updateLinePosition: function() {                var that = this,                    x = that._options.x,                    x1,                    x2;                if (that._basePosition > that._actualPosition) {                    x1 = x - 2;                    x2 = x                }                else if (that._basePosition < that._actualPosition) {                    x1 = x;                    x2 = x + 2                }                else {                    x1 = x - 1;                    x2 = x + 1                }                that._line.attr({points: [x1, that._lineFrom, x1, that._lineTo, x2, that._lineTo, x2, that._lineFrom]}).rotate(convertAngleToRendererSpace(that._actualPosition), x, that._options.y).sharp()            },            _getTooltipPosition: function() {                var that = this,                    cossin = getCosAndSin((that._basePosition + that._actualPosition) / 2),                    r = (that._minSide + that._maxSide) / 2;                return {                        x: that._options.x + cossin.cos * r,                        y: that._options.y - cossin.sin * r                    }            },            measure: function(layout) {                var that = this,                    result = {                        min: layout.radius - _Number(that._options.size),                        max: layout.radius                    };                that._measureText();                if (that._hasText) {                    result.max += _Number(that._options.text.indent);                    result.horizontalOffset = that._textWidth;                    result.verticalOffset = that._textHeight                }                return result            }        })    })(DevExpress);    /*! Module viz-gauges, file linearRangeBar.js */    (function(DX, undefined) {        var _Number = Number,            _String = String;        DX.viz.gauges.__internals.LinearRangeBar = DX.viz.gauges.__internals.BaseRangeBar.inherit({            _isEnabled: function() {                var that = this;                that.vertical = that._options.vertical;                that._inverted = that.vertical ? _String(that._options.horizontalOrientation).toLowerCase() === 'right' : _String(that._options.verticalOrientation).toLowerCase() === 'bottom';                return that._options.size > 0            },            _isVisible: function() {                return true            },            _createBarItem: function() {                return this._renderer.path([], "area").append(this._rootElement)            },            _createTracker: function() {                return this._renderer.path([], "area")            },            _setBarSides: function() {                var that = this,                    options = that._options,                    size = _Number(options.size),                    minSide,                    maxSide;                if (that.vertical)                    if (that._inverted) {                        minSide = options.x;                        maxSide = options.x + size                    }                    else {                        minSide = options.x - size;                        maxSide = options.x                    }                else if (that._inverted) {                    minSide = options.y;                    maxSide = options.y + size                }                else {                    minSide = options.y - size;                    maxSide = options.y                }                that._minSide = minSide;                that._maxSide = maxSide;                that._minBound = minSide;                that._maxBound = maxSide            },            _getSpace: function() {                var options = this._options;                return options.space > 0 ? _Number(options.space) : 0            },            _isTextVisible: function() {                var textOptions = this._options.text || {};                return textOptions.indent > 0 || textOptions.indent < 0            },            _getTextAlign: function() {                return this.vertical ? this._options.text.indent > 0 ? 'left' : 'right' : 'center'            },            _setTextItemsSides: function() {                var that = this,                    indent = _Number(that._options.text.indent);                if (indent > 0) {                    that._lineStart = that._maxSide;                    that._lineEnd = that._maxSide + indent;                    that._textPosition = that._lineEnd + (that.vertical ? 2 : that._textHeight / 2);                    that._maxBound = that._textPosition + (that.vertical ? that._textWidth : that._textHeight / 2)                }                else if (indent < 0) {                    that._lineStart = that._minSide;                    that._lineEnd = that._minSide + indent;                    that._textPosition = that._lineEnd - (that.vertical ? 2 : that._textHeight / 2);                    that._minBound = that._textPosition - (that.vertical ? that._textWidth : that._textHeight / 2)                }            },            _getPositions: function() {                var that = this,                    startPosition = that._startPosition,                    endPosition = that._endPosition,                    space = that._space,                    basePosition = that._basePosition,                    actualPosition = that._actualPosition,                    mainPosition1,                    mainPosition2,                    backPosition1,                    backPosition2;                if (startPosition < endPosition) {                    if (basePosition < actualPosition) {                        mainPosition1 = basePosition;                        mainPosition2 = actualPosition                    }                    else {                        mainPosition1 = actualPosition;                        mainPosition2 = basePosition                    }                    backPosition1 = mainPosition1 - space;                    backPosition2 = mainPosition2 + space                }                else {                    if (basePosition > actualPosition) {                        mainPosition1 = basePosition;                        mainPosition2 = actualPosition                    }                    else {                        mainPosition1 = actualPosition;                        mainPosition2 = basePosition                    }                    backPosition1 = mainPosition1 + space;                    backPosition2 = mainPosition2 - space                }                return {                        start: startPosition,                        end: endPosition,                        main1: mainPosition1,                        main2: mainPosition2,                        back1: backPosition1,                        back2: backPosition2                    }            },            _buildItemSettings: function(from, to) {                var that = this,                    side1 = that._minSide,                    side2 = that._maxSide,                    points = that.vertical ? [side1, from, side1, to, side2, to, side2, from] : [from, side1, from, side2, to, side2, to, side1];                return {points: points}            },            _updateTextPosition: function() {                var that = this;                that._text.attr(that.vertical ? {                    x: that._textPosition,                    y: that._actualPosition + that._textVerticalOffset                } : {                    x: that._actualPosition,                    y: that._textPosition + that._textVerticalOffset                })            },            _updateLinePosition: function() {                var that = this,                    actualPosition = that._actualPosition,                    side1,                    side2,                    points;                if (that.vertical) {                    if (that._basePosition >= actualPosition) {                        side1 = actualPosition;                        side2 = actualPosition + 2                    }                    else {                        side1 = actualPosition - 2;                        side2 = actualPosition                    }                    points = [that._lineStart, side1, that._lineStart, side2, that._lineEnd, side2, that._lineEnd, side1]                }                else {                    if (that._basePosition <= actualPosition) {                        side1 = actualPosition - 2;                        side2 = actualPosition                    }                    else {                        side1 = actualPosition;                        side2 = actualPosition + 2                    }                    points = [side1, that._lineStart, side1, that._lineEnd, side2, that._lineEnd, side2, that._lineStart]                }                that._line.attr({points: points}).sharp()            },            _getTooltipPosition: function() {                var that = this,                    crossCenter = (that._minSide + that._maxSide) / 2,                    alongCenter = (that._basePosition + that._actualPosition) / 2;                return that.vertical ? {                        x: crossCenter,                        y: alongCenter                    } : {                        x: alongCenter,                        y: crossCenter                    }            },            measure: function(layout) {                var that = this,                    size = _Number(that._options.size),                    textIndent = _Number(that._options.text.indent),                    minbound,                    maxbound,                    indent;                that._measureText();                if (that.vertical) {                    minbound = maxbound = layout.x;                    if (that._inverted)                        maxbound = maxbound + size;                    else                        minbound = minbound - size;                    if (that._hasText) {                        indent = that._textHeight / 2;                        if (textIndent > 0)                            maxbound += textIndent + that._textWidth;                        if (textIndent < 0)                            minbound += textIndent - that._textWidth                    }                }                else {                    minbound = maxbound = layout.y;                    if (that._inverted)                        maxbound = maxbound + size;                    else                        minbound = minbound - size;                    if (that._hasText) {                        indent = that._textWidth / 2;                        if (textIndent > 0)                            maxbound += textIndent + that._textHeight;                        if (textIndent < 0)                            minbound += textIndent - that._textHeight                    }                }                return {                        min: minbound,                        max: maxbound,                        indent: indent                    }            }        })    })(DevExpress);    /*! Module viz-gauges, file scale.js */    (function(DX, $, undefined) {        var viz = DX.viz,            core = viz.core,            _Number = Number,            _String = String,            _isFinite = isFinite,            _math = Math,            _min = _math.min,            _max = _math.max,            _abs = _math.abs,            PI_DIV_180 = _math.PI / 180,            utils = DX.utils,            _isFunction = utils.isFunction,            _isArray = utils.isArray,            _getCosAndSin = utils.getCosAndSin,            _convertAngleToRendererSpace = utils.convertAngleToRendererSpace,            _map = $.map,            _formatHelper = DX.formatHelper,            _createTickManager = core.CoreFactory.createTickManager;        function binarySearch(x, list) {            var a = 0,                b = list.length - 1,                flag = list[a] - list[b] < 0,                c,                k = -1;            if (list[a] === x)                k = a;            if (list[b] === x)                k = b;            while (k < 0 && a <= b) {                c = ~~((a + b) / 2);                if (list[c] === x)                    k = c;                else if (list[c] - x < 0 === flag)                    a = c + 1;                else                    b = c - 1            }            return k        }        function sortAsc(x, y) {            return x - y        }        viz.gauges.__internals.BaseScale = viz.gauges.__internals.BaseElement.inherit({            _init: function() {                var that = this;                that._root = that._renderer.g().attr({'class': 'dxg-scale'});                that._majorTicks = that._renderer.g().attr({'class': 'dxg-major-ticks'});                that._minorTicks = that._renderer.g().attr({'class': 'dxg-minor-ticks'});                that._labels = that._renderer.g().attr({'class': 'dxg-labels'})            },            clean: function() {                var that = this;                that._root.remove();                that._majorTicks.remove().clear();                that._minorTicks.remove().clear();                that._labels.remove().clear();                that._majorTicksEnabled = that._minorTicksEnabled = that._labelsEnabled = that._options = that.enabled = null;                return that            },            render: function(options) {                var that = this;                that._options = options;                that._processOptions(options);                if (that._majorTicksEnabled || that._minorTicksEnabled || that._labelsEnabled) {                    that.enabled = true;                    that._root.append(that._container);                    if (that._majorTicksEnabled)                        that._majorTicks.append(that._root);                    if (that._minorTicksEnabled)                        that._minorTicks.append(that._root);                    if (that._labelsEnabled) {                        that._labels.append(that._root);                        that._measureText()                    }                }                return that            },            _processOptions: function(options) {                var that = this;                that._majorTicksEnabled = options.majorTick.visible && options.majorTick.length > 0 && options.majorTick.width > 0;                that._minorTicksEnabled = options.minorTick.visible && options.minorTick.length > 0 && options.minorTick.width > 0;                that._labelsEnabled = options.label.visible && _Number(options.label.indentFromTick) !== 0;                that._setupOrientation()            },            _measureText: function() {                var that = this,                    domain = that._translator.getDomain(),                    options = that._options,                    tickManager = _createTickManager({}, {                        min: domain[0],                        max: domain[1],                        screenDelta: options.approximateScreenDelta                    }, {                        tickInterval: options.majorTick.tickInterval > 0 ? _Number(options.majorTick.tickInterval) : undefined,                        stick: true,                        textFontStyles: core.utils.patchFontOptions(options.label.font),                        gridSpacingFactor: that._getGridSpacingFactor().majorTicks,                        renderText: function(text, x, y, options) {                            return that._renderer.text(text, x, y, options).append(that._renderer.root)                        },                        getText: function(value) {                            return that._formatValue(value)                        },                        overlappingBehaviorType: that._overlappingBehaviorType                    }),                    maxTextParams = tickManager.getMaxLabelParams();                that._textVerticalOffset = -maxTextParams.y - maxTextParams.height / 2;                that._textWidth = maxTextParams.width;                that._textHeight = maxTextParams.height;                that._textLength = maxTextParams.length            },            _formatValue: function(value) {                var options = this._options.label,                    text = _formatHelper.format(value, options.format, options.precision);                if (_isFunction(options.customizeText)) {                    text = {                        value: value,                        valueText: text                    };                    text = _String(options.customizeText.call(text, text))                }                return text            },            _setupOrientation: null,            _getCustomValues: function(values, compare) {                var translator = this._translator,                    result = [];                if (_isArray(values)) {                    result = _map(values, function(x) {                        return _isFinite(translator.translate(x)) ? _Number(x) : null                    }).sort(compare);                    result = _map(result, function(x, i) {                        return x !== result[i - 1] ? x : null                    })                }                return result            },            _getLabelPosition: function(layout) {                return this._getAxisLabelPosition(_Number(this._options.majorTick.length), _Number(this._options.label.indentFromTick), layout)            },            _generateTicks: function(layout) {                var that = this,                    scaleOptions = that._options,                    translatorDomains = that._translator.getDomain(),                    data = {                        min: translatorDomains[0],                        max: translatorDomains[1],                        screenDelta: that._getScreenDelta(layout)                    },                    gridSpacingFactors = that._getGridSpacingFactor(),                    options = {                        tickInterval: scaleOptions.majorTick.tickInterval > 0 ? _Number(scaleOptions.majorTick.tickInterval) : undefined,                        minorTickInterval: scaleOptions.minorTick.tickInterval > 0 ? _Number(scaleOptions.minorTick.tickInterval) : undefined,                        gridSpacingFactor: gridSpacingFactors.majorTicks,                        minorGridSpacingFactor: gridSpacingFactors.minorTicks,                        numberMultipliers: [1, 2, 5],                        textFontStyles: core.utils.patchFontOptions(scaleOptions.label.font),                        labelOptions: scaleOptions.label,                        getText: function(value) {                            return that._formatValue(value)                        },                        isHorizontal: !that.vertical,                        stick: true,                        showMinorTicks: true                    },                    tickManager;                if (scaleOptions.majorTick.useTicksAutoArrangement) {                    options.useTicksAutoArrangement = true;                    options.renderText = function(text, x, y, options) {                        return that._renderer.text(text, x, y, options).append(that._renderer.root)                    };                    options.translate = that._getTranslateFunction(layout);                    that._applyOverlappingOptions(options, layout)                }                tickManager = _createTickManager({}, data, options);                return {                        majorTicks: tickManager.getTicks(true),                        minorTicks: tickManager.getMinorTicks()                    }            },            _getTicks: function(layout) {                var that = this,                    options = that._options,                    info = that._generateTicks(layout),                    majorValues = options.majorTick.showCalculatedTicks ? info.majorTicks : [],                    customMajorValues = _map(that._getCustomValues(options.majorTick.customTickValues, sortAsc), function(value) {                        return binarySearch(value, majorValues) === -1 ? value : null                    }),                    minorValues = _map(options.minorTick.showCalculatedTicks ? info.minorTicks : [], function(value) {                        return binarySearch(value, customMajorValues) === -1 ? value : null                    }),                    customMinorValues = that._getCustomValues(options.minorTick.customTickValues, sortAsc),                    list = majorValues.concat(minorValues, customMajorValues).sort(sortAsc);                customMinorValues = _map(customMinorValues, function(value) {                    return binarySearch(value, list) === -1 ? value : null                });                return {                        major: _map(majorValues.concat(customMajorValues), function(value) {                            return {                                    value: value,                                    position: that._translator.translate(value)                                }                        }),                        minor: _map(minorValues.concat(customMinorValues), function(value) {                            return {                                    value: value,                                    position: that._translator.translate(value)                                }                        })                    }            },            _createMajorTicks: function(ticks, layout) {                var that = this,                    points,                    i = 0,                    ii = ticks.length,                    element;                that._majorTicks.clear().attr({fill: that._options.majorTick.color});                points = that._getTickPoints(_Number(that._options.majorTick.length), _Number(that._options.majorTick.width), layout);                if (points) {                    that._options.hideFirstTick && ++i;                    that._options.hideLastTick && --ii;                    for (; i < ii; ++i) {                        element = that._renderer.path(points, "area");                        that._moveTick(element, ticks[i], layout);                        element.append(that._majorTicks)                    }                }            },            _createMinorTicks: function(ticks, layout) {                var that = this,                    points,                    i = 0,                    ii = ticks.length,                    element;                that._minorTicks.clear().attr({fill: that._options.minorTick.color});                points = that._getTickPoints(_Number(that._options.minorTick.length), _Number(that._options.minorTick.width), layout);                if (points)                    for (; i < ii; ++i) {                        element = that._renderer.path(points, "area");                        that._moveTick(element, ticks[i], layout);                        element.append(that._minorTicks)                    }            },            _createLabels: function(ticks, layout) {                var that = this,                    indentFromTick = _Number(that._options.label.indentFromTick),                    textPosition,                    i = 0,                    ii = ticks.length,                    points,                    text,                    fontStyles = {},                    rangeContainer;                that._labels.clear().attr({align: that._getLabelAlign(indentFromTick)}).css(core.utils.patchFontOptions(that._options.label.font));                textPosition = that._getLabelPosition(layout);                if (textPosition) {                    rangeContainer = that._options.label.useRangeColors ? that._options.rangeContainer : null;                    that._options.hideFirstLabel && ++i;                    that._options.hideLastLabel && --ii;                    for (; i < ii; ++i) {                        text = that._formatValue(ticks[i].value);                        fontStyles.fill = rangeContainer ? rangeContainer.getColorForValue(ticks[i].value) : null;                        points = that._getLabelOptions(text, textPosition, indentFromTick, ticks[i], layout);                        that._renderer.text(text, points.x, points.y + that._textVerticalOffset).css(fontStyles).append(that._labels)                    }                }            },            resize: function(layout) {                var that = this,                    ticks = that._getTicks(layout);                if (that._majorTicksEnabled)                    that._createMajorTicks(ticks.major, layout);                if (that._minorTicksEnabled)                    that._createMinorTicks(ticks.minor, layout);                if (that._labelsEnabled)                    that._createLabels(ticks.major, layout);                return that            }        });        viz.gauges.__internals.CircularScale = viz.gauges.__internals.BaseScale.inherit({            _getGridSpacingFactor: function() {                return {                        majorTicks: 17,                        minorTicks: 5                    }            },            _getTranslateFunction: function(layout) {                var that = this,                    indent = _Number(that._options.label.indentFromTick),                    translator = this._translator;                layout = layout || {                    x: 0,                    y: 0,                    radius: 0                };                return function(value) {                        var position = that._getLabelPosition(layout),                            text = that._formatValue(value);                        return that._getLabelOptions(text, position, indent, {position: translator.translate(value)}, layout)                    }            },            _overlappingBehaviorType: "circular",            _getScreenDelta: function(layout) {                return (this._translator.getCodomainStart() - this._translator.getCodomainEnd()) * layout.radius * PI_DIV_180            },            _setupOrientation: function() {                var that = this;                that._inner = that._outer = 0;                switch (that._options.orientation) {                    case'inside':                        that._inner = 1;                        break;                    case'center':                        that._inner = that._outer = 0.5;                        break;                    default:                        that._outer = 1;                        break                }            },            _getTickPoints: function(length, width, layout) {                var x1 = layout.x - width / 2,                    x2 = layout.x + width / 2,                    y1 = layout.y - layout.radius - length * this._outer,                    y2 = layout.y - layout.radius + length * this._inner;                return y1 > 0 && y2 > 0 ? [x1, y1, x2, y1, x2, y2, x1, y2] : null            },            _moveTick: function(element, tick, layout) {                element.rotate(_convertAngleToRendererSpace(tick.position), layout.x, layout.y)            },            _getAxisLabelPosition: function(tickLength, textIndent, layout) {                var position = layout.radius + tickLength * (textIndent >= 0 ? this._outer : -this._inner) + textIndent;                return position > 0 ? position : null            },            _getLabelAlign: function() {                return 'center'            },            _applyOverlappingOptions: function(options, layout) {                options.circularRadius = this._getLabelPosition(layout);                options.circularStartAngle = this._translator.getCodomainStart();                options.circularEndAngle = this._translator.getCodomainEnd();                options.overlappingBehaviorType = "circular"            },            _getLabelOptions: function(textValue, textPosition, textIndent, tick, layout) {                var cossin = _getCosAndSin(tick.position),                    x = layout.x + cossin.cos * textPosition,                    y = layout.y - cossin.sin * textPosition,                    dx = cossin.cos * (textValue.length / this._textLength) * this._textWidth / 2,                    dy = cossin.sin * this._textHeight / 2;                if (textIndent > 0) {                    x += dx;                    y -= dy                }                else {                    x -= dx;                    y += dy                }                return {                        x: x,                        y: y                    }            },            measure: function(layout) {                var that = this,                    result = {                        min: layout.radius,                        max: layout.radius                    };                if (that._majorTicksEnabled) {                    result.min = _min(result.min, layout.radius - that._inner * that._options.majorTick.length);                    result.max = _max(result.max, layout.radius + that._outer * that._options.majorTick.length)                }                if (that._minorTicksEnabled) {                    result.min = _min(result.min, layout.radius - that._inner * that._options.minorTick.length);                    result.max = _max(result.max, layout.radius + that._outer * that._options.minorTick.length)                }                if (that._labelsEnabled) {                    if (that._options.label.indentFromTick > 0) {                        result.horizontalOffset = _Number(that._options.label.indentFromTick) + that._textWidth;                        result.verticalOffset = _Number(that._options.label.indentFromTick) + that._textHeight                    }                    else {                        result.horizontalOffset = result.verticalOffset = 0;                        result.min -= -_Number(that._options.label.indentFromTick) + _max(that._textWidth, that._textHeight)                    }                    result.inverseHorizontalOffset = that._textWidth / 2;                    result.inverseVerticalOffset = that._textHeight / 2                }                return result            }        });        viz.gauges.__internals.LinearScale = viz.gauges.__internals.BaseScale.inherit({            _getGridSpacingFactor: function() {                return {                        majorTicks: 25,                        minorTicks: 5                    }            },            _getTranslateFunction: function() {                var tr = this._translator;                return function(value) {                        return tr.translate(value)                    }            },            _overlappingBehaviorType: "linear",            _getScreenDelta: function() {                return _abs(this._translator.getCodomainEnd() - this._translator.getCodomainStart())            },            _setupOrientation: function() {                var that = this;                that.vertical = that._options.vertical;                that._inner = that._outer = 0;                if (that.vertical)                    switch (that._options.horizontalOrientation) {                        case'left':                            that._inner = 1;                            break;                        case'center':                            that._inner = that._outer = 0.5;                            break;                        default:                            that._outer = 1;                            break                    }                else                    switch (that._options.verticalOrientation) {                        case'top':                            that._inner = 1;                            break;                        case'middle':                            that._inner = that._outer = 0.5;                            break;                        default:                            that._outer = 1;                            break                    }            },            _getTickPoints: function(length, width, layout) {                var that = this,                    x1,                    x2,                    y1,                    y2;                if (that.vertical) {                    x1 = layout.x - length * that._inner;                    x2 = layout.x + length * that._outer;                    y1 = -width / 2;                    y2 = +width / 2                }                else {                    x1 = -width / 2;                    x2 = +width / 2;                    y1 = layout.y - length * that._inner;                    y2 = layout.y + length * that._outer                }                return [x1, y1, x2, y1, x2, y2, x1, y2]            },            _moveTick: function(element, tick) {                var x = 0,                    y = 0;                if (this.vertical)                    y = tick.position;                else                    x = tick.position;                element.move(x, y)            },            _getAxisLabelPosition: function(tickLength, textIndent, layout) {                var position = tickLength * (textIndent >= 0 ? this._outer : -this._inner) + textIndent;                if (this.vertical)                    position += layout.x;                else                    position += layout.y + (textIndent >= 0 ? 1 : -1) * (this._textVerticalOffset || 0);                return position            },            _getLabelAlign: function(textIndent) {                return this.vertical ? textIndent > 0 ? 'left' : 'right' : 'center'            },            _applyOverlappingOptions: function(options) {                options.overlappingBehaviorType = "linear"            },            _getLabelOptions: function(textValue, textPosition, textIndent, tick) {                var x,                    y;                if (this.vertical) {                    x = textPosition;                    y = tick.position                }                else {                    x = tick.position;                    y = textPosition                }                return {                        x: x,                        y: y                    }            },            measure: function(layout) {                var that = this,                    p = layout[that.vertical ? 'x' : 'y'],                    result = {                        min: p,                        max: p                    };                if (that._majorTicksEnabled) {                    result.min = _min(result.min, p - that._inner * that._options.majorTick.length);                    result.max = _max(result.max, p + that._outer * that._options.majorTick.length)                }                if (that._minorTicksEnabled) {                    result.min = _min(result.min, p - that._inner * that._options.minorTick.length);                    result.max = _max(result.max, p + that._outer * that._options.minorTick.length)                }                if (that._labelsEnabled) {                    if (that._options.label.indentFromTick > 0)                        result.max += +_Number(that._options.label.indentFromTick) + that[that.vertical ? '_textWidth' : '_textHeight'];                    else                        result.min -= -_Number(that._options.label.indentFromTick) + that[that.vertical ? '_textWidth' : '_textHeight'];                    result.indent = that[that.vertical ? '_textHeight' : '_textWidth'] / 2                }                return result            }        })    })(DevExpress, jQuery);    /*! Module viz-gauges, file rangeContainer.js */    (function(DX, $, undefined) {        var _Number = Number,            _String = String,            _max = Math.max,            _abs = Math.abs,            _isString = DX.utils.isString,            _isArray = DX.utils.isArray,            _isFinite = isFinite,            _each = $.each,            _map = $.map,            _Palette = DX.viz.core.Palette;        DX.viz.gauges.__internals.BaseRangeContainer = DX.viz.gauges.__internals.BaseElement.inherit({            _init: function() {                this._root = this._renderer.g().attr({'class': 'dxg-range-container'})            },            clean: function() {                this._root.remove().clear();                this._options = this.enabled = null;                return this            },            _getRanges: function() {                var that = this,                    options = that._options,                    translator = that._translator,                    totalStart = translator.getDomain()[0],                    totalEnd = translator.getDomain()[1],                    totalDelta = totalEnd - totalStart,                    isNotEmptySegment = totalDelta >= 0 ? isNotEmptySegmentAsc : isNotEmptySegmentDes,                    subtractSegment = totalDelta >= 0 ? subtractSegmentAsc : subtractSegmentDes,                    list = [],                    ranges = [],                    backgroundRanges = [{                            start: totalStart,                            end: totalEnd                        }],                    threshold = _abs(totalDelta) / 1E4,                    palette = new _Palette(options.palette, {                        type: 'indicatingSet',                        theme: options.themeName                    }),                    backgroundColor = _isString(options.backgroundColor) ? options.backgroundColor : 'none',                    width = options.width || {},                    startWidth = _Number(width > 0 ? width : width.start),                    endWidth = _Number(width > 0 ? width : width.end),                    deltaWidth = endWidth - startWidth;                if (options.ranges !== undefined && !_isArray(options.ranges))                    return null;                if (!(startWidth >= 0 && endWidth >= 0 && startWidth + endWidth > 0))                    return null;                list = _map(_isArray(options.ranges) ? options.ranges : [], function(rangeOptions, i) {                    rangeOptions = rangeOptions || {};                    var start = translator.adjust(rangeOptions.startValue),                        end = translator.adjust(rangeOptions.endValue);                    return _isFinite(start) && _isFinite(end) && isNotEmptySegment(start, end, threshold) ? {                            start: start,                            end: end,                            color: rangeOptions.color,                            classIndex: i                        } : null                });                _each(list, function(i, item) {                    var paletteColor = palette.getNextColor();                    item.color = _isString(item.color) && item.color || paletteColor || 'none';                    item.className = 'dxg-range dxg-range-' + item.classIndex;                    delete item.classIndex                });                _each(list, function(_, item) {                    var i,                        ii,                        sub,                        subs,                        range,                        newRanges = [],                        newBackgroundRanges = [];                    for (i = 0, ii = ranges.length; i < ii; ++i) {                        range = ranges[i];                        subs = subtractSegment(range.start, range.end, item.start, item.end);                        (sub = subs[0]) && (sub.color = range.color) && (sub.className = range.className) && newRanges.push(sub);                        (sub = subs[1]) && (sub.color = range.color) && (sub.className = range.className) && newRanges.push(sub)                    }                    newRanges.push(item);                    ranges = newRanges;                    for (i = 0, ii = backgroundRanges.length; i < ii; ++i) {                        range = backgroundRanges[i];                        subs = subtractSegment(range.start, range.end, item.start, item.end);                        (sub = subs[0]) && newBackgroundRanges.push(sub);                        (sub = subs[1]) && newBackgroundRanges.push(sub)                    }                    backgroundRanges = newBackgroundRanges                });                _each(backgroundRanges, function(_, range) {                    range.color = backgroundColor;                    range.className = 'dxg-range dxg-background-range';                    ranges.push(range)                });                _each(ranges, function(_, range) {                    range.startWidth = (range.start - totalStart) / totalDelta * deltaWidth + startWidth;                    range.endWidth = (range.end - totalStart) / totalDelta * deltaWidth + startWidth                });                return ranges            },            render: function(options) {                var that = this;                that._options = options;                that._processOptions();                that._ranges = that._getRanges();                if (that._ranges) {                    that.enabled = true;                    that._root.append(that._container)                }                return that            },            resize: function(layout) {                var that = this;                that._root.clear();                if (that._isVisible(layout))                    _each(that._ranges, function(_, range) {                        that._createRange(range, layout).attr({                            fill: range.color,                            'class': range.className                        }).append(that._root)                    });                return that            },            _processOptions: null,            _isVisible: null,            _createRange: null,            getColorForValue: function(value) {                var color = null;                _each(this._ranges, function(_, range) {                    if (range.start <= value && value <= range.end || range.start >= value && value >= range.end) {                        color = range.color;                        return false                    }                });                return color            }        });        function subtractSegmentAsc(segmentStart, segmentEnd, otherStart, otherEnd) {            var result;            if (otherStart > segmentStart && otherEnd < segmentEnd)                result = [{                        start: segmentStart,                        end: otherStart                    }, {                        start: otherEnd,                        end: segmentEnd                    }];            else if (otherStart >= segmentEnd || otherEnd <= segmentStart)                result = [{                        start: segmentStart,                        end: segmentEnd                    }];            else if (otherStart <= segmentStart && otherEnd >= segmentEnd)                result = [];            else if (otherStart > segmentStart)                result = [{                        start: segmentStart,                        end: otherStart                    }];            else if (otherEnd < segmentEnd)                result = [{                        start: otherEnd,                        end: segmentEnd                    }];            return result        }        function subtractSegmentDes(segmentStart, segmentEnd, otherStart, otherEnd) {            var result;            if (otherStart < segmentStart && otherEnd > segmentEnd)                result = [{                        start: segmentStart,                        end: otherStart                    }, {                        start: otherEnd,                        end: segmentEnd                    }];            else if (otherStart <= segmentEnd || otherEnd >= segmentStart)                result = [{                        start: segmentStart,                        end: segmentEnd                    }];            else if (otherStart >= segmentStart && otherEnd <= segmentEnd)                result = [];            else if (otherStart < segmentStart)                result = [{                        start: segmentStart,                        end: otherStart                    }];            else if (otherEnd > segmentEnd)                result = [{                        start: otherEnd,                        end: segmentEnd                    }];            return result        }        function isNotEmptySegmentAsc(start, end, threshold) {            return end - start >= threshold        }        function isNotEmptySegmentDes(start, end, threshold) {            return start - end >= threshold        }        DX.viz.gauges.__internals.CircularRangeContainer = DX.viz.gauges.__internals.BaseRangeContainer.inherit({            _processOptions: function() {                var that = this;                that._inner = that._outer = 0;                switch (_String(that._options.orientation).toLowerCase()) {                    case'inside':                        that._inner = 1;                        break;                    case'center':                        that._inner = that._outer = 0.5;                        break;                    default:                        that._outer = 1;                        break                }            },            _isVisible: function(layout) {                var width = this._options.width;                width = _Number(width) || _max(_Number(width.start), _Number(width.end));                return layout.radius - this._inner * width > 0            },            _createRange: function(range, layout) {                var that = this,                    width = (range.startWidth + range.endWidth) / 2;                return that._renderer.arc(layout.x, layout.y, layout.radius - that._inner * width, layout.radius + that._outer * width, that._translator.translate(range.end), that._translator.translate(range.start)).attr({"stroke-linejoin": "round"})            },            measure: function(layout) {                var width = this._options.width;                width = _Number(width) || _max(_Number(width.start), _Number(width.end));                return {                        min: layout.radius - this._inner * width,                        max: layout.radius + this._outer * width                    }            }        });        DX.viz.gauges.__internals.LinearRangeContainer = DX.viz.gauges.__internals.BaseRangeContainer.inherit({            _processOptions: function() {                var that = this;                that.vertical = that._options.vertical;                that._inner = that._outer = 0;                if (that.vertical)                    switch (_String(that._options.horizontalOrientation).toLowerCase()) {                        case'left':                            that._inner = 1;                            break;                        case'center':                            that._inner = that._outer = 0.5;                            break;                        default:                            that._outer = 1;                            break                    }                else                    switch (_String(that._options.verticalOrientation).toLowerCase()) {                        case'top':                            that._inner = 1;                            break;                        case'middle':                            that._inner = that._outer = 0.5;                            break;                        default:                            that._outer = 1;                            break                    }            },            _isVisible: function() {                return true            },            _createRange: function(range, layout) {                var that = this,                    inner = that._inner,                    outer = that._outer,                    startPosition = that._translator.translate(range.start),                    endPosition = that._translator.translate(range.end),                    points,                    x = layout.x,                    y = layout.y,                    startWidth = range.startWidth,                    endWidth = range.endWidth;                if (that.vertical)                    points = [x - startWidth * inner, startPosition, x - endWidth * inner, endPosition, x + endWidth * outer, endPosition, x + startWidth * outer, startPosition];                else                    points = [startPosition, y + startWidth * outer, startPosition, y - startWidth * inner, endPosition, y - endWidth * inner, endPosition, y + endWidth * outer];                return that._renderer.path(points, "area")            },            measure: function(layout) {                var result = {},                    width;                result.min = result.max = layout[this.vertical ? 'x' : 'y'];                width = this._options.width;                width = _Number(width) || _max(_Number(width.start), _Number(width.end));                result.min -= this._inner * width;                result.max += this._outer * width;                return result            }        })    })(DevExpress, jQuery);    /*! Module viz-gauges, file title.js */    (function(DX, $, undefined) {        var viz = DX.viz,            core = viz.core,            _isString = DX.utils.isString,            _max = Math.max,            _extend = $.extend;        viz.gauges.__internals.Title = DX.Class.inherit({            ctor: function(parameters) {                this._renderer = parameters.renderer;                this._container = parameters.container            },            dispose: function() {                this._renderer = this._container = null;                return this            },            clean: function() {                var that = this;                if (that._root) {                    that._root.remove().clear();                    that._root = that._layout = null                }                return that            },            render: function(titleOptions, subtitleOptions) {                var that = this,                    hasTitle = _isString(titleOptions.text) && titleOptions.text.length > 0,                    hasSubtitle = _isString(subtitleOptions.text) && subtitleOptions.text.length > 0,                    element,                    bbox,                    totalWidth = 0,                    totalHeight = 0,                    y = 0;                if (!hasTitle && !hasSubtitle)                    return that;                that._root = that._renderer.g().attr({'class': 'dxg-title'}).append(that._container);                if (hasTitle) {                    element = that._renderer.text(titleOptions.text, 0, 0).attr({align: 'center'}).css(core.utils.patchFontOptions(titleOptions.font)).append(that._root);                    bbox = element.getBBox();                    y += -bbox.y;                    element.attr({y: y});                    y += bbox.height + bbox.y;                    totalWidth = _max(totalWidth, bbox.width);                    totalHeight += bbox.height                }                if (hasSubtitle) {                    element = that._renderer.text(subtitleOptions.text, 0, 0).attr({align: 'center'}).css(core.utils.patchFontOptions(subtitleOptions.font)).append(that._root);                    bbox = element.getBBox();                    y += -bbox.y;                    element.attr({y: y});                    totalWidth = _max(totalWidth, bbox.width);                    totalHeight += bbox.height                }                that._layout = _extend({                    position: titleOptions.position,                    width: totalWidth,                    height: totalHeight                }, titleOptions.layout);                return that            },            getLayoutOptions: function() {                return this._layout            },            locate: function(left, top) {                this._root.attr({                    translateX: left + this._layout.width / 2,                    translateY: top                });                return this            }        })    })(DevExpress, jQuery);    /*! Module viz-gauges, file layoutManager.js */    (function(DX, $, undefined) {        var _Number = Number,            _String = String,            _max = Math.max,            _each = $.each;        function patchLayoutOptions(options) {            if (options.position) {                var position = _String(options.position).toLowerCase().split('-');                options.verticalAlignment = position[0];                options.horizontalAlignment = position[1]            }        }        DX.viz.gauges.__internals.LayoutManager = DX.Class.inherit({            setRect: function(rect) {                this._currentRect = rect.clone();                return this            },            getRect: function() {                return this._currentRect.clone()            },            beginLayout: function(rect) {                this._rootRect = rect.clone();                this._currentRect = rect.clone();                this._cache = [];                return this            },            applyLayout: function(target) {                var options = target.getLayoutOptions(),                    currentRect,                    verticalOverlay;                if (!options)                    return this;                currentRect = this._currentRect;                verticalOverlay = _Number(options.overlay) || 0;                patchLayoutOptions(options);                switch (_String(options.verticalAlignment).toLowerCase()) {                    case'bottom':                        currentRect.bottom -= _max(options.height - verticalOverlay, 0);                        break;                    default:                        currentRect.top += _max(options.height - verticalOverlay, 0);                        break                }                this._cache.push({                    target: target,                    options: options                });                return this            },            endLayout: function() {                var that = this,                    rootRect = that._rootRect,                    currentRect = that._currentRect;                _each(that._cache, function(_, cacheItem) {                    var options = cacheItem.options,                        left,                        top,                        verticalOverlay = _Number(options.overlay) || 0;                    switch (_String(options.verticalAlignment).toLowerCase()) {                        case'bottom':                            top = currentRect.bottom - verticalOverlay;                            currentRect.bottom += _max(options.height - verticalOverlay, 0);                            break;                        default:                            top = currentRect.top - options.height + verticalOverlay;                            currentRect.top -= _max(options.height - verticalOverlay, 0);                            break                    }                    switch (_String(options.horizontalAlignment).toLowerCase()) {                        case'left':                            left = rootRect.left;                            break;                        case'right':                            left = rootRect.right - options.width;                            break;                        default:                            left = rootRect.horizontalMiddle() - options.width / 2;                            break                    }                    cacheItem.target.locate(left, top)                });                that._cache = null;                return that            },            selectRectByAspectRatio: function(aspectRatio, margins) {                var rect = this._currentRect.clone(),                    selfAspectRatio,                    width = 0,                    height = 0;                margins = margins || {};                if (aspectRatio > 0) {                    rect.left += margins.left || 0;                    rect.right -= margins.right || 0;                    rect.top += margins.top || 0;                    rect.bottom -= margins.bottom || 0;                    if (rect.width() > 0 && rect.height() > 0) {                        selfAspectRatio = rect.height() / rect.width();                        if (selfAspectRatio > 1)                            aspectRatio < selfAspectRatio ? width = rect.width() : height = rect.height();                        else                            aspectRatio > selfAspectRatio ? height = rect.height() : width = rect.width();                        width > 0 || (width = height / aspectRatio);                        height > 0 || (height = width * aspectRatio);                        width = (rect.width() - width) / 2;                        height = (rect.height() - height) / 2;                        rect.left += width;                        rect.right -= width;                        rect.top += height;                        rect.bottom -= height                    }                    else {                        rect.left = rect.right = rect.horizontalMiddle();                        rect.top = rect.bottom = rect.verticalMiddle()                    }                }                return rect            },            selectRectBySizes: function(sizes, margins) {                var rect = this._currentRect.clone(),                    step;                margins = margins || {};                if (sizes) {                    rect.left += margins.left || 0;                    rect.right -= margins.right || 0;                    rect.top += margins.top || 0;                    rect.bottom -= margins.bottom || 0;                    if (sizes.width > 0) {                        step = (rect.width() - sizes.width) / 2;                        if (step > 0) {                            rect.left += step;                            rect.right -= step                        }                    }                    if (sizes.height > 0) {                        step = (rect.height() - sizes.height) / 2;                        if (step > 0) {                            rect.top += step;                            rect.bottom -= step                        }                    }                }                return rect            }        })    })(DevExpress, jQuery);    /*! Module viz-gauges, file themeManager.js */    (function(DX, $, undefined) {        var _extend = $.extend;        DX.viz.gauges.__internals.ThemeManager = DX.viz.core.BaseThemeManager.inherit({            _themeSection: 'gauge',            _fontFields: ['scale.label.font', 'valueIndicators.rangebar.text.font', 'valueIndicators.textcloud.text.font', 'title.font', 'subtitle.font', 'tooltip.font', 'indicator.text.font', 'loadingIndicator.font'],            _initializeTheme: function() {                var that = this,                    subTheme;                if (that._subTheme) {                    subTheme = _extend(true, {}, that._theme[that._subTheme], that._theme);                    _extend(true, that._theme, subTheme)                }                that.callBase.apply(that, arguments)            }        })    })(DevExpress, jQuery);    /*! Module viz-gauges, file baseGauge.js */    (function(DX, $, undefined) {        var _Number = Number,            _isString = DX.utils.isString,            _getAppropriateFormat = DX.utils.getAppropriateFormat,            _extend = $.extend,            _each = $.each;        DX.viz.gauges.dxBaseGauge = DX.viz.core.BaseWidget.inherit({            _rootClassPrefix: "dxg",            _createThemeManager: function() {                return this._factory.createThemeManager()            },            _initCore: function() {                var that = this;                that._root = that._renderer.root;                that._translator = that._factory.createTranslator();                that._initNotifiers();                that._tracker = that._factory.createTracker({                    renderer: that._renderer,                    container: that._root                });                that._layoutManager = that._factory.createLayoutManager();                that._title = that._factory.createTitle({                    renderer: that._renderer,                    container: that._root                });                that._deltaIndicator = that._factory.createDeltaIndicator({                    renderer: that._renderer,                    container: that._root                });                that._setupDomain();                that._setTrackerCallbacks()            },            _setTrackerCallbacks: function() {                var that = this,                    renderer = that._renderer,                    tooltip = that._tooltip;                that._tracker.setCallbacks({                    'tooltip-show': function(target, info) {                        var tooltipParameters = target.getTooltipParameters(),                            offset = renderer.getRootOffset(),                            formatObject = _extend({                                value: tooltipParameters.value,                                valueText: tooltip.formatValue(tooltipParameters.value),                                color: tooltipParameters.color                            }, info);                        return tooltip.show(formatObject, {                                x: tooltipParameters.x + offset.left,                                y: tooltipParameters.y + offset.top,                                offset: tooltipParameters.offset                            }, {target: info})                    },                    'tooltip-hide': function() {                        return tooltip.hide()                    }                });                that._resetTrackerCallbacks = function() {                    that._resetTrackerCallbacks = that = renderer = tooltip = null                }            },            _initNotifiers: function() {                var that = this,                    counter = 0;                that._notifiers = {                    dirty: function() {                        that._resetIsReady();                        ++counter                    },                    ready: function() {                        if (--counter === 0)                            that._drawn()                    }                }            },            _disposeCore: function() {                var that = this;                that._themeManager.dispose();                that._tracker.dispose();                that._title.dispose();                that._deltaIndicator && that._deltaIndicator.dispose();                that._root = that._translator = that._notifiers = that._tracker = that._layoutManager = that._title = null            },            _refresh: function() {                var that = this,                    callBase = that.callBase;                that._endLoading(function() {                    callBase.call(that)                })            },            _clean: function() {                this._cleanCore()            },            _render: function() {                var that = this;                that._setupCodomain();                that._setupAnimationSettings();                that._setupDefaultFormat();                that._renderCore()            },            _cleanCore: function() {                var that = this;                that._title.clean();                that._deltaIndicator && that._deltaIndicator.clean();                that._tracker.deactivate();                that._cleanContent()            },            _renderCore: function() {                var that = this;                if (!that._isValidDomain)                    return;                var theme = that._themeManager.theme(),                    titleTheme = _extend(true, {}, theme.title, processTitleOptions(that.option("title"))),                    subTitleTheme = _extend(true, {}, theme.subtitle, processTitleOptions(that.option("subtitle")));                that._title.render(titleTheme, subTitleTheme);                that._deltaIndicator && that._deltaIndicator.render(_extend(true, {}, theme.indicator, that.option("indicator")));                that._layoutManager.beginLayout(that._rootRect);                _each([that._deltaIndicator, that._title], function(_, item) {                    item && that._layoutManager.applyLayout(item)                });                that._mainRect = that._layoutManager.getRect();                that._renderContent();                that._layoutManager.endLayout();                that._tracker.setTooltipState(that._tooltip.isEnabled());                that._tracker.activate();                that._noAnimation = null;                that.option("debugMode") === true && that._renderDebugInfo();                that._debug_rendered && that._debug_rendered()            },            _setTooltipOptions: function() {                var that = this;                that.callBase();                that._tracker && that._tracker.setTooltipState(that._tooltip.isEnabled())            },            _renderDebugInfo: function() {                var that = this,                    group = that._debugGroup || that._renderer.g().attr({"class": "debug-info"}).append(that._renderer.root),                    rect;                group.clear();                rect = that._rootRect;                that._renderer.rect(rect.left, rect.top, rect.width(), rect.height()).attr({                    stroke: "#000000",                    "stroke-width": 1,                    fill: "none"                }).append(group);                rect = that._mainRect;                that._renderer.rect(rect.left, rect.top, rect.width(), rect.height()).attr({                    stroke: "#0000FF",                    "stroke-width": 1,                    fill: "none"                }).append(group);                rect = that._layoutManager.getRect();                rect && that._renderer.rect(rect.left, rect.top, rect.width(), rect.height()).attr({                    stroke: "#FF0000",                    "stroke-width": 1,                    fill: "none"                }).append(group);                rect = that._title.getLayoutOptions() ? that._title._root.getBBox() : null;                rect && that._renderer.rect(rect.x, rect.y, rect.width, rect.height).attr({                    stroke: "#00FF00",                    "stroke-width": 1,                    fill: "none"                }).append(group);                rect = that._deltaIndicator && that._deltaIndicator.getLayoutOptions() ? that._deltaIndicator._root.getBBox() : null;                rect && that._renderer.rect(rect.x, rect.y, rect.width, rect.height).attr({                    stroke: "#00FF00",                    "stroke-width": 1,                    fill: "none"                }).append(group)            },            _applySize: function() {                var canvas = this._canvas;                this._rootRect = new DX.viz.core.Rectangle({                    left: canvas.left,                    top: canvas.top,                    right: canvas.width - canvas.right,                    bottom: canvas.height - canvas.bottom                });                this._width = canvas.width;                this._height = canvas.height            },            _resize: function() {                var that = this;                that._resizing = that._noAnimation = true;                that._cleanCore();                that._renderCore();                that._resizing = null            },            _optionChanged: function(args) {                var that = this;                switch (args.name) {                    case"startValue":                    case"endValue":                        that._setupDomain();                        that._invalidate();                        break;                    default:                        that.callBase(args);                        break                }            },            _setupDomain: function() {                var that = this;                that._setupDomainCore();                that._isValidDomain = isFinite(1 / (that._translator.getDomain()[1] - that._translator.getDomain()[0]));                if (!that._isValidDomain)                    that._incidentOccured("W2301")            },            _setupAnimationSettings: function() {                var that = this,                    option = that.option("animation");                that._animationSettings = null;                if (option === undefined || option) {                    option = _extend({                        enabled: true,                        duration: 1000,                        easing: "easeOutCubic"                    }, option);                    if (option.enabled && option.duration > 0)                        that._animationSettings = {                            duration: _Number(option.duration),                            easing: option.easing                        }                }                that._containerBackgroundColor = that.option("containerBackgroundColor") || that._themeManager.theme().containerBackgroundColor            },            _setupDefaultFormat: function() {                var domain = this._translator.getDomain();                this._defaultFormatOptions = _getAppropriateFormat(domain[0], domain[1], this._getApproximateScreenRange())            },            _setupDomainCore: null,            _calculateSize: null,            _cleanContent: null,            _renderContent: null,            _setupCodomain: null,            _getApproximateScreenRange: null,            _factory: {                createTranslator: function() {                    return new DX.viz.core.Translator1D                },                createTracker: function(parameters) {                    return new DX.viz.gauges.__internals.Tracker(parameters)                },                createLayoutManager: function() {                    return new DX.viz.gauges.__internals.LayoutManager                },                createTitle: function(parameters) {                    return new DX.viz.gauges.__internals.Title(parameters)                },                createDeltaIndicator: function(parameters) {                    return DX.viz.gauges.__internals.DeltaIndicator ? new DX.viz.gauges.__internals.DeltaIndicator(parameters) : null                }            }        });        function processTitleOptions(options) {            return _isString(options) ? {text: options} : options || {}        }    })(DevExpress, jQuery);    /*! Module viz-gauges, file gauge.js */    (function(DX, $, undefined) {        var _isDefined = DX.utils.isDefined,            _isArray = DX.utils.isArray,            _isNumber = DX.utils.isNumber,            _isFinite = isFinite,            _Number = Number,            _String = String,            _abs = Math.abs,            _extend = $.extend,            _each = $.each,            _map = $.map,            _noop = $.noop,            _factory = DX.viz.gauges.__factory,            OPTION_VALUE = 'value',            OPTION_SUBVALUES = 'subvalues';        function processValue(value, fallbackValue) {            return _isFinite(value) ? _Number(value) : fallbackValue        }        function parseArrayOfNumbers(arg) {            return _isArray(arg) ? arg : _isNumber(arg) ? [arg] : null        }        DX.viz.gauges.dxGauge = DX.viz.gauges.dxBaseGauge.inherit({            _initCore: function() {                var that = this;                that._setupValue(that.option(OPTION_VALUE));                that.__subvalues = parseArrayOfNumbers(that.option(OPTION_SUBVALUES));                that._setupSubvalues(that.__subvalues);                selectMode(that);                that.callBase.apply(that, arguments);                that._scale = that._createScale({                    renderer: that._renderer,                    container: that._root,                    translator: that._translator                });                that._rangeContainer = that._createRangeContainer({                    renderer: that._renderer,                    container: that._root,                    translator: that._translator                })            },            _disposeCore: function() {                var that = this;                that.callBase.apply(that, arguments);                that._scale.dispose();                that._rangeContainer.dispose();                that._disposeValueIndicators();                that._scale = that._rangeContainer = null            },            _disposeValueIndicators: function() {                var that = this;                that._valueIndicator && that._valueIndicator.dispose();                that._subvalueIndicatorsSet && that._subvalueIndicatorsSet.dispose();                that._valueIndicator = that._subvalueIndicatorsSet = null            },            _setupDomainCore: function() {                var that = this,                    scaleOption = that.option('scale') || {},                    startValue = that.option('startValue'),                    endValue = that.option('endValue');                startValue = _isNumber(startValue) ? _Number(startValue) : _isNumber(scaleOption.startValue) ? _Number(scaleOption.startValue) : 0;                endValue = _isNumber(endValue) ? _Number(endValue) : _isNumber(scaleOption.endValue) ? _Number(scaleOption.endValue) : 100;                that._baseValue = startValue < endValue ? startValue : endValue;                that._translator.setDomain(startValue, endValue)            },            _cleanContent: function() {                var that = this;                that._rangeContainer.clean();                that._scale.clean();                that._cleanValueIndicators()            },            _renderContent: function() {                var that = this,                    elements;                that._rangeContainer.render(_extend(that._getOption("rangeContainer"), {                    themeName: that._themeManager.themeName(),                    vertical: that._area.vertical                }));                that._scale.render(_extend(that._getOption("scale"), {                    rangeContainer: that._rangeContainer.enabled ? that._rangeContainer : null,                    approximateScreenDelta: that._getApproximateScreenRange(),                    offset: 0,                    vertical: that._area.vertical                }));                elements = _map([that._scale, that._rangeContainer].concat(that._prepareValueIndicators()), function(element) {                    return element && element.enabled ? element : null                });                that._applyMainLayout(elements);                _each(elements, function(_, element) {                    element.resize(that._getElementLayout(element.getOffset()))                });                that._updateActiveElements()            },            _updateIndicatorSettings: function(settings) {                var that = this;                settings.currentValue = settings.baseValue = _isFinite(that._translator.translate(settings.baseValue)) ? _Number(settings.baseValue) : that._baseValue;                settings.vertical = that._area.vertical;                if (settings.text && !settings.text.format && !settings.text.precision) {                    settings.text.format = that._defaultFormatOptions.format;                    settings.text.precision = that._defaultFormatOptions.precision                }            },            _prepareIndicatorSettings: function(options, defaultTypeField) {                var that = this,                    theme = that._themeManager.theme("valueIndicators"),                    type = _String(options.type || that._themeManager.theme(defaultTypeField)).toLowerCase(),                    settings = _extend(true, {}, theme._default, theme[type], options);                settings.type = type;                settings.animation = that._animationSettings;                settings.containerBackgroundColor = that._containerBackgroundColor;                that._updateIndicatorSettings(settings);                return settings            },            _cleanValueIndicators: function() {                this._valueIndicator && this._valueIndicator.clean();                this._subvalueIndicatorsSet && this._subvalueIndicatorsSet.clean()            },            _prepareValueIndicators: function() {                var that = this;                that._prepareValueIndicator();                that.__subvalues !== null && that._prepareSubvalueIndicators();                return [that._valueIndicator, that._subvalueIndicatorsSet]            },            _updateActiveElements: function() {                this._updateValueIndicator();                this._updateSubvalueIndicators()            },            _prepareValueIndicator: function() {                var that = this,                    target = that._valueIndicator,                    settings = that._prepareIndicatorSettings(that.option("valueIndicator") || {}, 'valueIndicatorType');                if (target && target.type !== settings.type) {                    target.dispose();                    target = null                }                if (!target)                    target = that._valueIndicator = that._createIndicator(settings.type, that._root, 'dxg-value-indicator', 'value-indicator');                target.render(settings)            },            _createSubvalueIndicatorsSet: function() {                var that = this,                    owner = that._renderer.g().attr({'class': 'dxg-subvalue-indicators'});                return new ValueIndicatorsSet({                        root: owner,                        container: that._root,                        createIndicator: function(type, i) {                            return that._createIndicator(type, owner, 'dxg-subvalue-indicator', 'subvalue-indicator', i)                        }                    })            },            _prepareSubvalueIndicators: function() {                var that = this,                    target = that._subvalueIndicatorsSet,                    settings = that._prepareIndicatorSettings(that.option("subvalueIndicator") || {}, 'subvalueIndicatorType'),                    isRecreate;                if (!target)                    target = that._subvalueIndicatorsSet = that._createSubvalueIndicatorsSet();                isRecreate = settings.type !== target.type;                target.type = settings.type;                if (that._createIndicator(settings.type))                    target.render(settings, isRecreate)            },            _setupValue: function(value) {                this.__value = processValue(value, this.__value)            },            _setupSubvalues: function(subvalues) {                var vals = subvalues === undefined ? this.__subvalues : parseArrayOfNumbers(subvalues),                    i,                    ii,                    list;                if (vals === null)                    return;                for (i = 0, ii = vals.length, list = []; i < ii; ++i)                    list.push(processValue(vals[i], this.__subvalues[i]));                this.__subvalues = list            },            _updateValueIndicator: function() {                var that = this;                that._valueIndicator && that._valueIndicator.value(that.__value, that._noAnimation);                that._resizing || that.hideLoadingIndicator()            },            _updateSubvalueIndicators: function() {                var that = this;                that._subvalueIndicatorsSet && that._subvalueIndicatorsSet.values(that.__subvalues, that._noAnimation);                that._resizing || that.hideLoadingIndicator()            },            value: function(arg) {                var that = this;                if (arg !== undefined) {                    that._setupValue(arg);                    that._updateValueIndicator();                    that.option(OPTION_VALUE, that.__value);                    return that                }                return that.__value            },            subvalues: function(arg) {                var that = this;                if (arg !== undefined) {                    if (that.__subvalues !== null) {                        that._setupSubvalues(arg);                        that._updateSubvalueIndicators();                        that.option(OPTION_SUBVALUES, that.__subvalues)                    }                    return that                }                return that.__subvalues !== null ? that.__subvalues.slice() : undefined            },            _valueChangedHandler: function(name, val) {                var that = this;                switch (name) {                    case OPTION_VALUE:                        that._setupValue(val);                        that._updateValueIndicator();                        that.option(OPTION_VALUE, that.__value);                        return true;                    case OPTION_SUBVALUES:                        if (that.__subvalues !== null) {                            that._setupSubvalues(val);                            that._updateSubvalueIndicators();                            that.option(OPTION_SUBVALUES, that.__subvalues);                            return true                        }                        return false;                    default:                        return false                }            },            _optionChanged: function(args) {                var that = this;                if (that._valueChangedHandler(args.name, args.value, args.previousValue))                    return;                if (args.name === "scale") {                    that._setupDomain();                    that._invalidate()                }                else                    that.callBase.apply(that, arguments)            },            _optionValuesEqual: function(name, oldValue, newValue) {                var result;                switch (name) {                    case OPTION_VALUE:                        result = oldValue === newValue;                        break;                    case OPTION_SUBVALUES:                        result = compareArrays(oldValue, newValue);                        break;                    default:                        result = this.callBase.apply(this, arguments);                        break                }                return result            },            _applyMainLayout: null,            _getElementLayout: null,            _createScale: function(parameters) {                return _factory[this._factoryMethods.scale](parameters)            },            _createRangeContainer: function(parameters) {                return _factory[this._factoryMethods.rangeContainer](parameters)            },            _createIndicator: function(type, owner, className, trackerType, trackerIndex, _strict) {                var that = this,                    indicator = _factory[that._factoryMethods.indicator]({                        renderer: that._renderer,                        translator: that._translator,                        notifiers: that._notifiers,                        owner: owner,                        tracker: that._tracker,                        className: className                    }, type, _strict);                if (indicator) {                    indicator.type = type;                    indicator._trackerInfo = {                        type: trackerType,                        index: trackerIndex                    }                }                return indicator            },            _getApproximateScreenRange: null        });        DX.viz.gauges.dxGauge.prototype._factory = DX.utils.clone(DX.viz.gauges.dxBaseGauge.prototype._factory);        DX.viz.gauges.dxGauge.prototype._factory.createThemeManager = function() {            return new DX.viz.gauges.__internals.ThemeManager        };        function valueGetter(arg) {            return arg ? arg.value : NaN        }        function setupValues(that, fieldName, optionItems) {            var currentValues = that[fieldName],                newValues = _isArray(optionItems) ? _map(optionItems, valueGetter) : [],                i = 0,                ii = newValues.length,                list = [];            for (; i < ii; ++i)                list.push(processValue(newValues[i], currentValues[i]));            that[fieldName] = list        }        function selectMode(gauge) {            if (gauge.option(OPTION_VALUE) === undefined && gauge.option(OPTION_SUBVALUES) === undefined)                if (gauge.option('valueIndicators') !== undefined) {                    disableDefaultMode(gauge);                    selectHardMode(gauge)                }        }        function disableDefaultMode(that) {            that.value = that.subvalues = _noop;            that._setupValue = that._setupSubvalues = that._updateValueIndicator = that._updateSubvalueIndicators = null        }        function selectHardMode(that) {            that._indicatorValues = [];            setupValues(that, '_indicatorValues', that.option('valueIndicators'));            that._valueIndicators = [];            that._valueChangedHandler = valueChangedHandler_hardMode;            that._updateActiveElements = updateActiveElements_hardMode;            that._prepareValueIndicators = prepareValueIndicators_hardMode;            that._disposeValueIndicators = disposeValueIndicators_hardMode;            that._cleanValueIndicators = cleanValueIndicators_hardMode;            that.indicatorValue = indicatorValue_hardMode        }        function valueChangedHandler_hardMode(name, val) {            if (name === 'valueIndicators') {                setupValues(this, '_indicatorValues', val);                this._invalidate();                return true            }            return false        }        function updateActiveElements_hardMode() {            var that = this;            _each(that._valueIndicators, function(_, valueIndicator) {                valueIndicator.value(that._indicatorValues[valueIndicator.index], that._noAnimation)            });            that._resizing || that.hideLoadingIndicator()        }        function prepareValueIndicators_hardMode() {            var that = this,                valueIndicators = that._valueIndicators || [],                userOptions = that.option('valueIndicators'),                optionList = [],                i = 0,                ii;            for (ii = _isArray(userOptions) ? userOptions.length : 0; i < ii; ++i)                optionList.push(userOptions[i]);            for (ii = valueIndicators.length; i < ii; ++i)                optionList.push(null);            var newValueIndicators = [];            _each(optionList, function(i, userSettings) {                var valueIndicator = valueIndicators[i];                if (!userSettings) {                    valueIndicator && valueIndicator.dispose();                    return                }                var settings = that._prepareIndicatorSettings(userSettings, "valueIndicatorType");                if (valueIndicator && valueIndicator.type !== settings.type) {                    valueIndicator.dispose();                    valueIndicator = null                }                if (!valueIndicator)                    valueIndicator = that._createIndicator(settings.type, that._root, 'dxg-value-indicator', 'value-indicator', i, true);                if (valueIndicator) {                    valueIndicator.index = i;                    valueIndicator.render(settings);                    newValueIndicators.push(valueIndicator)                }            });            that._valueIndicators = newValueIndicators;            return that._valueIndicators        }        function disposeValueIndicators_hardMode() {            _each(this._valueIndicators, function(_, valueIndicator) {                valueIndicator.dispose()            });            this._valueIndicators = null        }        function cleanValueIndicators_hardMode() {            _each(this._valueIndicators, function(_, valueIndicator) {                valueIndicator.clean()            })        }        function indicatorValue_hardMode(index, value) {            return accessPointerValue(this, this._valueIndicators, this._indicatorValues, index, value)        }        function accessPointerValue(that, pointers, values, index, value) {            if (value !== undefined) {                if (values[index] !== undefined) {                    values[index] = processValue(value, values[index]);                    pointers[index] && pointers[index].value(values[index]);                    that._resizing || that.hideLoadingIndicator()                }                return that            }            else                return values[index]        }        function compareArrays(array1, array2) {            var i,                ii;            if (array1 === array2)                return true;            if (_isArray(array1) && _isArray(array2) && array1.length === array2.length) {                for (i = 0, ii = array1.length; i < ii; ++i)                    if (_abs(array1[i] - array2[i]) > 1E-8)                        return false;                return true            }            return false        }        function ValueIndicatorsSet(parameters) {            this._parameters = parameters;            this._indicators = []        }        ValueIndicatorsSet.prototype = {            costructor: ValueIndicatorsSet,            dispose: function() {                var that = this;                _each(that._indicators, function(_, indicator) {                    indicator.dispose()                });                that._parameters = that._options = that._indicators = that._colorPalette = that._palette = null;                return that            },            clean: function() {                var that = this;                that._parameters.root.remove();                that._sample && that._sample.clean().dispose();                _each(that._indicators, function(_, indicator) {                    indicator.clean()                });                that._sample = that._options = that._palette = null;                return that            },            render: function(options, isRecreate) {                var that = this;                that._options = options;                that._sample = that._parameters.createIndicator(that.type);                that._sample.render(options);                that.enabled = that._sample.enabled;                that._palette = _isDefined(options.palette) ? new DX.viz.core.Palette(options.palette) : null;                if (that.enabled) {                    that._parameters.root.append(that._parameters.container);                    that._generatePalette(that._indicators.length);                    that._indicators = _map(that._indicators, function(indicator, i) {                        if (isRecreate) {                            indicator.dispose();                            indicator = that._parameters.createIndicator(that.type, i)                        }                        indicator.render(that._getIndicatorOptions(i));                        return indicator                    })                }                return that            },            getOffset: function() {                return _Number(this._options.offset) || 0            },            resize: function(layout) {                var that = this;                that._layout = layout;                _each(that._indicators, function(_, indicator) {                    indicator.resize(layout)                });                return that            },            measure: function(layout) {                return this._sample.measure(layout)            },            _getIndicatorOptions: function(index) {                var result = this._options;                if (this._colorPalette)                    result = _extend({}, result, {color: this._colorPalette[index]});                return result            },            _generatePalette: function(count) {                var that = this,                    colors = null;                if (that._palette) {                    colors = [];                    that._palette.reset();                    var i = 0;                    for (; i < count; ++i)                        colors.push(that._palette.getNextColor())                }                that._colorPalette = colors            },            _adjustIndicatorsCount: function(count) {                var that = this,                    indicators = that._indicators,                    i,                    ii,                    indicator,                    indicatorsLen = indicators.length;                if (indicatorsLen > count) {                    for (i = count, ii = indicatorsLen; i < ii; ++i)                        indicators[i].clean().dispose();                    that._indicators = indicators.slice(0, count);                    that._generatePalette(indicators.length)                }                else if (indicatorsLen < count) {                    that._generatePalette(count);                    for (i = indicatorsLen, ii = count; i < ii; ++i) {                        indicator = that._parameters.createIndicator(that.type, i);                        indicator.render(that._getIndicatorOptions(i)).resize(that._layout);                        indicators.push(indicator)                    }                }            },            values: function(arg, _noAnimation) {                var that = this;                if (!that.enabled)                    return;                if (arg !== undefined) {                    if (!_isArray(arg))                        arg = _isFinite(arg) ? [Number(arg)] : null;                    if (arg) {                        that._adjustIndicatorsCount(arg.length);                        _each(that._indicators, function(i, indicator) {                            indicator.value(arg[i], _noAnimation)                        })                    }                    return that                }                return _map(that._indicators, function(indicator) {                        return indicator.value()                    })            }        }    })(DevExpress, jQuery);    /*! Module viz-gauges, file circularGauge.js */    (function(DX, $, undefined) {        var _isFinite = isFinite,            _Number = Number,            _normalizeAngle = DX.utils.normalizeAngle,            _getCosAndSin = DX.utils.getCosAndSin,            _abs = Math.abs,            _max = Math.max,            _min = Math.min,            _round = Math.round,            _each = $.each,            PI = Math.PI;        function getSides(startAngle, endAngle) {            var startCosSin = _getCosAndSin(startAngle),                endCosSin = _getCosAndSin(endAngle),                startCos = startCosSin.cos,                startSin = startCosSin.sin,                endCos = endCosSin.cos,                endSin = endCosSin.sin;            return {                    left: startSin <= 0 && endSin >= 0 || startSin <= 0 && endSin <= 0 && startCos <= endCos || startSin >= 0 && endSin >= 0 && startCos >= endCos ? -1 : _min(startCos, endCos, 0),                    right: startSin >= 0 && endSin <= 0 || startSin >= 0 && endSin >= 0 && startCos >= endCos || startSin <= 0 && endSin <= 0 && startCos <= endCos ? 1 : _max(startCos, endCos, 0),                    up: startCos <= 0 && endCos >= 0 || startCos <= 0 && endCos <= 0 && startSin >= endSin || startCos >= 0 && endCos >= 0 && startSin <= endSin ? -1 : -_max(startSin, endSin, 0),                    down: startCos >= 0 && endCos <= 0 || startCos >= 0 && endCos >= 0 && startSin <= endSin || startCos <= 0 && endCos <= 0 && startSin >= endSin ? 1 : -_min(startSin, endSin, 0)                }        }        DX.registerComponent("dxCircularGauge", DX.viz.gauges, DX.viz.gauges.dxGauge.inherit({            _rootClass: "dxg-circular-gauge",            _factoryMethods: {                scale: 'createCircularScale',                rangeContainer: 'createCircularRangeContainer',                indicator: 'createCircularIndicator'            },            _setupCodomain: function() {                var that = this,                    geometry = that.option("geometry") || {},                    startAngle = geometry.startAngle,                    endAngle = geometry.endAngle,                    sides;                startAngle = _isFinite(startAngle) ? _normalizeAngle(startAngle) : 225;                endAngle = _isFinite(endAngle) ? _normalizeAngle(endAngle) : -45;                if (_abs(startAngle - endAngle) < 1) {                    endAngle -= 360;                    sides = {                        left: -1,                        up: -1,                        right: 1,                        down: 1                    }                }                else {                    startAngle < endAngle && (endAngle -= 360);                    sides = getSides(startAngle, endAngle)                }                that._area = {                    x: 0,                    y: 0,                    radius: 100,                    startCoord: startAngle,                    endCoord: endAngle,                    scaleRadius: geometry.scaleRadius > 0 ? _Number(geometry.scaleRadius) : undefined,                    sides: sides                };                that._translator.setCodomain(startAngle, endAngle)            },            _measureMainElements: function(elements) {                var that = this,                    radius = that._area.radius,                    maxRadius = 0,                    minRadius = Infinity,                    maxHorizontalOffset = 0,                    maxVerticalOffset = 0,                    maxInverseHorizontalOffset = 0,                    maxInverseVerticalOffset = 0;                _each(elements, function(_, element) {                    var bounds = element.measure({radius: radius - element.getOffset()});                    bounds.min > 0 && (minRadius = _min(minRadius, bounds.min));                    bounds.max > 0 && (maxRadius = _max(maxRadius, bounds.max));                    bounds.horizontalOffset > 0 && (maxHorizontalOffset = _max(maxHorizontalOffset, bounds.max + bounds.horizontalOffset));                    bounds.verticalOffset > 0 && (maxVerticalOffset = _max(maxVerticalOffset, bounds.max + bounds.verticalOffset));                    bounds.inverseHorizontalOffset > 0 && (maxInverseHorizontalOffset = _max(maxInverseHorizontalOffset, bounds.inverseHorizontalOffset));                    bounds.inverseVerticalOffset > 0 && (maxInverseVerticalOffset = _max(maxInverseVerticalOffset, bounds.inverseVerticalOffset))                });                maxHorizontalOffset = _max(maxHorizontalOffset - maxRadius, 0);                maxVerticalOffset = _max(maxVerticalOffset - maxRadius, 0);                return {                        minRadius: minRadius,                        maxRadius: maxRadius,                        horizontalMargin: maxHorizontalOffset,                        verticalMargin: maxVerticalOffset,                        inverseHorizontalMargin: maxInverseHorizontalOffset,                        inverseVerticalMargin: maxInverseVerticalOffset                    }            },            _applyMainLayout: function(elements) {                var that = this,                    measurements = that._measureMainElements(elements),                    area = that._area,                    sides = area.sides,                    margins = {                        left: (sides.left < -0.1 ? measurements.horizontalMargin : measurements.inverseHorizontalMargin) || 0,                        right: (sides.right > 0.1 ? measurements.horizontalMargin : measurements.inverseHorizontalMargin) || 0,                        top: (sides.up < -0.1 ? measurements.verticalMargin : measurements.inverseVerticalMargin) || 0,                        bottom: (sides.down > 0.1 ? measurements.verticalMargin : measurements.inverseVerticalMargin) || 0                    },                    rect = that._layoutManager.selectRectByAspectRatio((sides.down - sides.up) / (sides.right - sides.left), margins),                    radius = _min(rect.width() / (sides.right - sides.left), rect.height() / (sides.down - sides.up)),                    x,                    y,                    scaler = (measurements.maxRadius - area.radius + area.scaleRadius) / radius;                if (0 < scaler && scaler < 1) {                    rect = rect.scale(scaler);                    radius *= scaler                }                radius = radius - measurements.maxRadius + area.radius;                x = rect.left - rect.width() * sides.left / (sides.right - sides.left);                y = rect.top - rect.height() * sides.up / (sides.down - sides.up);                area.x = _round(x);                area.y = _round(y);                area.radius = radius;                rect.left -= margins.left;                rect.right += margins.right;                rect.top -= margins.top;                rect.bottom += margins.bottom;                that._layoutManager.setRect(rect)            },            _getElementLayout: function(offset) {                return {                        x: this._area.x,                        y: this._area.y,                        radius: _round(this._area.radius - offset)                    }            },            _getApproximateScreenRange: function() {                var that = this,                    area = that._area,                    r = _min(that._canvas.width / (area.sides.right - area.sides.left), that._canvas.height / (area.sides.down - area.sides.up));                r > area.totalRadius && (r = area.totalRadius);                r = 0.8 * r;                return -that._translator.getCodomainRange() * r * PI / 180            },            _getDefaultSize: function() {                return {                        width: 300,                        height: 300                    }            }        }));        DX.viz.gauges.dxCircularGauge.prototype._factory = DX.utils.clone(DX.viz.gauges.dxBaseGauge.prototype._factory);        DX.viz.gauges.dxCircularGauge.prototype._factory.createThemeManager = function() {            var themeManager = new DX.viz.gauges.__internals.ThemeManager;            themeManager._subTheme = "_circular";            return themeManager        }    })(DevExpress, jQuery);    /*! Module viz-gauges, file linearGauge.js */    (function(DX, $, undefined) {        var _String = String,            _Number = Number,            _max = Math.max,            _min = Math.min,            _round = Math.round,            _each = $.each;        DX.registerComponent("dxLinearGauge", DX.viz.gauges, DX.viz.gauges.dxGauge.inherit({            _rootClass: 'dxg-linear-gauge',            _factoryMethods: {                scale: 'createLinearScale',                rangeContainer: 'createLinearRangeContainer',                indicator: 'createLinearIndicator'            },            _setupCodomain: function() {                var that = this,                    geometry = that.option('geometry') || {},                    vertical = _String(geometry.orientation).toLowerCase() === 'vertical';                that._area = {                    vertical: vertical,                    x: 0,                    y: 0,                    startCoord: -100,                    endCoord: 100,                    scaleSize: geometry.scaleSize > 0 ? _Number(geometry.scaleSize) : undefined                };                that._scale.vertical = vertical;                that._rangeContainer.vertical = vertical            },            _measureMainElements: function(elements) {                var that = this,                    x = that._area.x,                    y = that._area.y,                    minBound = 1000,                    maxBound = 0,                    indent = 0;                _each(elements, function(_, element) {                    var bounds = element.measure({                            x: x + element.getOffset(),                            y: y + element.getOffset()                        });                    maxBound = _max(maxBound, bounds.max);                    minBound = _min(minBound, bounds.min);                    bounds.indent > 0 && (indent = _max(indent, bounds.indent))                });                return {                        minBound: minBound,                        maxBound: maxBound,                        indent: indent                    }            },            _applyMainLayout: function(elements) {                var that = this,                    measurements = that._measureMainElements(elements),                    area = that._area,                    rect,                    offset,                    counterSize = area.scaleSize + 2 * measurements.indent;                if (area.vertical) {                    rect = that._layoutManager.selectRectBySizes({                        width: measurements.maxBound - measurements.minBound,                        height: counterSize                    });                    offset = rect.horizontalMiddle() - (measurements.minBound + measurements.maxBound) / 2;                    area.startCoord = rect.bottom - measurements.indent;                    area.endCoord = rect.top + measurements.indent;                    area.x = _round(area.x + offset)                }                else {                    rect = that._layoutManager.selectRectBySizes({                        height: measurements.maxBound - measurements.minBound,                        width: counterSize                    });                    offset = rect.verticalMiddle() - (measurements.minBound + measurements.maxBound) / 2;                    area.startCoord = rect.left + measurements.indent;                    area.endCoord = rect.right - measurements.indent;                    area.y = _round(area.y + offset)                }                that._translator.setCodomain(area.startCoord, area.endCoord);                that._layoutManager.setRect(rect)            },            _getElementLayout: function(offset) {                return {                        x: _round(this._area.x + offset),                        y: _round(this._area.y + offset)                    }            },            _getApproximateScreenRange: function() {                var that = this,                    area = that._area,                    s = area.vertical ? that._canvas.height : that._canvas.width;                s > area.totalSize && (s = area.totalSize);                s = s * 0.8;                return s            },            _getDefaultSize: function() {                var geometry = this.option('geometry') || {};                if (geometry.orientation === 'vertical')                    return {                            width: 100,                            height: 300                        };                else                    return {                            width: 300,                            height: 100                        }            }        }));        DX.viz.gauges.dxLinearGauge.prototype._factory = DX.utils.clone(DX.viz.gauges.dxBaseGauge.prototype._factory);        DX.viz.gauges.dxLinearGauge.prototype._factory.createThemeManager = function() {            var themeManager = new DX.viz.gauges.__internals.ThemeManager;            themeManager._subTheme = '_linear';            return themeManager        }    })(DevExpress, jQuery);    /*! Module viz-gauges, file barGauge.js */    (function(DX, $, undefined) {        var PI_DIV_180 = Math.PI / 180,            _abs = Math.abs,            _round = Math.round,            _floor = Math.floor,            _min = Math.min,            _max = Math.max,            _isArray = DX.utils.isArray,            _convertAngleToRendererSpace = DX.utils.convertAngleToRendererSpace,            _getCosAndSin = DX.utils.getCosAndSin,            _patchFontOptions = DX.viz.core.utils.patchFontOptions,            _Number = Number,            _isFinite = isFinite,            _noop = $.noop,            _extend = $.extend,            _getSampleText = DX.viz.gauges.__internals.getSampleText,            _formatValue = DX.viz.gauges.__internals.formatValue,            _Palette = DX.viz.core.Palette,            OPTION_VALUES = "values";        var dxBarGauge = DX.viz.gauges.dxBaseGauge.inherit({                _rootClass: "dxbg-bar-gauge",                _initCore: function() {                    var that = this;                    that.callBase.apply(that, arguments);                    that._barsGroup = that._renderer.g().attr({"class": "dxbg-bars"});                    that._values = [];                    that._context = {                        renderer: that._renderer,                        translator: that._translator,                        tracker: that._tracker,                        group: that._barsGroup                    };                    that._animateStep = function(pos) {                        var bars = that._bars,                            i,                            ii;                        for (i = 0, ii = bars.length; i < ii; ++i)                            bars[i].animate(pos)                    };                    that._animateComplete = function() {                        var bars = that._bars,                            i,                            ii;                        for (i = 0, ii = bars.length; i < ii; ++i)                            bars[i].endAnimation();                        that._notifiers.ready()                    }                },                _disposeCore: function() {                    var that = this;                    that._barsGroup = that._values = that._context = that._animateStep = that._animateComplete = null;                    that.callBase.apply(that, arguments)                },                _setupDomainCore: function() {                    var that = this,                        startValue = that.option("startValue"),                        endValue = that.option("endValue");                    _isFinite(startValue) || (startValue = 0);                    _isFinite(endValue) || (endValue = 100);                    that._translator.setDomain(startValue, endValue);                    that._baseValue = that._translator.adjust(that.option("baseValue"));                    _isFinite(that._baseValue) || (that._baseValue = startValue < endValue ? startValue : endValue)                },                _getDefaultSize: function() {                    return {                            width: 300,                            height: 300                        }                },                _setupCodomain: DX.viz.gauges.dxCircularGauge.prototype._setupCodomain,                _getApproximateScreenRange: function() {                    var that = this,                        sides = that._area.sides,                        width = that._canvas.width / (sides.right - sides.left),                        height = that._canvas.height / (sides.down - sides.up),                        r = width < height ? width : height;                    return -that._translator.getCodomainRange() * r * PI_DIV_180                },                _setupAnimationSettings: function() {                    var that = this;                    that.callBase.apply(that, arguments);                    if (that._animationSettings) {                        that._animationSettings.step = that._animateStep;                        that._animationSettings.complete = that._animateComplete                    }                },                _cleanContent: function() {                    var that = this,                        i,                        ii;                    that._barsGroup.remove();                    that._animationSettings && that._barsGroup.stopAnimation();                    for (i = 0, ii = that._bars ? that._bars.length : 0; i < ii; ++i)                        that._bars[i].dispose();                    that._palette = that._bars = null                },                _renderContent: function() {                    var that = this,                        labelOptions = that.option("label"),                        text,                        bbox,                        context = that._context;                    that._barsGroup.append(that._root);                    context.textEnabled = labelOptions === undefined || labelOptions && (!("visible" in labelOptions) || labelOptions.visible);                    if (context.textEnabled) {                        context.textColor = labelOptions && labelOptions.font && labelOptions.font.color || null;                        labelOptions = _extend(true, {}, that._themeManager.theme().label, labelOptions);                        context.formatOptions = {                            format: labelOptions.format !== undefined || labelOptions.precision !== undefined ? labelOptions.format : that._defaultFormatOptions.format,                            precision: labelOptions.format !== undefined || labelOptions.precision !== undefined ? labelOptions.precision : that._defaultFormatOptions.precision,                            customizeText: labelOptions.customizeText                        };                        context.textOptions = {align: "center"};                        context.fontStyles = _patchFontOptions(_extend({}, that._themeManager.theme().label.font, labelOptions.font, {color: null}));                        that._textIndent = labelOptions.indent > 0 ? _Number(labelOptions.indent) : 0;                        context.lineWidth = labelOptions.connectorWidth > 0 ? _Number(labelOptions.connectorWidth) : 0;                        context.lineColor = labelOptions.connectorColor || null;                        text = that._renderer.text(_getSampleText(that._translator, context.formatOptions), 0, 0).attr(context.textOptions).css(context.fontStyles).append(that._barsGroup);                        bbox = text.getBBox();                        text.remove();                        context.textVerticalOffset = -bbox.y - bbox.height / 2;                        context.textWidth = bbox.width;                        context.textHeight = bbox.height                    }                    DX.viz.gauges.dxCircularGauge.prototype._applyMainLayout.call(that);                    that._renderBars()                },                _measureMainElements: function() {                    var result = {maxRadius: this._area.radius};                    if (this._context.textEnabled) {                        result.horizontalMargin = this._context.textWidth;                        result.verticalMargin = this._context.textHeight                    }                    return result                },                _renderBars: function() {                    var that = this,                        options = _extend({}, that._themeManager.theme(), that.option()),                        relativeInnerRadius,                        radius,                        area = that._area;                    that._palette = new _Palette(options.palette, {                        stepHighlight: 50,                        theme: that._themeManager.themeName()                    });                    relativeInnerRadius = options.relativeInnerRadius > 0 && options.relativeInnerRadius < 1 ? _Number(options.relativeInnerRadius) : 0.1;                    radius = area.radius;                    if (that._context.textEnabled) {                        that._textIndent = _round(_min(that._textIndent, radius / 2));                        radius -= that._textIndent                    }                    that._outerRadius = _floor(radius);                    that._innerRadius = _floor(radius * relativeInnerRadius);                    that._barSpacing = options.barSpacing > 0 ? _Number(options.barSpacing) : 0;                    _extend(that._context, {                        backgroundColor: options.backgroundColor,                        x: area.x,                        y: area.y,                        startAngle: area.startCoord,                        endAngle: area.endCoord,                        baseAngle: that._translator.translate(that._baseValue)                    });                    that._bars = [];                    that._updateValues(that.option(OPTION_VALUES))                },                _arrangeBars: function(count) {                    var that = this,                        radius = that._outerRadius - that._innerRadius,                        context = that._context,                        spacing,                        _count,                        unitOffset,                        i;                    context.barSize = count > 0 ? _max((radius - (count - 1) * that._barSpacing) / count, 1) : 0;                    spacing = count > 1 ? _max(_min((radius - count * context.barSize) / (count - 1), that._barSpacing), 0) : 0;                    _count = _min(_floor((radius + spacing) / context.barSize), count);                    that._setBarsCount(_count);                    radius = that._outerRadius;                    context.textRadius = radius + that._textIndent;                    that._palette.reset();                    unitOffset = context.barSize + spacing;                    for (i = 0; i < _count; ++i, radius -= unitOffset)                        that._bars[i].arrange({                            radius: radius,                            color: that._palette.getNextColor()                        })                },                _setBarsCount: function(count) {                    var that = this,                        i,                        ii;                    if (that._bars.length > count) {                        for (i = count, ii = that._bars.length; i < ii; ++i)                            that._bars[i].dispose();                        that._bars.splice(count, ii - count)                    }                    else if (that._bars.length < count)                        for (i = that._bars.length, ii = count; i < ii; ++i)                            that._bars.push(new BarWrapper(i, that._context));                    if (that._bars.length > 0) {                        if (that._dummyBackground) {                            that._dummyBackground.dispose();                            that._dummyBackground = null                        }                    }                    else {                        if (!that._dummyBackground)                            that._dummyBackground = that._renderer.arc().attr({"stroke-linejoin": "round"}).append(that._barsGroup);                        that._dummyBackground.attr({                            x: that._context.x,                            y: that._context.y,                            outerRadius: that._outerRadius,                            innerRadius: that._innerRadius,                            startAngle: that._context.endAngle,                            endAngle: that._context.startAngle,                            fill: that._context.backgroundColor                        })                    }                },                _updateBars: function(values) {                    var that = this,                        i,                        ii;                    for (i = 0, ii = that._bars.length; i < ii; ++i)                        that._bars[i].setValue(values[i])                },                _animateBars: function(values) {                    var that = this,                        i,                        ii = that._bars.length;                    if (ii > 0) {                        for (i = 0; i < ii; ++i)                            that._bars[i].beginAnimation(values[i]);                        that._barsGroup.animate({_: 0}, that._animationSettings)                    }                },                _updateValues: function(values) {                    var that = this,                        list = _isArray(values) && values || _isFinite(values) && [values] || [],                        i,                        ii = list.length,                        value,                        barValues = [],                        immediateReady = true;                    that._values.length = ii;                    for (i = 0; i < ii; ++i) {                        value = list[i];                        that._values[i] = value = _Number(_isFinite(value) ? value : that._values[i]);                        if (_isFinite(value))                            barValues.push(value)                    }                    that._notifiers.dirty();                    that._animationSettings && that._barsGroup.stopAnimation();                    if (that._bars) {                        that._arrangeBars(barValues.length);                        if (that._animationSettings && !that._noAnimation) {                            immediateReady = false;                            that._animateBars(barValues)                        }                        else                            that._updateBars(barValues)                    }                    immediateReady && that._notifiers.ready();                    if (!that._resizing) {                        that.option(OPTION_VALUES, that._values);                        that.hideLoadingIndicator()                    }                },                values: function(arg) {                    if (arg !== undefined) {                        this._updateValues(arg);                        return this                    }                    else                        return this._values.slice(0)                },                _optionChanged: function(args) {                    if (args.name === OPTION_VALUES)                        this._updateValues(args.value);                    else                        this.callBase.apply(this, arguments)                },                _optionValuesEqual: function(name, oldValue, newValue) {                    if (name === OPTION_VALUES)                        return compareArrays(oldValue, newValue);                    else                        return this.callBase.apply(this, arguments)                }            });        DX.registerComponent("dxBarGauge", DX.viz.gauges, dxBarGauge);        var ThemeManager = DX.viz.gauges.__internals.ThemeManager.inherit({                _themeSection: "barGauge",                _fontFields: ["label.font", "title.font", "tooltip.font", "loadingIndicator.font"]            });        dxBarGauge.prototype._factory = DX.utils.clone(DX.viz.gauges.dxBaseGauge.prototype._factory);        dxBarGauge.prototype._factory.createThemeManager = function() {            return new ThemeManager        };        var BarWrapper = function(index, context) {                var that = this;                that._context = context;                that._background = context.renderer.arc().attr({                    "stroke-linejoin": "round",                    fill: context.backgroundColor                }).append(context.group);                that._bar = context.renderer.arc().attr({"stroke-linejoin": "round"}).append(context.group);                if (context.textEnabled) {                    that._line = context.renderer.path([], "line").attr({"stroke-width": context.lineWidth}).append(context.group);                    that._text = context.renderer.text("", 0, 0).css(context.fontStyles).attr(context.textOptions).append(context.group)                }                that._tracker = context.renderer.arc().attr({"stroke-linejoin": "round"});                context.tracker.attach(that._tracker, that, {index: index});                that._index = index;                that._angle = context.baseAngle;                that._settings = {                    x: context.x,                    y: context.y,                    startAngle: context.baseAngle,                    endAngle: context.baseAngle                }            };        _extend(BarWrapper.prototype, {            dispose: function() {                var that = this;                that._background.dispose();                that._bar.dispose();                if (that._context.textEnabled) {                    that._line.dispose();                    that._text.dispose()                }                that._context.tracker.detach(that._tracker);                that._context = that._settings = that._background = that._bar = that._line = that._text = that._tracker = null;                return that            },            arrange: function(options) {                var that = this,                    context = that._context;                that._settings.outerRadius = options.radius;                that._settings.innerRadius = options.radius - context.barSize;                that._background.attr(_extend({}, that._settings, {                    startAngle: context.endAngle,                    endAngle: context.startAngle                }));                that._bar.attr(that._settings);                that._tracker.attr(that._settings);                that._color = options.color;                that._bar.attr({fill: options.color});                if (context.textEnabled) {                    that._line.attr({                        points: [context.x, context.y - that._settings.innerRadius, context.x, context.y - context.textRadius],                        stroke: context.lineColor || options.color                    }).sharp();                    that._text.css({fill: context.textColor || options.color})                }                return that            },            getTooltipParameters: function() {                var that = this,                    cossin = _getCosAndSin((that._angle + that._context.baseAngle) / 2);                return {                        x: _round(that._context.x + (that._settings.outerRadius + that._settings.innerRadius) / 2 * cossin.cos),                        y: _round(that._context.y - (that._settings.outerRadius + that._settings.innerRadius) / 2 * cossin.sin),                        offset: 0,                        color: that._color,                        value: that._value                    }            },            setAngle: function(angle) {                var that = this,                    cossin;                that._angle = angle;                setAngles(that._settings, that._context.baseAngle, that._angle);                that._bar.attr(that._settings);                that._tracker.attr(that._settings);                if (that._context.textEnabled) {                    that._line.rotate(_convertAngleToRendererSpace(that._angle), that._context.x, that._context.y);                    cossin = _getCosAndSin(that._angle);                    that._text.attr({                        text: _formatValue(that._value, that._context.formatOptions, {index: that._index}),                        x: that._context.x + (that._context.textRadius + that._context.textWidth * 0.6) * cossin.cos,                        y: that._context.y - (that._context.textRadius + that._context.textHeight * 0.6) * cossin.sin + that._context.textVerticalOffset                    })                }                return that            },            _processValue: function(value) {                this._value = this._context.translator.adjust(value);                return this._context.translator.translate(this._value)            },            setValue: function(value) {                return this.setAngle(this._processValue(value))            },            beginAnimation: function(value) {                var that = this,                    angle = this._processValue(value);                if (!compareFloats(that._angle, angle)) {                    that._start = that._angle;                    that._delta = angle - that._angle;                    that._tracker.attr({visibility: "hidden"});                    if (that._context.textEnabled) {                        that._line.attr({visibility: "hidden"});                        that._text.attr({visibility: "hidden"})                    }                }                else {                    that.animate = _noop;                    that.setAngle(that._angle)                }            },            animate: function(pos) {                var that = this;                that._angle = that._start + that._delta * pos;                setAngles(that._settings, that._context.baseAngle, that._angle);                that._bar.attr(that._settings)            },            endAnimation: function() {                var that = this;                if (that._delta !== undefined) {                    if (compareFloats(that._angle, that._start + that._delta)) {                        that._tracker.attr({visibility: null});                        if (that._context.textEnabled) {                            that._line.attr({visibility: null});                            that._text.attr({visibility: null})                        }                        that.setAngle(that._angle)                    }                }                else                    delete that.animate;                delete that._start;                delete that._delta            }        });        function setAngles(target, angle1, angle2) {            target.startAngle = angle1 < angle2 ? angle1 : angle2;            target.endAngle = angle1 < angle2 ? angle2 : angle1        }        function compareFloats(value1, value2) {            return _abs(value1 - value2) < 0.0001        }        function compareArrays(array1, array2) {            if (array1 === array2)                return true;            if (_isArray(array1) && _isArray(array2) && array1.length === array2.length) {                for (var i = 0, ii = array1.length; i < ii; ++i)                    if (!compareFloats(array1[i], array2[i]))                        return false;                return true            }            return false        }        var __BarWrapper = BarWrapper;        DX.viz.gauges.__tests.BarWrapper = __BarWrapper;        DX.viz.gauges.__tests.stubBarWrapper = function(barWrapperType) {            BarWrapper = barWrapperType        };        DX.viz.gauges.__tests.restoreBarWrapper = function() {            BarWrapper = __BarWrapper        }    })(DevExpress, jQuery);    /*! Module viz-gauges, file tracker.js */    (function(DX, $, undefined) {        var _abs = Math.abs,            TOOLTIP_SHOW_DELAY = 300,            TOOLTIP_HIDE_DELAY = 300,            TOOLTIP_TOUCH_SHOW_DELAY = 400,            TOOLTIP_TOUCH_HIDE_DELAY = 300;        DX.viz.gauges.__internals.Tracker = DX.Class.inherit({            ctor: function(parameters) {                DX.utils.debug.assertParam(parameters, 'parameters');                DX.utils.debug.assertParam(parameters.renderer, 'parameters.renderer');                DX.utils.debug.assertParam(parameters.container, 'parameters.container');                var that = this;                that._container = parameters.container;                that._element = parameters.renderer.g().attr({                    'class': 'dxg-tracker',                    stroke: 'none',                    "stroke-width": 0,                    fill: '#000000',                    opacity: 0.0001                });                that._showTooltipCallback = function() {                    that._showTooltipTimeout = null;                    var target = that._tooltipEvent.target,                        data = $(target).data();                    that._targetEvent = null;                    if (that._tooltipTarget !== target && that._callbacks['tooltip-show'](data.target, data.info))                        that._tooltipTarget = target                };                that._hideTooltipCallback = function() {                    that._hideTooltipTimeout = null;                    that._targetEvent = null;                    if (that._tooltipTarget) {                        that._callbacks['tooltip-hide']();                        that._tooltipTarget = null                    }                };                that._dispose = function() {                    clearTimeout(that._showTooltipTimeout);                    clearTimeout(that._hideTooltipTimeout);                    that._showTooltipCallback = that._hideTooltipCallback = that._dispose = null                };                that._DEBUG_showTooltipTimeoutSet = that._DEBUG_showTooltipTimeoutCleared = that._DEBUG_hideTooltipTimeoutSet = that._DEBUG_hideTooltipTimeoutCleared = 0;                that.TOOLTIP_SHOW_DELAY = TOOLTIP_SHOW_DELAY;                that.TOOLTIP_HIDE_DELAY = TOOLTIP_HIDE_DELAY;                that.TOOLTIP_TOUCH_SHOW_DELAY = TOOLTIP_TOUCH_SHOW_DELAY;                that.TOOLTIP_TOUCH_HIDE_DELAY = TOOLTIP_TOUCH_HIDE_DELAY            },            dispose: function() {                var that = this;                that._dispose();                that.deactivate();                that._element.remove();                that._container = that._element = that._context = that._callbacks = null;                return that            },            activate: function() {                this._element.append(this._container);                return this            },            deactivate: function() {                this._element.remove().clear();                return this            },            attach: function(element, target, info) {                element.data({                    target: target,                    info: info                }).append(this._element);                return this            },            detach: function(element) {                element.remove();                return this            },            setTooltipState: function(state) {                var that = this,                    data;                that._element.off(tooltipMouseEvents).off(tooltipTouchEvents).off(tooltipMouseWheelEvents);                if (state) {                    data = {tracker: that};                    that._element.on(tooltipMouseEvents, data).on(tooltipTouchEvents, data).on(tooltipMouseWheelEvents, data)                }                return that            },            setCallbacks: function(callbacks) {                this._callbacks = callbacks;                return this            },            _showTooltip: function(event, delay) {                var that = this;                that._hideTooltipTimeout && ++that._DEBUG_hideTooltipTimeoutCleared;                clearTimeout(that._hideTooltipTimeout);                that._hideTooltipTimeout = null;                if (that._tooltipTarget === event.target)                    return;                clearTimeout(that._showTooltipTimeout);                that._tooltipEvent = event;                ++that._DEBUG_showTooltipTimeoutSet;                that._showTooltipTimeout = setTimeout(that._showTooltipCallback, delay)            },            _hideTooltip: function(delay) {                var that = this;                that._showTooltipTimeout && ++that._DEBUG_showTooltipTimeoutCleared;                clearTimeout(that._showTooltipTimeout);                that._showTooltipTimeout = null;                clearTimeout(that._hideTooltipTimeout);                if (delay) {                    ++that._DEBUG_hideTooltipTimeoutSet;                    that._hideTooltipTimeout = setTimeout(that._hideTooltipCallback, delay)                }                else                    that._hideTooltipCallback()            }        });        var tooltipMouseEvents = {                'mouseover.gauge-tooltip': handleTooltipMouseOver,                'mouseout.gauge-tooltip': handleTooltipMouseOut            };        var tooltipMouseMoveEvents = {'mousemove.gauge-tooltip': handleTooltipMouseMove};        var tooltipMouseWheelEvents = {'dxmousewheel.gauge-tooltip': handleTooltipMouseWheel};        var tooltipTouchEvents = {'touchstart.gauge-tooltip': handleTooltipTouchStart};        function handleTooltipMouseOver(event) {            var tracker = event.data.tracker;            tracker._x = event.pageX;            tracker._y = event.pageY;            tracker._element.off(tooltipMouseMoveEvents).on(tooltipMouseMoveEvents, event.data);            tracker._showTooltip(event, TOOLTIP_SHOW_DELAY)        }        function handleTooltipMouseMove(event) {            var tracker = event.data.tracker;            if (tracker._showTooltipTimeout && _abs(event.pageX - tracker._x) > 4 || _abs(event.pageY - tracker._y) > 4) {                tracker._x = event.pageX;                tracker._y = event.pageY;                tracker._showTooltip(event, TOOLTIP_SHOW_DELAY)            }        }        function handleTooltipMouseOut(event) {            var tracker = event.data.tracker;            tracker._element.off(tooltipMouseMoveEvents);            tracker._hideTooltip(TOOLTIP_HIDE_DELAY)        }        function handleTooltipMouseWheel(event) {            event.data.tracker._hideTooltip()        }        var active_touch_tooltip_tracker = null;        DX.viz.gauges.__internals.Tracker._DEBUG_reset = function() {            active_touch_tooltip_tracker = null        };        function handleTooltipTouchStart(event) {            event.preventDefault();            var tracker = active_touch_tooltip_tracker;            if (tracker && tracker !== event.data.tracker)                tracker._hideTooltip(TOOLTIP_TOUCH_HIDE_DELAY);            tracker = active_touch_tooltip_tracker = event.data.tracker;            tracker._showTooltip(event, TOOLTIP_TOUCH_SHOW_DELAY);            tracker._touch = true        }        function handleTooltipDocumentTouchStart() {            var tracker = active_touch_tooltip_tracker;            if (tracker) {                if (!tracker._touch) {                    tracker._hideTooltip(TOOLTIP_TOUCH_HIDE_DELAY);                    active_touch_tooltip_tracker = null                }                tracker._touch = null            }        }        function handleTooltipDocumentTouchEnd() {            var tracker = active_touch_tooltip_tracker;            if (tracker)                if (tracker._showTooltipTimeout) {                    tracker._hideTooltip(TOOLTIP_TOUCH_HIDE_DELAY);                    active_touch_tooltip_tracker = null                }        }        $(window.document).on({            'touchstart.gauge-tooltip': handleTooltipDocumentTouchStart,            'touchend.gauge-tooltip': handleTooltipDocumentTouchEnd        })    })(DevExpress, jQuery);    DevExpress.MOD_VIZ_GAUGES = true}if (!DevExpress.MOD_VIZ_RANGESELECTOR) {    if (!DevExpress.MOD_VIZ_CORE)        throw Error('Required module is not referenced: viz-core');    /*! Module viz-rangeselector, file namespaces.js */    (function(DevExpress) {        DevExpress.viz.rangeSelector = {}    })(DevExpress);    /*! Module viz-rangeselector, file utils.js */    (function($, DX, undefined) {        var dxUtils = DX.utils;        var findLessOrEqualValueIndex = function(values, value) {                if (!values || values.length === 0)                    return -1;                var minIndex = 0,                    maxIndex = values.length - 1;                while (maxIndex - minIndex > 1) {                    var index = minIndex + maxIndex >> 1;                    if (values[index] > value)                        maxIndex = index;                    else                        minIndex = index                }                return values[maxIndex] <= value ? maxIndex : minIndex            };        var findLessOrEqualValue = function(values, value) {                var index = findLessOrEqualValueIndex(values, value);                if (values && index >= 0 && index < values.length)                    return values[index];                return value            };        var findNearValue = function(values, value) {                var index = findLessOrEqualValueIndex(values, value);                if (values && index >= 0 && index < values.length) {                    if (index + 1 < values.length)                        if (dxUtils.isDate(value)) {                            if (values[index + 1].getTime() - value.getTime() < value.getTime() - values[index].getTime())                                index++                        }                        else if (values[index + 1] - value < value - values[index])                            index++;                    return values[index]                }                return value            };        var findGreaterOrEqualValue = function(values, value) {                var index = findLessOrEqualValueIndex(values, value);                if (values && index >= 0 && index < values.length) {                    if (values[index] < value && index + 1 < values.length)                        index++;                    return values[index]                }                return value            };        var getEventPageX = function(eventArgs) {                var result = 0;                if (eventArgs.pageX)                    result = eventArgs.pageX;                else if (eventArgs.originalEvent && eventArgs.originalEvent.pageX)                    result = eventArgs.originalEvent.pageX;                if (eventArgs.originalEvent && eventArgs.originalEvent.touches)                    if (eventArgs.originalEvent.touches.length > 0)                        result = eventArgs.originalEvent.touches[0].pageX;                    else if (eventArgs.originalEvent.changedTouches.length > 0)                        result = eventArgs.originalEvent.changedTouches[0].pageX;                return result            };        var truncateSelectedRange = function(value, scaleOptions) {                var isDiscrete = scaleOptions.type === 'discrete',                    categories = isDiscrete ? scaleOptions._categoriesInfo.categories : undefined,                    startValue = scaleOptions.startValue,                    endValue = scaleOptions.endValue,                    min,                    max,                    valueIndex;                if (isDiscrete) {                    valueIndex = $.inArray(value, categories);                    return valueIndex < 0 ? startValue : value                }                else                    min = startValue > endValue ? endValue : startValue,                    max = startValue > endValue ? startValue : endValue;                if (value < min)                    value = min;                if (value > max)                    value = max;                return value            };        DX.viz.rangeSelector.utils = {            findLessOrEqualValue: findLessOrEqualValue,            findNearValue: findNearValue,            findGreaterOrEqualValue: findGreaterOrEqualValue,            getEventPageX: getEventPageX,            truncateSelectedRange: truncateSelectedRange,            trackerSettings: {                fill: 'grey',                stroke: 'grey',                opacity: 0.0001            },            animationSettings: {duration: 250}        }    })(jQuery, DevExpress);    /*! Module viz-rangeselector, file baseVisualElementMethods.js */    (function(DX) {        DX.viz.rangeSelector.baseVisualElementMethods = {            init: function(renderer) {                this._renderer = renderer;                this._isDrawn = false            },            applyOptions: function(options) {                this._options = options || {};                this._applyOptions(this._options)            },            _applyOptions: function(){},            redraw: function(group) {                var that = this;                if (!that._isDrawn) {                    that._isDrawn = that._draw(group || that._group) !== false;                    if (group)                        that._group = group                }                else                    that._update(group || that._group)            },            isDrawn: function() {                return !!this._isDrawn            },            isInitialized: function() {                return !!this._options            },            _draw: function(){},            _update: function(group) {                group.clear();                this._draw(group)            }        }    })(DevExpress);    /*! Module viz-rangeselector, file rangeSelector.js */    (function($, DX, undefined) {        var rangeSelector = DX.viz.rangeSelector,            utils = DX.utils,            core = DX.viz.core,            patchFontOptions = core.utils.patchFontOptions,            ParseUtils = core.ParseUtils,            formatHelper = DX.formatHelper,            SCALE_TEXT_SPACING = 5,            HEIGHT_COMPACT_MODE = 24,            POINTER_SIZE = 4,            EMPTY_SLIDER_MARKER_TEXT = '. . .',            _isDefined = utils.isDefined,            _isNumber = utils.isNumber,            _isDate = utils.isDate,            _max = Math.max,            _ceil = Math.ceil,            START_VALUE = 'startValue',            END_VALUE = 'endValue',            DATETIME = 'datetime',            SELECTED_RANGE = 'selectedRange',            DISCRETE = 'discrete',            STRING = 'string',            SELECTED_RANGE_CHANGED = SELECTED_RANGE + 'Changed',            CONTAINER_BACKGROUND_COLOR = "containerBackgroundColor",            SLIDER_MARKER = "sliderMarker",            BACKGROUND = "background",            LOGARITHMIC = "logarithmic",            INVISIBLE_POS = -1000,            logarithmBase = 10;        rangeSelector.consts = {            emptySliderMarkerText: EMPTY_SLIDER_MARKER_TEXT,            pointerSize: POINTER_SIZE        };        rangeSelector.HEIGHT_COMPACT_MODE = HEIGHT_COMPACT_MODE;        rangeSelector.__getTextBBox = getTextBBox;        function cloneSelectedRange(arg) {            return {                    startValue: arg.startValue,                    endValue: arg.endValue                }        }        var formatValue = rangeSelector.formatValue = function(value, formatOptions) {                var formatObject = {                        value: value,                        valueText: formatHelper.format(value, formatOptions.format, formatOptions.precision)                    };                return String(utils.isFunction(formatOptions.customizeText) ? formatOptions.customizeText.call(formatObject, formatObject) : formatObject.valueText)            };        var createRangeContainer = function(rangeContainerOptions) {                return rangeSelector.rangeSelectorFactory.createRangeContainer(rangeContainerOptions)            };        var createTranslator = function(range, canvas) {                return {                        x: core.CoreFactory.createTranslator2D(range.arg, canvas, {direction: "horizontal"}),                        y: core.CoreFactory.createTranslator2D(range.val, canvas)                    }            };        var createTranslatorCanvas = function(sizeOptions, rangeContainerCanvas, scaleLabelsAreaHeight) {                return {                        left: rangeContainerCanvas.left,                        top: rangeContainerCanvas.top,                        right: sizeOptions.width - rangeContainerCanvas.width - rangeContainerCanvas.left,                        bottom: sizeOptions.height - rangeContainerCanvas.height - rangeContainerCanvas.top + scaleLabelsAreaHeight,                        width: sizeOptions.width,                        height: sizeOptions.height                    }            };        var calculateMarkerHeight = function(renderer, value, sliderMarkerOptions) {                var formattedText = value === undefined ? EMPTY_SLIDER_MARKER_TEXT : formatValue(value, sliderMarkerOptions),                    textBBox = getTextBBox(renderer, formattedText, sliderMarkerOptions.font);                return _ceil(textBBox.height) + 2 * sliderMarkerOptions.paddingTopBottom + POINTER_SIZE            };        var calculateScaleLabelHalfWidth = function(renderer, value, scaleOptions) {                var formattedText = formatValue(value, scaleOptions.label),                    textBBox = getTextBBox(renderer, formattedText, scaleOptions.label.font);                return _ceil(textBBox.width / 2)            };        var calculateRangeContainerCanvas = function(size, indents, scaleLabelsAreaHeight, isCompactMode) {                var canvas = {                        left: size.left + indents.left,                        top: size.top + indents.top,                        width: size.width - size.left - size.right - indents.left - indents.right,                        height: !isCompactMode ? size.height - size.top - size.bottom - indents.top : HEIGHT_COMPACT_MODE + scaleLabelsAreaHeight                    };                if (canvas.width <= 0)                    canvas.width = 1;                return canvas            };        var parseSliderMarkersPlaceholderSize = function(placeholderSize) {                var placeholderWidthLeft,                    placeholderWidthRight,                    placeholderHeight;                if (_isNumber(placeholderSize))                    placeholderWidthLeft = placeholderWidthRight = placeholderHeight = placeholderSize;                else if (placeholderSize) {                    if (_isNumber(placeholderSize.height))                        placeholderHeight = placeholderSize.height;                    if (_isNumber(placeholderSize.width))                        placeholderWidthLeft = placeholderWidthRight = placeholderSize.width;                    else if (placeholderSize.width) {                        if (_isNumber(placeholderSize.width.left))                            placeholderWidthLeft = placeholderSize.width.left;                        if (_isNumber(placeholderSize.width.right))                            placeholderWidthRight = placeholderSize.width.right                    }                }                else                    return null;                return {                        widthLeft: placeholderWidthLeft,                        widthRight: placeholderWidthRight,                        height: placeholderHeight                    }            };        var calculateIndents = function(renderer, size, scale, sliderMarkerOptions, indentOptions) {                var leftMarkerHeight,                    leftScaleLabelWidth = 0,                    rightScaleLabelWidth = 0,                    rightMarkerHeight,                    placeholderWidthLeft = 0,                    placeholderWidthRight = 0,                    placeholderHeight,                    parsedPlaceholderSize;                indentOptions = indentOptions || {};                parsedPlaceholderSize = parseSliderMarkersPlaceholderSize(sliderMarkerOptions.placeholderSize);                if (parsedPlaceholderSize && indentOptions.left === undefined && indentOptions.right === undefined) {                    placeholderWidthLeft = parsedPlaceholderSize.widthLeft;                    placeholderWidthRight = parsedPlaceholderSize.widthRight                }                else {                    placeholderWidthLeft = indentOptions.left;                    placeholderWidthRight = indentOptions.right                }                if (parsedPlaceholderSize && sliderMarkerOptions.placeholderHeight === undefined)                    placeholderHeight = parsedPlaceholderSize.height;                else                    placeholderHeight = sliderMarkerOptions.placeholderHeight;                if (sliderMarkerOptions.visible) {                    leftMarkerHeight = calculateMarkerHeight(renderer, scale.startValue, sliderMarkerOptions);                    rightMarkerHeight = calculateMarkerHeight(renderer, scale.endValue, sliderMarkerOptions);                    if (placeholderHeight === undefined)                        placeholderHeight = _max(leftMarkerHeight, rightMarkerHeight)                }                if (scale.label.visible) {                    leftScaleLabelWidth = calculateScaleLabelHalfWidth(renderer, scale.startValue, scale);                    rightScaleLabelWidth = calculateScaleLabelHalfWidth(renderer, scale.endValue, scale)                }                placeholderWidthLeft = placeholderWidthLeft !== undefined ? placeholderWidthLeft : leftScaleLabelWidth;                placeholderWidthRight = (placeholderWidthRight !== undefined ? placeholderWidthRight : rightScaleLabelWidth) || 1;                return {                        left: placeholderWidthLeft,                        right: placeholderWidthRight,                        top: placeholderHeight || 0,                        bottom: 0                    }            };        var calculateValueType = function(firstValue, secondValue) {                var typeFirstValue = $.type(firstValue),                    typeSecondValue = $.type(secondValue),                    validType = function(type) {                        return typeFirstValue === type || typeSecondValue === type                    };                return validType('date') ? DATETIME : validType('number') ? 'numeric' : validType(STRING) ? STRING : ''            };        var showScaleMarkers = function(scaleOptions) {                return scaleOptions.valueType === DATETIME && scaleOptions.marker.visible            };        var updateTranslatorRangeInterval = function(translatorRange, scaleOptions) {                var intervalX = scaleOptions.minorTickInterval || scaleOptions.majorTickInterval;                if (scaleOptions.valueType === "datetime")                    intervalX = utils.dateToMilliseconds(intervalX);                translatorRange = translatorRange.arg.addRange({interval: intervalX})            };        var createRange = function(options) {                return new core.Range(options)            };        var checkLogarithmicOptions = function(options, defaultLogarithmBase, incidentOccured) {                var logarithmBase;                if (!options)                    return;                logarithmBase = options.logarithmBase;                if (options.type === LOGARITHMIC && logarithmBase <= 0 || logarithmBase && !_isNumber(logarithmBase)) {                    options.logarithmBase = defaultLogarithmBase;                    incidentOccured('E2104')                }                else if (options.type !== LOGARITHMIC)                    options.logarithmBase = undefined            };        var calculateScaleAreaHeight = function(renderer, scaleOptions, visibleMarkers) {                var textBBox,                    value = "0",                    formatObject = {                        value: 0,                        valueText: value                    },                    labelScaleOptions = scaleOptions.label,                    markerScaleOPtions = scaleOptions.marker,                    customizeText = labelScaleOptions.customizeText,                    placeholderHeight = scaleOptions.placeholderHeight,                    text = utils.isFunction(customizeText) ? customizeText.call(formatObject, formatObject) : value,                    visibleLabels = labelScaleOptions.visible;                if (placeholderHeight)                    return placeholderHeight;                else {                    textBBox = getTextBBox(renderer, text, labelScaleOptions.font);                    return (visibleLabels ? labelScaleOptions.topIndent + textBBox.height : 0) + (visibleMarkers ? markerScaleOPtions.topIndent + markerScaleOPtions.separatorHeight : 0)                }            };        var updateTickIntervals = function(scaleOptions, screenDelta, incidentOccured, stick, min, max) {                var categoriesInfo = scaleOptions._categoriesInfo,                    tickManager = core.CoreFactory.createTickManager({                        axisType: scaleOptions.type,                        dataType: scaleOptions.valueType                    }, {                        min: min,                        max: max,                        screenDelta: screenDelta,                        customTicks: categoriesInfo && categoriesInfo.categories                    }, {                        labelOptions: {},                        boundCoef: 1,                        minorTickInterval: scaleOptions.minorTickInterval,                        tickInterval: scaleOptions.majorTickInterval,                        incidentOccured: incidentOccured,                        base: scaleOptions.logarithmBase,                        showMinorTicks: true,                        withMinorCorrection: true,                        stick: stick !== false                    });                tickManager.getTicks(true);                return {                        majorTickInterval: tickManager.getTickInterval(),                        minorTickInterval: tickManager.getMinorTickInterval(),                        bounds: tickManager.getTickBounds()                    }            };        var calculateTranslatorRange = function(seriesDataSource, scaleOptions) {                var minValue,                    maxValue,                    inverted = false,                    isEqualDates,                    startValue = scaleOptions.startValue,                    endValue = scaleOptions.endValue,                    categories,                    categoriesInfo,                    translatorRange = seriesDataSource ? seriesDataSource.getBoundRange() : {                        arg: createRange(),                        val: createRange({isValueRange: true})                    },                    rangeForCategories;                if (scaleOptions.type === DISCRETE) {                    rangeForCategories = createRange({                        categories: scaleOptions.categories || (!seriesDataSource && startValue && endValue ? [startValue, endValue] : undefined),                        minVisible: startValue,                        maxVisible: endValue                    });                    rangeForCategories.addRange(translatorRange.arg);                    translatorRange.arg = rangeForCategories;                    categories = rangeForCategories.categories || [];                    scaleOptions._categoriesInfo = categoriesInfo = utils.getCategoriesInfo(categories, startValue || categories[0], endValue || categories[categories.length - 1])                }                if (_isDefined(startValue) && _isDefined(endValue)) {                    inverted = scaleOptions.inverted = categoriesInfo ? categoriesInfo.inverted : startValue > endValue;                    minValue = categoriesInfo ? categoriesInfo.start : inverted ? endValue : startValue;                    maxValue = categoriesInfo ? categoriesInfo.end : inverted ? startValue : endValue                }                else if (_isDefined(startValue) || _isDefined(endValue)) {                    minValue = startValue;                    maxValue = endValue                }                else if (categoriesInfo) {                    minValue = categoriesInfo.start;                    maxValue = categoriesInfo.end                }                isEqualDates = _isDate(minValue) && _isDate(maxValue) && minValue.getTime() === maxValue.getTime();                if (minValue !== maxValue && !isEqualDates)                    translatorRange.arg.addRange({                        invert: inverted,                        min: minValue,                        max: maxValue,                        minVisible: minValue,                        maxVisible: maxValue,                        dataType: scaleOptions.valueType                    });                translatorRange.arg.addRange({                    base: scaleOptions.logarithmBase,                    axisType: scaleOptions.type                });                if (!translatorRange.arg.isDefined()) {                    if (isEqualDates)                        scaleOptions.valueType = 'numeric';                    translatorRange.arg.setStubData(scaleOptions.valueType)                }                return translatorRange            };        var startEndNotDefined = function(start, end) {                return !_isDefined(start) || !_isDefined(end)            };        function getTextBBox(renderer, text, fontOptions) {            var textElement = renderer.text(text, INVISIBLE_POS, INVISIBLE_POS).css(patchFontOptions(fontOptions)).append(renderer.root);            var textBBox = textElement.getBBox();            textElement.remove();            return textBBox        }        function processValue(selectedRangeOptions, scaleOptions, entity, incidentOccured) {            var parsedValue,                value = selectedRangeOptions[entity],                parser = scaleOptions.parser || function() {                    return null                },                resultValue = scaleOptions[entity];            if (_isDefined(value))                parsedValue = parser(value);            if (!_isDefined(parsedValue))                incidentOccured("E2203", [entity]);            else                resultValue = parsedValue;            return rangeSelector.utils.truncateSelectedRange(resultValue, scaleOptions)        }        DX.registerComponent("dxRangeSelector", rangeSelector, core.BaseWidget.inherit({            _eventsMap: $.extend({}, core.BaseWidget.prototype._eventsMap, {                onSelectedRangeChanged: {                    name: SELECTED_RANGE_CHANGED,                    deprecated: SELECTED_RANGE_CHANGED,                    deprecatedContext: function() {                        return null                    },                    deprecatedArgs: function(arg) {                        return [cloneSelectedRange(arg)]                    }                },                selectedRangeChanged: {newName: "onSelectedRangeChanged"}            }),            _setDeprecatedOptions: function() {                this.callBase();                $.extend(this._deprecatedOptions, {                    selectedRangeChanged: {                        since: "14.2",                        message: "Use the 'onSelectedRangeChanged' option instead"                    },                    "sliderMarker.padding": {                        since: "15.1",                        message: "Use the 'paddingTopBottom' and 'paddingLeftRight' options instead"                    },                    "sliderMarker.placeholderSize": {                        since: "15.1",                        message: "Use the 'placeholderHeight' and 'indent' options instead"                    }                })            },            _rootClassPrefix: "dxrs",            _rootClass: "dxrs-range-selector",            _dataSourceOptions: function() {                return {paginate: false}            },            _dataIsReady: function() {                return this._isDataSourceReady()            },            _initCore: function() {                var that = this;                that.rangeContainer = createRangeContainer(that._renderer);                that._reinitDataSource();                that._renderer.root.css({                    "touch-action": "pan-y",                    "-ms-touch-action": "pan-y"                })            },            _initTooltip: $.noop,            _setTooltipRendererOptions: $.noop,            _setTooltipOptions: $.noop,            _getDefaultSize: function() {                return {                        width: 400,                        height: 160                    }            },            _handleLoadingIndicatorShown: $.noop,            _reinitDataSource: function() {                this._refreshDataSource()            },            _disposeCore: function() {                var that = this,                    disposeObject = function(propName) {                        that[propName] && that[propName].dispose(),                        that[propName] = null                    };                that.callBase();                disposeObject("renderer");                that.translators = null;                disposeObject("rangeContainer")            },            _createThemeManager: function() {                return rangeSelector.rangeSelectorFactory.createThemeManager()            },            _refresh: function() {                var that = this,                    callBase = that.callBase;                that._endLoading(function() {                    callBase.call(that)                })            },            _render: function(isResizing) {                var that = this,                    currentAnimationEnabled,                    renderer = that._renderer;                isResizing = isResizing || that.__isResizing;                that._applyOptions();                if (isResizing) {                    currentAnimationEnabled = renderer.animationEnabled();                    renderer.updateAnimationOptions({enabled: false});                    that.rangeContainer.redraw();                    renderer.updateAnimationOptions({enabled: currentAnimationEnabled})                }                else                    that.rangeContainer.redraw();                !isResizing && (!that._dataSource || that._dataSource && that._dataSource.isLoaded()) && that.hideLoadingIndicator();                that._drawn();                that.__rendered && that.__rendered()            },            _optionChanged: function(args) {                var that = this,                    name = args.name;                if (name === "dataSource")                    that._reinitDataSource();                else if (name === SELECTED_RANGE)                    that.setSelectedRange(that.option(SELECTED_RANGE));                else                    that.callBase(args)            },            _applySize: $.noop,            _resize: function() {                this._render(true)            },            _dataSourceChangedHandler: function() {                var that = this;                that._endLoading(function() {                    if (that._renderer.drawn)                        that._render()                })            },            _applyOptions: function() {                var that = this,                    rangeContainerCanvas,                    seriesDataSource,                    translatorRange,                    scaleLabelsAreaHeight,                    sizeOptions = that._canvas,                    indents,                    sliderMarkerOptions,                    selectedRange,                    chartOptions = that.option('chart'),                    shutterOptions = that._getOption("shutter"),                    background = that._getOption(BACKGROUND),                    isCompactMode,                    scaleOptions,                    chartThemeManager;                that._isUpdating = true;                seriesDataSource = that._createSeriesDataSource(chartOptions);                isCompactMode = !(seriesDataSource && seriesDataSource.isShowChart() || background && background.image && background.image.url);                if (seriesDataSource) {                    chartThemeManager = seriesDataSource.getThemeManager();                    checkLogarithmicOptions(chartOptions && chartOptions.valueAxis, chartThemeManager.getOptions("valueAxis").logarithmBase, that._incidentOccured)                }                scaleOptions = that._scaleOptions = that._prepareScaleOptions(seriesDataSource);                translatorRange = calculateTranslatorRange(seriesDataSource, scaleOptions);                that._updateScaleOptions(seriesDataSource, translatorRange.arg, sizeOptions.width);                updateTranslatorRangeInterval(translatorRange, scaleOptions);                sliderMarkerOptions = that._prepareSliderMarkersOptions(sizeOptions.width);                selectedRange = that._initSelection();                indents = calculateIndents(that._renderer, sizeOptions, scaleOptions, sliderMarkerOptions, that.option("indent"));                scaleLabelsAreaHeight = calculateScaleAreaHeight(that._renderer, scaleOptions, showScaleMarkers(scaleOptions));                rangeContainerCanvas = calculateRangeContainerCanvas(sizeOptions, indents, scaleLabelsAreaHeight, isCompactMode);                that.translators = createTranslator(translatorRange, createTranslatorCanvas(sizeOptions, rangeContainerCanvas, scaleLabelsAreaHeight));                scaleOptions.ticksInfo = that._getTicksInfo(rangeContainerCanvas.width);                that._testTicksInfo = scaleOptions.ticksInfo;                that._selectedRange = selectedRange;                if (seriesDataSource)                    seriesDataSource.adjustSeriesDimensions(that.translators);                shutterOptions.color = shutterOptions.color || that._getOption(CONTAINER_BACKGROUND_COLOR, true);                that.rangeContainer.applyOptions({                    canvas: rangeContainerCanvas,                    isCompactMode: isCompactMode,                    scaleLabelsAreaHeight: scaleLabelsAreaHeight,                    indents: indents,                    translators: that.translators,                    selectedRange: selectedRange,                    scale: scaleOptions,                    behavior: that._getOption('behavior'),                    background: background,                    chart: chartOptions,                    seriesDataSource: seriesDataSource,                    sliderMarker: sliderMarkerOptions,                    sliderHandle: that._getOption('sliderHandle'),                    shutter: shutterOptions,                    selectedRangeColor: that._getOption("selectedRangeColor", true),                    selectedRangeChanged: function(selectedRange, blockSelectedRangeChanged) {                        that.option(SELECTED_RANGE, selectedRange);                        if (!blockSelectedRangeChanged)                            that._eventTrigger(SELECTED_RANGE_CHANGED, cloneSelectedRange(selectedRange))                    },                    setSelectedRange: function(selectedRange) {                        that.setSelectedRange(selectedRange)                    }                });                that._isUpdating = false;                chartThemeManager && chartThemeManager.dispose()            },            _initSelection: function() {                var that = this,                    scaleOptions = that._scaleOptions,                    selectedRangeOptions = that.option(SELECTED_RANGE),                    incidentOccured = that._incidentOccured;                if (!selectedRangeOptions)                    return cloneSelectedRange(scaleOptions);                else                    return {                            startValue: processValue(selectedRangeOptions, scaleOptions, START_VALUE, incidentOccured),                            endValue: processValue(selectedRangeOptions, scaleOptions, END_VALUE, incidentOccured)                        }            },            _createSeriesDataSource: function(chartOptions) {                var that = this,                    seriesDataSource,                    dataSource = that._dataSource && that._dataSource.items(),                    scaleOptions = that._getOption('scale'),                    valueType = scaleOptions.valueType,                    backgroundOption = that.option(BACKGROUND);                if (!valueType)                    valueType = calculateValueType(scaleOptions.startValue, scaleOptions.endValue);                if (dataSource || chartOptions && chartOptions.series) {                    chartOptions = $.extend({}, chartOptions, {theme: that.option("theme")});                    seriesDataSource = new rangeSelector.SeriesDataSource({                        renderer: that._renderer,                        dataSource: dataSource,                        valueType: (valueType || '').toLowerCase(),                        axisType: scaleOptions.type,                        chart: chartOptions,                        dataSourceField: that.option('dataSourceField'),                        backgroundColor: backgroundOption && backgroundOption.color,                        incidentOccured: that._incidentOccured,                        categories: scaleOptions.categories                    })                }                return seriesDataSource            },            _prepareScaleOptions: function(seriesDataSource) {                var that = this,                    scaleOptions = that._getOption('scale'),                    parsedValue = 0,                    parseUtils = new ParseUtils,                    valueType = parseUtils.correctValueType((scaleOptions.valueType || '').toLowerCase()),                    parser,                    validateStartEndValues = function(field, parser) {                        var messageToIncidentOccured = field === START_VALUE ? 'start' : 'end';                        if (_isDefined(scaleOptions[field])) {                            parsedValue = parser(scaleOptions[field]);                            if (_isDefined(parsedValue))                                scaleOptions[field] = parsedValue;                            else {                                scaleOptions[field] = undefined;                                that._incidentOccured("E2202", [messageToIncidentOccured])                            }                        }                    };                if (seriesDataSource)                    valueType = seriesDataSource.getCalculatedValueType() || valueType;                if (!valueType)                    valueType = calculateValueType(scaleOptions.startValue, scaleOptions.endValue) || 'numeric';                if (valueType === STRING || scaleOptions.categories) {                    scaleOptions.type = DISCRETE;                    valueType = STRING                }                scaleOptions.valueType = valueType;                parser = parseUtils.getParser(valueType, 'scale');                validateStartEndValues(START_VALUE, parser);                validateStartEndValues(END_VALUE, parser);                checkLogarithmicOptions(scaleOptions, logarithmBase, that._incidentOccured);                if (!scaleOptions.type)                    scaleOptions.type = 'continuous';                scaleOptions.parser = parser;                return scaleOptions            },            _prepareSliderMarkersOptions: function(screenDelta) {                var that = this,                    scaleOptions = that._scaleOptions,                    minorTickInterval = scaleOptions.minorTickInterval,                    majorTickInterval = scaleOptions.majorTickInterval,                    endValue = scaleOptions.endValue,                    startValue = scaleOptions.startValue,                    sliderMarkerOptions = that._getOption(SLIDER_MARKER),                    businessInterval,                    sliderMarkerUserOption = that.option(SLIDER_MARKER) || {};                sliderMarkerOptions.borderColor = that._getOption(CONTAINER_BACKGROUND_COLOR, true);                if (!sliderMarkerOptions.format) {                    if (!that._getOption('behavior').snapToTicks && _isNumber(scaleOptions.startValue)) {                        businessInterval = Math.abs(endValue - startValue);                        sliderMarkerOptions.format = 'fixedPoint';                        sliderMarkerOptions.precision = utils.getSignificantDigitPosition(businessInterval / screenDelta)                    }                    if (scaleOptions.valueType === DATETIME)                        if (!scaleOptions.marker.visible) {                            if (_isDefined(startValue) && _isDefined(endValue))                                sliderMarkerOptions.format = formatHelper.getDateFormatByTickInterval(startValue, endValue, minorTickInterval !== 0 ? minorTickInterval : majorTickInterval)                        }                        else                            sliderMarkerOptions.format = utils.getDateUnitInterval(_isDefined(minorTickInterval) && minorTickInterval !== 0 ? minorTickInterval : majorTickInterval)                }                if (sliderMarkerUserOption.padding !== undefined && sliderMarkerUserOption.paddingLeftRight === undefined && sliderMarkerUserOption.paddingTopBottom === undefined)                    sliderMarkerOptions.paddingLeftRight = sliderMarkerOptions.paddingTopBottom = sliderMarkerUserOption.padding;                return sliderMarkerOptions            },            _updateScaleOptions: function(seriesDataSource, translatorRange, screenDelta) {                var scaleOptions = this._scaleOptions,                    min = _isDefined(translatorRange.minVisible) ? translatorRange.minVisible : translatorRange.min,                    max = _isDefined(translatorRange.maxVisible) ? translatorRange.maxVisible : translatorRange.max,                    tickIntervalsInfo = updateTickIntervals(scaleOptions, screenDelta, this._incidentOccured, translatorRange.stick, min, max),                    bounds,                    isEmptyInterval,                    categoriesInfo = scaleOptions._categoriesInfo;                if (seriesDataSource && !seriesDataSource.isEmpty() && !translatorRange.stubData) {                    bounds = tickIntervalsInfo.bounds;                    translatorRange.addRange(bounds);                    scaleOptions.startValue = scaleOptions.inverted ? bounds.maxVisible : bounds.minVisible;                    scaleOptions.endValue = scaleOptions.inverted ? bounds.minVisible : bounds.maxVisible                }                if (categoriesInfo) {                    scaleOptions.startValue = categoriesInfo.start;                    scaleOptions.endValue = categoriesInfo.end                }                isEmptyInterval = _isDate(scaleOptions.startValue) && _isDate(scaleOptions.endValue) && scaleOptions.startValue.getTime() === scaleOptions.endValue.getTime() || scaleOptions.startValue === scaleOptions.endValue;                scaleOptions.isEmpty = startEndNotDefined(scaleOptions.startValue, scaleOptions.endValue) || isEmptyInterval;                if (scaleOptions.isEmpty)                    scaleOptions.startValue = scaleOptions.endValue = undefined;                else {                    scaleOptions.minorTickInterval = tickIntervalsInfo.minorTickInterval;                    scaleOptions.majorTickInterval = tickIntervalsInfo.majorTickInterval;                    if (scaleOptions.valueType === DATETIME && !_isDefined(scaleOptions.label.format))                        if (!scaleOptions.marker.visible)                            scaleOptions.label.format = formatHelper.getDateFormatByTickInterval(scaleOptions.startValue, scaleOptions.endValue, scaleOptions.majorTickInterval);                        else                            scaleOptions.label.format = utils.getDateUnitInterval(scaleOptions.majorTickInterval)                }            },            _getStubTicks: function(scaleOptions) {                scaleOptions.isEmpty = true;                return ["canvas_position_left", "canvas_position_center", "canvas_position_right"]            },            _getTickManagerOptions: function(scaleOptions, isEmpty, startValue, endValue) {                var that = this;                return {                        labelOptions: {},                        minorTickInterval: isEmpty ? 0 : that._getOption('scale').minorTickInterval,                        tickInterval: scaleOptions.majorTickInterval,                        addMinMax: scaleOptions.showCustomBoundaryTicks ? {                            min: true,                            max: true                        } : undefined,                        minorTickCount: scaleOptions.minorTickCount,                        textOptions: {                            align: 'center',                            font: scaleOptions.label.font                        },                        textFontStyles: patchFontOptions(scaleOptions.label.font),                        incidentOccured: that._incidentOccured,                        isHorizontal: true,                        renderText: function(text, x, y, options) {                            return that._renderer.text(text, x, y, options).append(that._renderer.root)                        },                        getText: startEndNotDefined(startValue, endValue) ? function(value) {                            return value                        } : function(value) {                            return formatValue(value, scaleOptions.label)                        },                        translate: function(value) {                            return that.translators.x.translate(value)                        },                        textSpacing: SCALE_TEXT_SPACING,                        setTicksAtUnitBeginning: scaleOptions.setTicksAtUnitBeginning,                        useTicksAutoArrangement: scaleOptions.useTicksAutoArrangement,                        base: scaleOptions.logarithmBase,                        stick: true,                        showMinorTicks: true,                        withMinorCorrection: true                    }            },            _getTicksInfo: function(screenDelta) {                var that = this,                    scaleOptions = that._scaleOptions,                    translators = that.translators,                    isEmpty = scaleOptions.isEmpty,                    businessRange = translators.x.getBusinessRange(),                    categoriesInfo = scaleOptions._categoriesInfo,                    tickManagerTypes = {                        axisType: scaleOptions.type,                        dataType: scaleOptions.valueType                    },                    tickManagerData,                    startValue = scaleOptions.startValue,                    endValue = scaleOptions.endValue,                    tickManagerOptions = that._getTickManagerOptions(scaleOptions, isEmpty, startValue, endValue),                    majorTicks,                    customBoundaryTicks,                    tickManager,                    fullTicks,                    noInfoFromMinMax;                tickManagerData = {                    min: isEmpty ? businessRange.min : startValue,                    max: isEmpty ? businessRange.max : endValue,                    screenDelta: screenDelta,                    customTicks: categoriesInfo && categoriesInfo.categories                };                tickManager = core.CoreFactory.createTickManager(tickManagerTypes, tickManagerData, tickManagerOptions);                if (scaleOptions.type === DISCRETE)                    noInfoFromMinMax = !_isDefined(tickManagerData.min) || !_isDefined(tickManagerData.max);                else                    noInfoFromMinMax = !_isDefined(tickManagerData.min) && !_isDefined(tickManagerData.max);                majorTicks = noInfoFromMinMax && !_isDefined(tickManagerData.customTicks) ? that._getStubTicks(scaleOptions) : tickManager.getTicks(true);                customBoundaryTicks = tickManager.getBoundaryTicks();                fullTicks = tickManager.getFullTicks();                if (customBoundaryTicks.length) {                    if (majorTicks[0].valueOf() === customBoundaryTicks[0].valueOf())                        majorTicks.splice(0, 1);                    if (majorTicks[majorTicks.length - 1].valueOf() === customBoundaryTicks[customBoundaryTicks.length - 1].valueOf())                        majorTicks.pop()                }                return {                        majorTicks: majorTicks,                        minorTicks: tickManager.getMinorTicks(),                        majorTickInterval: tickManager.getTickInterval(),                        fullTicks: fullTicks,                        customBoundaryTicks: customBoundaryTicks                    }            },            getSelectedRange: function() {                return cloneSelectedRange(this.rangeContainer.slidersContainer.getSelectedRange())            },            setSelectedRange: function(selectedRange) {                var that = this;                if (that._isUpdating || !selectedRange)                    return;                var oldSelectedRange = that.rangeContainer.slidersContainer.getSelectedRange();                if (oldSelectedRange && oldSelectedRange.startValue === selectedRange.startValue && oldSelectedRange.endValue === selectedRange.endValue)                    return;                that.rangeContainer.slidersContainer.setSelectedRange(selectedRange)            },            resetSelectedRange: function(blockSelectedRangeChanged) {                var data = cloneSelectedRange(this._scaleOptions);                data.blockSelectedRangeChanged = blockSelectedRangeChanged;                this.setSelectedRange(data)            },            render: function(isResizing) {                var that = this;                that.__isResizing = isResizing;                that.callBase.apply(that, arguments);                that.__isResizing = null;                return that            }        }).include(DX.ui.DataHelperMixin))    })(jQuery, DevExpress);    /*! Module viz-rangeselector, file rangeContainer.js */    (function($, DX, undefined) {        var rangeSelector = DX.viz.rangeSelector,            baseVisualElementMethods = rangeSelector.baseVisualElementMethods,            RangeContainer;        var createSlidersContainer = function(options) {                return rangeSelector.rangeSelectorFactory.createSlidersContainer(options)            };        var createScale = function(options) {                return rangeSelector.rangeSelectorFactory.createScale(options)            };        var createRangeView = function(options) {                return rangeSelector.rangeSelectorFactory.createRangeView(options)            };        var _createClipRectCanvas = function(canvas, indents) {                return {                        left: canvas.left - indents.left,                        top: canvas.top - indents.top,                        width: canvas.width + indents.right + indents.left,                        height: canvas.height + indents.bottom + indents.top                    }            };        function canvasOptionsToRenderOptions(canvasOptions) {            return {                    x: canvasOptions.left,                    y: canvasOptions.top,                    width: canvasOptions.width,                    height: canvasOptions.height                }        }        RangeContainer = function(renderer) {            baseVisualElementMethods.init.apply(this, arguments);            this.slidersContainer = createSlidersContainer(renderer);            this.rangeView = createRangeView(renderer);            this.scale = createScale(renderer)        };        RangeContainer.prototype = $.extend({}, baseVisualElementMethods, {            constructor: RangeContainer,            dispose: function() {                this.slidersContainer.dispose();                this.slidersContainer = null            },            _applyOptions: function(options) {                var that = this,                    scaleLabelsAreaHeight = options.scaleLabelsAreaHeight,                    canvas = options.canvas,                    isCompactMode = options.isCompactMode,                    viewCanvas = {                        left: canvas.left,                        top: canvas.top,                        width: canvas.width,                        height: canvas.height >= scaleLabelsAreaHeight ? canvas.height - scaleLabelsAreaHeight : 0                    };                that._viewCanvas = viewCanvas;                that.slidersContainer.applyOptions({                    isCompactMode: isCompactMode,                    canvas: viewCanvas,                    selectedRangeColor: options.selectedRangeColor,                    translator: options.translators.x,                    scale: options.scale,                    selectedRange: options.selectedRange,                    sliderMarker: options.sliderMarker,                    sliderHandle: options.sliderHandle,                    shutter: options.shutter,                    behavior: options.behavior,                    selectedRangeChanged: options.selectedRangeChanged                });                that.rangeView.applyOptions({                    isCompactMode: isCompactMode,                    canvas: viewCanvas,                    translators: options.translators,                    background: options.background,                    chart: options.chart,                    seriesDataSource: options.seriesDataSource,                    behavior: options.behavior,                    isEmpty: options.scale.isEmpty                });                that.scale.applyOptions({                    isCompactMode: isCompactMode,                    canvas: canvas,                    translator: options.translators.x,                    scale: options.scale,                    scaleLabelsAreaHeight: scaleLabelsAreaHeight,                    setSelectedRange: options.setSelectedRange                })            },            _draw: function() {                var that = this,                    containerGroup,                    rangeViewGroup,                    slidersContainerGroup,                    scaleGroup,                    trackersGroup,                    options = that._options,                    clipRectCanvas = _createClipRectCanvas(options.canvas, options.indents),                    viewCanvas = that._viewCanvas,                    renderer = that._renderer,                    slidersContainer = that.slidersContainer;                that._clipRect = renderer.clipRect(clipRectCanvas.left, clipRectCanvas.top, clipRectCanvas.width, clipRectCanvas.height);                that._viewClipRect = renderer.clipRect(viewCanvas.left, viewCanvas.top, viewCanvas.width, viewCanvas.height);                containerGroup = renderer.g().attr({                    'class': 'rangeContainer',                    clipId: that._clipRect.id                }).append(renderer.root);                rangeViewGroup = renderer.g().attr({                    'class': 'view',                    clipId: that._viewClipRect.id                });                that._slidersGroup = slidersContainerGroup = renderer.g().attr({'class': 'slidersContainer'});                scaleGroup = renderer.g().attr({'class': 'scale'});                trackersGroup = renderer.g().attr({'class': 'trackers'});                rangeViewGroup.append(containerGroup);                if (!options.isCompactMode) {                    slidersContainerGroup.append(containerGroup);                    scaleGroup.append(containerGroup)                }                else {                    scaleGroup.append(containerGroup);                    slidersContainerGroup.append(containerGroup)                }                trackersGroup.append(containerGroup);                that.rangeView.redraw(rangeViewGroup);                slidersContainer.redraw(slidersContainerGroup);                that.scale.redraw(scaleGroup);                that._trackersGroup = trackersGroup;                slidersContainer.appendTrackers(trackersGroup)            },            _update: function() {                var that = this,                    options = that._options,                    slidersContainer = that.slidersContainer;                that._clipRect.attr(canvasOptionsToRenderOptions(_createClipRectCanvas(options.canvas, options.indents)));                that._viewClipRect.attr(canvasOptionsToRenderOptions(that._viewCanvas));                that.rangeView.redraw();                slidersContainer.redraw(that._slidersGroup);                slidersContainer.appendTrackers(that._trackersGroup);                that.scale.redraw()            },            createSlidersContainer: createSlidersContainer,            createScale: createScale        });        rangeSelector.RangeContainer = RangeContainer    })(jQuery, DevExpress);    /*! Module viz-rangeselector, file scale.js */    (function($, DX, undefined) {        var viz = DX.viz,            rangeSelector = viz.rangeSelector,            formatHelper = DX.formatHelper,            rangeSelectorUtils = rangeSelector.utils,            utils = DX.utils,            _isDefined = utils.isDefined,            HALF_TICK_LENGTH = 6,            MINOR_TICK_OPACITY_COEF = 0.6,            Scale,            baseVisualElementMethods = rangeSelector.baseVisualElementMethods,            _extend = $.extend;        function calculateRangeByMarkerPosition(posX, markerDatePositions, scaleOptions) {            var selectedRange = {},                position,                i;            for (i = 0; i < markerDatePositions.length; i++) {                position = markerDatePositions[i];                if (!scaleOptions.inverted) {                    if (posX >= position.posX)                        selectedRange.startValue = position.date;                    else if (!selectedRange.endValue)                        selectedRange.endValue = position.date                }                else if (posX < position.posX)                    selectedRange.endValue = position.date;                else if (!selectedRange.startValue)                    selectedRange.startValue = position.date            }            selectedRange.startValue = selectedRange.startValue || scaleOptions.startValue;            selectedRange.endValue = selectedRange.endValue || scaleOptions.endValue;            return selectedRange        }        var dateSetters = {};        dateSetters.millisecond = function(date) {            date.setMilliseconds(0)        };        dateSetters.second = function(date) {            date.setSeconds(0, 0)        };        dateSetters.minute = function(date) {            date.setMinutes(0, 0, 0)        };        dateSetters.hour = function(date) {            date.setHours(0, 0, 0, 0)        };        dateSetters.week = dateSetters.day = function(date) {            date.setDate(1);            dateSetters.hour(date)        };        dateSetters.month = function(date) {            date.setMonth(0);            dateSetters.day(date)        };        dateSetters.quarter = function(date) {            date.setMonth(formatHelper.getFirstQuarterMonth(date.getMonth()));            dateSetters.day(date)        };        function getMarkerDate(date, tickInterval) {            var markerDate = new Date(date.getTime()),                setter = dateSetters[tickInterval];            setter && setter(markerDate);            return markerDate        }        function prepareDatesDifferences(datesDifferences, tickInterval) {            var deleteDifferent = tickInterval,                dateUnitInterval,                i;            if (deleteDifferent === 'week')                deleteDifferent = 'day';            if (deleteDifferent === 'quarter')                deleteDifferent = 'month';            if (datesDifferences[deleteDifferent])                for (i = 0; i < utils.dateUnitIntervals.length; i++) {                    dateUnitInterval = utils.dateUnitIntervals[i];                    if (datesDifferences[dateUnitInterval]) {                        datesDifferences[dateUnitInterval] = false;                        datesDifferences.count--                    }                    if (dateUnitInterval === deleteDifferent)                        break                }        }        function getLabel(value, options) {            var formatObject = {                    value: value,                    valueText: formatHelper.format(value, options.format, options.precision)                };            return String(utils.isFunction(options.customizeText) ? options.customizeText.call(formatObject, formatObject) : formatObject.valueText)        }        Scale = function() {            baseVisualElementMethods.init.apply(this, arguments)        };        Scale.prototype = _extend({}, baseVisualElementMethods, {            constructor: Scale,            _setupDateUnitInterval: function(scaleOptions) {                var key,                    millisecTickInterval,                    majorTickInterval = scaleOptions.ticksInfo.majorTickInterval,                    majorTicks = scaleOptions.ticksInfo.majorTicks;                if (scaleOptions.valueType === 'datetime') {                    if (majorTicks && majorTicks.autoArrangementStep > 1) {                        if (utils.isString(majorTickInterval))                            majorTickInterval = utils.getDateIntervalByString(majorTickInterval);                        for (key in majorTickInterval)                            if (majorTickInterval.hasOwnProperty(key)) {                                majorTickInterval[key] *= majorTicks.autoArrangementStep;                                millisecTickInterval = utils.dateToMilliseconds(majorTickInterval)                            }                        majorTickInterval = utils.convertMillisecondsToDateUnits(millisecTickInterval)                    }                    this.dateUnitInterval = utils.getDateUnitInterval(majorTickInterval)                }            },            _getDrawnDateMarker: function(date, options) {                var that = this,                    labelPosX,                    labelPosY,                    scaleOptions = that._options.scale,                    textElement,                    textElementWidth,                    textIndent,                    pathElement;                if (options.x === null)                    return;                that.textOptions.align = "left";                pathElement = that._renderer.path([options.x, options.y, options.x, options.y + scaleOptions.marker.separatorHeight], "line").attr(that._majorTickStyle).append(options.group);                textElement = that._renderer.text(getLabel(date, options.label), 0, 0).attr(that.textOptions).css(that.fontOptions).append(options.group);                textElementWidth = textElement.getBBox().width;                textIndent = scaleOptions.tick.width + scaleOptions.marker.textLeftIndent;                labelPosX = scaleOptions.inverted ? options.x - textIndent - textElementWidth : options.x + textIndent;                labelPosY = options.y + scaleOptions.marker.textTopIndent + that.fontOptions["font-size"];                textElement.move(labelPosX, labelPosY);                return {                        x1: labelPosX,                        x2: labelPosX + textElementWidth,                        path: pathElement,                        text: textElement                    }            },            _deleteDrawnDateMarker: function(marker) {                marker.path.dispose();                marker.path = null;                marker.text.dispose();                marker.text = null            },            _drawDateMarkers: function(dates, group) {                var that = this,                    i,                    options = that._options,                    datesLength = dates.length,                    datesDifferences,                    markerDate,                    posX,                    markerDatePositions = [],                    prevDateMarker,                    dateMarker;                if (options.scale.valueType !== 'datetime' || !that.visibleMarkers)                    return;                if (dates.length > 1) {                    for (i = 1; i < datesLength; i++) {                        datesDifferences = utils.getDatesDifferences(dates[i - 1], dates[i]);                        prepareDatesDifferences(datesDifferences, that.dateUnitInterval);                        if (datesDifferences.count > 0) {                            markerDate = getMarkerDate(dates[i], that.dateUnitInterval);                            that.markerDates = that.markerDates || [];                            that.markerDates.push(markerDate);                            posX = that.translator.translate(markerDate);                            dateMarker = that._getDrawnDateMarker(markerDate, {                                group: group,                                y: options.canvas.top + options.canvas.height - that.markersAreaHeight + options.scale.marker.topIndent,                                x: posX,                                label: that._getLabelFormatOptions(formatHelper.getDateFormatByDifferences(datesDifferences))                            });                            if (prevDateMarker === undefined || dateMarker.x1 > prevDateMarker.x2 || dateMarker.x2 < prevDateMarker.x1) {                                posX !== null && markerDatePositions.push({                                    date: markerDate,                                    posX: posX                                });                                prevDateMarker = dateMarker                            }                            else                                that._deleteDrawnDateMarker(dateMarker)                        }                    }                    that._initializeMarkersEvents(markerDatePositions, group)                }            },            _getLabelFormatOptions: function(formatString) {                if (!_isDefined(this._options.scale.marker.label.format))                    return _extend({}, this._options.scale.marker.label, {format: formatString});                return this._options.scale.marker.label            },            _initializeMarkersEvents: function(markerDatePositions, group) {                var that = this,                    options = that._options,                    markersAreaTop = options.canvas.top + options.canvas.height - this.markersAreaHeight + options.scale.marker.topIndent,                    markersTracker,                    svgOffsetLeft,                    posX,                    selectedRange;                if (markerDatePositions.length > 0) {                    markersTracker = that._renderer.rect(options.canvas.left, markersAreaTop, options.canvas.width, options.scale.marker.separatorHeight).attr(rangeSelectorUtils.trackerSettings).append(group);                    markersTracker.on(rangeSelector.events.start, function(e) {                        svgOffsetLeft = that._renderer.getRootOffset().left;                        posX = rangeSelectorUtils.getEventPageX(e) - svgOffsetLeft;                        selectedRange = calculateRangeByMarkerPosition(posX, markerDatePositions, options.scale);                        options.setSelectedRange(selectedRange)                    });                    that._markersTracker = markersTracker                }            },            _drawLabel: function(text, group) {                var that = this,                    options = that._options,                    canvas = options.canvas,                    textY = canvas.top + canvas.height - that.markersAreaHeight,                    textElements = that._renderer.text(getLabel(text, options.scale.label), that.translator.translate(text), textY).attr(that.textOptions).css(that.fontOptions).append(group);                that.textElements = that.textElements || [];                that.textElements.push(textElements)            },            _drawTicks: function(ticks, group, directionOffset, coords, style, labelsGroup) {                var that = this,                    i,                    posX,                    tickElement;                for (i = 0; i < ticks.length; i++) {                    if (labelsGroup)                        that._drawLabel(ticks[i], labelsGroup);                    posX = that.translator.translate(ticks[i], directionOffset);                    tickElement = that._createLine([posX, coords[0], posX, coords[1]], group, style);                    that.tickElements = that.tickElements || [];                    that.tickElements.push(tickElement)                }            },            _createLine: function(points, group, options) {                return this._renderer.path(points, "line").attr(options).append(group)            },            _redraw: function(group) {                var that = this,                    options = that._options,                    scaleOptions = options.scale,                    renderer = that._renderer,                    labelsGroup = renderer.g().append(group),                    ticksGroup = renderer.g(),                    ticksInfo = scaleOptions.ticksInfo,                    majorTicks = ticksInfo.majorTicks,                    minorTicks = ticksInfo.minorTicks,                    customBoundaryTicks = ticksInfo.customBoundaryTicks,                    hideLabels = scaleOptions.isEmpty || !scaleOptions.label.visible,                    isDiscrete = scaleOptions.type === "discrete",                    directionOffset = isDiscrete ? -1 : 0,                    isCompactMode = options.isCompactMode,                    canvas = options.canvas,                    bottom = canvas.top + canvas.height - that.scaleLabelsAreaHeight,                    center = canvas.top + (bottom - canvas.top) / 2,                    coords = isCompactMode ? [center - HALF_TICK_LENGTH, center + HALF_TICK_LENGTH] : [canvas.top, bottom],                    categoriesInfo = scaleOptions._categoriesInfo,                    majorTickStyle = that._majorTickStyle;                that._drawTicks(majorTicks, ticksGroup, directionOffset, coords, majorTickStyle, !hideLabels && labelsGroup);                if (scaleOptions.showMinorTicks || isDiscrete)                    that._drawTicks(minorTicks, ticksGroup, directionOffset, coords, that._minorTickStyle);                that._drawTicks(customBoundaryTicks, ticksGroup, 0, coords, majorTickStyle);                isDiscrete && categoriesInfo && _isDefined(categoriesInfo.end) && that._drawTicks([categoriesInfo.end], ticksGroup, 1, coords, majorTickStyle);                if (isCompactMode)                    that._createLine([canvas.left, center, canvas.width + canvas.left, center], group, _extend({}, majorTickStyle, {sharp: "v"}));                ticksGroup.append(group);                that._drawDateMarkers(majorTicks, labelsGroup)            },            _applyOptions: function(options) {                var that = this,                    scaleOptions = options.scale,                    labelsAreaHeight,                    tick = scaleOptions.tick;                that.textOptions = {align: 'center'};                that.fontOptions = viz.core.utils.patchFontOptions(scaleOptions.label.font);                that._majorTickStyle = {                    "stroke-width": tick.width,                    stroke: tick.color,                    "stroke-opacity": tick.opacity,                    sharp: "h"                };                that._minorTickStyle = _extend({}, that._majorTickStyle, {"stroke-opacity": tick.opacity * MINOR_TICK_OPACITY_COEF});                that._setupDateUnitInterval(scaleOptions);                that.visibleMarkers = scaleOptions.marker.visible === undefined ? true : scaleOptions.marker.visible;                labelsAreaHeight = scaleOptions.label.visible ? scaleOptions.label.topIndent + that.fontOptions["font-size"] : 0;                that.scaleLabelsAreaHeight = options.scaleLabelsAreaHeight;                that.markersAreaHeight = that.scaleLabelsAreaHeight - labelsAreaHeight;                that.translator = options.translator            },            _draw: function(group) {                this._redraw(group)            },            _update: function() {                if (this._markersTracker)                    this._markersTracker.off(rangeSelector.events.start, '**');                baseVisualElementMethods._update.apply(this, arguments)            }        });        Scale.prototype._calculateRangeByMarkerPosition = calculateRangeByMarkerPosition;        Scale.prototype._prepareDatesDifferences = prepareDatesDifferences;        rangeSelector.Scale = Scale    })(jQuery, DevExpress);    /*! Module viz-rangeselector, file rangeFactory.js */    (function($, DX, undefined) {        var rangeSelector = DX.viz.rangeSelector;        rangeSelector.rangeSelectorFactory = function() {            return {                    createRangeContainer: function(rangeContainerOptions) {                        return new rangeSelector.RangeContainer(rangeContainerOptions)                    },                    createSlidersContainer: function(options) {                        return new rangeSelector.SlidersContainer(options)                    },                    createScale: function(options) {                        return new rangeSelector.Scale(options)                    },                    createSliderMarker: function(options) {                        return new rangeSelector.SliderMarker(options)                    },                    createRangeView: function(options) {                        return new rangeSelector.RangeView(options)                    },                    createThemeManager: function(options) {                        return new rangeSelector.ThemeManager(options)                    },                    createSlider: function(renderer, sliderIndex) {                        return new rangeSelector.Slider(renderer, sliderIndex)                    },                    createSlidersEventsManager: function(renderer, slidersController, processSelectionChanged) {                        return new rangeSelector.SlidersEventsManager(renderer, slidersController, processSelectionChanged)                    },                    createSlidersController: function(sliders) {                        return new rangeSelector.SlidersController(sliders)                    }                }        }()    })(jQuery, DevExpress);    /*! Module viz-rangeselector, file slidersContainer.js */    (function($, DX, undefined) {        var rangeSelector = DX.viz.rangeSelector,            utils = DX.utils,            msPointerEnabled = DX.support.pointer,            isNumber = utils.isNumber,            isDate = utils.isDate,            isString = utils.isString,            rangeSelectorUtils = rangeSelector.utils,            baseVisualElementMethods = rangeSelector.baseVisualElementMethods,            rangeSelectorFactory = rangeSelector.rangeSelectorFactory,            trackerAttributes = rangeSelectorUtils.trackerSettings;        function SlidersContainer() {            var that = this;            baseVisualElementMethods.init.apply(that, arguments);            that._controller = rangeSelectorFactory.createSlidersController(that._renderer);            that._eventsManager = rangeSelectorFactory.createSlidersEventsManager(that._renderer, that._controller, function(moving) {                that._processSelectionChanged(moving)            });            that._lastSelectedRange = {}        }        SlidersContainer.prototype = $.extend({}, baseVisualElementMethods, {            constructor: SlidersContainer,            _drawAreaTracker: function(group) {                var that = this,                    areaTracker,                    selectedAreaTracker,                    canvas = that._options.canvas,                    renderer = that._renderer;                areaTracker = renderer.rect(canvas.left, canvas.top, canvas.width, canvas.height).attr(trackerAttributes).append(group);                selectedAreaTracker = renderer.rect(canvas.left, canvas.top, canvas.width, canvas.height).attr(trackerAttributes).css({cursor: 'pointer'}).append(group);                that._controller.setAreaTrackers(areaTracker, selectedAreaTracker)            },            dispose: function() {                this._eventsManager.dispose();                this._controller.dispose();                this._eventManager = null            },            _processSelectionChanged: function(moving, blockSelectedRangeChanged) {                var that = this,                    equalLastSelectedRange = function(selectedRange) {                        return selectedRange && that._lastSelectedRange.startValue === selectedRange.startValue && that._lastSelectedRange.endValue === selectedRange.endValue                    },                    selectedRange = that.getSelectedRange();                if ((!moving || (that._options.behavior.callSelectedRangeChanged || '').toLowerCase() === "onmoving") && that._options.selectedRangeChanged && !equalLastSelectedRange(selectedRange)) {                    that._updateLastSelectedRange(selectedRange);                    if (utils.isFunction(that._options.selectedRangeChanged))                        that._options.selectedRangeChanged.call(null, selectedRange, blockSelectedRangeChanged);                    if (!moving && !equalLastSelectedRange(selectedRange))                        that.setSelectedRange(selectedRange)                }            },            _updateLastSelectedRange: function(selectedRange) {                selectedRange = selectedRange || this._options.selectedRange;                this._lastSelectedRange = {                    startValue: selectedRange.startValue,                    endValue: selectedRange.endValue                }            },            getSelectedRange: function() {                return this._controller.getSelectedRange()            },            setSelectedRange: function(selectedRange) {                var that = this,                    scale = that._options.scale,                    startValue,                    endValue,                    currentSelectedRange = that._options.selectedRange,                    checkTypes = function(valueName, value) {                        var valueFromScale = scale[valueName];                        if (isNumber(valueFromScale) && isNumber(value) || isDate(valueFromScale) && isDate(value) || isString(valueFromScale) && isString(value))                            currentSelectedRange[valueName] = value                    };                if (selectedRange) {                    startValue = selectedRange.startValue;                    endValue = selectedRange.endValue                }                checkTypes('startValue', startValue);                checkTypes('endValue', endValue);                currentSelectedRange.startValue = rangeSelectorUtils.truncateSelectedRange(currentSelectedRange.startValue, scale);                currentSelectedRange.endValue = rangeSelectorUtils.truncateSelectedRange(currentSelectedRange.endValue, scale);                that._controller.applySelectedRange(currentSelectedRange);                that._controller.applyPosition();                that._processSelectionChanged(false, selectedRange && selectedRange.blockSelectedRangeChanged)            },            appendTrackers: function(group) {                this._controller.appendTrackers(group)            },            _applyOptions: function(options) {                var that = this;                that._controller.applyOptions({                    isCompactMode: options.isCompactMode,                    translator: options.translator,                    canvas: options.canvas,                    sliderMarker: options.sliderMarker,                    sliderHandle: options.sliderHandle,                    shutter: options.shutter,                    scale: options.scale,                    behavior: options.behavior                });                that._eventsManager.applyOptions({behavior: options.behavior})            },            _draw: function(group) {                var that = this,                    rootElement;                if (msPointerEnabled) {                    rootElement = that._renderer.root;                    rootElement && rootElement.css({msTouchAction: "pinch-zoom"})                }                that._controller.redraw(group);                that._drawAreaTracker(group);                that._eventsManager.initialize();                that._update(group)            },            _updateSelectedView: function(group) {                var that = this,                    options = that._options,                    canvas = options.canvas,                    lineOptions = {                        "stroke-width": 3,                        stroke: options.selectedRangeColor,                        sharp: "v"                    },                    center = canvas.top + canvas.height / 2,                    selectedView = that._selectedView,                    selectedViewAppended = that._selectedViewAppended,                    controller = that._controller;                if (!options.isCompactMode) {                    if (selectedView && selectedViewAppended) {                        selectedView.remove();                        that._selectedViewAppended = false                    }                    controller.createShutters()                }                else {                    if (!selectedView) {                        that._selectedView = selectedView = that._renderer.path([canvas.left, center, canvas.left, center], "line").attr(lineOptions);                        controller.setSelectedView(selectedView)                    }                    else                        selectedView.attr(lineOptions);                    if (!selectedViewAppended) {                        selectedView.append(group);                        controller.removeShutters();                        that._selectedViewAppended = true                    }                }            },            _update: function(group) {                var that = this,                    isEmpty = that._options.scale.isEmpty,                    controller = that._controller;                that._eventsManager.setEnabled(!isEmpty);                !isEmpty && that._updateSelectedView(group);                controller.applySelectedRange(isEmpty ? {} : that._options.selectedRange);                controller.applyPosition(that.isDrawn());                that._updateLastSelectedRange();                controller.redraw()            },            getController: function() {                return this._controller            }        });        rangeSelector.SlidersContainer = SlidersContainer    })(jQuery, DevExpress);    /*! Module viz-rangeselector, file slidersController.js */    (function($, DX, undefined) {        var rangeSelector = DX.viz.rangeSelector,            createSlider = rangeSelector.rangeSelectorFactory.createSlider,            utils = DX.utils,            rangeSelectorUtils = rangeSelector.utils,            _SliderController,            START_VALUE_INDEX = 0,            END_VALUE_INDEX = 1,            DISCRETE = 'discrete';        _SliderController = rangeSelector.SlidersController = function(renderer) {            var sliders = [createSlider(renderer, START_VALUE_INDEX), createSlider(renderer, END_VALUE_INDEX)];            sliders[START_VALUE_INDEX].setAnotherSlider(sliders[END_VALUE_INDEX]);            sliders[END_VALUE_INDEX].setAnotherSlider(sliders[START_VALUE_INDEX]);            this._sliders = sliders        };        _SliderController.prototype = {            constructor: _SliderController,            setAreaTrackers: function(areaTracker, selectedAreaTracker) {                this._areaTracker = areaTracker;                this._selectedAreaTracker = selectedAreaTracker            },            applyOptions: function(options) {                var that = this,                    values = null,                    startSlider = that.getSlider(START_VALUE_INDEX),                    endSlider = that.getSlider(END_VALUE_INDEX),                    scaleOptions = options.scale;                that._options = options;                startSlider.applyOptions(options);                endSlider.applyOptions(options);                if (options.behavior.snapToTicks && scaleOptions.type !== DISCRETE) {                    values = scaleOptions.ticksInfo.fullTicks;                    if (values.length > 1 && values[0] > values[values.length - 1])                        values = values.reverse()                }                startSlider.setAvailableValues(values);                endSlider.setAvailableValues(values)            },            processDocking: function(sliderIndex) {                var that = this;                if (sliderIndex !== undefined)                    that.getSlider(sliderIndex).processDocking();                else {                    that.getSlider(START_VALUE_INDEX).processDocking();                    that.getSlider(END_VALUE_INDEX).processDocking()                }                that.setTrackersCursorStyle('default');                that.applyAreaTrackersPosition();                that._applySelectedRangePosition()            },            _applySelectedRangePosition: function(disableAnimation) {                var that = this,                    options = that._options,                    canvas = options.canvas,                    center = canvas.top + canvas.height / 2,                    isAnimation = options.behavior.animationEnabled && !disableAnimation,                    startSliderPos = that.getSlider(START_VALUE_INDEX).getPosition(),                    interval = that.getSelectedRangeInterval(),                    points = [startSliderPos, center, startSliderPos + interval, center],                    selectedView = that._selectedView;                if (!selectedView || !options.isCompactMode)                    return;                if (isAnimation)                    selectedView.animate({points: points}, rangeSelectorUtils.animationSettings);                else                    selectedView.stopAnimation().attr({points: points})            },            setSelectedView: function(selectedView) {                this._selectedView = selectedView            },            getSelectedRangeInterval: function() {                var that = this;                return that.getSlider(END_VALUE_INDEX).getPosition() - that.getSlider(START_VALUE_INDEX).getPosition()            },            moveSliders: function(postitionDelta, selectedRangeInterval) {                var startSlider = this.getSlider(START_VALUE_INDEX);                startSlider.setPosition(startSlider.getPosition() + postitionDelta, false, selectedRangeInterval);                this.applyPosition(true)            },            moveSlider: function(sliderIndex, fastSwap, position, offsetPosition, startOffsetPosition, startOffsetPositionChangedCallback) {                var that = this,                    slider = that.getSlider(sliderIndex),                    anotherSlider = slider.getAnotherSlider(),                    anotherSliderPosition = anotherSlider.getPosition(),                    doSwap;                if (slider.canSwap())                    if (sliderIndex === START_VALUE_INDEX ? position > anotherSliderPosition : position < anotherSliderPosition) {                        doSwap = fastSwap;                        if (!fastSwap)                            if (Math.abs(offsetPosition) >= Math.abs(startOffsetPosition)) {                                doSwap = true;                                if (offsetPosition * startOffsetPosition < 0) {                                    position += 2 * startOffsetPosition;                                    startOffsetPositionChangedCallback(-startOffsetPosition)                                }                                else {                                    position -= 2 * startOffsetPosition;                                    startOffsetPositionChangedCallback(startOffsetPosition)                                }                            }                        if (doSwap) {                            that.swapSliders();                            anotherSlider.applyPosition(true)                        }                    }                slider.setPosition(position, true);                slider.applyPosition(true);                that.applyAreaTrackersPosition();                that._applySelectedRangePosition(true);                that.setTrackersCursorStyle('w-resize')            },            applySelectedAreaCenterPosition: function(pos) {                var that = this,                    startSlider = that.getSlider(START_VALUE_INDEX),                    slidersContainerHalfWidth = (that.getSlider(END_VALUE_INDEX).getPosition() - startSlider.getPosition()) / 2,                    selectedRangeInterval = that.getSelectedRangeInterval();                startSlider.setPosition(pos - slidersContainerHalfWidth, false, selectedRangeInterval);                that.applyPosition();                that.processDocking()            },            endSelection: function() {                var startSlider = this.getSlider(START_VALUE_INDEX),                    endSlider = this.getSlider(END_VALUE_INDEX),                    cloudSpacing = startSlider.getCloudBorder() - endSlider.getCloudBorder(),                    overlappedState;                if (cloudSpacing > 0)                    overlappedState = true;                else                    overlappedState = false;                startSlider.setOverlapped(overlappedState);                endSlider.setOverlapped(overlappedState)            },            processManualSelection: function(startPosition, endPosition, eventArgs) {                var that = this,                    animateSliderIndex,                    movingSliderIndex,                    positionRange = [Math.min(startPosition, endPosition), Math.max(startPosition, endPosition)],                    movingSlider,                    animatedSlider;                animateSliderIndex = startPosition < endPosition ? START_VALUE_INDEX : END_VALUE_INDEX;                movingSliderIndex = startPosition < endPosition ? END_VALUE_INDEX : START_VALUE_INDEX;                movingSlider = that.getSlider(movingSliderIndex);                animatedSlider = that.getSlider(animateSliderIndex);                movingSlider.setPosition(positionRange[movingSliderIndex]);                animatedSlider.setPosition(positionRange[animateSliderIndex]);                movingSlider.setPosition(positionRange[movingSliderIndex], true);                movingSlider.startEventHandler(eventArgs);                animatedSlider.processDocking();                movingSlider.applyPosition(true)            },            applySelectedRange: function(selectedRange) {                utils.debug.assertParam(selectedRange, 'selectedRange not passed');                var that = this,                    scaleoptions = that._options.scale,                    inverted = scaleoptions.inverted,                    startSlider = that.getSlider(START_VALUE_INDEX),                    endSlider = that.getSlider(END_VALUE_INDEX),                    startValue = selectedRange.startValue,                    endValue = selectedRange.endValue,                    categoriesInfo,                    setValues = function(startValue, endValue, isInverted) {                        (isInverted ? endSlider : startSlider).setValue(startValue);                        (isInverted ? startSlider : endSlider).setValue(endValue)                    };                if (scaleoptions.type !== DISCRETE)                    if (!inverted && startValue > endValue || inverted && startValue < endValue)                        setValues(startValue, endValue, true);                    else                        setValues(startValue, endValue);                else {                    categoriesInfo = utils.getCategoriesInfo(scaleoptions._categoriesInfo.categories, startValue, endValue);                    setValues(categoriesInfo.start, categoriesInfo.end, categoriesInfo.inverted ^ scaleoptions.inverted)                }            },            getSelectedRange: function() {                return {                        startValue: this.getSlider(START_VALUE_INDEX).getValue(),                        endValue: this.getSlider(END_VALUE_INDEX).getValue()                    }            },            swapSliders: function() {                var that = this;                that._sliders.reverse();                that.getSlider(START_VALUE_INDEX).changeLocation();                that.getSlider(END_VALUE_INDEX).changeLocation()            },            applyAreaTrackersPosition: function() {                var that = this,                    selectedRange = that.getSelectedRange(),                    canvas = that._options.canvas,                    scaleOptions = that._options.scale,                    startSlider = that.getSlider(START_VALUE_INDEX),                    width = that.getSlider(END_VALUE_INDEX).getPosition() - startSlider.getPosition(),                    options = {                        x: startSlider.getPosition(),                        width: width < 0 ? 0 : width,                        y: canvas.top,                        height: canvas.height                    },                    style = {cursor: scaleOptions.endValue - scaleOptions.startValue === selectedRange.endValue - selectedRange.startValue ? 'default' : 'pointer'};                that._selectedAreaTracker.attr(options).css(style);                that._areaTracker.attr({                    x: canvas.left,                    width: canvas.width,                    y: canvas.top,                    height: canvas.height                })            },            applyPosition: function(disableAnimation) {                var that = this;                that.getSlider(START_VALUE_INDEX).applyPosition(disableAnimation);                that.getSlider(END_VALUE_INDEX).applyPosition(disableAnimation);                that.applyAreaTrackersPosition();                that._applySelectedRangePosition(disableAnimation)            },            redraw: function(group) {                var that = this;                that.getSlider(START_VALUE_INDEX).redraw(group);                that.getSlider(END_VALUE_INDEX).redraw(group);                that._foregroundSliderIndex = END_VALUE_INDEX            },            toForeground: function(slider) {                var that = this,                    sliderIndex = slider.getIndex();                if (that._foregroundSliderIndex !== sliderIndex) {                    slider.toForeground();                    that._foregroundSliderIndex = sliderIndex                }            },            appendTrackers: function(group) {                var that = this;                if (that._areaTracker && that._selectedAreaTracker) {                    that._areaTracker.append(group);                    that._selectedAreaTracker.append(group)                }                that.getSlider(START_VALUE_INDEX).appendTrackers(group);                that.getSlider(END_VALUE_INDEX).appendTrackers(group)            },            getSlider: function(sliderIndex) {                return this._sliders[sliderIndex]            },            getAreaTracker: function() {                return this._areaTracker            },            getSelectedAreaTracker: function() {                return this._selectedAreaTracker            },            setTrackersCursorStyle: function(style) {                var that = this;                that._selectedAreaTracker.css({cursor: style});                that._areaTracker.css({cursor: style})            },            createShutters: function() {                var sliders = this._sliders;                sliders[0].createShutter();                sliders[1].createShutter()            },            removeShutters: function() {                var sliders = this._sliders;                sliders[0].removeShutter();                sliders[1].removeShutter()            },            dispose: function() {                var sliders = this._sliders;                sliders[0].dispose();                sliders[1].dispose()            }        }    })(jQuery, DevExpress);    /*! Module viz-rangeselector, file slidersEventsManager.js */    (function($, DX, undefined) {        var rangeSelector = DX.viz.rangeSelector,            MIN_MANUAL_SELECTING_WIDTH = 10,            START_VALUE_INDEX = 0,            END_VALUE_INDEX = 1,            addNamespace = DX.ui.events.addNamespace,            _SlidersEventManager,            rangeSelectorUtils = rangeSelector.utils,            getEventPageX = rangeSelectorUtils.getEventPageX,            rangeSelectorCount = 0;        rangeSelector.events = {            start: "dxpointerdown",            move: "dxpointermove",            end: "dxpointerup"        };        var isLeftButtonPressed = function(event) {                var e = event || window.event,                    originalEvent = e.originalEvent,                    touches = e.touches,                    pointerType = originalEvent ? originalEvent.pointerType : false,                    eventTouches = originalEvent ? originalEvent.touches : false,                    isIE8LeftClick = e.which === undefined && e.button === 1,                    isMSPointerLeftClick = originalEvent && pointerType !== undefined && (pointerType === (originalEvent.MSPOINTER_TYPE_TOUCH || 'touch') || pointerType === (originalEvent.MSPOINTER_TYPE_MOUSE || 'mouse') && originalEvent.buttons === 1),                    isLeftClick = isIE8LeftClick || e.which === 1,                    isTouches = touches && touches.length > 0 || eventTouches && eventTouches.length > 0;                return isLeftClick || isMSPointerLeftClick || isTouches            };        var isMultiTouches = function(event) {                var originalEvent = event.originalEvent,                    touches = event.touches,                    eventTouches = originalEvent ? originalEvent.touches : false;                return touches && touches.length > 1 || eventTouches && eventTouches.length > 1 || null            };        var isTouchEventArgs = function(e) {                return e && e.type && e.type.indexOf('touch') === 0            };        _SlidersEventManager = rangeSelector.SlidersEventsManager = function(renderer, slidersController, processSelectionChanged) {            var that = this,                uniqueNS = that._uniqueNS = 'dx-range-selector_' + rangeSelectorCount++,                rangeSelectorEvents = rangeSelector.events;            that._renderer = renderer;            that._slidersController = slidersController;            that._processSelectionChanged = processSelectionChanged;            that._enabled = true;            that._eventsNames = {                start: addNamespace(rangeSelectorEvents.start, uniqueNS),                move: addNamespace(rangeSelectorEvents.move, uniqueNS),                end: addNamespace(rangeSelectorEvents.end, uniqueNS)            }        };        _SlidersEventManager.prototype = {            constructor: _SlidersEventManager,            _initializeSliderEvents: function(sliderIndex) {                var that = this,                    isTouchEvent,                    slidersController = that._slidersController,                    processSelectionChanged = that._processSelectionChanged,                    slider = slidersController.getSlider(sliderIndex),                    fastSwap,                    startOffsetPosition,                    splitterMoving,                    sliderEndHandler = function() {                        if (splitterMoving) {                            splitterMoving = false;                            slidersController.endSelection();                            slidersController.processDocking();                            processSelectionChanged(false)                        }                    },                    sliderMoveHandler = function(e) {                        var pageX,                            offsetPosition,                            svgOffsetLeft = that._renderer.getRootOffset().left,                            position,                            sliderIndex = slider.getIndex();                        if (isTouchEvent !== isTouchEventArgs(e))                            return;                        if (!isLeftButtonPressed(e, true) && splitterMoving) {                            splitterMoving = false;                            slidersController.processDocking();                            processSelectionChanged(false)                        }                        else if (splitterMoving) {                            if (!isMultiTouches(e)) {                                this.preventedDefault = true;                                e.preventDefault()                            }                            pageX = getEventPageX(e);                            position = pageX - startOffsetPosition - svgOffsetLeft;                            offsetPosition = pageX - slider.getPosition() - svgOffsetLeft;                            slidersController.moveSlider(sliderIndex, fastSwap, position, offsetPosition, startOffsetPosition, function(newStartOffsetPosition) {                                startOffsetPosition = newStartOffsetPosition                            });                            processSelectionChanged(true)                        }                        slidersController.endSelection()                    },                    eventsNames = that._eventsNames;                slider.startEventHandler = function(e) {                    if (!that._enabled || !isLeftButtonPressed(e) || splitterMoving)                        return;                    fastSwap = this === slider.getSliderTracker().element;                    splitterMoving = true;                    isTouchEvent = isTouchEventArgs(e);                    startOffsetPosition = getEventPageX(e) - slider.getPosition() - that._renderer.getRootOffset().left;                    if (!isMultiTouches(e)) {                        this.preventedDefault = true;                        e.stopPropagation();                        e.preventDefault()                    }                };                slider.on(eventsNames.move, function() {                    slidersController.toForeground(slider)                });                slider.on(eventsNames.start, slider.startEventHandler);                $(document).on(eventsNames.end, sliderEndHandler).on(eventsNames.move, sliderMoveHandler);                slider.__moveEventHandler = sliderMoveHandler            },            _initializeAreaEvents: function() {                var that = this,                    isTouchEvent,                    slidersController = that._slidersController,                    processSelectionChanged = that._processSelectionChanged,                    areaTracker = slidersController.getAreaTracker(),                    unselectedAreaProcessing = false,                    startPageX,                    areaEndHandler = function(e) {                        var pageX;                        if (unselectedAreaProcessing) {                            pageX = getEventPageX(e);                            if (that._options.behavior.moveSelectedRangeByClick && Math.abs(startPageX - pageX) < MIN_MANUAL_SELECTING_WIDTH)                                slidersController.applySelectedAreaCenterPosition(pageX - that._renderer.getRootOffset().left);                            unselectedAreaProcessing = false;                            slidersController.endSelection();                            processSelectionChanged(false)                        }                    },                    areaMoveHandler = function(e) {                        var pageX,                            startPosition,                            endPosition,                            svgOffsetLeft = that._renderer.getRootOffset().left;                        if (isTouchEvent !== isTouchEventArgs(e))                            return;                        if (unselectedAreaProcessing && !isLeftButtonPressed(e)) {                            unselectedAreaProcessing = false;                            processSelectionChanged(false)                        }                        if (unselectedAreaProcessing) {                            pageX = getEventPageX(e);                            if (that._options.behavior.manualRangeSelectionEnabled && Math.abs(startPageX - pageX) >= MIN_MANUAL_SELECTING_WIDTH) {                                startPosition = startPageX - svgOffsetLeft;                                endPosition = pageX - svgOffsetLeft;                                slidersController.processManualSelection(startPosition, endPosition, e);                                unselectedAreaProcessing = false;                                processSelectionChanged(true)                            }                        }                    },                    eventsNames = that._eventsNames;                areaTracker.on(eventsNames.start, function(e) {                    if (!that._enabled || !isLeftButtonPressed(e) || unselectedAreaProcessing)                        return;                    unselectedAreaProcessing = true;                    isTouchEvent = isTouchEventArgs(e);                    startPageX = getEventPageX(e)                });                $(document).on(eventsNames.end, areaEndHandler).on(eventsNames.move, areaMoveHandler);                that.__areaMoveEventHandler = areaMoveHandler            },            _initializeSelectedAreaEvents: function() {                var that = this,                    isTouchEvent,                    slidersController = that._slidersController,                    processSelectionChanged = that._processSelectionChanged,                    selectedAreaTracker = slidersController.getSelectedAreaTracker(),                    selectedAreaMoving = false,                    offsetStartPosition,                    selectedRangeInterval,                    selectedAreaEndHandler = function() {                        if (selectedAreaMoving) {                            selectedAreaMoving = false;                            slidersController.processDocking();                            processSelectionChanged(false)                        }                    },                    selectedAreaMoveHandler = function(e) {                        var positionDelta,                            pageX;                        if (isTouchEvent !== isTouchEventArgs(e))                            return;                        if (selectedAreaMoving && !isLeftButtonPressed(e)) {                            selectedAreaMoving = false;                            slidersController.processDocking();                            processSelectionChanged(false)                        }                        if (selectedAreaMoving) {                            if (!isMultiTouches(e)) {                                this.preventedDefault = true;                                e.preventDefault()                            }                            pageX = getEventPageX(e);                            positionDelta = pageX - slidersController.getSlider(START_VALUE_INDEX).getPosition() - offsetStartPosition;                            slidersController.moveSliders(positionDelta, selectedRangeInterval);                            processSelectionChanged(true)                        }                        slidersController.endSelection()                    },                    eventsNames = that._eventsNames;                selectedAreaTracker.on(eventsNames.start, function(e) {                    if (!that._enabled || !isLeftButtonPressed(e) || selectedAreaMoving)                        return;                    selectedAreaMoving = true;                    isTouchEvent = isTouchEventArgs(e);                    offsetStartPosition = getEventPageX(e) - slidersController.getSlider(START_VALUE_INDEX).getPosition();                    selectedRangeInterval = slidersController.getSelectedRangeInterval();                    if (!isMultiTouches(e)) {                        this.preventedDefault = true;                        e.stopPropagation();                        e.preventDefault()                    }                });                $(document).on(eventsNames.end, selectedAreaEndHandler).on(eventsNames.move, selectedAreaMoveHandler);                that.__selectedAreaMoveEventHandler = selectedAreaMoveHandler            },            applyOptions: function(options) {                this._options = options            },            dispose: function() {                $(document).off('.' + this._uniqueNS)            },            initialize: function() {                var that = this;                that._initializeSelectedAreaEvents(that);                that._initializeAreaEvents();                that._initializeSliderEvents(START_VALUE_INDEX);                that._initializeSliderEvents(END_VALUE_INDEX)            },            setEnabled: function(enabled) {                this._enabled = enabled            }        }    })(jQuery, DevExpress);    /*! Module viz-rangeselector, file slider.js */    (function($, DX, undefined) {        var rangeSelector = DX.viz.rangeSelector,            utils = DX.utils,            rangeSelectorUtils = rangeSelector.utils,            _inArray = $.inArray,            dxSupport = DX.support,            touchSupport = dxSupport.touchEvents,            msPointerEnabled = dxSupport.pointer,            SPLITTER_WIDTH = 8,            TOUCH_SPLITTER_WIDTH = 20,            START_VALUE_INDEX = 0,            END_VALUE_INDEX = 1,            DISCRETE = 'discrete',            baseVisualElementMethods = rangeSelector.baseVisualElementMethods;        function checkItemsSpacing(firstSliderPosition, secondSliderPosition, distance) {            return Math.abs(secondSliderPosition - firstSliderPosition) < distance        }        function getValidCategories(categories, curValue, anotherSliderValue, offset) {            var curValueindex = _inArray(curValue, categories);            if (curValueindex === 0 || curValueindex === categories.length - 1)                return anotherSliderValue;            return categories[curValueindex - offset]        }        function Slider(renderer, index) {            baseVisualElementMethods.init.apply(this, arguments);            this._index = index        }        Slider.prototype = $.extend({}, baseVisualElementMethods, {            getText: function() {                if (this._marker)                    return this._marker.getText()            },            getAvailableValues: function() {                return this._values            },            getShutter: function() {                return this._shutter            },            getMarker: function() {                return this._marker            },            constructor: Slider,            _createSlider: function(group) {                var that = this,                    sliderHandle,                    sliderGroup,                    sliderHandleOptions = that._options.sliderHandle,                    canvas = that._options.canvas,                    renderer = that._renderer;                sliderGroup = renderer.g().attr({                    'class': 'slider',                    translateX: canvas.left,                    translateY: canvas.top                }).append(group);                sliderHandle = renderer.path([0, 0, 0, canvas.height], "line").attr({                    "stroke-width": sliderHandleOptions.width,                    stroke: sliderHandleOptions.color,                    "stroke-opacity": sliderHandleOptions.opacity,                    sharp: "h"                }).append(sliderGroup);                sliderGroup.setValid = function(correct) {                    sliderHandle.attr({stroke: correct ? that._options.sliderHandle.color : that._options.sliderMarker.invalidRangeColor})                };                sliderGroup.updateHeight = function() {                    sliderHandle.attr({points: [0, 0, 0, that._options.canvas.height]})                };                sliderGroup.applyOptions = function(options) {                    sliderHandle.attr(options)                };                sliderGroup.__line = sliderHandle;                return sliderGroup            },            _createSliderTracker: function(group) {                var that = this,                    sliderHandleWidth = that._options.sliderHandle.width,                    splitterWidth = SPLITTER_WIDTH < sliderHandleWidth ? sliderHandleWidth : SPLITTER_WIDTH,                    sliderWidth = touchSupport || msPointerEnabled ? TOUCH_SPLITTER_WIDTH : splitterWidth,                    sliderTracker,                    canvas = that._options.canvas,                    renderer = that._renderer,                    sliderTrackerGroup = renderer.g().attr({                        'class': 'sliderTracker',                        translateX: 0,                        translateY: canvas.top                    }).append(group);                sliderTracker = renderer.rect(-sliderWidth / 2, 0, sliderWidth, canvas.height).attr(rangeSelectorUtils.trackerSettings).css({cursor: 'w-resize'}).append(sliderTrackerGroup);                sliderTrackerGroup.updateHeight = function() {                    sliderTracker.attr({height: that._options.canvas.height})                };                sliderTrackerGroup.__rect = sliderTracker;                return sliderTrackerGroup            },            _setPosition: function(position, correctByMinMaxRange) {                var that = this,                    correctedPosition = that._correctPosition(position),                    value = that._options.translator.untranslate(correctedPosition, that._getValueDirection());                that.setValue(value, correctByMinMaxRange, false);                that._position = correctedPosition            },            _getValueDirection: function() {                return this._options.scale.type === DISCRETE ? this.getIndex() === START_VALUE_INDEX ? -1 : 1 : 0            },            _setPositionForBothSliders: function(startPosition, interval) {                var that = this,                    anotherSlider = that.getAnotherSlider(),                    startValue,                    endValue,                    endPosition,                    options = that._options,                    scale = options.scale,                    canvas = options.canvas,                    rightBorderCoords = canvas.left + canvas.width,                    translator = options.translator,                    valueDirection = that._getValueDirection(),                    valueDirectionAnotherSlider = anotherSlider._getValueDirection(),                    getNextValue = function(value, isNegative, reverseValueDirection) {                        var curValueDirection = !reverseValueDirection ? valueDirection : valueDirectionAnotherSlider,                            curAnotherValueDirection = reverseValueDirection ? valueDirection : valueDirectionAnotherSlider;                        return translator.untranslate(that._correctBounds(utils.addInterval(translator.translate(value, curValueDirection), interval, isNegative)), curAnotherValueDirection)                    };                startPosition = that._correctBounds(startPosition);                startValue = translator.untranslate(startPosition, valueDirection);                endValue = getNextValue(startValue);                endPosition = startPosition + interval;                if (endPosition > rightBorderCoords) {                    endValue = scale.endValue;                    endPosition = rightBorderCoords;                    startValue = getNextValue(endValue, true, true);                    startPosition = that._correctBounds(endPosition - interval)                }                else                    endPosition = that._correctBounds(endPosition);                if (that._values)                    if (!scale.inverted ? startValue < that._values[0] : startValue > that._values[that._values.length - 1]) {                        startValue = that._correctByAvailableValues(startValue, false);                        endValue = getNextValue(startValue)                    }                    else {                        endValue = that._correctByAvailableValues(endValue, false);                        startValue = getNextValue(endValue, true)                    }                anotherSlider.setValue(endValue, undefined, false);                that.setValue(startValue, undefined, false);                that._position = startPosition;                anotherSlider._position = endPosition            },            _correctPosition: function(position) {                return this._correctBounds(this._correctInversion(position))            },            _correctInversion: function(position) {                var that = this,                    correctedPosition = position,                    anotherSliderPosition = that.getAnotherSlider().getPosition(),                    slidersInverted = that.getIndex() === START_VALUE_INDEX ? position > anotherSliderPosition : position < anotherSliderPosition;                if (slidersInverted)                    correctedPosition = anotherSliderPosition;                return correctedPosition            },            _correctBounds: function(position) {                var that = this,                    correctedPosition = position,                    canvas = that._options.canvas;                if (position < canvas.left)                    correctedPosition = canvas.left;                if (position > canvas.left + canvas.width)                    correctedPosition = canvas.left + canvas.width;                return correctedPosition            },            _correctValue: function(businessValue, correctByMinMaxRange, skipCorrection) {                var that = this,                    result = that._correctByAvailableValues(businessValue, skipCorrection);                if (correctByMinMaxRange)                    result = that._correctByMinMaxRange(result);                if (that._options.scale.type !== DISCRETE)                    result = that.correctByMinRange(result);                return result            },            _correctByAvailableValues: function(businessValue, skipCorrection) {                var values = this._values;                if (!skipCorrection && values)                    return rangeSelectorUtils.findNearValue(values, businessValue);                return businessValue            },            _correctByMinMaxRange: function(businessValue) {                var that = this,                    result = businessValue,                    scale = that._options.scale,                    values = that._values,                    sliderIndex = that.getIndex(),                    anotherSlider = that.getAnotherSlider(),                    anotherBusinessValue = anotherSlider.getValue(),                    isValid = true,                    minValue,                    maxValue,                    maxRange = scale.maxRange,                    minRange = scale.minRange,                    categoriesInfo;                if (scale.type === DISCRETE) {                    categoriesInfo = scale._categoriesInfo;                    if (checkItemsSpacing(that.getPosition(), anotherSlider.getPosition(), that._options.translator.getInterval() / 2)) {                        isValid = false;                        result = getValidCategories(categoriesInfo.categories, businessValue, anotherSlider.getValue(), sliderIndex === START_VALUE_INDEX ? 1 : -1)                    }                }                else {                    if (!scale.inverted && sliderIndex === START_VALUE_INDEX || scale.inverted && sliderIndex === END_VALUE_INDEX) {                        if (maxRange)                            minValue = that._addInterval(anotherBusinessValue, maxRange, true);                        if (minRange)                            maxValue = that._addInterval(anotherBusinessValue, minRange, true)                    }                    else {                        if (maxRange)                            maxValue = that._addInterval(anotherBusinessValue, maxRange);                        if (minRange)                            minValue = that._addInterval(anotherBusinessValue, minRange)                    }                    if (maxValue !== undefined && result > maxValue) {                        result = values ? rangeSelectorUtils.findLessOrEqualValue(values, maxValue) : maxValue;                        isValid = false                    }                    else if (minValue !== undefined && result < minValue) {                        result = values ? rangeSelectorUtils.findGreaterOrEqualValue(values, minValue) : minValue;                        isValid = false                    }                }                that._setValid(isValid);                return result            },            _addInterval: function(value, interval, isNegative) {                var result,                    type = this._options.scale.type,                    base = type === "logarithmic" && this._options.scale.logarithmBase,                    power;                if (base) {                    power = utils.addInterval(utils.getLog(value, base), interval, isNegative);                    result = Math.pow(base, power)                }                else                    result = utils.addInterval(value, interval, isNegative);                return result            },            correctByMinRange: function(businessValue) {                var that = this,                    startValue,                    endValue,                    scale = that._options.scale,                    result = businessValue;                if (scale.minRange)                    if (that.getIndex() === END_VALUE_INDEX) {                        startValue = that._addInterval(scale.startValue, scale.minRange, scale.inverted);                        if (!scale.inverted && result < startValue || scale.inverted && result > startValue)                            result = startValue                    }                    else if (that.getIndex() === START_VALUE_INDEX) {                        endValue = that._addInterval(scale.endValue, scale.minRange, !scale.inverted);                        if (!scale.inverted && result > endValue || scale.inverted && result < endValue)                            result = endValue                    }                return result            },            _applySliderPosition: function(position, disableAnimation) {                var that = this,                    options = that._options,                    isAnimation = options.behavior.animationEnabled && !disableAnimation,                    slider = that._slider,                    sliderTracker = that._sliderTracker,                    attrs = {                        translateX: position,                        translateY: options.canvas.top                    },                    animationSettings = rangeSelectorUtils.animationSettings;                that._marker && that._marker.setPosition(position);                if (isAnimation) {                    slider.animate(attrs, animationSettings);                    sliderTracker.animate(attrs, animationSettings)                }                else {                    slider.stopAnimation().attr(attrs);                    sliderTracker.stopAnimation().attr(attrs)                }                sliderTracker.updateHeight();                slider.updateHeight()            },            _applyShutterPosition: function(position, disableAnimation) {                var that = this,                    shutterSettings,                    options = that._options,                    shutter = that._shutter,                    isAnimation = options.behavior.animationEnabled && !disableAnimation,                    sliderIndex = that.getIndex(),                    canvas = options.canvas,                    halfSliderHandleWidth = options.sliderHandle.width / 2,                    width;                if (!shutter)                    return;                if (sliderIndex === START_VALUE_INDEX) {                    width = position - canvas.left - Math.floor(halfSliderHandleWidth);                    if (width < 0)                        width = 0;                    shutterSettings = {                        x: canvas.left,                        y: canvas.top,                        width: width,                        height: canvas.height                    }                }                else if (sliderIndex === END_VALUE_INDEX)                    shutterSettings = {                        x: position + Math.ceil(halfSliderHandleWidth),                        y: canvas.top,                        width: canvas.left + canvas.width - position,                        height: canvas.height                    };                if (isAnimation)                    shutter.animate(shutterSettings, rangeSelectorUtils.animationSettings);                else                    shutter.stopAnimation().attr(shutterSettings)            },            _setValid: function(isValid) {                this._marker && this._marker.setValid(isValid);                this._slider.setValid(isValid)            },            _setText: function(text) {                this._marker && this._marker.setText(text)            },            _update: function() {                var that = this,                    options = that._options,                    shutterOptions = options.shutter,                    sliderHandleOptions = options.sliderHandle,                    marker = that._marker;                if (marker) {                    marker.applyOptions(options.sliderMarker);                    marker.setCanvas(that._options.canvas)                }                that._shutter && that._shutter.attr({                    fill: shutterOptions.color,                    "fill-opacity": shutterOptions.opacity                });                that._slider && that._slider.applyOptions({                    "stroke-width": sliderHandleOptions.width,                    stroke: sliderHandleOptions.color,                    "stroke-opacity": sliderHandleOptions.opacity                })            },            _draw: function(group) {                var that = this,                    slider,                    marker,                    sliderAreaGroup,                    options = that._options,                    renderer = that._renderer;                that._container = sliderAreaGroup = renderer.g().attr({'class': 'sliderArea'}).append(group);                slider = that._createSlider(sliderAreaGroup);                if (options.sliderMarker.visible) {                    marker = rangeSelector.rangeSelectorFactory.createSliderMarker({                        renderer: renderer,                        isLeftPointer: that.getIndex() === END_VALUE_INDEX,                        sliderMarkerOptions: options.sliderMarker                    });                    marker.setCanvas(options.canvas);                    marker.draw(slider)                }                that._slider = slider;                that._marker = marker;                that._sliderTracker = that._createSliderTracker(group)            },            toForeground: function() {                this._container.toForeground()            },            _applyOptions: function() {                this._lastPosition = null            },            getIndex: function() {                return this._index            },            setAvailableValues: function(values) {                this._values = values            },            setAnotherSlider: function(slider) {                this._anotherSlider = slider            },            getAnotherSlider: function() {                return this._anotherSlider            },            appendTrackers: function(group) {                this._sliderTracker && this._sliderTracker.append(group)            },            getSliderTracker: function() {                return this._sliderTracker            },            changeLocation: function() {                var that = this;                that._marker && that._marker.changeLocation();                that._index = that._index === START_VALUE_INDEX ? END_VALUE_INDEX : START_VALUE_INDEX;                if (that._options.scale.type === DISCRETE)                    that.setPosition(that._position);                that._lastPosition = null            },            setPosition: function(position, correctByMinMaxRange, selectedRangeInterval) {                var that = this,                    slider;                if (selectedRangeInterval !== undefined) {                    slider = that.getIndex() === START_VALUE_INDEX ? that : that.getAnotherSlider();                    slider._setPositionForBothSliders(position, selectedRangeInterval)                }                else                    that._setPosition(position, correctByMinMaxRange)            },            getPosition: function() {                return this._position            },            setValue: function(value, correctByMinMaxRange, skipCorrection) {                var that = this,                    options = that._options,                    canvas = options.canvas,                    position,                    text;                if (value === undefined) {                    that._value = undefined;                    position = that.getIndex() === START_VALUE_INDEX ? canvas.left : canvas.left + canvas.width;                    text = rangeSelector.consts.emptySliderMarkerText                }                else {                    that._value = that._correctValue(value, correctByMinMaxRange, utils.isDefined(skipCorrection) ? !!skipCorrection : true);                    position = options.translator.translate(that._value, that._getValueDirection());                    text = rangeSelector.formatValue(that._value, options.sliderMarker)                }                that._setText(text);                that._valuePosition = that._position = position            },            setOverlapped: function(isOverlapped) {                this._marker && this._marker.setOverlapped(isOverlapped)            },            getValue: function() {                return this._value            },            canSwap: function() {                var that = this,                    scale = that._options.scale,                    startValue,                    endValue,                    anotherSliderValue;                if (that._options.behavior.allowSlidersSwap) {                    if (scale.minRange) {                        anotherSliderValue = that.getAnotherSlider().getValue();                        if (that.getIndex() === START_VALUE_INDEX) {                            endValue = that._addInterval(scale.endValue, scale.minRange, !scale.inverted);                            if (!scale.inverted && anotherSliderValue > endValue || scale.inverted && anotherSliderValue < endValue)                                return false                        }                        else {                            startValue = that._addInterval(scale.startValue, scale.minRange, scale.inverted);                            if (!scale.inverted && anotherSliderValue < startValue || scale.inverted && anotherSliderValue > startValue)                                return false                        }                    }                    return true                }                return false            },            processDocking: function() {                var that = this;                that._position = that._valuePosition;                that.applyPosition(false);                that._setValid(true)            },            applyPosition: function(disableAnimation) {                var that = this,                    position = that.getPosition();                if (that._lastPosition !== position) {                    that._applySliderPosition(position, disableAnimation);                    that._applyShutterPosition(position, disableAnimation);                    that._lastPosition = position                }            },            on: function(event, handler) {                var that = this,                    marker = that._marker,                    tracker = marker && marker.getTracker(),                    sliderTracker = that._sliderTracker;                sliderTracker && sliderTracker.on(event, handler);                tracker && tracker.on(event, handler)            },            createShutter: function() {                var that = this,                    index = that.getIndex(),                    canvas = that._options.canvas,                    renderer = that._renderer,                    shutter = that._shutter;                if (!shutter) {                    if (index === START_VALUE_INDEX)                        shutter = renderer.rect(canvas.left, canvas.top, 0, canvas.height);                    else if (index === END_VALUE_INDEX)                        shutter = renderer.rect(canvas.left, canvas.top, canvas.width, canvas.height);                    that._shutter = shutter                }                shutter.append(that._container)            },            removeShutter: function() {                var shutter = this._shutter;                shutter && shutter.remove()            },            getCloudBorder: function() {                return this._marker ? this._marker.getBorderPosition() : 0            },            dispose: function() {                var marker = this._marker;                marker && marker.dispose()            }        });        rangeSelector.Slider = Slider    })(jQuery, DevExpress);    /*! Module viz-rangeselector, file sliderMarker.js */    (function($, DX, undefined) {        var viz = DX.viz,            core = viz.core,            rangeSelector = viz.rangeSelector,            SliderMarker,            SLIDER_MARKER_UPDATE_DELAY = 75,            POINTER_SIZE = rangeSelector.consts.pointerSize;        var getRectSize = function(that, textSize) {                var options = that._options;                return {                        width: Math.round(2 * options.paddingLeftRight + textSize.width),                        height: Math.round(2 * options.paddingTopBottom + textSize.height)                    }            };        var getAreaPointsInfo = function(that, textSize) {                var rectSize = getRectSize(that, textSize),                    rectWidth = rectSize.width,                    rectHeight = rectSize.height,                    rectLeftBorder = -rectWidth,                    rectRightBorder = 0,                    pointerRightPoint = POINTER_SIZE,                    pointerCenterPoint = 0,                    pointerLeftPoint = -POINTER_SIZE,                    position = that._position,                    canvas = that._canvas,                    isLeft = that._isLeftPointer,                    correctCloudBorders = function() {                        rectLeftBorder++;                        rectRightBorder++;                        pointerRightPoint++;                        pointerCenterPoint++;                        pointerLeftPoint++                    },                    checkPointerBorders = function() {                        if (pointerRightPoint > rectRightBorder)                            pointerRightPoint = rectRightBorder;                        else if (pointerLeftPoint < rectLeftBorder)                            pointerLeftPoint = rectLeftBorder;                        isLeft && correctCloudBorders()                    },                    borderPosition = position;                if (isLeft)                    if (position > canvas.left + canvas.width - rectWidth) {                        rectRightBorder = -position + (canvas.left + canvas.width);                        rectLeftBorder = rectRightBorder - rectWidth;                        checkPointerBorders();                        borderPosition += rectLeftBorder                    }                    else {                        rectLeftBorder = pointerLeftPoint = 0;                        rectRightBorder = rectWidth                    }                else if (position - canvas.left < rectWidth) {                    rectLeftBorder = -(position - canvas.left);                    rectRightBorder = rectLeftBorder + rectWidth;                    checkPointerBorders();                    borderPosition += rectRightBorder                }                else {                    pointerRightPoint = 0;                    correctCloudBorders()                }                that._borderPosition = borderPosition;                return {                        offset: rectLeftBorder,                        isCutted: (!isLeft || pointerCenterPoint !== pointerLeftPoint) && (isLeft || pointerCenterPoint !== pointerRightPoint),                        points: [rectLeftBorder, 0, rectRightBorder, 0, rectRightBorder, rectHeight, pointerRightPoint, rectHeight, pointerCenterPoint, rectHeight + POINTER_SIZE, pointerLeftPoint, rectHeight, rectLeftBorder, rectHeight]                    }            };        var getTextSize = function(that) {                var textSize = that._label.getBBox();                if (!that._textHeight && isFinite(textSize.height))                    that._textHeight = textSize.height;                return {                        width: textSize.width,                        height: that._textHeight,                        y: textSize.y                    }            };        SliderMarker = rangeSelector.SliderMarker = function(options) {            var that = this;            that._renderer = options.renderer;            that._text = options.text;            that._isLeftPointer = options.isLeftPointer;            that._options = $.extend(true, {}, options.sliderMarkerOptions);            that._options.textFontStyles = core.utils.patchFontOptions(that._options.font);            that._isValid = true;            that._isOverlapped = false        };        SliderMarker.prototype = {            constructor: SliderMarker,            draw: function(group) {                var that = this,                    options = that._options,                    sliderMarkerGroup = that._sliderMarkerGroup = that._renderer.g().attr({'class': 'sliderMarker'}).append(group);                that._area = that._renderer.path([], "area").attr({fill: options.color}).append(sliderMarkerGroup);                that._label = that._renderer.text(that._text, 0, 0).attr({align: 'left'}).css(options.textFontStyles).append(sliderMarkerGroup);                that._tracker = that._renderer.rect(0, 0, 2 * options.paddingLeftRight, 2 * options.paddingTopBottom + POINTER_SIZE).attr(rangeSelector.utils.trackerSettings).css({cursor: 'pointer'}).append(sliderMarkerGroup);                that._border = that._renderer.rect(0, 0, 1, 0).attr({fill: options.borderColor});                that._drawn = true;                that._update()            },            _update: function() {                var that = this,                    textSize,                    options = that._options,                    currentTextSize,                    rectSize;                clearTimeout(that._timeout);                if (!that._drawn)                    return;                that._label.attr({text: that._text || ""});                currentTextSize = getTextSize(that);                rectSize = getRectSize(that, currentTextSize);                textSize = that._textSize || currentTextSize;                textSize = that._textSize = currentTextSize.width > textSize.width || currentTextSize.height > textSize.height ? currentTextSize : textSize;                that._timeout = setTimeout(function() {                    updateSliderMarker(currentTextSize, rectSize);                    that._textSize = currentTextSize                }, SLIDER_MARKER_UPDATE_DELAY);                function updateSliderMarker(size, rectSize) {                    var points,                        pointsData,                        offset;                    rectSize = rectSize || getRectSize(that, size);                    that._sliderMarkerGroup.attr({translateY: -(rectSize.height + POINTER_SIZE)});                    pointsData = getAreaPointsInfo(that, size);                    points = pointsData.points;                    offset = pointsData.offset;                    that._area.attr({points: points});                    that._border.attr({                        x: that._isLeftPointer ? points[0] - 1 : points[2],                        height: pointsData.isCutted ? rectSize.height : rectSize.height + POINTER_SIZE                    });                    that._tracker.attr({                        translateX: offset,                        width: rectSize.width,                        height: rectSize.height + POINTER_SIZE                    });                    that._label.attr({                        translateX: options.paddingLeftRight + offset,                        translateY: rectSize.height / 2 - (size.y + size.height / 2)                    })                }                updateSliderMarker(textSize)            },            setText: function(value) {                var that = this;                if (that._text !== value)                    that._text = value            },            setPosition: function(position) {                this._position = position;                this._update()            },            changeLocation: function() {                var that = this;                that._isLeftPointer = !that._isLeftPointer;                that._update()            },            applyOptions: function(options) {                var that = this,                    fontSyles,                    opt = that._options = $.extend(true, {}, options);                fontSyles = opt.textFontStyles = core.utils.patchFontOptions(opt.font);                that._textHeight = null;                that._area.attr({fill: options.color});                that._border.attr({fill: options.borderColor});                that._label.css(fontSyles);                that._update()            },            getTracker: function() {                return this._tracker            },            setValid: function(isValid) {                var that = this,                    options = that._options;                if (that._isValid !== isValid) {                    that._isValid = isValid;                    that._area.attr({fill: isValid ? options.color : options.invalidRangeColor})                }            },            dispose: function() {                clearTimeout(this._timeout)            },            setOverlapped: function(isOverlapped) {                var border = this._border,                    currentOverlappedState = this._isOverlapped;                if (currentOverlappedState === isOverlapped)                    return;                if (isOverlapped)                    border.append(this._sliderMarkerGroup);                else                    this._isOverlapped && border.remove();                this._isOverlapped = isOverlapped            },            getBorderPosition: function() {                return this._borderPosition            },            setCanvas: function(canvas) {                this._canvas = canvas            }        };        SliderMarker.prototype.updateDelay = SLIDER_MARKER_UPDATE_DELAY;        SliderMarker.prototype.getText = function() {            return this._text        }    })(jQuery, DevExpress);    /*! Module viz-rangeselector, file rangeView.js */    (function($, DX, undefined) {        var rangeSelector = DX.viz.rangeSelector,            RangeView,            baseVisualElementMethods = rangeSelector.baseVisualElementMethods;        RangeView = function() {            baseVisualElementMethods.init.apply(this, arguments)        };        RangeView.prototype = $.extend({}, baseVisualElementMethods, {            constructor: RangeView,            _draw: function(group) {                var that = this,                    series,                    i,                    options = that._options,                    isCompactMode = options.isCompactMode,                    canvas = options.canvas,                    isEmpty = options.isEmpty,                    renderer = that._renderer,                    seriesDataSource = options.seriesDataSource,                    showChart = seriesDataSource && seriesDataSource.isShowChart() && !isEmpty,                    background = options.background,                    backgroundColor = showChart ? seriesDataSource.getBackgroundColor() : background.color,                    backgroundImage = background.image,                    backgroundIsVisible = background.visible;                if (isCompactMode)                    return;                if (backgroundIsVisible && !isEmpty && backgroundColor)                    renderer.rect(canvas.left, canvas.top, canvas.width + 1, canvas.height).attr({                        fill: backgroundColor,                        'class': 'dx-range-selector-background'                    }).append(group);                if (backgroundIsVisible && backgroundImage && backgroundImage.url)                    renderer.image(canvas.left, canvas.top, canvas.width + 1, canvas.height, backgroundImage.url, backgroundImage.location).append(group);                if (showChart) {                    series = seriesDataSource.getSeries();                    seriesDataSource.adjustSeriesDimensions(options.translators, options.chart.useAggregation);                    for (i = 0; i < series.length; i++) {                        series[i]._extGroups.seriesGroup = group;                        series[i]._extGroups.labelsGroup = group;                        series[i].draw(options.translators, options.behavior && options.behavior.animationEnabled && renderer.animationEnabled())                    }                }            }        });        rangeSelector.RangeView = RangeView    })(jQuery, DevExpress);    /*! Module viz-rangeselector, file seriesDataSource.js */    (function($, DX, undefined) {        var rangeSelector = DX.viz.rangeSelector,            charts = DX.viz.charts,            core = DX.viz.core,            coreFactory = core.CoreFactory,            utils = DX.utils,            _SeriesDatasource;        var createThemeManager = function(chartOptions) {                return charts.factory.createThemeManager(chartOptions, 'rangeSelector.chart')            };        var isArrayOfSimpleTypes = function(data) {                return $.isArray(data) && data.length > 0 && (utils.isNumber(data[0]) || utils.isDate(data[0]))            };        var convertToArrayOfObjects = function(data) {                return $.map(data, function(item, i) {                        return {                                arg: item,                                val: i                            }                    })            };        var processSeriesFamilies = function(series, equalBarWidth, minBubbleSize, maxBubbleSize) {                var families = [],                    types = [];                $.each(series, function(i, item) {                    if ($.inArray(item.type, types) === -1)                        types.push(item.type)                });                $.each(types, function(_, type) {                    var family = new coreFactory.createSeriesFamily({                            type: type,                            equalBarWidth: equalBarWidth,                            minBubbleSize: minBubbleSize,                            maxBubbleSize: maxBubbleSize                        });                    family.add(series);                    family.adjustSeriesValues();                    families.push(family)                });                return families            };        var isStickType = function(type) {                var nonStickTypes = ["bar", "candlestick", "stock", "bubble"],                    stickType = true;                type = type.toLowerCase();                $.each(nonStickTypes, function(_, item) {                    if (type.indexOf(item) !== -1) {                        stickType = false;                        return false                    }                });                return stickType            };        function setTemplateFields(data, templateData, series) {            $.each(data, function(_, data) {                $.each(series.getTeamplatedFields(), function(_, field) {                    data[field.teamplateField] = data[field.originalField]                });                templateData.push(data)            });            series.updateTeamplateFieldNames()        }        _SeriesDatasource = rangeSelector.SeriesDataSource = function(options) {            var that = this,                templatedSeries,                seriesTemplate,                themeManager = that._themeManager = createThemeManager(options.chart),                topIndent,                bottomIndent;            themeManager._fontFields = ["commonSeriesSettings.label.font"];            themeManager.setTheme(options.chart.theme);            topIndent = themeManager.getOptions('topIndent');            bottomIndent = themeManager.getOptions('bottomIndent');            that._indent = {                top: topIndent >= 0 && topIndent < 1 ? topIndent : 0,                bottom: bottomIndent >= 0 && bottomIndent < 1 ? bottomIndent : 0            };            that._valueAxis = themeManager.getOptions('valueAxisRangeSelector') || {};            that._hideChart = false;            seriesTemplate = themeManager.getOptions('seriesTemplate');            if (options.dataSource && seriesTemplate)                templatedSeries = utils.processSeriesTemplate(seriesTemplate, options.dataSource);            that._series = that._calculateSeries(options, templatedSeries);            that._seriesFamilies = processSeriesFamilies(that._series, themeManager.getOptions('equalBarWidth'), themeManager.getOptions('minBubbleSize'), themeManager.getOptions('maxBubbleSize'))        };        _SeriesDatasource.prototype = {            constructor: _SeriesDatasource,            _calculateSeries: function(options, templatedSeries) {                var that = this,                    series = [],                    particularSeriesOptions,                    seriesTheme,                    data,                    groupSeries,                    parsedData,                    chartThemeManager = that._themeManager,                    hasSeriesTemplate = !!chartThemeManager.getOptions('seriesTemplate'),                    allSeriesOptions = hasSeriesTemplate ? templatedSeries : options.chart.series,                    seriesValueType = options.chart.valueAxis && options.chart.valueAxis.valueType,                    dataSourceField,                    i,                    newSeries,                    particularSeries;                that.teamplateData = [];                if (options.dataSource && !allSeriesOptions) {                    if (isArrayOfSimpleTypes(options.dataSource))                        options.dataSource = convertToArrayOfObjects(options.dataSource);                    dataSourceField = options.dataSourceField || 'arg';                    allSeriesOptions = {                        argumentField: dataSourceField,                        valueField: dataSourceField                    };                    that._hideChart = true                }                allSeriesOptions = $.isArray(allSeriesOptions) ? allSeriesOptions : allSeriesOptions ? [allSeriesOptions] : [];                that._backgroundColor = options.backgroundColor;                for (i = 0; i < allSeriesOptions.length; i++) {                    particularSeriesOptions = $.extend(true, {incidentOccured: options.incidentOccured}, allSeriesOptions[i]);                    particularSeriesOptions.rotated = false;                    data = particularSeriesOptions.data || options.dataSource;                    seriesTheme = chartThemeManager.getOptions("series", particularSeriesOptions);                    seriesTheme.argumentField = seriesTheme.argumentField || options.dataSourceField;                    if (data && data.length > 0) {                        newSeries = coreFactory.createSeries({renderer: options.renderer}, seriesTheme);                        series.push(newSeries)                    }                    if (hasSeriesTemplate)                        setTemplateFields(data, that.teamplateData, newSeries)                }                data = hasSeriesTemplate ? that.teamplateData : data;                groupSeries = [series];                groupSeries.argumentOptions = {                    categories: options.categories,                    argumentType: options.valueType,                    type: options.axisType                };                groupSeries[0].valueOptions = {valueType: dataSourceField ? options.valueType : seriesValueType};                that._dataValidator = core.CoreFactory.createDataValidator(data, groupSeries, options.incidentOccured, chartThemeManager.getOptions("dataPrepareSettings"));                parsedData = that._dataValidator.validate();                for (i = 0; i < series.length; i++) {                    particularSeries = series[i];                    particularSeries.updateData(parsedData)                }                return series            },            adjustSeriesDimensions: function(translators, useAggregation) {                var that = this;                if (useAggregation)                    $.each(that._series || [], function(_, s) {                        s.resamplePoints(translators.x)                    });                $.each(that._seriesFamilies, function(_, family) {                    family.adjustSeriesDimensions({                        arg: translators.x,                        val: translators.y                    })                })            },            getBoundRange: function() {                var that = this,                    rangeData,                    valueAxisMin = that._valueAxis.min,                    valueAxisMax = that._valueAxis.max,                    valRange = new core.Range({                        isValueRange: true,                        min: valueAxisMin,                        minVisible: valueAxisMin,                        max: valueAxisMax,                        maxVisible: valueAxisMax,                        axisType: that._valueAxis.type,                        base: that._valueAxis.logarithmBase                    }),                    argRange = new core.Range({}),                    rangeYSize,                    rangeVisibleSizeY,                    minIndent,                    maxIndent;                $.each(that._series, function(_, series) {                    rangeData = series.getRangeData();                    valRange.addRange(rangeData.val);                    argRange.addRange(rangeData.arg);                    if (!isStickType(series.type))                        argRange.addRange({stick: false})                });                if (valRange.isDefined() && argRange.isDefined()) {                    minIndent = that._valueAxis.inverted ? that._indent.top : that._indent.bottom;                    maxIndent = that._valueAxis.inverted ? that._indent.bottom : that._indent.top;                    rangeYSize = valRange.max - valRange.min;                    rangeVisibleSizeY = ($.isNumeric(valRange.maxVisible) ? valRange.maxVisible : valRange.max) - ($.isNumeric(valRange.minVisible) ? valRange.minVisible : valRange.min);                    if (utils.isDate(valRange.min))                        valRange.min = new Date(valRange.min.valueOf() - rangeYSize * minIndent);                    else                        valRange.min -= rangeYSize * minIndent;                    if (utils.isDate(valRange.max))                        valRange.max = new Date(valRange.max.valueOf() + rangeYSize * maxIndent);                    else                        valRange.max += rangeYSize * maxIndent;                    if ($.isNumeric(rangeVisibleSizeY)) {                        valRange.maxVisible = valRange.maxVisible ? valRange.maxVisible + rangeVisibleSizeY * maxIndent : undefined;                        valRange.minVisible = valRange.minVisible ? valRange.minVisible - rangeVisibleSizeY * minIndent : undefined                    }                    valRange.invert = that._valueAxis.inverted                }                return {                        arg: argRange,                        val: valRange                    }            },            getSeries: function() {                var that = this;                return that._series            },            getBackgroundColor: function() {                return this._backgroundColor            },            isEmpty: function() {                var that = this;                return that.getSeries().length === 0            },            isShowChart: function() {                var that = this;                return !that.isEmpty() && !that._hideChart            },            getCalculatedValueType: function() {                var that = this,                    result;                if (that._series.length)                    result = that._series[0].argumentType;                return result            },            getThemeManager: function() {                return this._themeManager            }        }    })(jQuery, DevExpress);    /*! Module viz-rangeselector, file themeManager.js */    (function($, DX, undefined) {        DX.viz.rangeSelector.ThemeManager = DX.viz.core.BaseThemeManager.inherit({            _themeSection: 'rangeSelector',            _fontFields: ['scale.label.font', 'sliderMarker.font', 'loadingIndicator.font']        })    })(jQuery, DevExpress);    DevExpress.MOD_VIZ_RANGESELECTOR = true}if (!DevExpress.MOD_VIZ_VECTORMAP) {    if (!DevExpress.MOD_VIZ_CORE)        throw Error('Required module is not referenced: viz-core');    /*! Module viz-vectormap, file map.js */    (function(DX, $, undefined) {        DX.viz.map = {};        var _parseScalar = DX.viz.core.utils.parseScalar,            DEFAULT_WIDTH = 800,            DEFAULT_HEIGHT = 400,            TOOLTIP_OFFSET = 12,            _extend = $.extend,            nextDataKey = 1;        function generateDataKey() {            return "vectormap-data-" + nextDataKey++        }        var Map = DX.viz.core.BaseWidget.inherit({                _eventsMap: _extend({}, DX.viz.core.BaseWidget.prototype._eventsMap, {                    onClick: {                        name: "click",                        deprecated: "click",                        deprecatedContext: function(arg) {                            return arg.component                        },                        deprecatedArgs: function(arg) {                            return [arg.jQueryEvent]                        }                    },                    click: {newName: "onClick"},                    onCenterChanged: {                        name: "centerChanged",                        deprecated: "centerChanged",                        deprecatedContext: function(arg) {                            return arg.component                        },                        deprecatedArgs: function(arg) {                            return [arg.center]                        }                    },                    centerChanged: {newName: "onCenterChanged"},                    onZoomFactorChanged: {                        name: "zoomFactorChanged",                        deprecated: "zoomFactorChanged",                        deprecatedContext: function(arg) {                            return arg.component                        },                        deprecatedArgs: function(arg) {                            return [arg.zoomFactor]                        }                    },                    zoomFactorChanged: {newName: "onZoomFactorChanged"},                    onAreaClick: {                        name: "areaClick",                        deprecated: "areaSettings.click",                        deprecatedContext: function(arg) {                            return arg.target                        },                        deprecatedArgs: function(arg) {                            return [arg.target, arg.jQueryEvent]                        }                    },                    onAreaHoverChanged: {name: "areaHoverChanged"},                    onAreaSelectionChanged: {                        name: "areaSelectionChanged",                        deprecated: "areaSettings.selectionChanged",                        deprecatedContext: function(arg) {                            return arg.target                        },                        deprecatedArgs: function(arg) {                            return [arg.target]                        }                    },                    onMarkerClick: {                        name: "markerClick",                        deprecated: "markerSettings.click",                        deprecatedContext: function(arg) {                            return arg.target                        },                        deprecatedArgs: function(arg) {                            return [arg.target, arg.jQueryEvent]                        }                    },                    onMarkerHoverChanged: {name: "markerHoverChanged"},                    onMarkerSelectionChanged: {                        name: "markerSelectionChanged",                        deprecated: "markerSettings.selectionChanged",                        deprecatedContext: function(arg) {                            return arg.target                        },                        deprecatedArgs: function(arg) {                            return [arg.target]                        }                    }                }),                _setDeprecatedOptions: function() {                    this.callBase();                    $.extend(this._deprecatedOptions, {                        click: {                            since: "14.2",                            message: 'Use the "onClick" option instead'                        },                        centerChanged: {                            since: "14.2",                            message: 'Use the "onCenterChanged" option instead'                        },                        zoomFactorChanged: {                            since: "14.2",                            message: 'Use the "onZoomFactorChanged" option instead'                        },                        "areaSettings.click": {                            since: "14.2",                            message: 'Use the "onAreaClick" option instead'                        },                        "areaSettings.selectionChanged": {                            since: "14.2",                            message: 'Use the "onAreaSelectionChanged" option instead'                        },                        "markerSettings.click": {                            since: "14.2",                            message: 'Use the "onMarkerClick" option instead'                        },                        "markerSettings.selectionChanged": {                            since: "14.2",                            message: 'Use the "onMarkerSelectionChanged" option instead'                        },                        "markerSettings.font": {                            since: "14.2",                            message: 'Use the "label.font" option instead'                        }                    })                },                _rootClassPrefix: "dxm",                _rootClass: "dxm-vector-map",                _createThemeManager: function() {                    return this._factory.createThemeManager()                },                _initBackground: function(dataKey) {                    this._background = this._renderer.rect(0, 0, 0, 0).attr({"class": "dxm-background"}).data(dataKey, {type: "background"})                },                _initAreasManager: function(dataKey, notifyDirty, notifyReady) {                    var that = this;                    that._areasManager = that._factory.createAreasManager({                        container: that._root,                        renderer: that._renderer,                        projection: that._projection,                        themeManager: that._themeManager,                        tracker: that._tracker,                        dataKey: dataKey,                        eventTrigger: that._eventTrigger,                        dataExchanger: that._dataExchanger,                        notifyDirty: notifyDirty,                        notifyReady: notifyReady                    })                },                _initMarkersManager: function(dataKey, notifyDirty, notifyReady) {                    var that = this;                    that._markersManager = that._factory.createMarkersManager({                        container: that._root,                        renderer: that._renderer,                        projection: that._projection,                        themeManager: that._themeManager,                        tracker: that._tracker,                        eventTrigger: that._eventTrigger,                        dataExchanger: that._dataExchanger,                        dataKey: dataKey,                        notifyDirty: notifyDirty,                        notifyReady: notifyReady                    })                },                _initLegendsControl: function() {                    var that = this;                    that._legendsControl = that._factory.createLegendsControl({                        container: that._root,                        renderer: that._renderer,                        layoutControl: that._layoutControl,                        dataExchanger: that._dataExchanger                    })                },                _initControlBar: function(dataKey) {                    var that = this;                    that._controlBar = that._factory.createControlBar({                        container: that._root,                        renderer: that._renderer,                        layoutControl: that._layoutControl,                        projection: that._projection,                        dataKey: dataKey                    })                },                _initElements: function() {                    var that = this,                        dataKey = generateDataKey(),                        notifyCounter = 0;                    that._dataExchanger = new DataExchanger;                    that._initCenterHandler();                    that._projection = that._factory.createProjection();                    that._tracker = that._factory.createTracker({                        root: that._root,                        projection: that._projection,                        dataKey: dataKey                    });                    that._layoutControl = that._factory.createLayoutControl();                    that._initBackground(dataKey);                    that._initAreasManager(dataKey, notifyDirty, notifyReady);                    that._initMarkersManager(dataKey, notifyDirty, notifyReady);                    that._initLegendsControl();                    that._initControlBar(dataKey);                    function notifyDirty() {                        that._resetIsReady();                        ++notifyCounter                    }                    function notifyReady() {                        if (--notifyCounter === 0) {                            that._drawn();                            that.hideLoadingIndicator()                        }                    }                },                _initCore: function() {                    var that = this;                    that._root = that._renderer.root;                    that._root.attr({                        align: 'center',                        cursor: 'default'                    });                    that._initElements();                    that._projection.setBounds(that.option("bounds")).setMaxZoom(that.option("maxZoomFactor")).setZoom(that.option("zoomFactor"), true).setCenter(that.option("center"), true);                    that._setTrackerCallbacks();                    that._setControlBarCallbacks();                    that._setProjectionCallbacks()                },                _init: function() {                    var that = this;                    that.callBase.apply(that, arguments);                    that._areasManager.setData(that.option("mapData"));                    that._markersManager.setData(that.option("markers"))                },                _disposeCore: function() {                    var that = this;                    that._resetProjectionCallbacks();                    that._resetTrackerCallbacks();                    that._resetControlBarCallbacks();                    that._tracker.dispose();                    that._legendsControl.dispose();                    that._areasManager.dispose();                    that._markersManager.dispose();                    that._controlBar.dispose();                    that._layoutControl.dispose();                    that._disposeCenterHandler();                    that._dataExchanger.dispose();                    that._projection.dispose();                    that._dataExchanger = that._projection = that._tracker = that._layoutControl = that._root = that._background = that._areasManager = that._markersManager = that._controlBar = that._legendsControl = null                },                _initCenterHandler: function() {                    var that = this,                        xdrag,                        ydrag,                        isCursorChanged = false;                    that._centerHandler = {                        processStart: function(arg) {                            if (that._centeringEnabled) {                                xdrag = arg.x;                                ydrag = arg.y;                                that._noCenterChanged = true                            }                        },                        processMove: function(arg) {                            if (that._centeringEnabled) {                                if (!isCursorChanged) {                                    that._root.attr({cursor: "move"});                                    isCursorChanged = true                                }                                that._projection.moveCenter(xdrag - arg.x, ydrag - arg.y);                                xdrag = arg.x;                                ydrag = arg.y                            }                        },                        processEnd: function() {                            if (that._centeringEnabled) {                                that._root.attr({cursor: "default"});                                that._noCenterChanged = null;                                isCursorChanged && that._raiseCenterChanged();                                isCursorChanged = false                            }                        }                    }                },                _disposeCenterHandler: function() {                    this._centerHandler = null                },                _setProjectionCallbacks: function() {                    var that = this;                    that._projection.on({                        center: function() {                            that._raiseCenterChanged()                        },                        zoom: function() {                            that._raiseZoomFactorChanged()                        }                    });                    that._resetProjectionCallbacks = function() {                        that._resetProjectionCallbacks = that = null                    }                },                _setTrackerCallbacks: function() {                    var that = this,                        centerHandler = that._centerHandler,                        renderer = that._renderer,                        managers = {                            area: that._areasManager,                            marker: that._markersManager                        },                        controlBar = that._controlBar,                        tooltip = that._tooltip,                        isControlDrag = false;                    that._tracker.setCallbacks({                        click: function(arg) {                            var offset = renderer.getRootOffset(),                                manager;                            arg.$event.x = arg.x - offset.left;                            arg.$event.y = arg.y - offset.top;                            manager = managers[arg.data.type];                            if (manager)                                manager.raiseClick(arg.data.index, arg.$event);                            if (manager || arg.data.type === "background")                                that._eventTrigger("click", {jQueryEvent: arg.$event})                        },                        start: function(arg) {                            isControlDrag = arg.data.type === "control-bar";                            if (isControlDrag) {                                arg.data = arg.data.index;                                controlBar.processStart(arg)                            }                            else                                centerHandler.processStart(arg)                        },                        move: function(arg) {                            if (isControlDrag) {                                arg.data = arg.data.index;                                controlBar.processMove(arg)                            }                            else                                centerHandler.processMove(arg)                        },                        end: function(arg) {                            if (isControlDrag) {                                arg.data = arg.data.index;                                controlBar.processEnd(arg);                                isControlDrag = false                            }                            else                                centerHandler.processEnd()                        },                        zoom: function(arg) {                            controlBar.processZoom(arg)                        },                        "hover-on": function(arg) {                            var manager = managers[arg.data.type];                            if (manager)                                manager.hoverItem(arg.data.index, true)                        },                        "hover-off": function(arg) {                            var manager = managers[arg.data.type];                            if (manager)                                manager.hoverItem(arg.data.index, false)                        },                        "focus-on": function(arg, done) {                            var result = false,                                proxy;                            if (tooltip.isEnabled()) {                                proxy = managers[arg.data.type] ? managers[arg.data.type].getProxyItem(arg.data.index) : null;                                if (proxy && tooltip.show(proxy, {                                    x: 0,                                    y: 0,                                    offset: 0                                }, {target: proxy})) {                                    tooltip.move(arg.x, arg.y, TOOLTIP_OFFSET);                                    result = true                                }                            }                            done(result)                        },                        "focus-move": function(arg) {                            tooltip.move(arg.x, arg.y, TOOLTIP_OFFSET)                        },                        "focus-off": function() {                            tooltip.hide()                        }                    });                    that._resetTrackerCallbacks = function() {                        that._resetTrackerCallbacks = that = centerHandler = renderer = managers = controlBar = tooltip = null                    }                },                _setControlBarCallbacks: function() {                    var that = this,                        projection = that._projection,                        isZoomChanged;                    that._projection.on({zoom: function() {                            isZoomChanged = true                        }});                    that._controlBar.setCallbacks({                        reset: function(isCenter, isZoom) {                            if (isCenter)                                projection.setCenter(null);                            if (isZoom)                                projection.setZoom(null)                        },                        beginMove: function() {                            that._noCenterChanged = true                        },                        endMove: function() {                            that._noCenterChanged = null;                            that._raiseCenterChanged()                        },                        move: function(dx, dy) {                            projection.moveCenter(dx, dy)                        },                        zoom: function(zoom, center) {                            var coords,                                screenPosition;                            if (center) {                                screenPosition = that._renderer.getRootOffset();                                screenPosition = [center[0] - screenPosition.left, center[1] - screenPosition.top];                                coords = projection.fromScreenPoint(screenPosition[0], screenPosition[1])                            }                            isZoomChanged = false;                            projection.setScaledZoom(zoom);                            if (isZoomChanged && center)                                projection.setCenterByPoint(coords, screenPosition)                        }                    });                    that._resetControlBarCallbacks = function() {                        that._resetControlBarCallbacks = that = projection = null                    }                },                _setupInteraction: function() {                    var that = this;                    that._centerHandler.processEnd();                    that._centeringEnabled = !!_parseScalar(this._getOption("panningEnabled", true), true);                    that._zoomingEnabled = !!_parseScalar(this._getOption("zoomingEnabled", true), true);                    that._controlBar.setInteraction({                        centeringEnabled: that._centeringEnabled,                        zoomingEnabled: that._zoomingEnabled                    })                },                _getDefaultSize: function() {                    return {                            width: DEFAULT_WIDTH,                            height: DEFAULT_HEIGHT                        }                },                _applySize: function() {                    var that = this,                        width = that._canvas.width,                        height = that._canvas.height;                    that._projection.setSize(width, height);                    that._layoutControl.setSize(width, height);                    that._background.attr({                        x: 0,                        y: 0,                        width: width,                        height: height                    })                },                _resize: $.noop,                _clean: function() {                    var that = this;                    that._tracker.reset();                    that._layoutControl.stop();                    that._background.remove();                    that._areasManager.clean();                    that._markersManager.clean();                    that._controlBar.clean();                    that._legendsControl.clean()                },                _render: function() {                    var that = this;                    that._background.append(that._root);                    that._areasManager.render();                    that._markersManager.render();                    that._controlBar.render();                    that._legendsControl.render();                    that._layoutControl.start()                },                _optionChanged: function(args) {                    var that = this,                        value = args.value;                    switch (args.name) {                        case"mapData":                            that._areasManager.setData(value);                            break;                        case"markers":                            that._markersManager.setData(value);                            break;                        case"bounds":                            that._projection.setBounds(value);                            break;                        case"maxZoomFactor":                            that._projection.setMaxZoom(value);                            break;                        case"zoomFactor":                            that._projection.setZoom(value);                            break;                        case"center":                            that._projection.setCenter(value);                            break;                        case"background":                            that._setBackgroundOptions();                            break;                        case"areaSettings":                            that._setAreasManagerOptions();                            break;                        case"markerSettings":                            that._setMarkersManagerOptions();                            break;                        case"controlBar":                            that._setControlBarOptions();                            break;                        case"legends":                            that._setLegendsOptions();                            break;                        case"touchEnabled":                        case"wheelEnabled":                            that._setTrackerOptions();                            break;                        case"panningEnabled":                        case"zoomingEnabled":                            that._setupInteraction();                            break;                        default:                            that.callBase.apply(that, arguments);                            break                    }                },                _handleThemeOptionsCore: function() {                    var that = this;                    that._setBackgroundOptions();                    that._setAreasManagerOptions();                    that._setMarkersManagerOptions();                    that._setControlBarOptions();                    that._setLegendsOptions();                    that._setTrackerOptions();                    that._setupInteraction()                },                _setBackgroundOptions: function() {                    var settings = this._getOption("background");                    this._background.attr({                        "stroke-width": settings.borderWidth,                        stroke: settings.borderColor,                        fill: settings.color                    })                },                _setAreasManagerOptions: function() {                    this._areasManager.setOptions(this.option("areaSettings"));                    this._eventTrigger.update("onAreaClick");                    this._eventTrigger.update("onAreaSelectionChanged")                },                _setMarkersManagerOptions: function() {                    this._markersManager.setOptions(this.option("markerSettings"));                    this._eventTrigger.update("onMarkerClick");                    this._eventTrigger.update("onMarkerSelectionChanged")                },                _setControlBarOptions: function() {                    this._controlBar.setOptions(this._getOption("controlBar"))                },                _setLegendsOptions: function() {                    this._legendsControl.setOptions(this.option("legends"), this._themeManager.theme("legend"))                },                _setTrackerOptions: function() {                    this._tracker.setOptions({                        touchEnabled: this._getOption("touchEnabled", true),                        wheelEnabled: this._getOption("wheelEnabled", true)                    })                },                _raiseCenterChanged: function() {                    !this._noCenterChanged && this._eventTrigger("centerChanged", {center: this._projection.getCenter()})                },                _raiseZoomFactorChanged: function() {                    !this._noZoomFactorChanged && this._eventTrigger("zoomFactorChanged", {zoomFactor: this._projection.getZoom()})                },                _refresh: function() {                    var that = this,                        callBase = that.callBase;                    that._endLoading(function() {                        callBase.call(that)                    })                },                getAreas: function() {                    return this._areasManager.getProxyItems()                },                getMarkers: function() {                    return this._markersManager.getProxyItems()                },                clearAreaSelection: function(_noEvent) {                    this._areasManager.clearSelection(_noEvent);                    return this                },                clearMarkerSelection: function(_noEvent) {                    this._markersManager.clearSelection(_noEvent);                    return this                },                clearSelection: function(_noEvent) {                    return this.clearAreaSelection(_noEvent).clearMarkerSelection(_noEvent)                },                center: function(value, _noEvent) {                    var that = this;                    if (value === undefined)                        return that._projection.getCenter();                    else {                        that._noCenterChanged = _noEvent;                        that._projection.setCenter(value);                        that._noCenterChanged = null;                        return that                    }                },                zoomFactor: function(value, _noEvent) {                    var that = this;                    if (value === undefined)                        return that._projection.getZoom();                    else {                        that._noZoomFactorChanged = _noEvent;                        that._projection.setZoom(value);                        that._noZoomFactorChanged = null;                        return that                    }                },                viewport: function(value, _noEvent) {                    var that = this;                    if (value === undefined)                        return that._projection.getViewport();                    else {                        that._noCenterChanged = that._noZoomFactorChanged = _noEvent;                        that._projection.setViewport(value);                        that._noCenterChanged = that._noZoomFactorChanged = null;                        return that                    }                },                convertCoordinates: function(x, y) {                    return this._projection.fromScreenPoint(x, y)                },                _factory: {}            });        var DataExchanger = function() {                this._store = {}            };        DataExchanger.prototype = {            constructor: DataExchanger,            dispose: function() {                this._store = null;                return this            },            _get: function(category, name) {                var store = this._store[category] || (this._store[category] = {});                return store[name] || (store[name] = {})            },            set: function(category, name, data) {                var item = this._get(category, name);                item.data = data;                item.callback && item.callback(data);                return this            },            bind: function(category, name, callback) {                var item = this._get(category, name);                item.callback = callback;                item.data && callback(item.data);                return this            },            unbind: function(category, name) {                var item = this._get(category, name);                item.data = item.callback = null;                return this            }        };        DX.registerComponent("dxVectorMap", DX.viz.map, Map);        DX.viz.map._internal = {};        DX.viz.map.sources = {};        DX.viz.map._tests = {};        DX.viz.map._tests.DataExchanger = DataExchanger;        DX.viz.map._tests.stubDataExchanger = function(stub) {            DataExchanger = stub        }    })(DevExpress, jQuery);    /*! Module viz-vectormap, file projection.js */    (function(DX, $, undefined) {        var _Number = Number,            _isArray = DX.utils.isArray,            _math = Math,            _min = _math.min,            _max = _math.max,            _abs = _math.abs,            _tan = _math.tan,            _atan = _math.atan,            _exp = _math.exp,            _round = _math.round,            _ln = _math.log,            _pow = _math.pow,            PI = _math.PI,            QUARTER_PI = PI / 4,            PI_TO_360 = PI / 360,            TWO_TO_LN2 = 2 / _math.LN2,            MIN_BOUNDS_RANGE = 1 / 3600 / 180 / 10,            DEFAULT_MIN_ZOOM = 1,            DEFAULT_MAX_ZOOM = 1 << 8,            MERCATOR_MIN_LON = -180,            MERCATOR_MAX_LON = 180,            MERCATOR_MIN_LAT = -85.0511,            MERCATOR_MAX_LAT = 85.0511;        var mercator = {                aspectRatio: 1,                project: function(coordinates) {                    var lon = coordinates[0],                        lat = coordinates[1];                    return [lon <= MERCATOR_MIN_LON ? -1 : lon >= MERCATOR_MAX_LON ? +1 : lon / 180, lat <= MERCATOR_MIN_LAT ? +1 : lat >= MERCATOR_MAX_LAT ? -1 : -_ln(_tan(QUARTER_PI + lat * PI_TO_360)) / PI]                },                unproject: function(coordinates) {                    var x = coordinates[0],                        y = coordinates[1];                    return [x <= -1 ? MERCATOR_MIN_LON : x >= +1 ? MERCATOR_MAX_LON : 180 * x, y <= -1 ? MERCATOR_MAX_LAT : y >= +1 ? MERCATOR_MIN_LAT : (_atan(_exp(-PI * coordinates[1])) - QUARTER_PI) / PI_TO_360]                }            };        function createProjectUnprojectMethods(p1, p2, delta) {            var x0 = (p1[0] + p2[0]) / 2 - delta / 2,                y0 = (p1[1] + p2[1]) / 2 - delta / 2,                k = 2 / delta;            return {                    project: function(coordinates) {                        var p = mercator.project(coordinates);                        return [-1 + (p[0] - x0) * k, -1 + (p[1] - y0) * k]                    },                    unproject: function(coordinates) {                        var p = [x0 + (coordinates[0] + 1) / k, y0 + (coordinates[1] + 1) / k];                        return mercator.unproject(p)                    }                }        }        function floatsEqual(f1, f2) {            return _abs(f1 - f2) < 1E-8        }        function truncate(value, min, max, fallback) {            var _value = _Number(value);            if (_value < min)                _value = min;            else if (_value > max)                _value = max;            else if (!(min <= _value && _value <= max))                _value = fallback;            return _value        }        function truncateQuad(quad, min, max) {            return {                    lt: [truncate(quad[0], min[0], max[0], min[0]), truncate(quad[1], min[1], max[1], min[1])],                    rb: [truncate(quad[2], min[0], max[0], max[0]), truncate(quad[3], min[1], max[1], max[1])]                }        }        function parseBounds(bounds) {            var p1 = mercator.unproject([-1, -1]),                p2 = mercator.unproject([+1, +1]),                min = [_min(p1[0], p2[0]), _min(p1[1], p2[1])],                max = [_max(p1[0], p2[0]), _max(p1[1], p2[1])],                quad = bounds;            if (quad)                quad = truncateQuad(quad, min, max);            return {                    min: quad ? [_min(quad.lt[0], quad.rb[0]), _min(quad.lt[1], quad.rb[1])] : min,                    max: quad ? [_max(quad.lt[0], quad.rb[0]), _max(quad.lt[1], quad.rb[1])] : max                }        }        function selectCenterValue(value1, value2, center1, center2) {            var result;            if (value1 > -1 && value2 >= +1)                result = center1;            else if (value1 <= -1 && value2 < +1)                result = center2;            else                result = (center1 + center2) / 2;            return result        }        function Projection() {            this._events = {                project: $.Callbacks(),                transform: $.Callbacks(),                center: $.Callbacks(),                zoom: $.Callbacks(),                "max-zoom": $.Callbacks()            };            this.setBounds(null)        }        Projection.prototype = {            constructor: Projection,            _minZoom: DEFAULT_MIN_ZOOM,            _maxZoom: DEFAULT_MAX_ZOOM,            _zoom: DEFAULT_MIN_ZOOM,            _center: [NaN, NaN],            dispose: function() {                this._events = null;                return this            },            setSize: function(width, height) {                var that = this;                that._x0 = width / 2;                that._y0 = height / 2;                if (width / height <= mercator.aspectRatio) {                    that._xradius = width / 2;                    that._yradius = width / 2 / mercator.aspectRatio                }                else {                    that._xradius = height / 2 * mercator.aspectRatio;                    that._yradius = height / 2                }                that._events["transform"].fire(that.getTransform());                return that            },            setBounds: function(bounds) {                var that = this,                    _bounds = parseBounds(bounds),                    p1,                    p2,                    delta,                    methods;                that._minBound = _bounds.min;                that._maxBound = _bounds.max;                p1 = mercator.project(_bounds.min);                p2 = mercator.project(_bounds.max);                delta = [_abs(p2[0] - p1[0]), _abs(p2[1] - p1[1])];                delta = _min(delta[0] > MIN_BOUNDS_RANGE ? delta[0] : 2, delta[1] > MIN_BOUNDS_RANGE ? delta[1] : 2);                methods = delta < 2 ? createProjectUnprojectMethods(p1, p2, delta) : mercator;                that._project = methods.project;                that._unproject = methods.unproject;                that._defaultCenter = that._unproject([0, 0]);                that.setCenter(that._defaultCenter);                that._events.project.fire();                return that            },            _toScreen: function(coordinates) {                return [this._x0 + this._xradius * coordinates[0], this._y0 + this._yradius * coordinates[1]]            },            _fromScreen: function(coordinates) {                return [(coordinates[0] - this._x0) / this._xradius, (coordinates[1] - this._y0) / this._yradius]            },            _toTransformed: function(coordinates) {                return [coordinates[0] * this._zoom + this._dxcenter, coordinates[1] * this._zoom + this._dycenter]            },            _toTransformedFast: function(coordinates) {                return [coordinates[0] * this._zoom, coordinates[1] * this._zoom]            },            _fromTransformed: function(coordinates) {                return [(coordinates[0] - this._dxcenter) / this._zoom, (coordinates[1] - this._dycenter) / this._zoom]            },            _adjustCenter: function() {                var that = this,                    center = that._project(that._center);                that._dxcenter = -center[0] * that._zoom;                that._dycenter = -center[1] * that._zoom            },            projectArea: function(coordinates) {                var i = 0,                    ii = _isArray(coordinates) ? coordinates.length : 0,                    subcoords,                    j,                    jj,                    subresult,                    result = [];                for (; i < ii; ++i) {                    subcoords = coordinates[i];                    subresult = [];                    for (j = 0, jj = _isArray(subcoords) ? subcoords.length : 0; j < jj; ++j)                        subresult.push(this._project(subcoords[j]));                    result.push(subresult)                }                return result            },            projectPoint: function(coordinates) {                return coordinates ? this._project(coordinates) : []            },            getAreaCoordinates: function(data) {                var k = 0,                    kk = data.length,                    partialData,                    i,                    ii,                    list = [],                    partialPath,                    point;                for (; k < kk; ++k) {                    partialData = data[k];                    partialPath = [];                    for (i = 0, ii = partialData.length; i < ii; ++i) {                        point = this._toScreen(this._toTransformedFast(partialData[i]));                        partialPath.push(point[0], point[1])                    }                    list.push(partialPath)                }                return list            },            getPointCoordinates: function(data) {                var point = this._toScreen(this._toTransformedFast(data));                return {                        x: _round(point[0]),                        y: _round(point[1])                    }            },            getSquareSize: function(size) {                return [size[0] * this._zoom * this._xradius, size[1] * this._zoom * this._yradius]            },            getZoom: function() {                return this._zoom            },            setZoom: function(zoom, _forceEvent) {                var that = this,                    zoom__ = that._zoom;                that._zoom = truncate(zoom, that._minZoom, that._maxZoom, that._minZoom);                that._adjustCenter();                if (!floatsEqual(zoom__, that._zoom) || _forceEvent)                    that._events.zoom.fire(that.getZoom(), that.getTransform());                return that            },            getScaledZoom: function() {                return _round((this._scale.length - 1) * _ln(this._zoom) / _ln(this._maxZoom))            },            setScaledZoom: function(scaledZoom) {                return this.setZoom(this._scale[_round(scaledZoom)])            },            getZoomScalePartition: function() {                return this._scale.length - 1            },            _setupScaling: function() {                var that = this,                    k = _round(TWO_TO_LN2 * _ln(that._maxZoom)),                    step,                    zoom,                    i = 1;                k = k > 4 ? k : 4;                step = _pow(that._maxZoom, 1 / k);                zoom = that._minZoom;                that._scale = [zoom];                for (; i <= k; ++i)                    that._scale.push(zoom *= step)            },            setMaxZoom: function(maxZoom) {                var that = this;                that._minZoom = DEFAULT_MIN_ZOOM;                that._maxZoom = truncate(maxZoom, that._minZoom, _Number.MAX_VALUE, DEFAULT_MAX_ZOOM);                that._setupScaling();                if (that._zoom > that._maxZoom)                    that.setZoom(that._maxZoom);                that._events["max-zoom"].fire(that._maxZoom);                return that            },            getMinZoom: function() {                return this._minZoom            },            getMaxZoom: function() {                return this._maxZoom            },            getCenter: function() {                return [this._center[0], this._center[1]]            },            setCenter: function(center, _forceEvent) {                var that = this,                    _center = _isArray(center) ? center : [],                    center__ = that._center;                that._center = [truncate(_center[0], that._minBound[0], that._maxBound[0], that._defaultCenter[0]), truncate(_center[1], that._minBound[1], that._maxBound[1], that._defaultCenter[1])];                that._adjustCenter();                if (!floatsEqual(center__[0], that._center[0]) || !floatsEqual(center__[1], that._center[1]) || _forceEvent)                    that._events.center.fire(that.getCenter(), that.getTransform());                return that            },            setCenterByPoint: function(coordinates, screenPosition) {                var that = this,                    p = that._project(coordinates),                    q = that._fromScreen(screenPosition);                return that.setCenter(that._unproject([-q[0] / that._zoom + p[0], -q[1] / that._zoom + p[1]]))            },            moveCenter: function(screenDx, screenDy) {                var that = this,                    current = that._toScreen(that._toTransformed(that._project(that._center))),                    center = that._unproject(that._fromTransformed(that._fromScreen([current[0] + screenDx, current[1] + screenDy])));                return that.setCenter(center)            },            getViewport: function() {                var p1 = this._unproject(this._fromTransformed([-1, -1])),                    p2 = this._unproject(this._fromTransformed([+1, +1]));                return [p1[0], p1[1], p2[0], p2[1]]            },            setViewport: function(viewport) {                var that = this;                if (!_isArray(viewport))                    return that.setZoom(that._minZoom).setCenter(that._defaultCenter);                var _viewport = truncateQuad(viewport, that._minBound, that._maxBound),                    lt = that._project(_viewport.lt),                    rb = that._project(_viewport.rb),                    l = _min(lt[0], rb[0]),                    t = _min(lt[1], rb[1]),                    r = _max(lt[0], rb[0]),                    b = _max(lt[1], rb[1]),                    zoom = 2 / _max(r - l, b - t),                    xc = selectCenterValue(l, r, -1 - zoom * l, +1 - zoom * r),                    yc = selectCenterValue(t, b, -1 - zoom * t, +1 - zoom * b);                return that.setZoom(zoom).setCenter(that._unproject([-xc / zoom, -yc / zoom]))            },            getTransform: function() {                return {                        translateX: this._dxcenter * this._xradius,                        translateY: this._dycenter * this._yradius                    }            },            fromScreenPoint: function(x, y) {                return this._unproject(this._fromTransformed(this._fromScreen([x, y])))            },            on: function(obj) {                $.each(this._events, function(name, list) {                    obj[name] && list.add(obj[name])                });                return this            }        };        DX.viz.map._tests.Projection = Projection;        DX.viz.map._tests.mercator = mercator;        DX.viz.map._tests._DEBUG_stubMercator = function(stub) {            mercator = stub        };        DX.viz.map._tests._DEBUG_restoreMercator = function() {            mercator = DX.viz.map._tests.mercator        };        DX.viz.map.dxVectorMap.prototype._factory.createProjection = function() {            return new Projection        }    })(DevExpress, jQuery);    /*! Module viz-vectormap, file controlBar.js */    (function(DX, undefined) {        var _Number = Number,            _math = Math,            _round = _math.round,            _floor = _math.floor,            _pow = _math.pow,            _ln = _math.log,            _LN2 = _math.LN2,            utils = DX.viz.core.utils,            _parseScalar = utils.parseScalar,            parseHorizontalAlignment = utils.enumParser(["left", "center", "right"]),            parseVerticalAlignment = utils.enumParser(["top", "bottom"]),            COMMAND_RESET = "command-reset",            COMMAND_MOVE_UP = "command-move-up",            COMMAND_MOVE_RIGHT = "command-move-right",            COMMAND_MOVE_DOWN = "command-move-down",            COMMAND_MOVE_LEFT = "command-move-left",            COMMAND_ZOOM_IN = "command-zoom-in",            COMMAND_ZOOM_OUT = "command-zoom-out",            COMMAND_ZOOM_DRAG_LINE = "command-zoom-drag-line",            COMMAND_ZOOM_DRAG = "command-zoom-drag",            EVENT_TARGET_TYPE = "control-bar",            FLAG_CENTERING = 1,            FLAG_ZOOMING = 2,            SIZE_OPTIONS = {                bigCircleSize: 58,                smallCircleSize: 28,                buttonSize: 10,                arrowButtonOffset: 20,                incdecButtonSize: 11,                incButtonOffset: 66,                decButtonOffset: 227,                sliderLineStartOffset: 88.5,                sliderLineEndOffset: 205.5,                sliderLength: 20,                sliderWidth: 8,                trackerGap: 4            },            OFFSET_X = 30.5,            OFFSET_Y = 30.5,            TOTAL_WIDTH = 61,            TOTAL_HEIGHT = 274,            COMMAND_TO_TYPE_MAP = {};        COMMAND_TO_TYPE_MAP[COMMAND_RESET] = ResetCommand;        COMMAND_TO_TYPE_MAP[COMMAND_MOVE_UP] = COMMAND_TO_TYPE_MAP[COMMAND_MOVE_RIGHT] = COMMAND_TO_TYPE_MAP[COMMAND_MOVE_DOWN] = COMMAND_TO_TYPE_MAP[COMMAND_MOVE_LEFT] = MoveCommand;        COMMAND_TO_TYPE_MAP[COMMAND_ZOOM_IN] = COMMAND_TO_TYPE_MAP[COMMAND_ZOOM_OUT] = ZoomCommand;        COMMAND_TO_TYPE_MAP[COMMAND_ZOOM_DRAG] = ZoomDragCommand;        var ControlBar = DX.Class.inherit({                _flags: 0,                ctor: function(parameters) {                    var that = this;                    that._params = parameters;                    that._createElements(parameters.renderer, parameters.dataKey);                    parameters.layoutControl.addItem(that);                    that._subscribeToProjection(parameters.projection);                    that._setVisibility(false)                },                setCallbacks: function(callbacks) {                    this._callbacks = callbacks;                    return this                },                _createElements: function(renderer, dataKey) {                    var that = this,                        buttonsGroups,                        trackersGroup;                    that._root = renderer.g().attr({"class": "dxm-control-bar"});                    buttonsGroups = that._buttonsGroup = renderer.g().attr({"class": "dxm-control-buttons"}).append(that._root);                    trackersGroup = renderer.g().attr({                        stroke: "none",                        "stroke-width": 0,                        fill: "#000000",                        opacity: 0.0001                    }).css({cursor: "pointer"}).append(that._root);                    that._createButtons(renderer, dataKey, buttonsGroups);                    that._createTrackers(renderer, dataKey, trackersGroup)                },                _createButtons: function(renderer, dataKey, group) {                    var that = this,                        options = SIZE_OPTIONS,                        size = options.buttonSize / 2,                        offset1 = options.arrowButtonOffset - size,                        offset2 = options.arrowButtonOffset,                        incdecButtonSize = options.incdecButtonSize / 2,                        directionOptions = {                            "stroke-linecap": "square",                            fill: "none"                        },                        line = "line";                    renderer.circle(0, 0, options.bigCircleSize / 2).append(group);                    renderer.circle(0, 0, size).attr({fill: "none"}).append(group);                    renderer.path([-size, -offset1, 0, -offset2, size, -offset1], line).attr(directionOptions).append(group);                    renderer.path([offset1, -size, offset2, 0, offset1, size], line).attr(directionOptions).append(group);                    renderer.path([size, offset1, 0, offset2, -size, offset1], line).attr(directionOptions).append(group);                    renderer.path([-offset1, size, -offset2, 0, -offset1, -size], line).attr(directionOptions).append(group);                    renderer.circle(0, options.incButtonOffset, options.smallCircleSize / 2).append(group);                    renderer.path([[-incdecButtonSize, options.incButtonOffset, incdecButtonSize, options.incButtonOffset], [0, options.incButtonOffset - incdecButtonSize, 0, options.incButtonOffset + incdecButtonSize]], "area").append(group);                    renderer.circle(0, options.decButtonOffset, options.smallCircleSize / 2).append(group);                    renderer.path([-incdecButtonSize, options.decButtonOffset, incdecButtonSize, options.decButtonOffset], "area").append(group);                    that._progressBar = renderer.path([], "area").append(group);                    that._zoomDrag = renderer.rect(_floor(-options.sliderLength / 2), _floor(options.sliderLineEndOffset - options.sliderWidth / 2), options.sliderLength, options.sliderWidth).append(group);                    that._sliderLineLength = options.sliderLineEndOffset - options.sliderLineStartOffset                },                _createTrackers: function(renderer, dataKey, group) {                    var options = SIZE_OPTIONS,                        size = _round((options.arrowButtonOffset - options.trackerGap) / 2),                        offset1 = options.arrowButtonOffset - size,                        offset2 = _round(_pow(options.bigCircleSize * options.bigCircleSize / 4 - size * size, 0.5)),                        size2 = offset2 - offset1;                    renderer.rect(-size, -size, size * 2, size * 2).data(dataKey, {                        index: COMMAND_RESET,                        type: EVENT_TARGET_TYPE                    }).append(group);                    renderer.rect(-size, -offset2, size * 2, size2).data(dataKey, {                        index: COMMAND_MOVE_UP,                        type: EVENT_TARGET_TYPE                    }).append(group);                    renderer.rect(offset1, -size, size2, size * 2).data(dataKey, {                        index: COMMAND_MOVE_RIGHT,                        type: EVENT_TARGET_TYPE                    }).append(group);                    renderer.rect(-size, offset1, size * 2, size2).data(dataKey, {                        index: COMMAND_MOVE_DOWN,                        type: EVENT_TARGET_TYPE                    }).append(group);                    renderer.rect(-offset2, -size, size2, size * 2).data(dataKey, {                        index: COMMAND_MOVE_LEFT,                        type: EVENT_TARGET_TYPE                    }).append(group);                    renderer.circle(0, options.incButtonOffset, options.smallCircleSize / 2).data(dataKey, {                        index: COMMAND_ZOOM_IN,                        type: EVENT_TARGET_TYPE                    }).append(group);                    renderer.circle(0, options.decButtonOffset, options.smallCircleSize / 2).data(dataKey, {                        index: COMMAND_ZOOM_OUT,                        type: EVENT_TARGET_TYPE                    }).append(group);                    renderer.rect(-2, options.sliderLineStartOffset - 2, 4, options.sliderLineEndOffset - options.sliderLineStartOffset + 4).css({cursor: "default"}).data(dataKey, {                        index: COMMAND_ZOOM_DRAG_LINE,                        type: EVENT_TARGET_TYPE                    }).append(group);                    this._zoomDragCover = renderer.rect(-options.sliderLength / 2, options.sliderLineEndOffset - options.sliderWidth / 2, options.sliderLength, options.sliderWidth).data(dataKey, {                        index: COMMAND_ZOOM_DRAG,                        type: EVENT_TARGET_TYPE                    }).append(group)                },                _subscribeToProjection: function(projection) {                    var that = this;                    projection.on({                        zoom: function() {                            that._adjustZoom(projection.getScaledZoom())                        },                        "max-zoom": function() {                            that._zoomPartition = projection.getZoomScalePartition();                            that._sliderUnitLength = that._sliderLineLength / that._zoomPartition;                            that._adjustZoom(projection.getScaledZoom())                        }                    })                },                dispose: function() {                    var that = this;                    that._params.layoutControl.removeItem(that);                    that._root.clear();                    that._params = that._callbacks = that._root = that._buttonsGroup = that._zoomDrag = that._zoomDragCover = that._progressBar = null;                    return that                },                resize: function(size) {                    this._setVisibility(size !== null && this._options.enabled && this._flags);                    return this                },                _setVisibility: function(state) {                    this._root.attr({visibility: state ? null : "hidden"})                },                getLayoutOptions: function() {                    var options = this._options;                    return this._rendered && options.enabled && this._flags ? {                            width: 2 * options.margin + TOTAL_WIDTH,                            height: 2 * options.margin + TOTAL_HEIGHT,                            horizontalAlignment: options.horizontalAlignment,                            verticalAlignment: options.verticalAlignment                        } : null                },                locate: function(x, y) {                    this._root.attr({                        translateX: x + this._options.margin + OFFSET_X,                        translateY: y + this._options.margin + OFFSET_Y                    });                    return this                },                setInteraction: function(interaction) {                    var that = this;                    that.processEnd();                    if (_parseScalar(interaction.centeringEnabled, true))                        that._flags |= FLAG_CENTERING;                    else                        that._flags &= ~FLAG_CENTERING;                    if (_parseScalar(interaction.zoomingEnabled, true))                        that._flags |= FLAG_ZOOMING;                    else                        that._flags &= ~FLAG_ZOOMING;                    if (that._rendered)                        that._refresh();                    return that                },                setOptions: function(options) {                    var that = this;                    that.processEnd();                    that._buttonsGroup.attr({                        "stroke-width": options.borderWidth,                        stroke: options.borderColor,                        fill: options.color,                        "fill-opacity": options.opacity                    });                    that._options = {                        enabled: !!_parseScalar(options.enabled, true),                        margin: options.margin > 0 ? _Number(options.margin) : 0,                        horizontalAlignment: parseHorizontalAlignment(options.horizontalAlignment, "left"),                        verticalAlignment: parseVerticalAlignment(options.verticalAlignment, "top")                    };                    that._rendered && that._refresh();                    return that                },                _refresh: function() {                    var isVisible = this._flags && this._options.enabled;                    this._setVisibility(isVisible);                    if (isVisible)                        this.updateLayout()                },                clean: function() {                    var that = this;                    that._rendered = null;                    that._root.remove();                    return that                },                render: function() {                    var that = this;                    that._rendered = true;                    that._root.append(that._params.container);                    that._refresh();                    return that                },                _adjustZoom: function(zoom) {                    var that = this,                        transform,                        y,                        start = SIZE_OPTIONS.sliderLineStartOffset,                        end = SIZE_OPTIONS.sliderLineEndOffset,                        h = SIZE_OPTIONS.sliderWidth;                    that._zoomFactor = _round(zoom);                    that._zoomFactor >= 0 || (that._zoomFactor = 0);                    that._zoomFactor <= that._zoomPartition || (that._zoomFactor = that._zoomPartition);                    transform = {translateY: -that._zoomFactor * that._sliderUnitLength};                    y = end - h / 2 + transform.translateY;                    that._progressBar.attr({points: [[0, start, 0, _math.max(start, y)], [0, _math.min(end, y + h), 0, end]]});                    that._zoomDrag.attr(transform);                    that._zoomDragCover.attr(transform)                },                _applyZoom: function(center) {                    this._callbacks.zoom(this._zoomFactor, this._flags & FLAG_CENTERING ? center : undefined)                },                processStart: function(arg) {                    var commandType = COMMAND_TO_TYPE_MAP[arg.data];                    this._command = commandType && this._options.enabled && commandType.flags & this._flags ? new commandType(this, arg) : null;                    return this                },                processMove: function(arg) {                    this._command && this._command.update(arg);                    return this                },                processEnd: function() {                    this._command && this._command.finish();                    this._command = null;                    return this                },                processZoom: function(arg) {                    var that = this,                        zoomFactor;                    if (that._flags & FLAG_ZOOMING) {                        if (arg.delta)                            zoomFactor = arg.delta;                        else if (arg.ratio)                            zoomFactor = _ln(arg.ratio) / _LN2;                        that._adjustZoom(that._zoomFactor + zoomFactor);                        that._applyZoom([arg.x, arg.y])                    }                    return that                }            });        function disposeCommand(command) {            delete command._owner;            command.update = function(){};            command.finish = function(){}        }        function ResetCommand(owner, arg) {            this._owner = owner;            this._command = arg.data        }        ResetCommand.flags = FLAG_CENTERING | FLAG_ZOOMING;        ResetCommand.prototype.update = function(arg) {            arg.data !== this._command && disposeCommand(this)        };        ResetCommand.prototype.finish = function() {            var flags = this._owner._flags;            this._owner._callbacks.reset(!!(flags & FLAG_CENTERING), !!(flags & FLAG_ZOOMING));            if (flags & FLAG_ZOOMING)                this._owner._adjustZoom(0);            disposeCommand(this)        };        function MoveCommand(owner, arg) {            this._command = arg.data;            var timeout = null,                interval = 100,                dx = 0,                dy = 0;            switch (this._command) {                case COMMAND_MOVE_UP:                    dy = -10;                    break;                case COMMAND_MOVE_RIGHT:                    dx = 10;                    break;                case COMMAND_MOVE_DOWN:                    dy = 10;                    break;                case COMMAND_MOVE_LEFT:                    dx = -10;                    break            }            function callback() {                owner._callbacks.move(dx, dy);                timeout = setTimeout(callback, interval)            }            this._stop = function() {                clearTimeout(timeout);                owner._callbacks.endMove();                this._stop = owner = null;                return this            };            arg = null;            owner._callbacks.beginMove();            callback()        }        MoveCommand.flags = FLAG_CENTERING;        MoveCommand.prototype.update = function(arg) {            this._command !== arg.data && this.finish()        };        MoveCommand.prototype.finish = function() {            disposeCommand(this._stop())        };        function ZoomCommand(owner, arg) {            this._owner = owner;            this._command = arg.data;            var timeout = null,                interval = 150,                dzoom = this._command === COMMAND_ZOOM_IN ? 1 : -1;            function callback() {                owner._adjustZoom(owner._zoomFactor + dzoom);                timeout = setTimeout(callback, interval)            }            this._stop = function() {                clearTimeout(timeout);                this._stop = owner = null;                return this            };            arg = null;            callback()        }        ZoomCommand.flags = FLAG_ZOOMING;        ZoomCommand.prototype.update = function(arg) {            this._command !== arg.data && this.finish()        };        ZoomCommand.prototype.finish = function() {            this._owner._applyZoom();            disposeCommand(this._stop())        };        function ZoomDragCommand(owner, arg) {            this._owner = owner;            this._zoomFactor = owner._zoomFactor;            this._pos = arg.y        }        ZoomDragCommand.flags = FLAG_ZOOMING;        ZoomDragCommand.prototype.update = function(arg) {            var owner = this._owner;            owner._adjustZoom(this._zoomFactor + owner._zoomPartition * (this._pos - arg.y) / owner._sliderLineLength)        };        ZoomDragCommand.prototype.finish = function() {            this._owner._applyZoom();            disposeCommand(this)        };        DX.viz.map._tests.ControlBar = ControlBar;        var COMMAND_TO_TYPE_MAP__ORIGINAL = COMMAND_TO_TYPE_MAP;        DX.viz.map._tests.stubCommandToTypeMap = function(map) {            COMMAND_TO_TYPE_MAP = map        };        DX.viz.map._tests.restoreCommandToTypeMap = function() {            COMMAND_TO_TYPE_MAP = COMMAND_TO_TYPE_MAP__ORIGINAL        };        DX.viz.map.dxVectorMap.prototype._factory.createControlBar = function(parameters) {            return new ControlBar(parameters)        }    })(DevExpress);    /*! Module viz-vectormap, file tracker.js */    (function(DX, $, undefined) {        var _math = Math,            _abs = _math.abs,            _sqrt = _math.sqrt,            _round = _math.round,            _addNamespace = DX.ui.events.addNamespace,            _parseScalar = DX.viz.core.utils.parseScalar,            _now = $.now,            _NAME = DX.viz.map.dxVectorMap.prototype.NAME,            EVENTS = {};        setupEvents();        var EVENT_START = "start",            EVENT_MOVE = "move",            EVENT_END = "end",            EVENT_ZOOM = "zoom",            EVENT_HOVER_ON = "hover-on",            EVENT_HOVER_OFF = "hover-off",            EVENT_CLICK = "click",            EVENT_FOCUS_ON = "focus-on",            EVENT_FOCUS_MOVE = "focus-move",            EVENT_FOCUS_OFF = "focus-off",            CLICK_TIME_THRESHOLD = 500,            CLICK_COORD_THRESHOLD_MOUSE = 5,            CLICK_COORD_THRESHOLD_TOUCH = 20,            DRAG_COORD_THRESHOLD_MOUSE = 5,            DRAG_COORD_THRESHOLD_TOUCH = 10,            FOCUS_ON_DELAY_MOUSE = 300,            FOCUS_OFF_DELAY_MOUSE = 300,            FOCUS_ON_DELAY_TOUCH = 300,            FOCUS_OFF_DELAY_TOUCH = 400,            FOCUS_COORD_THRESHOLD_MOUSE = 5,            WHEEL_COOLDOWN = 50,            WHEEL_DIRECTION_COOLDOWN = 300;        function Tracker(parameters) {            var that = this;            that._root = parameters.root;            that._callbacks = {};            that._createEventHandlers(parameters.dataKey);            that._createProjectionHandlers(parameters.projection);            that._focus = new Focus(that._callbacks);            that._attachHandlers()        }        Tracker.prototype = {            constructor: Tracker,            dispose: function() {                var that = this;                that._detachHandlers();                that._focus.dispose();                that._root = that._callbacks = that._focus = that._docHandlers = that._rootHandlers = null;                return that            },            _startClick: function(event, data) {                if (!data)                    return;                var coords = getEventCoords(event);                this._clickState = {                    x: coords.x,                    y: coords.y,                    threshold: isTouchEvent(event) ? CLICK_COORD_THRESHOLD_TOUCH : CLICK_COORD_THRESHOLD_MOUSE,                    time: _now()                }            },            _endClick: function(event, data) {                var state = this._clickState,                    threshold,                    coords;                if (!state)                    return;                if (_now() - state.time <= CLICK_TIME_THRESHOLD) {                    threshold = state.threshold;                    coords = getEventCoords(event);                    if (_abs(coords.x - state.x) <= threshold && _abs(coords.y - state.y) <= threshold)                        this._callbacks[EVENT_CLICK]({                            data: data,                            x: coords.x,                            y: coords.y,                            $event: event                        })                }                this._clickState = null            },            _startDrag: function(event, data) {                if (!data)                    return;                var coords = getEventCoords(event),                    state = this._dragState = {                        x: coords.x,                        y: coords.y,                        data: data                    };                this._callbacks[EVENT_START]({                    x: state.x,                    y: state.y,                    data: state.data                })            },            _moveDrag: function(event, data) {                var state = this._dragState,                    coords,                    threshold;                if (!state)                    return;                coords = getEventCoords(event);                threshold = isTouchEvent(event) ? DRAG_COORD_THRESHOLD_TOUCH : DRAG_COORD_THRESHOLD_MOUSE;                if (state.active || _abs(coords.x - state.x) > threshold || _abs(coords.y - state.y) > threshold) {                    state.x = coords.x;                    state.y = coords.y;                    state.active = true;                    state.data = data || {};                    this._callbacks[EVENT_MOVE]({                        x: state.x,                        y: state.y,                        data: state.data                    })                }            },            _endDrag: function() {                var state = this._dragState;                if (!state)                    return;                this._dragState = null;                this._callbacks[EVENT_END]({                    x: state.x,                    y: state.y,                    data: state.data                })            },            _wheelZoom: function(event, data) {                if (!data)                    return;                var that = this,                    lock = that._wheelLock,                    time = _now(),                    delta,                    coords;                if (time - lock.time <= WHEEL_COOLDOWN)                    return;                if (time - lock.dirTime > WHEEL_DIRECTION_COOLDOWN)                    lock.dir = 0;                delta = adjustWheelDelta(event.originalEvent.wheelDelta / 120 || event.originalEvent.detail / -3 || 0, lock);                if (delta === 0)                    return;                coords = getEventCoords(event);                that._callbacks[EVENT_ZOOM]({                    delta: delta,                    x: coords.x,                    y: coords.y                });                lock.time = lock.dirTime = time            },            _startZoom: function(event, data) {                if (!isTouchEvent(event) || !data)                    return;                var state = this._zoomState = this._zoomState || {},                    coords,                    pointer2;                if (state.pointer1 && state.pointer2)                    return;                if (state.pointer1 === undefined) {                    state.pointer1 = getPointerId(event) || 0;                    coords = getMultitouchEventCoords(event, state.pointer1);                    state.x1 = state.x1_0 = coords.x;                    state.y1 = state.y1_0 = coords.y                }                if (state.pointer2 === undefined) {                    pointer2 = getPointerId(event) || 1;                    if (pointer2 !== state.pointer1) {                        coords = getMultitouchEventCoords(event, pointer2);                        if (coords) {                            state.x2 = state.x2_0 = coords.x;                            state.y2 = state.y2_0 = coords.y;                            state.pointer2 = pointer2;                            state.ready = true;                            this._endDrag()                        }                    }                }            },            _moveZoom: function(event) {                var state = this._zoomState,                    coords;                if (!state || !isTouchEvent(event))                    return;                if (state.pointer1 !== undefined) {                    coords = getMultitouchEventCoords(event, state.pointer1);                    if (coords) {                        state.x1 = coords.x;                        state.y1 = coords.y                    }                }                if (state.pointer2 !== undefined) {                    coords = getMultitouchEventCoords(event, state.pointer2);                    if (coords) {                        state.x2 = coords.x;                        state.y2 = coords.y                    }                }            },            _endZoom: function(event) {                var state = this._zoomState,                    startDistance,                    currentDistance;                if (!state || !isTouchEvent(event))                    return;                if (state.ready) {                    startDistance = getDistance(state.x1_0, state.y1_0, state.x2_0, state.y2_0);                    currentDistance = getDistance(state.x1, state.y1, state.x2, state.y2);                    this._callbacks[EVENT_ZOOM]({                        ratio: currentDistance / startDistance,                        x: (state.x1_0 + state.x2_0) / 2,                        y: (state.y1_0 + state.y2_0) / 2                    })                }                this._zoomState = null            },            _startHover: function(event, data) {                this._doHover(event, data, true)            },            _moveHover: function(event, data) {                this._doHover(event, data, false)            },            _doHover: function(event, data, isTouch) {                var that = this;                if (that._dragState && that._dragState.active || that._zoomState && that._zoomState.ready) {                    that._cancelHover();                    return                }                if (isTouchEvent(event) !== isTouch || that._hoverTarget === event.target || that._hoverState && that._hoverState.data === data)                    return;                that._cancelHover();                if (data) {                    that._hoverState = {data: data};                    that._callbacks[EVENT_HOVER_ON]({data: data})                }                that._hoverTarget = event.target            },            _cancelHover: function() {                var state = this._hoverState;                this._hoverState = this._hoverTarget = null;                if (state)                    this._callbacks[EVENT_HOVER_OFF]({data: state.data})            },            _startFocus: function(event, data) {                this._doFocus(event, data, true)            },            _moveFocus: function(event, data) {                this._doFocus(event, data, false)            },            _doFocus: function(event, data, isTouch) {                var that = this;                if (that._dragState && that._dragState.active || that._zoomState && that._zoomState.ready) {                    that._cancelFocus();                    return                }                if (isTouchEvent(event) !== isTouch)                    return;                that._focus.turnOff(isTouch ? FOCUS_OFF_DELAY_TOUCH : FOCUS_OFF_DELAY_MOUSE);                data && that._focus.turnOn(data, getEventCoords(event), isTouch ? FOCUS_ON_DELAY_TOUCH : FOCUS_ON_DELAY_MOUSE, isTouch)            },            _endFocus: function(event) {                if (!isTouchEvent(event))                    return;                this._focus.cancelOn()            },            _cancelFocus: function() {                this._focus.cancel()            },            _createEventHandlers: function(DATA_KEY) {                var that = this;                that._docHandlers = {};                that._rootHandlers = {};                that._docHandlers[EVENTS.start] = function(event) {                    var isTouch = isTouchEvent(event),                        data = $(event.target).data(DATA_KEY);                    if (isTouch && !that._isTouchEnabled)                        return;                    data && event.preventDefault();                    that._startClick(event, data);                    that._startDrag(event, data);                    that._startZoom(event, data);                    that._startHover(event, data);                    that._startFocus(event, data)                };                that._docHandlers[EVENTS.move] = function(event) {                    var isTouch = isTouchEvent(event),                        data = $(event.target).data(DATA_KEY);                    if (isTouch && !that._isTouchEnabled)                        return;                    that._moveDrag(event, data);                    that._moveZoom(event, data);                    that._moveHover(event, data);                    that._moveFocus(event, data)                };                that._docHandlers[EVENTS.end] = function(event) {                    var isTouch = isTouchEvent(event),                        data = $(event.target).data(DATA_KEY);                    if (isTouch && !that._isTouchEnabled)                        return;                    that._endClick(event, data);                    that._endDrag(event, data);                    that._endZoom(event, data);                    that._endFocus(event, data)                };                that._rootHandlers[EVENTS.wheel] = function(event) {                    that._cancelFocus();                    if (!that._isWheelEnabled)                        return;                    var data = $(event.target).data(DATA_KEY);                    if (data) {                        event.preventDefault();                        event.stopPropagation();                        that._wheelZoom(event, data)                    }                };                that._wheelLock = {dir: 0}            },            _createProjectionHandlers: function(projection) {                var that = this;                projection.on({                    center: handler,                    zoom: handler                });                function handler() {                    that._cancelFocus()                }            },            reset: function() {                var that = this;                that._clickState = null;                that._endDrag();                that._cancelHover();                that._cancelFocus();                return that            },            setCallbacks: function(callbacks) {                $.extend(this._callbacks, callbacks);                return this            },            setOptions: function(options) {                var that = this;                that.reset();                that._detachHandlers();                that._isTouchEnabled = !!_parseScalar(options.touchEnabled, true);                that._isWheelEnabled = !!_parseScalar(options.wheelEnabled, true);                that._attachHandlers();                return that            },            _detachHandlers: function() {                var that = this;                if (that._isTouchEnabled)                    that._root.css({                        "touch-action": "",                        "-ms-touch-action": "",                        "-webkit-user-select": ""                    }).off(_addNamespace("MSHoldVisual", _NAME)).off(_addNamespace("contextmenu", _NAME));                $(document).off(that._docHandlers);                that._root.off(that._rootHandlers)            },            _attachHandlers: function() {                var that = this;                if (that._isTouchEnabled)                    that._root.css({                        "touch-action": "none",                        "-ms-touch-action": "none",                        "-webkit-user-select": "none"                    }).on(_addNamespace("MSHoldVisual", _NAME), function(event) {                        event.preventDefault()                    }).on(_addNamespace("contextmenu", _NAME), function(event) {                        isTouchEvent(event) && event.preventDefault()                    });                $(document).on(that._docHandlers);                that._root.on(that._rootHandlers)            }        };        var Focus = function(callbacks) {                var that = this,                    _activeData = null,                    _data = null,                    _disabled = false,                    _onTimer = null,                    _offTimer = null,                    _x,                    _y;                that.dispose = function() {                    clearTimeout(_onTimer);                    clearTimeout(_offTimer);                    that.turnOn = that.turnOff = that.cancel = that.cancelOn = that.dispose = that = callbacks = _activeData = _data = _onTimer = _offTimer = null                };                that.turnOn = function(data, coords, timeout, forceTimeout) {                    if (data === _data && _disabled)                        return;                    _disabled = false;                    _data = data;                    if (_activeData) {                        _x = coords.x;                        _y = coords.y;                        clearTimeout(_onTimer);                        _onTimer = setTimeout(function() {                            _onTimer = null;                            if (_data === _activeData) {                                callbacks[EVENT_FOCUS_MOVE]({                                    data: _data,                                    x: _x,                                    y: _y                                });                                onCheck(true)                            }                            else                                callbacks[EVENT_FOCUS_ON]({                                    data: _data,                                    x: _x,                                    y: _y                                }, onCheck)                        }, forceTimeout ? timeout : 0)                    }                    else if (!_onTimer || _abs(coords.x - _x) > FOCUS_COORD_THRESHOLD_MOUSE || _abs(coords.y - _y) > FOCUS_COORD_THRESHOLD_MOUSE || forceTimeout) {                        _x = coords.x;                        _y = coords.y;                        clearTimeout(_onTimer);                        _onTimer = setTimeout(function() {                            _onTimer = null;                            callbacks[EVENT_FOCUS_ON]({                                data: _data,                                x: _x,                                y: _y                            }, onCheck)                        }, timeout)                    }                    function onCheck(result) {                        _disabled = !result;                        if (result) {                            _activeData = _data;                            clearTimeout(_offTimer);                            _offTimer = null                        }                    }                };                that.turnOff = function(timeout) {                    clearTimeout(_onTimer);                    _onTimer = null;                    _data = null;                    if (_activeData && !_disabled)                        _offTimer = _offTimer || setTimeout(function() {                            _offTimer = null;                            callbacks[EVENT_FOCUS_OFF]({data: _activeData});                            _activeData = null                        }, timeout)                };                that.cancel = function() {                    clearTimeout(_onTimer);                    clearTimeout(_offTimer);                    if (_activeData)                        callbacks[EVENT_FOCUS_OFF]({data: _activeData});                    _activeData = _data = _onTimer = _offTimer = null                };                that.cancelOn = function() {                    clearTimeout(_onTimer);                    _onTimer = null                }            };        DX.viz.map._tests.Tracker = Tracker;        DX.viz.map._tests._DEBUG_forceEventMode = function(mode) {            setupEvents(mode)        };        DX.viz.map._tests.Focus = Focus;        DX.viz.map._tests._DEBUG_stubFocusType = function(focusType) {            Focus = focusType        };        DX.viz.map._tests._DEBUG_restoreFocusType = function() {            Focus = DX.viz.map._tests.Focus        };        DX.viz.map.dxVectorMap.prototype._factory.createTracker = function(parameters) {            return new Tracker(parameters)        };        function getDistance(x1, y1, x2, y2) {            return _sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2))        }        function isTouchEvent(event) {            var type = event.originalEvent.type,                pointerType = event.originalEvent.pointerType;            return /^touch/.test(type) || /^MSPointer/.test(type) && pointerType !== 4 || /^pointer/.test(type) && pointerType !== "mouse"        }        function selectItem(flags, items) {            var i = 0,                ii = flags.length,                item;            for (; i < ii; ++i)                if (flags[i]) {                    item = items[i];                    break                }            return _addNamespace(item || items[i], _NAME)        }        function setupEvents() {            var flags = [navigator.pointerEnabled, navigator.msPointerEnabled, "ontouchstart" in window];            if (arguments.length)                flags = [arguments[0] === "pointer", arguments[0] === "MSPointer", arguments[0] === "touch"];            EVENTS = {                start: selectItem(flags, ["pointerdown", "MSPointerDown", "touchstart mousedown", "mousedown"]),                move: selectItem(flags, ["pointermove", "MSPointerMove", "touchmove mousemove", "mousemove"]),                end: selectItem(flags, ["pointerup", "MSPointerUp", "touchend mouseup", "mouseup"]),                wheel: selectItem([], ["mousewheel DOMMouseScroll"])            }        }        function getEventCoords(event) {            var originalEvent = event.originalEvent,                touch = originalEvent.touches && originalEvent.touches[0] || {};            return {                    x: touch.pageX || originalEvent.pageX || event.pageX,                    y: touch.pageY || originalEvent.pageY || event.pageY                }        }        function getPointerId(event) {            return event.originalEvent.pointerId        }        function getMultitouchEventCoords(event, pointerId) {            var originalEvent = event.originalEvent;            if (originalEvent.pointerId !== undefined)                originalEvent = originalEvent.pointerId === pointerId ? originalEvent : null;            else                originalEvent = originalEvent.touches[pointerId];            return originalEvent ? {                    x: originalEvent.pageX || event.pageX,                    y: originalEvent.pageY || event.pageY                } : null        }        function adjustWheelDelta(delta, lock) {            if (delta === 0)                return 0;            var _delta = _abs(delta),                sign = _round(delta / _delta);            if (lock.dir && sign !== lock.dir)                return 0;            lock.dir = sign;            if (_delta < 0.1)                _delta = 0;            else if (_delta < 1)                _delta = 1;            else if (_delta > 4)                _delta = 4;            else                _delta = _round(_delta);            return sign * _delta        }    })(DevExpress, jQuery);    /*! Module viz-vectormap, file themeManager.js */    (function(DX, $, undefined) {        var _Number = Number,            _extend = $.extend,            _each = $.each;        var ThemeManager = DX.viz.core.BaseThemeManager.inherit({                _themeSection: "map",                _fontFields: ["areaSettings.label.font", "markerSettings.label.font", "tooltip.font", "legend.font", "loadingIndicator.font"],                getCommonAreaSettings: function(options) {                    var settings = _extend(true, {}, this._theme.areaSettings, options),                        palette,                        i,                        colors;                    if (settings.paletteSize > 0) {                        palette = new DX.viz.core.GradientPalette(settings.palette, settings.paletteSize);                        for (i = 0, colors = []; i < settings.paletteSize; ++i)                            colors.push(palette.getColor(i));                        settings._colors = colors                    }                    return settings                },                getAreaSettings: function(commonSettings, options) {                    var settings = _extend(true, {}, commonSettings, options);                    settings.borderWidth = _Number(settings.borderWidth) || 0;                    settings.borderColor = settings.borderColor || null;                    if (options.color === undefined && options.paletteIndex >= 0)                        settings.color = commonSettings._colors[options.paletteIndex];                    settings.color = settings.color || null;                    settings.hoveredBorderWidth = _Number(settings.hoveredBorderWidth) || settings.borderWidth;                    settings.hoveredBorderColor = settings.hoveredBorderColor || settings.borderColor;                    settings.hoveredColor = settings.hoveredColor || settings.color;                    settings.selectedBorderWidth = _Number(settings.selectedBorderWidth) || settings.borderWidth;                    settings.selectedBorderColor = settings.selectedBorderColor || settings.borderColor;                    settings.selectedColor = settings.selectedColor || settings.color;                    return settings                },                getCommonMarkerSettings: function(options) {                    options && !options.label && options.font && (options.label = {font: options.font}) && (options.font = undefined);                    var theme = _extend({}, this._theme.markerSettings),                        _options = _extend({}, options),                        themeParts = {},                        optionsParts = {},                        settings;                    _each(theme, function(name, themePart) {                        if (name[0] === "_") {                            themeParts[name] = themePart;                            optionsParts[name] = _options[name];                            theme[name] = _options[name] = undefined                        }                    });                    settings = _extend(true, {}, theme, _options);                    _each(themeParts, function(name, themePart) {                        settings[name] = _extend(true, {}, theme, themePart, _options, optionsParts[name])                    });                    return settings                },                getMarkerSettings: function(commonSettings, options, type) {                    var settings = _extend(true, {}, commonSettings["_" + type], options);                    settings.borderWidth = _Number(settings.borderWidth) || 0;                    settings.borderColor = settings.borderColor || null;                    settings.color = settings.color || null;                    settings.opacity = settings.opacity || null;                    settings.hoveredBorderWidth = _Number(settings.hoveredBorderWidth) || settings.borderWidth;                    settings.hoveredBorderColor = settings.hoveredBorderColor || settings.borderColor;                    settings.hoveredColor = settings.hoveredColor || settings.color;                    settings.hoveredOpacity = settings.hoveredOpacity || settings.opacity;                    settings.selectedBorderWidth = _Number(settings.selectedBorderWidth) || settings.borderWidth;                    settings.selectedBorderColor = settings.selectedBorderColor || settings.borderColor;                    settings.selectedColor = settings.selectedColor || settings.color;                    settings.selectedOpacity = settings.selectedOpacity || settings.opacity;                    return settings                },                getPieColors: function(commonSettings, count) {                    var colors = commonSettings._pie._colors || [],                        palette,                        i,                        _count = count > 8 ? count : 8;                    if (colors.length < _count) {                        palette = new DX.viz.core.Palette(commonSettings._pie.palette, {                            stepHighlight: 50,                            theme: this.themeName()                        });                        for (i = 0, colors = []; i < _count; ++i)                            colors.push(palette.getNextColor());                        commonSettings._pie._colors = colors                    }                    return colors                }            });        DX.viz.map._tests.ThemeManager = ThemeManager;        DX.viz.map.dxVectorMap.prototype._factory.createThemeManager = function() {            return new ThemeManager        }    })(DevExpress, jQuery);    /*! Module viz-vectormap, file legend.js */    (function(DX, $, undefined) {        var _String = String,            _isArray = DX.utils.isArray,            _extend = $.extend,            _each = $.each,            _BaseLegend = DX.viz.core.Legend;        function Legend(parameters) {            var that = this;            that._params = parameters;            that._root = parameters.renderer.g().attr({"class": "dxm-legend"});            parameters.layoutControl.addItem(that);            _BaseLegend.apply(that, [{                    renderer: parameters.renderer,                    group: that._root,                    backgroundClass: null,                    itemsGroupClass: null,                    textField: "text",                    getFormatObject: function(data) {                        return data                    }                }]);            that._onDataChanged = function(items) {                var itemsForUpdate = $.map(items, function(item) {                        return _extend(true, {states: {normal: {fill: item.color}}}, item)                    });                that.update(itemsForUpdate, that._options);                that._refresh()            }        }        var legendPrototype = Legend.prototype = DX.utils.clone(_BaseLegend.prototype);        legendPrototype.constructor = Legend;        legendPrototype.dispose = function() {            var that = this;            that._params.layoutControl.removeItem(that);            that._unbindData();            that._params = that._root = that._onDataChanged = null;            return _BaseLegend.prototype.dispose.apply(that, arguments)        };        legendPrototype.clean = function() {            this._rendered = false;            this._root.remove();            return this        };        legendPrototype.render = function() {            var that = this;            that._root.append(that._params.container);            that._rendered = true;            that._refresh();            return that        };        legendPrototype.resize = function(size) {            if (size === null)                this.erase();            else                this.setSize(size).draw();            return this        };        legendPrototype.locate = _BaseLegend.prototype.shift;        legendPrototype._unbindData = function() {            if (this._dataCategory)                this._params.dataExchanger.unbind(this._dataCategory, this._dataName)        };        legendPrototype._bindData = function(info) {            this._params.dataExchanger.bind(this._dataCategory = info.category, this._dataName = info.name, this._onDataChanged)        };        var sourceMap = {                areacolorgroups: {                    category: "areas",                    name: "color"                },                markercolorgroups: {                    category: "markers",                    name: "color"                },                markersizegroups: {                    category: "markers",                    name: "size"                }            };        var unknownSource = {                category: "UNKNOWN",                name: "UNKNOWN"            };        legendPrototype.setOptions = function(options) {            var that = this;            that.update(that._data, options);            that._unbindData();            that._bindData(sourceMap[_String(options.source).toLowerCase()] || unknownSource);            that._refresh();            return that        };        legendPrototype._refresh = function() {            if (this._rendered)                this.updateLayout()        };        function LegendsControl(parameters) {            this._parameters = parameters;            this._items = []        }        LegendsControl.prototype = {            constructor: LegendsControl,            dispose: function() {                _each(this._items, function(_, item) {                    item.dispose()                });                this._parameters = this._items = null;                return this            },            setOptions: function(options, theme) {                var optionList = _isArray(options) ? options : [],                    i = 0,                    ii = optionList.length,                    item,                    newItems = [],                    items = this._items;                for (; i < ii; ++i) {                    item = (items[i] || new Legend(this._parameters)).setOptions(_extend(true, {}, theme, optionList[i]));                    newItems.push(item)                }                for (ii = items.length; i < ii; ++i)                    items[i].clean().dispose();                this._items = newItems            },            clean: function() {                _each(this._items, function(_, item) {                    item.clean()                });                return this            },            render: function() {                _each(this._items, function(_, item) {                    item.render()                });                return this            }        };        DX.viz.map.dxVectorMap.prototype._factory.createLegendsControl = function(parameters) {            return new LegendsControl(parameters)        };        DX.viz.map._tests.Legend = Legend;        DX.viz.map._tests.LegendsControl = LegendsControl;        DX.viz.map._tests.stubLegendType = function(stub) {            Legend = stub        };        DX.viz.map._tests.restoreLegendType = function() {            Legend = DX.viz.map._tests.Legend        };        DX.viz.map._tests.extendLegendSourceMap = function(name, value) {            sourceMap[name] = value        }    })(DevExpress, jQuery);    /*! Module viz-vectormap, file layout.js */    (function(DX, $, undefined) {        var _round = Math.round,            _min = Math.min,            _max = Math.max,            _each = $.each,            _inArray = $.inArray,            horizontalAlignmentMap = {                left: 0,                center: 1,                right: 2            },            verticalAlignmentMap = {                top: 0,                bottom: 1            };        function getCellIndex(options) {            return verticalAlignmentMap[options.verticalAlignment] * 3 + horizontalAlignmentMap[options.horizontalAlignment]        }        function createCells(canvas, items) {            var hstep = (canvas.right - canvas.left) / 3,                vstep = (canvas.bottom - canvas.top) / 2,                h1 = canvas.left,                h2 = _round(h1 + hstep),                h3 = _round(h1 + hstep + hstep),                h4 = canvas.right,                v1 = canvas.top,                v2 = _round(v1 + vstep),                v3 = canvas.bottom,                cells = [{rect: [h1, v1, h2, v2]}, {                        rect: [h2, v1, h3, v2],                        center: true                    }, {                        rect: [h3, v1, h4, v2],                        horInv: true                    }, {                        rect: [h1, v2, h2, v3],                        verInv: true                    }, {                        rect: [h2, v2, h3, v3],                        center: true,                        verInv: true                    }, {                        rect: [h3, v2, h4, v3],                        horInv: true,                        verInv: true                    }],                itemsList = [[], [], [], [], [], []];            _each(items, function(_, item) {                var options = item.getLayoutOptions();                if (options)                    itemsList[getCellIndex(options)].push({                        item: item,                        width: options.width,                        height: options.height                    })            });            _each(cells, function(i, cell) {                if (itemsList[i].length)                    cell.items = itemsList[i];                else {                    if (cell.center)                        cell.rect[0] = cell.rect[2] = (cell.rect[0] + cell.rect[2]) / 2;                    else                        cell.rect[cell.horInv ? 0 : 2] = cell.rect[cell.horInv ? 2 : 0];                    cell.rect[cell.verInv ? 1 : 3] = cell.rect[cell.verInv ? 3 : 1]                }            });            return cells        }        function adjustCellSizes(cells) {            _each([0, 1, 2, 3, 4, 5], function(_, index) {                var cell = cells[index],                    otherCell = cells[(index + 3) % 6];                if (cell.items)                    if (!otherCell.items) {                        cell.rect[1] = _min(cell.rect[1], otherCell.rect[3]);                        cell.rect[3] = _max(cell.rect[3], otherCell.rect[1])                    }            });            _each([1, 4], function(_, index) {                var cell = cells[index],                    otherCell1 = cells[index - 1],                    otherCell2 = cells[index + 1],                    size1,                    size2;                if (cell.items) {                    if (!otherCell1.items && !otherCell2.items) {                        size1 = cell.rect[0] - otherCell1.rect[2];                        size2 = otherCell2.rect[0] - cell.rect[2];                        if (size1 > size2)                            if (size1 / size2 >= 2) {                                cell.rect[0] -= size1;                                cell.right = true                            }                            else {                                cell.rect[0] -= size2;                                cell.rect[2] += size2                            }                        else if (size2 / size1 >= 2) {                            cell.rect[2] += size2;                            cell.center = null                        }                        else {                            cell.rect[0] -= size1;                            cell.rect[2] += size1                        }                    }                }                else {                    if (otherCell1.items)                        otherCell1.rect[2] = (cell.rect[0] + cell.rect[2]) / 2;                    if (otherCell2.items)                        otherCell2.rect[0] = (cell.rect[0] + cell.rect[2]) / 2                }            })        }        function adjustCellsAndApplyLayout(cells, forceMode) {            var hasHiddenItems = false;            adjustCellSizes(cells);            _each(cells, function(_, cell) {                if (cell.items)                    hasHiddenItems = applyCellLayout(cell, forceMode) || hasHiddenItems            });            return hasHiddenItems        }        function applyCellLayout(cell, forceMode) {            var cellRect = cell.rect,                cellWidth = cellRect[2] - cellRect[0],                cellHeight = cellRect[3] - cellRect[1],                xoffset = 0,                yoffset = 0,                currentHeight = 0,                totalL = cellRect[2],                totalT = cellRect[3],                totalR = cellRect[0],                totalB = cellRect[1],                moves = [],                hasHiddenItems = false;            _each(cell.items, function(_, item) {                if (item.width > cellWidth || item.height > cellHeight) {                    moves.push(null);                    hasHiddenItems = true;                    return forceMode || false                }                if (xoffset + item.width > cellWidth) {                    yoffset += currentHeight;                    xoffset = currentHeight = 0                }                if (yoffset + item.height > cellHeight) {                    moves.push(null);                    hasHiddenItems = true;                    return forceMode || false                }                currentHeight = _max(currentHeight, item.height);                var dx = cell.horInv ? cellRect[2] - item.width - xoffset : cellRect[0] + xoffset,                    dy = cell.verInv ? cellRect[3] - item.height - yoffset : cellRect[1] + yoffset;                xoffset += item.width;                totalL = _min(totalL, dx);                totalT = _min(totalT, dy);                totalR = _max(totalR, dx + item.width);                totalB = _max(totalB, dy + item.height);                moves.push([dx, dy])            });            if (forceMode || !hasHiddenItems) {                xoffset = 0;                if (cell.right)                    xoffset = cellRect[2] - cellRect[0] - totalR + totalL;                else if (cell.center)                    xoffset = _round((cellRect[2] - cellRect[0] - totalR + totalL) / 2);                _each(cell.items, function(i, item) {                    var move = moves[i];                    if (move)                        item.item.locate(move[0] + xoffset, move[1]);                    else                        item.item.resize(null)                });                cell.rect = [totalL, totalT, totalR, totalB];                cell.items = null            }            return hasHiddenItems        }        function applyLayout(canvas, items) {            var cells = createCells(canvas, items);            if (adjustCellsAndApplyLayout(cells))                adjustCellsAndApplyLayout(cells, true)        }        function LayoutControl() {            var that = this;            that._items = [];            that._suspended = true;            that._updateLayout = function() {                that._update()            }        }        LayoutControl.prototype = {            constructor: LayoutControl,            dispose: function() {                this._items = this._updateLayout = null;                return this            },            setSize: function(width, height) {                this._size = {                    width: width,                    height: height                };                this._update();                return this            },            stop: function() {                this._suspended = true;                return this            },            start: function() {                this._suspended = null;                this._update();                return this            },            addItem: function(item) {                this._items.push(item);                item.updateLayout = this._updateLayout;                return this            },            removeItem: function(item) {                this._items.splice(_inArray(item, this._items), 1);                item.updateLayout = null;                return this            },            _update: function() {                if (this._suspended)                    return;                var size = this._size;                _each(this._items, function(_, item) {                    item.resize(size)                });                applyLayout({                    left: 0,                    top: 0,                    right: size.width,                    bottom: size.height                }, this._items)            }        };        DX.viz.map.dxVectorMap.prototype._factory.createLayoutControl = function() {            return new LayoutControl        };        DX.viz.map._tests.LayoutControl = LayoutControl    })(DevExpress, jQuery);    /*! Module viz-vectormap, file mapItemsManager.js */    (function(DX, $, undefined) {        var _isFinite = isFinite,            _utils = DX.utils,            _coreUtils = DX.viz.core.utils,            _isString = _utils.isString,            _isArray = _utils.isArray,            _isFunction = _utils.isFunction,            _patchFontOptions = _coreUtils.patchFontOptions,            _parseScalar = _coreUtils.parseScalar,            _extend = $.extend,            _each = $.each,            _map = $.map;        var SELECTIONS = {                none: null,                single: -1,                multiple: NaN            };        function getSelection(selectionMode) {            var selection = String(selectionMode).toLowerCase();            selection = selection in SELECTIONS ? SELECTIONS[selection] : SELECTIONS.single;            if (selection !== null)                selection = {                    state: {},                    single: selection || null                };            return selection        }        function createEventTriggers(context, trigger, names) {            context.raiseHoverChanged = function(handle, state) {                trigger(names.hoverChanged, {                    target: handle.proxy,                    state: state                })            };            context.raiseSelectionChanged = function(handle) {                trigger(names.selectionChanged, {target: handle.proxy})            }        }        var MapItemsManager = DX.Class.inherit({                _rootClass: null,                ctor: function(parameters) {                    var that = this;                    that._params = parameters;                    that._init();                    parameters.projection.on({                        project: function() {                            that._reproject()                        },                        transform: function(transform) {                            that._transform(transform);                            that._relocate()                        },                        center: function(_, transform) {                            that._transform(transform)                        },                        zoom: function(_, transform) {                            that._transform(transform);                            that._relocate()                        }                    })                },                _init: function() {                    var that = this;                    that._context = {                        renderer: that._params.renderer,                        projection: that._params.projection,                        dataKey: that._params.dataKey,                        selection: null,                        getItemSettings: that._createItemSettingsBuilder()                    };                    that._initRoot();                    createEventTriggers(that._context, that._params.eventTrigger, that._eventNames)                },                _createItemSettingsBuilder: function() {                    var that = this;                    return function(proxy, settings) {                            var result = {};                            _each(that._grouping, function(settingField, grouping) {                                var value,                                    index;                                if (_isFinite(value = grouping.callback(proxy)) && (index = findGroupPosition(value, grouping.groups)) >= 0)                                    result[settingField] = grouping.groups[index][settingField]                            });                            return that._getItemSettings(proxy, _extend({}, settings, result))                        }                },                _initRoot: function() {                    this._context.root = this._root = this._params.renderer.g().attr({"class": this._rootClass})                },                dispose: function() {                    var that = this;                    that._destroyHandles();                    that._params = that._context = that._grouping = null;                    that._disposeRoot();                    return that                },                _disposeRoot: function() {                    this._root = null                },                clean: function() {                    var that = this;                    that._destroyItems();                    that._removeRoot();                    that._rendered = false;                    return that                },                _removeRoot: function() {                    this._root.remove()                },                setOptions: function(options) {                    var that = this;                    that._processOptions(options || {});                    that._params.notifyDirty();                    that._destroyItems();                    that._createItems(that._params.notifyReady);                    return that                },                render: function() {                    var that = this;                    that._rendered = true;                    that._params.notifyDirty();                    that._appendRoot();                    that._createItems(that._params.notifyReady, true);                    return that                },                _processOptions: function(options) {                    var that = this,                        settings = that._commonSettings = that._getCommonSettings(options),                        context = that._context;                    that._customizeCallback = _isFunction(settings.customize) ? settings.customize : $.noop;                    context.hover = !!_parseScalar(settings.hoverEnabled, true);                    if (context.selection)                        _each(context.selection.state, function(_, handle) {                            handle && handle.resetSelected()                        });                    context.selection = getSelection(settings.selectionMode);                    that._grouping = {};                    that._updateGrouping()                },                _appendRoot: function() {                    this._root.append(this._params.container)                },                _destroyItems: function() {                    var that = this;                    that._clearRoot();                    clearTimeout(that._labelsTimeout);                    that._rendered && that._handles && _each(that._handles, function(_, handle) {                        if (handle.item) {                            handle.item.dispose();                            handle.item = null                        }                    })                },                _clearRoot: function() {                    this._root.clear()                },                _destroyHandles: function() {                    this._handles && _each(this._handles, function(_, handle) {                        handle.dispose()                    });                    this._handles = null                },                _createHandles: function(source) {                    var that = this;                    if (_isArray(source))                        that._handles = _map(source, function(dataItem, i) {                            dataItem = dataItem || {};                            var handle = new MapItemHandle(that._context, that._getItemCoordinates(dataItem), that._getItemAttributes(dataItem), i, that._itemType),                                proxy = handle.proxy;                            that._initProxy(proxy, dataItem);                            handle.settings = that._customizeCallback.call(proxy, proxy) || {};                            if (handle.settings.isSelected)                                proxy.selected(true);                            return handle                        })                },                _createItems: function(notifyReady) {                    var that = this,                        selectedItems = [],                        immediateReady = true;                    if (that._rendered && that._handles) {                        _each(that._handles, function(_, handle) {                            handle.item = that._createItem(handle.proxy).init(that._context, handle.proxy).project().update(handle.settings).locate();                            if (handle.proxy.selected())                                selectedItems.push(handle.item)                        });                        _each(selectedItems, function(_, item) {                            item.setSelectedState()                        });                        that._arrangeItems();                        if (that._commonSettings.label.enabled) {                            immediateReady = false;                            clearTimeout(that._labelsTimeout);                            that._labelsTimeout = setTimeout(function() {                                _each(that._handles, function(_, handle) {                                    handle.item.createLabel()                                });                                notifyReady()                            })                        }                    }                    immediateReady && notifyReady()                },                _processSource: null,                setData: function(data) {                    var that = this;                    that._params.notifyDirty();                    if (_isString(data))                        $.getJSON(data).done(updateSource).fail(function() {                            updateSource(null)                        });                    else                        updateSource(data);                    return that;                    function updateSource(source) {                        if (that._rendered)                            that._params.tracker.reset();                        that._destroyItems();                        that._destroyHandles();                        that._createHandles(that._processSource(source));                        that._createItems(that._params.notifyReady)                    }                },                _transform: function(transform) {                    this._root.attr(transform)                },                _reproject: function() {                    this._rendered && this._handles && _each(this._handles, function(_, handle) {                        handle.item.project().locate()                    })                },                _relocate: function() {                    this._rendered && this._handles && _each(this._handles, function(_, handle) {                        handle.item.locate()                    })                },                hoverItem: function(index, state) {                    this._handles[index].setHovered(state);                    return this                },                selectItem: function(index, state, noCallback) {                    this._handles[index].setSelected(state, noCallback);                    return this                },                clearSelection: function() {                    var selection = this._context.selection;                    if (selection)                        _each(selection.state, function(_, handle) {                            handle && handle.setSelected(false)                        });                    return this                },                raiseClick: function(index, $event) {                    this._params.eventTrigger(this._eventNames.click, {                        target: this._handles[index].proxy,                        jQueryEvent: $event                    });                    return this                },                getProxyItems: function() {                    return _map(this._handles, function(handle) {                            return handle.proxy                        })                },                getProxyItem: function(index) {                    return this._handles[index].proxy                },                _performGrouping: function(partition, settingField, valueCallback, valuesCallback) {                    var groups = createGroups(partition),                        values;                    if (groups) {                        values = valuesCallback(groups.length);                        _each(groups, function(i, group) {                            group.index = i;                            group[settingField] = values[i]                        });                        this._grouping[settingField] = {                            callback: valueCallback,                            groups: groups                        }                    }                    else {                        delete this._grouping[settingField];                        groups = []                    }                    this._params.dataExchanger.set(this._dataCategory, settingField, groups)                },                _groupByColor: function(colorGroups, palette, valueCallback) {                    this._performGrouping(colorGroups, "color", valueCallback, function(count) {                        var _palette = new DX.viz.core.GradientPalette(palette, count),                            i = 0,                            list = [];                        for (; i < count; ++i)                            list.push(_palette.getColor(i));                        return list                    })                }            });        MapItemsManager.prototype.TEST_getContext = function() {            return this._context        };        MapItemsManager.prototype.TEST_performGrouping = MapItemsManager.prototype._performGrouping;        MapItemsManager.prototype.TEST_groupByColor = MapItemsManager.prototype._groupByColor;        DX.viz.map._internal.mapItemBehavior = {            init: function(ctx, proxy) {                var that = this;                that._ctx = ctx;                that._data = {                    index: proxy.index,                    type: proxy.type                };                that._proxy = proxy;                that._root = that._createRoot().append(that._ctx.root);                return that            },            dispose: function() {                disposeItem(this);                return this            },            project: function() {                var that = this;                that._coords = that._project(that._ctx.projection, that._proxy.coordinates());                return this            },            locate: function() {                var that = this;                that._locate(that._transform(that._ctx.projection, that._coords));                that._label && that._label.value && that._locateLabel();                return that            },            update: function(settings) {                var that = this;                that._settings = that._ctx.getItemSettings(that._proxy, settings);                that._update(that._settings);                that._label && that._updateLabel();                return that            },            createLabel: function() {                var that = this;                that._label = {                    root: that._createLabelRoot(),                    text: that._ctx.renderer.text(),                    tracker: that._ctx.renderer.rect().attr({                        stroke: "none",                        "stroke-width": 0,                        fill: "#000000",                        opacity: 0.0001                    }).data(that._ctx.dataKey, that._data)                };                that._updateLabel();                return that            },            _updateLabel: function() {                var that = this,                    settings = that._settings.label;                that._label.value = String(this._proxy.text || this._proxy.attribute(this._settings.label.dataField) || "");                if (that._label.value) {                    that._label.text.attr({                        text: that._label.value,                        x: 0,                        y: 0                    }).css(_patchFontOptions(settings.font)).attr({                        align: "center",                        stroke: settings.stroke,                        "stroke-width": settings["stroke-width"],                        "stroke-opacity": settings["stroke-opacity"]                    }).append(that._label.root);                    that._label.tracker.append(that._label.root);                    that._adjustLabel();                    that._locateLabel()                }            }        };        var MapItemHandle = function(context, coordinates, attributes, index, type) {                var handle = this;                handle._ctx = context;                handle._idx = index;                handle._hovered = handle._selected = false;                attributes = _extend({}, attributes);                handle.proxy = {                    index: index,                    type: type,                    coordinates: function() {                        return coordinates                    },                    attribute: function(name, value) {                        if (arguments.length > 1) {                            attributes[name] = value;                            return this                        }                        else                            return arguments.length > 0 ? attributes[name] : attributes                    },                    selected: function(state, _noEvent) {                        if (arguments.length > 0) {                            handle.setSelected(!!state, _noEvent);                            return this                        }                        else                            return handle._selected                    },                    applySettings: function(settings) {                        _extend(true, handle.settings, settings);                        handle.item && handle.item.update(handle.settings);                        return this                    }                }            };        MapItemHandle.prototype = {            constructor: MapItemHandle,            dispose: function() {                disposeItem(this.proxy);                disposeItem(this);                return this            },            setHovered: function(state) {                state = !!state;                var that = this;                if (that._ctx.hover && that._hovered !== state) {                    that._hovered = state;                    if (that.item) {                        if (that._hovered)                            that.item.onHover();                        if (!that._selected) {                            that.item[that._hovered ? "setHoveredState" : "setDefaultState"]();                            that._ctx.raiseHoverChanged(that, that._hovered)                        }                    }                }                return that            },            resetSelected: function() {                this._selected = false;                return this            },            setSelected: function(state, _noEvent) {                state = !!state;                var that = this,                    context = that._ctx,                    selection = that._ctx.selection,                    tmp;                if (selection && that._selected !== state) {                    that._selected = state;                    tmp = selection.state[selection.single];                    selection.state[selection.single] = null;                    if (tmp)                        tmp.setSelected(false);                    selection.state[selection.single || that._idx] = state ? that : null;                    if (that.item) {                        that.item[state ? "setSelectedState" : that._hovered ? "setHoveredState" : "setDefaultState"]();                        if (!_noEvent)                            context.raiseSelectionChanged(that)                    }                }                return that            }        };        function disposeItem(item) {            _each(item, function(name) {                item[name] = null            })        }        function createGroups(partition) {            var i,                ii,                groups = null;            if (_isArray(partition) && partition.length > 1) {                groups = [];                for (i = 0, ii = partition.length - 1; i < ii; ++i)                    groups.push({                        start: Number(partition[i]),                        end: Number(partition[i + 1])                    })            }            return groups        }        function findGroupPosition(value, groups) {            var i = 0,                ii = groups.length;            for (; i < ii; ++i)                if (groups[i].start <= value && value <= groups[i].end)                    return i;            return -1        }        _extend(DX.viz.map._tests, {            MapItemsManager: MapItemsManager,            MapItemHandle: MapItemHandle,            stubMapItemHandle: function(mapItemHandleType) {                MapItemHandle = mapItemHandleType            },            restoreMapItemHandle: function() {                MapItemHandle = DX.viz.map._tests.MapItemHandle            }        });        DX.viz.map.dxVectorMap.prototype._factory.MapItemsManager = MapItemsManager    })(DevExpress, jQuery);    /*! Module viz-vectormap, file areasManager.js */    (function(DX, $, undefined) {        var _abs = Math.abs,            _sqrt = Math.sqrt,            _noop = $.noop,            TOLERANCE = 1;        var AreasManager = DX.viz.map.dxVectorMap.prototype._factory.MapItemsManager.inherit({                _rootClass: "dxm-areas",                _dataCategory: "areas",                _eventNames: {                    click: "areaClick",                    hoverChanged: "areaHoverChanged",                    selectionChanged: "areaSelectionChanged"                },                _initRoot: function() {                    var that = this;                    that.callBase.apply(that, arguments);                    that._context.labelRoot = that._labelRoot = that._params.renderer.g().attr({"class": "dxm-area-labels"})                },                _disposeRoot: function() {                    this.callBase.apply(this, arguments);                    this._labelRoot = null                },                _processSource: function(source) {                    var isGeoJson = source && source.type === "FeatureCollection";                    this._getItemCoordinates = isGeoJson ? getCoordinatesGeoJson : getCoordinatesDefault;                    this._getItemAttributes = isGeoJson ? getAttributesGeoJson : getAttributesDefault;                    return isGeoJson ? source.features : source                },                _getCommonSettings: function(options) {                    return this._params.themeManager.getCommonAreaSettings(options)                },                _initProxy: _noop,                _itemType: "area",                _removeRoot: function() {                    this.callBase.apply(this, arguments);                    this._labelRoot.remove()                },                _appendRoot: function() {                    var that = this;                    that.callBase.apply(that, arguments);                    if (that._commonSettings.label.enabled)                        that._labelRoot.append(that._params.container)                },                _clearRoot: function() {                    this.callBase.apply(this, arguments);                    this._labelRoot.clear()                },                _getItemSettings: function(_, options) {                    return this._params.themeManager.getAreaSettings(this._commonSettings, options)                },                _transform: function(transform) {                    this.callBase.apply(this, arguments);                    this._labelRoot.attr(transform)                },                _createItem: function() {                    return new Area                },                _updateGrouping: function() {                    var commonSettings = this._commonSettings,                        attributeName = commonSettings.colorGroupingField;                    this._groupByColor(commonSettings.colorGroups, commonSettings.palette, function(proxy) {                        return proxy.attribute(attributeName)                    })                },                _arrangeItems: _noop            });        function getCoordinatesDefault(dataItem) {            return dataItem.coordinates        }        function getCoordinatesGeoJson(dataItem) {            var coordinates,                type;            if (dataItem.geometry) {                type = dataItem.geometry.type;                coordinates = dataItem.geometry.coordinates;                if (coordinates && (type === "Polygon" || type === "MultiPolygon"))                    type === "MultiPolygon" && (coordinates = [].concat.apply([], coordinates));                else                    coordinates = undefined            }            return coordinates        }        function getAttributesDefault(dataItem) {            return dataItem.attributes        }        function getAttributesGeoJson(dataItem) {            return dataItem.properties        }        function Area(){}        $.extend(Area.prototype, DX.viz.map._internal.mapItemBehavior, {            _project: function(projection, coords) {                return projection.projectArea(coords)            },            _createRoot: function() {                return this._ctx.renderer.path([], "area").data(this._ctx.dataKey, this._data)            },            _update: function(settings) {                this._styles = {                    normal: {                        "class": "dxm-area",                        stroke: settings.borderColor,                        "stroke-width": settings.borderWidth,                        fill: settings.color                    },                    hovered: {                        "class": "dxm-area dxm-area-hovered",                        stroke: settings.hoveredBorderColor,                        "stroke-width": settings.hoveredBorderWidth,                        fill: settings.hoveredColor                    },                    selected: {                        "class": "dxm-area dxm-area-selected",                        stroke: settings.selectedBorderColor,                        "stroke-width": settings.selectedBorderWidth,                        fill: settings.selectedColor                    }                };                this._root.attr(this._styles.normal);                return this            },            _transform: function(projection, coords) {                return projection.getAreaCoordinates(coords)            },            _locate: function(coords) {                this._root.attr({points: coords})            },            onHover: _noop,            setDefaultState: function() {                this._root.attr(this._styles.normal).toBackground()            },            setHoveredState: function() {                this._root.attr(this._styles.hovered).toForeground()            },            setSelectedState: function() {                this._root.attr(this._styles.selected).toForeground()            },            _createLabelRoot: function() {                return this._ctx.renderer.g().attr({"class": "dxm-area-label"}).append(this._ctx.labelRoot)            },            _adjustLabel: function() {                var that = this,                    centroid = calculateAreaCentroid(that._coords),                    bbox = that._label.text.getBBox(),                    offset = -bbox.y - bbox.height / 2;                that._centroid = centroid.coords;                that._areaSize = _sqrt(centroid.area);                that._labelSize = [bbox.width, bbox.height];                that._label.text.attr({y: offset});                that._label.tracker.attr({                    x: bbox.x,                    y: bbox.y + offset,                    width: bbox.width,                    height: bbox.height                })            },            _locateLabel: function() {                var that = this,                    coords = that._ctx.projection.getPointCoordinates(that._centroid),                    size = that._ctx.projection.getSquareSize([that._areaSize, that._areaSize]);                that._label.root.attr({                    translateX: coords.x,                    translateY: coords.y,                    visibility: that._labelSize[0] / size[0] < TOLERANCE && that._labelSize[1] / size[1] < TOLERANCE ? null : "hidden"                })            }        });        function calculatePolygonCentroid(coordinates) {            var i = 0,                ii = coordinates.length,                v1,                v2 = coordinates[ii - 1],                cross,                cx = 0,                cy = 0,                area = 0;            for (; i < ii; ++i) {                v1 = v2;                v2 = coordinates[i];                cross = v1[0] * v2[1] - v2[0] * v1[1];                area += cross;                cx += (v1[0] + v2[0]) * cross;                cy += (v1[1] + v2[1]) * cross            }            area /= 2;            cx /= 6 * area;            cy /= 6 * area;            return {                    coords: [cx, cy],                    area: _abs(area)                }        }        function calculateAreaCentroid(coordinates) {            var i = 0,                ii = coordinates.length,                centroid,                resultCentroid,                maxArea = 0;            for (; i < ii; ++i) {                centroid = calculatePolygonCentroid(coordinates[i]);                if (centroid.area > maxArea) {                    maxArea = centroid.area;                    resultCentroid = centroid                }            }            return resultCentroid        }        DX.viz.map._internal.AreasManager = AreasManager;        DX.viz.map._internal.Area = Area;        DX.viz.map._tests.AreasManager = AreasManager;        DX.viz.map._tests.Area = Area;        DX.viz.map.dxVectorMap.prototype._factory.createAreasManager = function(parameters) {            return new AreasManager(parameters)        }    })(DevExpress, jQuery);    /*! Module viz-vectormap, file markersManager.js */    (function(DX, $, undefined) {        var _Number = Number,            _String = String,            _isFinite = isFinite,            _math = Math,            _round = _math.round,            _max = _math.max,            _min = _math.min,            _extend = $.extend,            _each = $.each,            _isArray = DX.utils.isArray,            CLASS_DEFAULT = "dxm-marker",            CLASS_HOVERED = "dxm-marker dxm-marker-hovered",            CLASS_SELECTED = "dxm-marker dxm-marker-selected",            DOT = "dot",            BUBBLE = "bubble",            PIE = "pie",            IMAGE = "image",            DEFAULT_MARKER_TYPE = null,            MARKER_TYPES = {};        var MarkersManager = DX.viz.map.dxVectorMap.prototype._factory.MapItemsManager.inherit({                _rootClass: "dxm-markers",                _dataCategory: "markers",                _eventNames: {                    click: "markerClick",                    hoverChanged: "markerHoverChanged",                    selectionChanged: "markerSelectionChanged"                },                _init: function() {                    var that = this;                    that.callBase.apply(that, arguments);                    that._context.getPieColors = function(count) {                        return that._params.themeManager.getPieColors(that._commonSettings, count)                    };                    that._filter = that._params.renderer.shadowFilter("-40%", "-40%", "180%", "200%", 0, 1, 1, "#000000", 0.2)                },                _dispose: function() {                    this.callBase.apply(this, arguments);                    this._filter.dispose();                    this._filter = null                },                _getItemCoordinates: function(dataItem) {                    return dataItem.coordinates                },                _getItemAttributes: function(dataItem) {                    return dataItem.attributes                },                _processSource: function(source) {                    return source                },                _getCommonSettings: function(options) {                    return this._params.themeManager.getCommonMarkerSettings(options)                },                _processOptions: function(options) {                    var that = this;                    that._commonType = parseMarkerType(options && options.type, DEFAULT_MARKER_TYPE);                    that.callBase.apply(that, arguments);                    that._commonSettings._filter = that._filter.ref                },                _arrangeBubbles: function() {                    var markers = this._handles,                        bubbles = [],                        i,                        ii = markers.length,                        marker,                        values = [],                        minValue,                        maxValue,                        deltaValue;                    if (this._commonSettings._bubble.sizeGroups)                        return;                    for (i = 0; i < ii; ++i) {                        marker = markers[i];                        if (marker.item.type === BUBBLE) {                            bubbles.push(marker);                            if (_isFinite(marker.proxy.value))                                values.push(marker.proxy.value)                        }                    }                    minValue = _min.apply(null, values);                    maxValue = _max.apply(null, values);                    deltaValue = maxValue - minValue || 1;                    for (i = 0, ii = bubbles.length; i < ii; ++i) {                        marker = bubbles[i];                        marker.item.setSize(_isFinite(marker.proxy.value) ? (marker.proxy.value - minValue) / deltaValue : 0)                    }                },                _itemType: "marker",                _initProxy: function(proxy, dataItem) {                    _each(dataItem, function(name, value) {                        if (proxy[name] === undefined)                            proxy[name] = value                    });                    proxy._TYPE = parseMarkerType(dataItem.type, null)                },                _getItemSettings: function(proxy, options) {                    var type = proxy._TYPE || this._commonType,                        settings = this._params.themeManager.getMarkerSettings(this._commonSettings, _extend({}, proxy.style, options), type);                    proxy.text = proxy.text || settings.text;                    return settings                },                _createItem: function(proxy) {                    return new MARKER_TYPES[proxy._TYPE || this._commonType]                },                _updateGrouping: function() {                    var that = this,                        markerType = that._commonType,                        colorDataField,                        sizeDataField,                        commonSettings = that._commonSettings["_" + markerType];                    if (markerType === DOT || markerType === BUBBLE) {                        colorDataField = commonSettings.colorGroupingField;                        that._groupByColor(commonSettings.colorGroups, commonSettings.palette, function(proxy) {                            return !proxy._TYPE || proxy._TYPE === markerType ? proxy.attribute(colorDataField) : NaN                        })                    }                    sizeDataField = commonSettings.sizeGroupingField;                    that._performGrouping(commonSettings.sizeGroups, "size", function(proxy) {                        return !proxy._TYPE || proxy._TYPE === markerType ? proxy.value || proxy.attribute(sizeDataField) : NaN                    }, function(count) {                        var minSize = commonSettings.minSize > 0 ? _Number(commonSettings.minSize) : 0,                            maxSize = commonSettings.maxSize >= minSize ? _Number(commonSettings.maxSize) : 0,                            i = 0,                            sizes = [];                        for (i = 0; i < count; ++i)                            sizes.push((minSize * (count - i - 1) + maxSize * i) / (count - 1));                        return sizes                    })                },                _updateLegendForPies: function() {                    var count = 0;                    _each(this._handles, function(_, handle) {                        var proxy = handle.proxy,                            values;                        if (!proxy._TYPE || proxy._TYPE === PIE) {                            values = proxy.values;                            if (values && values.length > count)                                count = values.length                        }                    });                    if (count > 0)                        this._params.dataExchanger.set(this._dataCategory, "color", $.map(this._context.getPieColors(count).slice(0, count), function(color, i) {                            return {                                    index: i,                                    color: color                                }                        }))                },                _arrangeItems: function() {                    this._arrangeBubbles();                    this._updateLegendForPies()                }            });        var baseMarkerBehavior = _extend({}, DX.viz.map._internal.mapItemBehavior, {                _project: function(projection, coords) {                    return projection.projectPoint(coords)                },                _createRoot: function() {                    return this._ctx.renderer.g()                },                _update: function(settings) {                    var that = this;                    that._root.attr({"class": CLASS_DEFAULT}).clear();                    that._create(settings, that._ctx.renderer, that._root);                    return that                },                _transform: function(projection, coords) {                    return projection.getPointCoordinates(coords)                },                _locate: function(coords) {                    this._root.attr({                        translateX: coords.x,                        translateY: coords.y                    })                },                onHover: function() {                    this._root.toForeground()                },                setDefaultState: function() {                    this._root.attr({"class": CLASS_DEFAULT}).toBackground();                    this._applyDefault()                },                setHoveredState: function() {                    this._root.attr({"class": CLASS_HOVERED});                    this._applyHovered()                },                setSelectedState: function() {                    this._root.attr({"class": CLASS_SELECTED}).toForeground();                    this._applySelected()                },                _createLabelRoot: function() {                    return this._root                },                _adjustLabel: function() {                    var bbox = this._label.text.getBBox(),                        x = _round(-bbox.x + this._size / 2) + 2,                        y = _round(-bbox.y - bbox.height / 2) - 1;                    this._label.text.attr({                        x: x,                        y: y                    });                    this._label.tracker.attr({                        x: x + bbox.x - 1,                        y: y + bbox.y - 1,                        width: bbox.width + 2,                        height: bbox.height + 2                    })                },                _locateLabel: $.noop            });        function DotMarker(){}        _extend(DotMarker.prototype, baseMarkerBehavior, {            type: DOT,            _create: function(style, renderer, root) {                var that = this,                    size = that._size = style.size > 0 ? _Number(style.size) : 0,                    hoveredSize = size,                    selectedSize = size + (style.selectedStep > 0 ? _Number(style.selectedStep) : 0),                    hoveredBackSize = hoveredSize + (style.backStep > 0 ? _Number(style.backStep) : 0),                    selectedBackSize = selectedSize + (style.backStep > 0 ? _Number(style.backStep) : 0),                    r = size / 2;                that._dotDefault = {                    cx: 0,                    cy: 0,                    r: r,                    stroke: style.borderColor,                    "stroke-width": style.borderWidth,                    fill: style.color,                    filter: style.shadow ? style._filter : null                };                that._dotHovered = {                    cx: 0,                    cy: 0,                    r: hoveredSize / 2,                    stroke: style.hoveredBorderColor,                    "stroke-width": style.hoveredBorderWidth,                    fill: style.hoveredColor                };                that._dotSelected = {                    cx: 0,                    cy: 0,                    r: selectedSize / 2,                    stroke: style.selectedBorderColor,                    "stroke-width": style.selectedBorderWidth,                    fill: style.selectedColor                };                that._backDefault = {                    cx: 0,                    cy: 0,                    r: r,                    stroke: "none",                    "stroke-width": 0,                    fill: style.backColor,                    opacity: style.backOpacity                };                that._backHovered = {                    cx: 0,                    cy: 0,                    r: hoveredBackSize / 2,                    stroke: "none",                    "stroke-width": 0,                    fill: style.backColor,                    opacity: style.backOpacity                };                that._backSelected = {                    cx: 0,                    cy: 0,                    r: selectedBackSize / 2,                    stroke: "none",                    "stroke-width": 0,                    fill: style.backColor,                    opacity: style.backOpacity                };                that._back = renderer.circle().sharp().attr(that._backDefault).data(that._ctx.dataKey, that._data).append(root);                that._dot = renderer.circle().sharp().attr(that._dotDefault).data(that._ctx.dataKey, that._data).append(root)            },            _destroy: function() {                this._back = this._dot = null            },            _applyDefault: function() {                this._back.attr(this._backDefault);                this._dot.attr(this._dotDefault)            },            _applyHovered: function() {                this._back.attr(this._backHovered);                this._dot.attr(this._dotHovered)            },            _applySelected: function() {                this._back.attr(this._backSelected);                this._dot.attr(this._dotSelected)            }        });        function BubbleMarker(){}        _extend(BubbleMarker.prototype, baseMarkerBehavior, {            type: BUBBLE,            _create: function(style, renderer, root) {                var that = this;                that._minSize = style.minSize > 0 ? _Number(style.minSize) : 0;                that._maxSize = style.maxSize > that._minSize ? _Number(style.maxSize) : that._minSize;                that.value = _isFinite(that._proxy.value) ? _Number(that._proxy.value) : null;                that._default = {                    stroke: style.borderColor,                    "stroke-width": style.borderWidth,                    fill: style.color,                    opacity: style.opacity                };                that._hovered = {                    stroke: style.hoveredBorderColor,                    "stroke-width": style.hoveredBorderWidth,                    fill: style.hoveredColor,                    opacity: style.hoveredOpacity                };                that._selected = {                    stroke: style.selectedBorderColor,                    "stroke-width": style.selectedBorderWidth,                    fill: style.selectedColor,                    opacity: style.selectedOpacity                };                that._bubble = renderer.circle(0, 0, 0).sharp().attr(that._default).data(that._ctx.dataKey, that._data).append(root);                that.setSize(style.size / that._maxSize || 1)            },            _applyDefault: function() {                this._bubble.attr(this._default)            },            _applyHovered: function() {                this._bubble.attr(this._hovered)            },            _applySelected: function() {                this._bubble.attr(this._selected)            },            setSize: function(ratio) {                var that = this,                    r = (that._minSize + ratio * (that._maxSize - that._minSize)) / 2;                that._default.r = that._hovered.r = that._selected.r = r;                that._size = 2 * r;                that._bubble.attr({r: r});                return that            }        });        function PieMarker(){}        _extend(PieMarker.prototype, baseMarkerBehavior, {            type: PIE,            _create: function(style, renderer, root) {                var that = this,                    r = (style.size > 0 ? _Number(style.size) : 0) / 2,                    srcValues,                    i = 0,                    ii,                    values,                    value,                    sum = 0,                    translator,                    startAngle,                    endAngle,                    colors;                that._size = 2 * r;                that._pieDefault = {opacity: style.opacity};                that._pieHovered = {opacity: style.hoveredOpacity};                that._pieSelected = {opacity: style.selectedOpacity};                that._borderDefault = {                    stroke: style.borderColor,                    "stroke-width": style.borderWidth                };                that._borderHovered = {                    stroke: style.hoveredBorderColor,                    "stroke-width": style.hoveredBorderWidth                };                that._borderSelected = {                    stroke: style.selectedBorderColor,                    "stroke-width": style.selectedBorderWidth                };                srcValues = that._proxy.values;                ii = _isArray(srcValues) ? srcValues.length : 0;                values = [];                for (; i < ii; ++i) {                    value = _Number(srcValues[i]);                    if (_isFinite(value)) {                        values.push(value);                        sum += value                    }                }                that._pie = renderer.g().attr(that._pieDefault);                translator = new DX.viz.core.Translator1D(0, sum, 90, 450);                startAngle = translator.translate(0);                colors = that._ctx.getPieColors(values.length);                for (value = 0, i = 0, ii = values.length; i < ii; ++i) {                    value += values[i];                    endAngle = translator.translate(value);                    renderer.arc(0, 0, 0, r, startAngle, endAngle).attr({                        "stroke-linejoin": "round",                        fill: colors[i]                    }).data(that._ctx.dataKey, that._data).append(that._pie);                    startAngle = endAngle                }                that._pie.append(root);                that._border = renderer.circle(0, 0, r).sharp().attr(that._borderDefault).data(that._ctx.dataKey, that._data).append(root)            },            _applyDefault: function() {                this._pie.attr(this._pieDefault);                this._border.attr(this._borderDefault)            },            _applyHovered: function() {                this._pie.attr(this._pieHovered);                this._border.attr(this._borderHovered)            },            _applySelected: function() {                this._pie.attr(this._pieSelected);                this._border.attr(this._borderSelected)            }        });        function ImageMarker(){}        _extend(ImageMarker.prototype, baseMarkerBehavior, {            type: IMAGE,            _create: function(style, renderer, root) {                var that = this,                    size = that._size = style.size > 0 ? _Number(style.size) : 0,                    hoveredSize = size + (style.hoveredStep > 0 ? _Number(style.hoveredStep) : 0),                    selectedSize = size + (style.selectedStep > 0 ? _Number(style.selectedStep) : 0);                that._default = {                    x: -size / 2,                    y: -size / 2,                    width: size,                    height: size                };                that._hovered = {                    x: -hoveredSize / 2,                    y: -hoveredSize / 2,                    width: hoveredSize,                    height: hoveredSize                };                that._selected = {                    x: -selectedSize / 2,                    y: -selectedSize / 2,                    width: selectedSize,                    height: selectedSize                };                that._image = renderer.image().attr(that._default).attr({                    href: that._proxy.url,                    location: "center"                }).append(root);                that._tracker = renderer.rect().attr(that._default).attr({                    stroke: "none",                    "stroke-width": 0,                    fill: "#000000",                    opacity: 0.0001                }).data(that._ctx.dataKey, that._data).append(root)            },            _applyDefault: function() {                this._image.attr(this._default);                this._tracker.attr(this._default)            },            _applyHovered: function() {                this._image.attr(this._hovered);                this._tracker.attr(this._hovered)            },            _applySelected: function() {                this._image.attr(this._selected);                this._tracker.attr(this._selected)            }        });        _each([DotMarker, BubbleMarker, PieMarker, ImageMarker], function(_, markerType) {            DEFAULT_MARKER_TYPE = DEFAULT_MARKER_TYPE || markerType.prototype.type;            MARKER_TYPES[markerType.prototype.type] = markerType        });        function parseMarkerType(type, defaultType) {            var _type = _String(type).toLowerCase();            return MARKER_TYPES[_type] ? _type : defaultType        }        var __originalDefaultMarkerType = DEFAULT_MARKER_TYPE,            __originalMarkerTypes = _extend({}, MARKER_TYPES);        DX.viz.map._tests.stubMarkerTypes = function(markerTypes, defaultMarkerType) {            DEFAULT_MARKER_TYPE = defaultMarkerType;            MARKER_TYPES = markerTypes        };        DX.viz.map._tests.restoreMarkerTypes = function() {            DEFAULT_MARKER_TYPE = __originalDefaultMarkerType;            MARKER_TYPES = __originalMarkerTypes        };        DX.viz.map._tests.baseMarkerBehavior = baseMarkerBehavior;        DX.viz.map._tests.MarkersManager = MarkersManager;        DX.viz.map._tests.DotMarker = DotMarker;        DX.viz.map._tests.BubbleMarker = BubbleMarker;        DX.viz.map._tests.PieMarker = PieMarker;        DX.viz.map._tests.ImageMarker = ImageMarker;        DX.viz.map.dxVectorMap.prototype._factory.createMarkersManager = function(parameters) {            return new MarkersManager(parameters)        }    })(DevExpress, jQuery);    DevExpress.MOD_VIZ_VECTORMAP = true}if (!DevExpress.MOD_VIZ_SPARKLINES) {    if (!DevExpress.MOD_VIZ_CORE)        throw Error('Required module is not referenced: viz-core');    /*! Module viz-sparklines, file baseSparkline.js */    (function($, DX, undefined) {        var DEFAULT_LINE_SPACING = 2,            DEFAULT_EVENTS_DELAY = 200,            TOUCH_EVENTS_DELAY = 1000,            _extend = $.extend,            _abs = Math.abs,            core = DX.viz.core;        function generateDefaultCustomizeTooltipCallback(fontOptions, rtlEnabled) {            var lineSpacing = fontOptions.lineSpacing,                lineHeight = (lineSpacing !== undefined && lineSpacing !== null ? lineSpacing : DEFAULT_LINE_SPACING) + fontOptions.size;            DX.viz.sparklines.generated_customize_tooltip = function() {                return {                        lineHeight: lineHeight,                        rtlEnabled: rtlEnabled                    }            };            return function(customizeObject) {                    var html = "",                        vt = customizeObject.valueText;                    for (var i = 0; i < vt.length; i += 2)                        html += "<tr><td>" + vt[i] + "</td><td style='width: 15px'></td><td style='text-align: " + (rtlEnabled ? "left" : "right") + "'>" + vt[i + 1] + "</td></tr>";                    return {html: "<table style='border-spacing:0px; line-height: " + lineHeight + "px'>" + html + "</table>"}                }        }        DX.viz.sparklines = {};        DX.viz.sparklines.BaseSparkline = core.BaseWidget.inherit({            _setDeprecatedOptions: function() {                this.callBase();                $.extend(this._deprecatedOptions, {                    "tooltip.verticalAlignment": {                        since: "15.1",                        message: "Now tootips are aligned automatically"                    },                    "tooltip.horizontalAlignment": {                        since: "15.1",                        message: "Now tootips are aligned automatically"                    }                })            },            _clean: function() {                var that = this;                if (that._tooltipShown) {                    that._tooltipShown = false;                    that._tooltip.hide()                }                that._cleanWidgetElements();                that._cleanTranslators()            },            _initCore: function() {                var that = this;                that._tooltipTracker = that._renderer.root;                that._tooltipTracker.attr({"pointer-events": "visible"});                that._createHtmlElements();                that._initTooltipEvents()            },            _initTooltip: function() {                this._initTooltipBase = this.callBase;                return            },            _getDefaultSize: function() {                return this._defaultSize            },            _isContainerVisible: function() {                return true            },            _disposeCore: function() {                this._disposeWidgetElements();                this._disposeTooltipEvents();                this._ranges = null            },            _render: function() {                this._prepareOptions();                this._updateWidgetElements();                this._drawWidgetElements()            },            _updateWidgetElements: function() {                this._updateRange();                this._updateTranslator()            },            _applySize: function() {                if (this._allOptions)                    this._allOptions.size = {                        width: this._canvas.width,                        height: this._canvas.height                    }            },            _cleanTranslators: function() {                this._translatorX = null;                this._translatorY = null            },            _setupResizeHandler: $.noop,            _resize: function() {                var that = this;                that._redrawWidgetElements();                if (that._tooltipShown) {                    that._tooltipShown = false;                    that._tooltip.hide()                }                that._drawn()            },            _prepareOptions: function() {                return _extend(true, {}, this._themeManager.theme(), this.option())            },            _createThemeManager: function() {                var themeManager = new DX.viz.core.BaseThemeManager;                themeManager._themeSection = this._widgetType;                themeManager._fontFields = ["tooltip.font"];                return themeManager            },            _getTooltipCoords: function() {                var canvas = this._canvas,                    rootOffset = this._renderer.getRootOffset();                return {                        x: canvas.width / 2 + rootOffset.left,                        y: canvas.height / 2 + rootOffset.top                    }            },            _initTooltipEvents: function() {                var that = this,                    data = {widget: that};                that._showTooltipCallback = function() {                    var tooltip;                    that._showTooltipTimeout = null;                    if (!that._tooltipShown) {                        that._tooltipShown = true;                        tooltip = that._getTooltip();                        tooltip.isEnabled() && that._tooltip.show(that._getTooltipData(), that._getTooltipCoords(), {})                    }                    that._DEBUG_showCallback && that._DEBUG_showCallback()                };                that._hideTooltipCallback = function() {                    var tooltipWasShown = that._tooltipShown;                    that._hideTooltipTimeout = null;                    if (that._tooltipShown) {                        that._tooltipShown = false;                        that._tooltip.hide()                    }                    that._DEBUG_hideCallback && that._DEBUG_hideCallback(tooltipWasShown)                };                that._disposeCallbacks = function() {                    that = that._showTooltipCallback = that._hideTooltipCallback = that._disposeCallbacks = null                };                that._tooltipTracker.on(mouseEvents, data).on(touchEvents, data).on(mouseWheelEvents, data);                that._tooltipTracker.on(menuEvents)            },            _disposeTooltipEvents: function() {                var that = this;                clearTimeout(that._showTooltipTimeout);                clearTimeout(that._hideTooltipTimeout);                that._tooltipTracker.off();                that._disposeCallbacks()            },            _updateTranslator: function() {                var that = this,                    canvas = this._canvas,                    ranges = this._ranges;                that._translatorX = new core.Translator2D(ranges.arg, canvas, {direction: "horizontal"});                that._translatorY = new core.Translator2D(ranges.val, canvas)            },            _getTooltip: function() {                var that = this;                if (!that._tooltip) {                    that._initTooltipBase();                    that._setTooltipRendererOptions(that._tooltipRendererOptions);                    that._tooltipRendererOptions = null;                    that._setTooltipOptions()                }                return that._tooltip            },            _setTooltipRendererOptions: function(options) {                if (this._tooltip)                    this._tooltip.setRendererOptions(options);                else                    this._tooltipRendererOptions = options            },            _setTooltipOptions: function() {                var tooltip = this._tooltip,                    options = tooltip && this._getOption("tooltip");                tooltip && tooltip.update($.extend({}, options, {                    customizeTooltip: !$.isFunction(options.customizeTooltip) ? generateDefaultCustomizeTooltipCallback(options.font, this.option("rtlEnabled")) : options.customizeTooltip,                    enabled: options.enabled && this._isTooltipEnabled()                }))            },            _showTooltip: function(delay) {                var that = this;                ++that._DEBUG_clearHideTooltipTimeout;                clearTimeout(that._hideTooltipTimeout);                that._hideTooltipTimeout = null;                clearTimeout(that._showTooltipTimeout);                ++that._DEBUG_showTooltipTimeoutSet;                that._showTooltipTimeout = setTimeout(that._showTooltipCallback, delay)            },            _hideTooltip: function(delay) {                var that = this;                ++that._DEBUG_clearShowTooltipTimeout;                clearTimeout(that._showTooltipTimeout);                that._showTooltipTimeout = null;                clearTimeout(that._hideTooltipTimeout);                if (delay) {                    ++that._DEBUG_hideTooltipTimeoutSet;                    that._hideTooltipTimeout = setTimeout(that._hideTooltipCallback, delay)                }                else                    that._hideTooltipCallback()            },            _initLoadingIndicator: $.noop,            _disposeLoadingIndicator: $.noop,            _handleLoadingIndicatorOptionChanged: $.noop,            showLoadingIndicator: $.noop,            hideLoadingIndicator: $.noop        });        var menuEvents = {                "contextmenu.sparkline-tooltip": function(event) {                    if (DX.ui.events.isTouchEvent(event) || DX.ui.events.isPointerEvent(event))                        event.preventDefault()                },                "MSHoldVisual.sparkline-tooltip": function(event) {                    event.preventDefault()                }            };        var mouseEvents = {                "mouseover.sparkline-tooltip": function(event) {                    isPointerDownCalled = false;                    var widget = event.data.widget;                    widget._x = event.pageX;                    widget._y = event.pageY;                    widget._tooltipTracker.off(mouseMoveEvents).on(mouseMoveEvents, event.data);                    widget._showTooltip(DEFAULT_EVENTS_DELAY)                },                "mouseout.sparkline-tooltip": function(event) {                    if (isPointerDownCalled)                        return;                    var widget = event.data.widget;                    widget._tooltipTracker.off(mouseMoveEvents);                    widget._hideTooltip(DEFAULT_EVENTS_DELAY)                }            };        var mouseWheelEvents = {"dxmousewheel.sparkline-tooltip": function(event) {                    event.data.widget._hideTooltip()                }};        var mouseMoveEvents = {"mousemove.sparkline-tooltip": function(event) {                    var widget = event.data.widget;                    if (widget._showTooltipTimeout && (_abs(widget._x - event.pageX) > 3 || _abs(widget._y - event.pageY) > 3)) {                        widget._x = event.pageX;                        widget._y = event.pageY;                        widget._showTooltip(DEFAULT_EVENTS_DELAY)                    }                }};        var active_touch_tooltip_widget = null,            touchstartTooltipProcessing = function(event) {                event.preventDefault();                var widget = active_touch_tooltip_widget;                if (widget && widget !== event.data.widget)                    widget._hideTooltip(DEFAULT_EVENTS_DELAY);                widget = active_touch_tooltip_widget = event.data.widget;                widget._showTooltip(TOUCH_EVENTS_DELAY);                widget._touch = true            },            touchstartDocumentProcessing = function() {                var widget = active_touch_tooltip_widget;                if (widget) {                    if (!widget._touch) {                        widget._hideTooltip(DEFAULT_EVENTS_DELAY);                        active_touch_tooltip_widget = null                    }                    widget._touch = null                }            },            touchendDocumentProcessing = function() {                var widget = active_touch_tooltip_widget;                if (widget)                    if (widget._showTooltipTimeout) {                        widget._hideTooltip(DEFAULT_EVENTS_DELAY);                        active_touch_tooltip_widget = null                    }            },            isPointerDownCalled = false;        var touchEvents = {                "pointerdown.sparkline-tooltip": touchstartTooltipProcessing,                "touchstart.sparkline-tooltip": touchstartTooltipProcessing            };        $(document).on({            "pointerdown.sparkline-tooltip": function() {                isPointerDownCalled = true;                touchstartDocumentProcessing()            },            "touchstart.sparkline-tooltip": touchstartDocumentProcessing,            "pointerup.sparkline-tooltip": touchendDocumentProcessing,            "touchend.sparkline-tooltip": touchendDocumentProcessing        });        DX.viz.sparklines.BaseSparkline._DEBUG_reset = function() {            active_touch_tooltip_widget = null        }    })(jQuery, DevExpress);    /*! Module viz-sparklines, file sparkline.js */    (function($, DX, undefined) {        var viz = DX.viz,            core = viz.core,            MIN_BAR_WIDTH = 1,            MAX_BAR_WIDTH = 50,            DEFAULT_BAR_INTERVAL = 4,            DEFAULT_CANVAS_WIDTH = 250,            DEFAULT_CANVAS_HEIGHT = 30,            DEFAULT_HORIZONTAL_MARGIN = 5,            DEFAULT_VERTICAL_MARGIN = 3,            ALLOWED_TYPES = {                line: true,                spline: true,                stepline: true,                area: true,                steparea: true,                splinearea: true,                bar: true,                winloss: true            },            _map = $.map,            _math = Math,            _abs = _math.abs,            _round = _math.round,            _max = _math.max,            _min = _math.min,            _isFinite = isFinite,            _isDefined = DX.utils.isDefined,            _Number = Number,            _String = String;        DX.registerComponent("dxSparkline", viz.sparklines, viz.sparklines.BaseSparkline.inherit({            _rootClassPrefix: "dxsl",            _rootClass: "dxsl-sparkline",            _widgetType: "sparkline",            _defaultSize: {                width: DEFAULT_CANVAS_WIDTH,                height: DEFAULT_CANVAS_HEIGHT,                left: DEFAULT_HORIZONTAL_MARGIN,                right: DEFAULT_HORIZONTAL_MARGIN,                top: DEFAULT_VERTICAL_MARGIN,                bottom: DEFAULT_VERTICAL_MARGIN            },            _initCore: function() {                this.callBase();                this._refreshDataSource();                this._createSeries()            },            _dataSourceChangedHandler: function() {                if (this._initialized) {                    this._clean();                    this._updateWidgetElements();                    this._drawWidgetElements()                }            },            _updateWidgetElements: function() {                this._updateSeries();                this.callBase()            },            _dataSourceOptions: function() {                return {paginate: false}            },            _redrawWidgetElements: function() {                this._updateTranslator();                this._correctPoints();                this._series.draw({                    x: this._translatorX,                    y: this._translatorY                });                this._seriesGroup.append(this._renderer.root)            },            _disposeWidgetElements: function() {                var that = this;                delete that._seriesGroup;                delete that._seriesLabelGroup;                that._series && that._series.dispose();                that._series = null            },            _cleanWidgetElements: function() {                this._seriesGroup.remove();                this._seriesLabelGroup.remove();                this._seriesGroup.clear();                this._seriesLabelGroup.clear()            },            _drawWidgetElements: function() {                if (this._isDataSourceReady()) {                    this._drawSeries();                    this._drawn()                }            },            _prepareOptions: function() {                this._allOptions = this.callBase();                this._allOptions.type = _String(this._allOptions.type).toLowerCase();                if (!ALLOWED_TYPES[this._allOptions.type])                    this._allOptions.type = "line"            },            _createHtmlElements: function() {                this._seriesGroup = this._renderer.g().attr({"class": "dxsl-series"});                this._seriesLabelGroup = this._renderer.g().attr({"class": "dxsl-series-labels"})            },            _createSeries: function() {                this._series = new core.series.Series({                    renderer: this._renderer,                    seriesGroup: this._seriesGroup,                    labelsGroup: this._seriesLabelGroup                }, {                    widgetType: "chart",                    type: "line"                })            },            getSeriesOptions: function() {                return this._series.getOptions()            },            _updateSeries: function() {                var that = this,                    groupSeries,                    dataValidator,                    seriesOptions;                that._prepareDataSource();                seriesOptions = that._prepareSeriesOptions();                that._series.updateOptions(seriesOptions);                groupSeries = [[that._series]];                groupSeries.argumentOptions = {type: seriesOptions.type === "bar" ? "discrete" : undefined};                dataValidator = new core.DataValidator(that._simpleDataSource, groupSeries, that._incidentOccured, {                    checkTypeForAllData: false,                    convertToAxisDataType: true,                    sortingMethod: true                });                that._simpleDataSource = dataValidator.validate();                that._series.updateData(that._simpleDataSource)            },            _optionChanged: function(args) {                if (args.name === "dataSource" && this._allOptions)                    this._refreshDataSource();                else                    this.callBase.apply(this, arguments)            },            _parseNumericDataSource: function(data, argField, valField) {                var ignoreEmptyPoints = this.option("ignoreEmptyPoints");                return _map(data, function(dataItem, index) {                        var item = null,                            isDataNumber,                            value;                        if (dataItem !== undefined) {                            item = {};                            isDataNumber = _isFinite(dataItem);                            item[argField] = isDataNumber ? _String(index) : dataItem[argField];                            value = isDataNumber ? dataItem : dataItem[valField];                            item[valField] = value === null ? ignoreEmptyPoints ? undefined : value : _Number(value);                            item = item[argField] !== undefined && item[valField] !== undefined ? item : null                        }                        return item                    })            },            _parseWinlossDataSource: function(data, argField, valField) {                var lowBarValue = -1,                    zeroBarValue = 0,                    highBarValue = 1,                    delta = 0.0001,                    target = this._allOptions.winlossThreshold;                return _map(data, function(dataItem) {                        var item = {};                        item[argField] = dataItem[argField];                        if (_abs(dataItem[valField] - target) < delta)                            item[valField] = zeroBarValue;                        else if (dataItem[valField] > target)                            item[valField] = highBarValue;                        else                            item[valField] = lowBarValue;                        return item                    })            },            _prepareDataSource: function() {                var that = this,                    options = that._allOptions,                    argField = options.argumentField,                    valField = options.valueField,                    dataSource = that._dataSource ? that._dataSource.items() : [],                    data = that._parseNumericDataSource(dataSource, argField, valField);                if (options.type === "winloss") {                    that._winlossDataSource = data;                    that._simpleDataSource = that._parseWinlossDataSource(data, argField, valField)                }                else                    that._simpleDataSource = data            },            _prepareSeriesOptions: function() {                var that = this,                    options = that._allOptions,                    type = options.type === "winloss" ? "bar" : options.type;                return {                        visible: true,                        argumentField: options.argumentField,                        valueField: options.valueField,                        color: options.lineColor,                        width: options.lineWidth,                        widgetType: "chart",                        type: type,                        opacity: type.indexOf("area") !== -1 ? that._allOptions.areaOpacity : undefined,                        customizePoint: that._getCustomizeFunction(),                        point: {                            size: options.pointSize,                            symbol: options.pointSymbol,                            border: {                                visible: true,                                width: 2                            },                            color: options.pointColor,                            visible: false,                            hoverStyle: {border: {}},                            selectionStyle: {border: {}}                        },                        border: {                            color: options.lineColor,                            width: options.lineWidth,                            visible: type !== "bar"                        }                    }            },            _createBarCustomizeFunction: function(pointIndexes) {                var that = this,                    options = that._allOptions,                    winlossData = that._winlossDataSource;                return function() {                        var index = this.index,                            isWinloss = options.type === "winloss",                            target = isWinloss ? options.winlossThreshold : 0,                            value = isWinloss ? winlossData[index][options.valueField] : this.value,                            positiveColor = isWinloss ? options.winColor : options.barPositiveColor,                            negativeColor = isWinloss ? options.lossColor : options.barNegativeColor,                            color;                        if (value >= target)                            color = positiveColor;                        else                            color = negativeColor;                        if (index === pointIndexes.first || index === pointIndexes.last)                            color = options.firstLastColor;                        if (index === pointIndexes.min)                            color = options.minColor;                        if (index === pointIndexes.max)                            color = options.maxColor;                        return {color: color}                    }            },            _createLineCustomizeFunction: function(pointIndexes) {                var that = this,                    options = that._allOptions;                return function() {                        var color,                            index = this.index;                        if (index === pointIndexes.first || index === pointIndexes.last)                            color = options.firstLastColor;                        if (index === pointIndexes.min)                            color = options.minColor;                        if (index === pointIndexes.max)                            color = options.maxColor;                        return color ? {                                visible: true,                                border: {color: color}                            } : {}                    }            },            _getCustomizeFunction: function() {                var that = this,                    options = that._allOptions,                    dataSource = that._winlossDataSource || that._simpleDataSource,                    drawnPointIndexes = that._getExtremumPointsIndexes(dataSource),                    customizeFunction;                if (options.type === "winloss" || options.type === "bar")                    customizeFunction = that._createBarCustomizeFunction(drawnPointIndexes);                else                    customizeFunction = that._createLineCustomizeFunction(drawnPointIndexes);                return customizeFunction            },            _getExtremumPointsIndexes: function(data) {                var that = this,                    options = that._allOptions,                    lastIndex = data.length - 1,                    indexes = {};                that._minMaxIndexes = that._findMinMax(data);                if (options.showFirstLast) {                    indexes.first = 0;                    indexes.last = lastIndex                }                if (options.showMinMax) {                    indexes.min = that._minMaxIndexes.minIndex;                    indexes.max = that._minMaxIndexes.maxIndex                }                return indexes            },            _findMinMax: function(data) {                var that = this,                    valField = that._allOptions.valueField,                    firstItem = data[0] || {},                    firstValue = firstItem[valField] || 0,                    min = firstValue,                    max = firstValue,                    minIndex = 0,                    maxIndex = 0,                    dataLength = data.length,                    value,                    i;                for (i = 1; i < dataLength; i++) {                    value = data[i][valField];                    if (value < min) {                        min = value;                        minIndex = i                    }                    if (value > max) {                        max = value;                        maxIndex = i                    }                }                return {                        minIndex: minIndex,                        maxIndex: maxIndex                    }            },            _updateRange: function() {                var that = this,                    series = that._series,                    type = series.type,                    isBarType = type === "bar",                    isWinlossType = type === "winloss",                    DEFAULT_VALUE_RANGE_MARGIN = 0.15,                    DEFAULT_ARGUMENT_RANGE_MARGIN = 0.1,                    WINLOSS_MAX_RANGE = 1,                    WINLOSS_MIN_RANGE = -1,                    rangeData = series.getRangeData(),                    minValue = that._allOptions.minValue,                    hasMinY = _isDefined(minValue) && _isFinite(minValue),                    maxValue = that._allOptions.maxValue,                    hasMaxY = _isDefined(maxValue) && _isFinite(maxValue),                    valCoef,                    argCoef;                valCoef = (rangeData.val.max - rangeData.val.min) * DEFAULT_VALUE_RANGE_MARGIN;                if (isBarType || isWinlossType || type === "area") {                    if (rangeData.val.min !== 0)                        rangeData.val.min -= valCoef;                    if (rangeData.val.max !== 0)                        rangeData.val.max += valCoef                }                else {                    rangeData.val.min -= valCoef;                    rangeData.val.max += valCoef                }                if (hasMinY || hasMaxY) {                    if (hasMinY && hasMaxY) {                        rangeData.val.minVisible = _min(minValue, maxValue);                        rangeData.val.maxVisible = _max(minValue, maxValue)                    }                    else {                        rangeData.val.minVisible = hasMinY ? _Number(minValue) : undefined;                        rangeData.val.maxVisible = hasMaxY ? _Number(maxValue) : undefined                    }                    if (isWinlossType) {                        rangeData.val.minVisible = hasMinY ? _max(rangeData.val.minVisible, WINLOSS_MIN_RANGE) : undefined;                        rangeData.val.maxVisible = hasMaxY ? _min(rangeData.val.maxVisible, WINLOSS_MAX_RANGE) : undefined                    }                }                if (series.getPoints().length > 1)                    if (isBarType) {                        argCoef = (rangeData.arg.max - rangeData.arg.min) * DEFAULT_ARGUMENT_RANGE_MARGIN;                        rangeData.arg.min = rangeData.arg.min - argCoef;                        rangeData.arg.max = rangeData.arg.max + argCoef                    }                    else                        rangeData.arg.stick = true;                that._ranges = rangeData            },            _getBarWidth: function(pointsCount) {                var that = this,                    canvas = that._canvas,                    intervalWidth = pointsCount * DEFAULT_BAR_INTERVAL,                    rangeWidth = canvas.width - canvas.left - canvas.right - intervalWidth,                    width = _round(rangeWidth / pointsCount);                if (width < MIN_BAR_WIDTH)                    width = MIN_BAR_WIDTH;                if (width > MAX_BAR_WIDTH)                    width = MAX_BAR_WIDTH;                return width            },            _correctPoints: function() {                var that = this,                    seriesType = that._allOptions.type,                    seriesPoints = that._series.getPoints(),                    pointsLength = seriesPoints.length,                    barWidth,                    i;                if (seriesType === "bar" || seriesType === "winloss") {                    barWidth = that._getBarWidth(pointsLength);                    for (i = 0; i < pointsLength; i++)                        seriesPoints[i].correctCoordinates({                            width: barWidth,                            offset: 0                        })                }            },            _drawSeries: function() {                var that = this;                if (that._simpleDataSource.length > 0) {                    that._correctPoints();                    that._series.draw({                        x: that._translatorX,                        y: that._translatorY                    });                    that._seriesGroup.append(that._renderer.root)                }            },            _isTooltipEnabled: function() {                return !!this._simpleDataSource.length            },            _getTooltipData: function() {                var that = this,                    options = that._allOptions,                    dataSource = that._winlossDataSource || that._simpleDataSource,                    tooltip = that._tooltip;                if (dataSource.length === 0)                    return {};                var minMax = that._minMaxIndexes,                    valueField = options.valueField,                    first = dataSource[0][valueField],                    last = dataSource[dataSource.length - 1][valueField],                    min = dataSource[minMax.minIndex][valueField],                    max = dataSource[minMax.maxIndex][valueField],                    formattedFirst = tooltip.formatValue(first),                    formattedLast = tooltip.formatValue(last),                    formattedMin = tooltip.formatValue(min),                    formattedMax = tooltip.formatValue(max),                    customizeObject = {                        firstValue: formattedFirst,                        lastValue: formattedLast,                        minValue: formattedMin,                        maxValue: formattedMax,                        originalFirstValue: first,                        originalLastValue: last,                        originalMinValue: min,                        originalMaxValue: max,                        valueText: ["Start:", formattedFirst, "End:", formattedLast, "Min:", formattedMin, "Max:", formattedMax]                    };                if (options.type === "winloss") {                    customizeObject.originalThresholdValue = options.winlossThreshold;                    customizeObject.thresholdValue = tooltip.formatValue(options.winlossThreshold)                }                return customizeObject            }        }).include(DX.ui.DataHelperMixin))    })(jQuery, DevExpress);    /*! Module viz-sparklines, file bullet.js */    (function($, DX, undefined) {        var TARGET_MIN_Y = 0.02,            TARGET_MAX_Y = 0.98,            BAR_VALUE_MIN_Y = 0.1,            BAR_VALUE_MAX_Y = 0.9,            DEFAULT_CANVAS_WIDTH = 300,            DEFAULT_CANVAS_HEIGHT = 30,            DEFAULT_HORIZONTAL_MARGIN = 1,            DEFAULT_VERTICAL_MARGIN = 2,            _Number = Number,            _isFinite = isFinite;        DX.registerComponent("dxBullet", DX.viz.sparklines, DX.viz.sparklines.BaseSparkline.inherit({            _rootClassPrefix: "dxb",            _rootClass: "dxb-bullet",            _widgetType: "bullet",            _defaultSize: {                width: DEFAULT_CANVAS_WIDTH,                height: DEFAULT_CANVAS_HEIGHT,                left: DEFAULT_HORIZONTAL_MARGIN,                right: DEFAULT_HORIZONTAL_MARGIN,                top: DEFAULT_VERTICAL_MARGIN,                bottom: DEFAULT_VERTICAL_MARGIN            },            _disposeWidgetElements: function() {                delete this._zeroLevelPath;                delete this._targetPath;                delete this._barValuePath            },            _redrawWidgetElements: function() {                this._updateTranslator();                this._drawBarValue();                this._drawTarget();                this._drawZeroLevel()            },            _cleanWidgetElements: function() {                this._zeroLevelPath.remove();                this._targetPath.remove();                this._barValuePath.remove()            },            _drawWidgetElements: function() {                this._drawBullet();                this._drawn()            },            _createHtmlElements: function() {                var renderer = this._renderer;                this._zeroLevelPath = renderer.path(undefined, "line").attr({                    "class": "dxb-zero-level",                    "stroke-linecap": "square"                });                this._targetPath = renderer.path(undefined, "line").attr({                    "class": "dxb-target",                    "stroke-linecap": "square"                });                this._barValuePath = renderer.path(undefined, "line").attr({                    "class": "dxb-bar-value",                    "stroke-linecap": "square"                })            },            _prepareOptions: function() {                var that = this,                    options,                    startScaleValue,                    endScaleValue,                    level,                    value,                    target,                    isValueUndefined,                    isTargetUndefined;                that._allOptions = options = that.callBase();                isValueUndefined = that._allOptions.value === undefined;                isTargetUndefined = that._allOptions.target === undefined;                that._tooltipEnabled = !(isValueUndefined && isTargetUndefined);                if (isValueUndefined)                    that._allOptions.value = 0;                if (isTargetUndefined)                    that._allOptions.target = 0;                options.value = value = _Number(options.value);                options.target = target = _Number(options.target);                if (that._allOptions.startScaleValue === undefined) {                    that._allOptions.startScaleValue = target < value ? target : value;                    that._allOptions.startScaleValue = that._allOptions.startScaleValue < 0 ? that._allOptions.startScaleValue : 0                }                if (that._allOptions.endScaleValue === undefined)                    that._allOptions.endScaleValue = target > value ? target : value;                options.startScaleValue = startScaleValue = _Number(options.startScaleValue);                options.endScaleValue = endScaleValue = _Number(options.endScaleValue);                if (endScaleValue < startScaleValue) {                    level = endScaleValue;                    that._allOptions.endScaleValue = startScaleValue;                    that._allOptions.startScaleValue = level;                    that._allOptions.inverted = true                }            },            _updateRange: function() {                var that = this,                    options = that._allOptions;                that._ranges = {                    arg: {                        invert: options.inverted,                        min: options.startScaleValue,                        max: options.endScaleValue,                        axisType: "continuous",                        dataType: "numeric"                    },                    val: {                        min: 0,                        max: 1,                        axisType: "continuous",                        dataType: "numeric"                    }                }            },            _drawBullet: function() {                var that = this,                    options = that._allOptions,                    isValidBounds = options.startScaleValue !== options.endScaleValue,                    isValidMin = _isFinite(options.startScaleValue),                    isValidMax = _isFinite(options.endScaleValue),                    isValidValue = _isFinite(options.value),                    isValidTarget = _isFinite(options.target);                if (isValidBounds && isValidMax && isValidMin && isValidTarget && isValidValue) {                    this._drawBarValue();                    this._drawTarget();                    this._drawZeroLevel()                }            },            _getTargetParams: function() {                var that = this,                    options = that._allOptions,                    translatorY = that._translatorY,                    x = that._translatorX.translate(options.target);                return {                        points: [x, translatorY.translate(TARGET_MIN_Y), x, translatorY.translate(TARGET_MAX_Y)],                        stroke: options.targetColor,                        "stroke-width": options.targetWidth                    }            },            _getBarValueParams: function() {                var that = this,                    options = that._allOptions,                    translatorX = that._translatorX,                    translatorY = that._translatorY,                    startLevel = options.startScaleValue,                    endLevel = options.endScaleValue,                    value = options.value,                    y2 = translatorY.translate(BAR_VALUE_MIN_Y),                    y1 = translatorY.translate(BAR_VALUE_MAX_Y),                    x1,                    x2;                if (value > 0) {                    x1 = startLevel <= 0 ? 0 : startLevel;                    x2 = value >= endLevel ? endLevel : value < x1 ? x1 : value                }                else {                    x1 = endLevel >= 0 ? 0 : endLevel;                    x2 = value < startLevel ? startLevel : value > x1 ? x1 : value                }                x1 = translatorX.translate(x1);                x2 = translatorX.translate(x2);                return {                        points: [x1, y1, x2, y1, x2, y2, x1, y2],                        fill: options.color                    }            },            _getZeroLevelParams: function() {                var that = this,                    translatorY = that._translatorY,                    x = that._translatorX.translate(0);                return {                        points: [x, translatorY.translate(TARGET_MIN_Y), x, translatorY.translate(TARGET_MAX_Y)],                        stroke: that._allOptions.targetColor,                        "stroke-width": 1                    }            },            _drawZeroLevel: function() {                var that = this,                    options = that._allOptions;                if (0 > options.endScaleValue || 0 < options.startScaleValue || !options.showZeroLevel)                    return;                that._zeroLevelPath.attr(that._getZeroLevelParams()).sharp().append(that._renderer.root)            },            _drawTarget: function() {                var that = this,                    options = that._allOptions,                    target = options.target;                if (target > options.endScaleValue || target < options.startScaleValue || !options.showTarget)                    return;                that._targetPath.attr(that._getTargetParams()).sharp().append(that._renderer.root)            },            _drawBarValue: function() {                this._barValuePath.attr(this._getBarValueParams()).append(this._renderer.root)            },            _getTooltipCoords: function() {                var canvas = this._canvas,                    rootOffset = this._renderer.getRootOffset(),                    bbox = this._barValuePath.getBBox();                return {                        x: bbox.x + bbox.width / 2 + rootOffset.left,                        y: canvas.height / 2 + rootOffset.top                    }            },            _getTooltipData: function() {                var that = this,                    tooltip = that._tooltip,                    options = that._allOptions,                    value = options.value,                    target = options.target;                return {                        originalValue: value,                        originalTarget: target,                        value: tooltip.formatValue(value),                        target: tooltip.formatValue(target),                        valueText: ["Actual Value:", value, "Target Value:", target]                    }            },            _isTooltipEnabled: function() {                return this._tooltipEnabled            }        }))    })(jQuery, DevExpress);    DevExpress.MOD_VIZ_SPARKLINES = true}
 |