| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817 | /** * @license Highcharts JS v7.0.2 (2019-01-17) * * (c) 2009-2018 Torstein Honsi * * License: www.highcharts.com/license */'use strict';(function (factory) {	if (typeof module === 'object' && module.exports) {		factory['default'] = factory;		module.exports = factory;	} else if (typeof define === 'function' && define.amd) {		define(function () {			return factory;		});	} else {		factory(typeof Highcharts !== 'undefined' ? Highcharts : undefined);	}}(function (Highcharts) {	(function (H) {		/* *		 * (c) 2010-2019 Torstein Honsi		 *		 * License: www.highcharts.com/license		 */		var CenteredSeriesMixin = H.CenteredSeriesMixin,		    extend = H.extend,		    merge = H.merge,		    splat = H.splat;		/**		 * The Pane object allows options that are common to a set of X and Y axes.		 *		 * In the future, this can be extended to basic Highcharts and Highstock.		 *		 * @private		 * @class		 * @name Highcharts.Pane		 *		 * @param {Highcharts.PaneOptions} options		 *		 * @param {Highcharts.Chart} chart		 */		function Pane(options, chart) {		    this.init(options, chart);		}		// Extend the Pane prototype		extend(Pane.prototype, {		    coll: 'pane', // Member of chart.pane		    /**		     * Initiate the Pane object		     *		     * @private		     * @function Highcharts.Pane#init		     *		     * @param {Highcharts.PaneOptions} options		     *		     * @param {Highcharts.Chart} chart		     */		    init: function (options, chart) {		        this.chart = chart;		        this.background = [];		        chart.pane.push(this);		        this.setOptions(options);		    },		    /**		     * @private		     * @function Highcharts.Pane#setOptions		     *		     * @param {Highcharts.PaneOptions} options		     */		    setOptions: function (options) {		        // Set options. Angular charts have a default background (#3318)		        this.options = options = merge(		            this.defaultOptions,		            this.chart.angular ? { background: {} } : undefined,		            options		        );		    },		    /**		     * Render the pane with its backgrounds.		     *		     * @private		     * @function Highcharts.Pane#render		     */		    render: function () {		        var options = this.options,		            backgroundOption = this.options.background,		            renderer = this.chart.renderer,		            len,		            i;		        if (!this.group) {		            this.group = renderer.g('pane-group')		                .attr({ zIndex: options.zIndex || 0 })		                .add();		        }		        this.updateCenter();		        // Render the backgrounds		        if (backgroundOption) {		            backgroundOption = splat(backgroundOption);		            len = Math.max(		                backgroundOption.length,		                this.background.length || 0		            );		            for (i = 0; i < len; i++) {		                // #6641 - if axis exists, chart is circular and apply		                // background		                if (backgroundOption[i] && this.axis) {		                    this.renderBackground(		                        merge(		                            this.defaultBackgroundOptions,		                            backgroundOption[i]		                        ),		                        i		                    );		                } else if (this.background[i]) {		                    this.background[i] = this.background[i].destroy();		                    this.background.splice(i, 1);		                }		            }		        }		    },		    /**		     * Render an individual pane background.		     *		     * @private		     * @function Highcharts.Pane#renderBackground		     *		     * @param {Highcharts.PaneBackgroundOptions} backgroundOptions		     *        Background options		     *		     * @param {number} i		     *        The index of the background in this.backgrounds		     */		    renderBackground: function (backgroundOptions, i) {		        var method = 'animate',		            attribs = {		                'class':		                    'highcharts-pane ' + (backgroundOptions.className || '')		            };		        if (!this.chart.styledMode) {		            extend(attribs, {		                'fill': backgroundOptions.backgroundColor,		                'stroke': backgroundOptions.borderColor,		                'stroke-width': backgroundOptions.borderWidth		            });		        }		        if (!this.background[i]) {		            this.background[i] = this.chart.renderer.path()		                .add(this.group);		            method = 'attr';		        }		        this.background[i][method]({		            'd': this.axis.getPlotBandPath(		                backgroundOptions.from,		                backgroundOptions.to,		                backgroundOptions		            )		        }).attr(attribs);		    },		    /**		     * The pane serves as a container for axes and backgrounds for circular		     * gauges and polar charts.		     *		     * @since        2.3.0		     * @product      highcharts		     * @optionparent pane		     */		    defaultOptions: {		        /**		         * The end angle of the polar X axis or gauge value axis, given in		         * degrees where 0 is north. Defaults to [startAngle](#pane.startAngle)		         * + 360.		         *		         * @sample {highcharts} highcharts/demo/gauge-vu-meter/		         *         VU-meter with custom start and end angle		         *		         * @type      {number}		         * @since     2.3.0		         * @product   highcharts		         * @apioption pane.endAngle		         */		        /**		         * The center of a polar chart or angular gauge, given as an array		         * of [x, y] positions. Positions can be given as integers that		         * transform to pixels, or as percentages of the plot area size.		         *		         * @sample {highcharts} highcharts/demo/gauge-vu-meter/		         *         Two gauges with different center		         *		         * @type    {Array<string|number>}		         * @default ["50%", "50%"]		         * @since   2.3.0		         * @product highcharts		         */		        center: ['50%', '50%'],		        /**		         * The size of the pane, either as a number defining pixels, or a		         * percentage defining a percentage of the plot are.		         *		         * @sample {highcharts} highcharts/demo/gauge-vu-meter/		         *         Smaller size		         *		         * @type    {number|string}		         * @product highcharts		         */		        size: '85%',		        /**		         * The start angle of the polar X axis or gauge axis, given in degrees		         * where 0 is north. Defaults to 0.		         *		         * @sample {highcharts} highcharts/demo/gauge-vu-meter/		         *         VU-meter with custom start and end angle		         *		         * @since   2.3.0		         * @product highcharts		         */		        startAngle: 0		    },		    /**		     * An array of background items for the pane.		     *		     * @sample {highcharts} highcharts/demo/gauge-speedometer/		     *         Speedometer gauge with multiple backgrounds		     *		     * @type         {Array<*>}		     * @optionparent pane.background		     */		    defaultBackgroundOptions: {		        /**		         * The class name for this background.		         *		         * @sample {highcharts} highcharts/css/pane/		         *         Panes styled by CSS		         * @sample {highstock} highcharts/css/pane/		         *         Panes styled by CSS		         * @sample {highmaps} highcharts/css/pane/		         *         Panes styled by CSS		         *		         * @type      {string}		         * @default   highcharts-pane		         * @since     5.0.0		         * @apioption pane.background.className		         */		        /**		         * The shape of the pane background. When `solid`, the background		         * is circular. When `arc`, the background extends only from the min		         * to the max of the value axis.		         *		         * @type       {string}		         * @since      2.3.0		         * @validvalue ["arc", "circle", "solid"]		         * @product    highcharts		         */		        shape: 'circle',		        /**		         * The pixel border width of the pane background.		         *		         * @since 2.3.0		         * @product highcharts		         */		        borderWidth: 1,		        /**		         * The pane background border color.		         *		         * @type    {Highcharts.ColorString}		         * @since   2.3.0		         * @product highcharts		         */		        borderColor: '#cccccc',		        /**		         * The background color or gradient for the pane.		         *		         * @type    {Highcharts.GradientColorObject}		         * @default { linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 }, stops: [[0, #ffffff], [1, #e6e6e6]] }		         * @since   2.3.0		         * @product highcharts		         */		        backgroundColor: {		            /**		             * @ignore		             */		            linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 },		            /**		             * @ignore		             */		            stops: [		                [0, '#ffffff'],		                [1, '#e6e6e6']		            ]		        },		        /** @ignore-option */		        from: -Number.MAX_VALUE, // corrected to axis min		        /**		         * The inner radius of the pane background. Can be either numeric		         * (pixels) or a percentage string.		         *		         * @type    {number|string}		         * @since   2.3.0		         * @product highcharts		         */		        innerRadius: 0,		        /**		         * @ignore-option		         */		        to: Number.MAX_VALUE, // corrected to axis max		        /**		         * The outer radius of the circular pane background. Can be either		         * numeric (pixels) or a percentage string.		         *		         * @type     {number|string}		         * @since    2.3.0		         * @product  highcharts		         */		        outerRadius: '105%'		    },		    /**		     * Gets the center for the pane and its axis.		     *		     * @private		     * @function Highcharts.Pane#updateCenter		     *		     * @param {Highcharts.RadialAxis} axis		     */		    updateCenter: function (axis) {		        this.center = (axis || this.axis || {}).center =		            CenteredSeriesMixin.getCenter.call(this);		    },		    /**		     * Destroy the pane item		     *		     * @ignore		     * @private		     * @function Highcharts.Pane#destroy		     * /		    destroy: function () {		        H.erase(this.chart.pane, this);		        this.background.forEach(function (background) {		            background.destroy();		        });		        this.background.length = 0;		        this.group = this.group.destroy();		    },		    */		    /**		     * Update the pane item with new options		     *		     * @private		     * @function Highcharts.Pane#update		     *		     * @param {Highcharts.PaneOptions} options		     *        New pane options		     *		     * @param {boolean} redraw		     */		    update: function (options, redraw) {		        merge(true, this.options, options);		        this.setOptions(this.options);		        this.render();		        this.chart.axes.forEach(function (axis) {		            if (axis.pane === this) {		                axis.pane = null;		                axis.update({}, redraw);		            }		        }, this);		    }		});		H.Pane = Pane;	}(Highcharts));	(function (H) {		/* *		 * (c) 2010-2019 Torstein Honsi		 *		 * License: www.highcharts.com/license		 */		var addEvent = H.addEvent,		    Axis = H.Axis,		    extend = H.extend,		    merge = H.merge,		    noop = H.noop,		    pick = H.pick,		    pInt = H.pInt,		    Tick = H.Tick,		    wrap = H.wrap,		    correctFloat = H.correctFloat,		    hiddenAxisMixin, // @todo Extract this to a new file		    radialAxisMixin, // @todo Extract this to a new file		    axisProto = Axis.prototype,		    tickProto = Tick.prototype;		if (!H.radialAxisExtended) {		    H.radialAxisExtended = true;		    // Augmented methods for the x axis in order to hide it completely, used for		    // the X axis in gauges		    hiddenAxisMixin = {		        getOffset: noop,		        redraw: function () {		            this.isDirty = false; // prevent setting Y axis dirty		        },		        render: function () {		            this.isDirty = false; // prevent setting Y axis dirty		        },		        setScale: noop,		        setCategories: noop,		        setTitle: noop		    };		    // Augmented methods for the value axis		    radialAxisMixin = {		        // The default options extend defaultYAxisOptions		        defaultRadialGaugeOptions: {		            labels: {		                align: 'center',		                x: 0,		                y: null // auto		            },		            minorGridLineWidth: 0,		            minorTickInterval: 'auto',		            minorTickLength: 10,		            minorTickPosition: 'inside',		            minorTickWidth: 1,		            tickLength: 10,		            tickPosition: 'inside',		            tickWidth: 2,		            title: {		                rotation: 0		            },		            zIndex: 2 // behind dials, points in the series group		        },		        // Circular axis around the perimeter of a polar chart		        defaultRadialXOptions: {		            gridLineWidth: 1, // spokes		            labels: {		                align: null, // auto		                distance: 15,		                x: 0,		                y: null, // auto		                style: {		                    textOverflow: 'none' // wrap lines by default (#7248)		                }		            },		            maxPadding: 0,		            minPadding: 0,		            showLastLabel: false,		            tickLength: 0		        },		        // Radial axis, like a spoke in a polar chart		        defaultRadialYOptions: {		            gridLineInterpolation: 'circle',		            labels: {		                align: 'right',		                x: -3,		                y: -2		            },		            showLastLabel: false,		            title: {		                x: 4,		                text: null,		                rotation: 90		            }		        },		        // Merge and set options		        setOptions: function (userOptions) {		            var options = this.options = merge(		                this.defaultOptions,		                this.defaultRadialOptions,		                userOptions		            );		            // Make sure the plotBands array is instanciated for each Axis		            // (#2649)		            if (!options.plotBands) {		                options.plotBands = [];		            }		            H.fireEvent(this, 'afterSetOptions');		        },		        // Wrap the getOffset method to return zero offset for title or labels		        // in a radial axis		        getOffset: function () {		            // Call the Axis prototype method (the method we're in now is on the		            // instance)		            axisProto.getOffset.call(this);		            // Title or label offsets are not counted		            this.chart.axisOffset[this.side] = 0;		        },		        // Get the path for the axis line. This method is also referenced in the		        // getPlotLinePath method.		        getLinePath: function (lineWidth, radius) {		            var center = this.center,		                end,		                chart = this.chart,		                r = pick(radius, center[2] / 2 - this.offset),		                path;		            if (this.isCircular || radius !== undefined) {		                path = this.chart.renderer.symbols.arc(		                    this.left + center[0],		                    this.top + center[1],		                    r,		                    r,		                    {		                        start: this.startAngleRad,		                        end: this.endAngleRad,		                        open: true,		                        innerR: 0		                    }		                );		                // Bounds used to position the plotLine label next to the line		                // (#7117)		                path.xBounds = [this.left + center[0]];		                path.yBounds = [this.top + center[1] - r];		            } else {		                end = this.postTranslate(this.angleRad, r);		                path = [		                    'M',		                    center[0] + chart.plotLeft,		                    center[1] + chart.plotTop,		                    'L',		                    end.x,		                    end.y		                ];		            }		            return path;		        },		        /* *		         * Override setAxisTranslation by setting the translation to the		         * difference in rotation. This allows the translate method to return		         * angle for any given value.		         */		        setAxisTranslation: function () {		            // Call uber method		            axisProto.setAxisTranslation.call(this);		            // Set transA and minPixelPadding		            if (this.center) { // it's not defined the first time		                if (this.isCircular) {		                    this.transA = (this.endAngleRad - this.startAngleRad) /		                        ((this.max - this.min) || 1);		                } else {		                    this.transA = (		                        (this.center[2] / 2) /		                        ((this.max - this.min) || 1)		                    );		                }		                if (this.isXAxis) {		                    this.minPixelPadding = this.transA * this.minPointOffset;		                } else {		                    // This is a workaround for regression #2593, but categories		                    // still don't position correctly.		                    this.minPixelPadding = 0;		                }		            }		        },		        /* *		         * In case of auto connect, add one closestPointRange to the max value		         * right before tickPositions are computed, so that ticks will extend		         * passed the real max.		         */		        beforeSetTickPositions: function () {		            // If autoConnect is true, polygonal grid lines are connected, and		            // one closestPointRange is added to the X axis to prevent the last		            // point from overlapping the first.		            this.autoConnect = (		                this.isCircular &&		                pick(this.userMax, this.options.max) === undefined &&		                correctFloat(this.endAngleRad - this.startAngleRad) ===		                correctFloat(2 * Math.PI)		            );		            if (this.autoConnect) {		                this.max += (		                    (this.categories && 1) ||		                    this.pointRange ||		                    this.closestPointRange ||		                    0		                ); // #1197, #2260		            }		        },		        /* *		         * Override the setAxisSize method to use the arc's circumference as		         * length. This allows tickPixelInterval to apply to pixel lengths along		         * the perimeter		         */		        setAxisSize: function () {		            axisProto.setAxisSize.call(this);		            if (this.isRadial) {		                // Set the center array		                this.pane.updateCenter(this);		                // The sector is used in Axis.translate to compute the		                // translation of reversed axis points (#2570)		                if (this.isCircular) {		                    this.sector = this.endAngleRad - this.startAngleRad;		                }		                // Axis len is used to lay out the ticks		                this.len = this.width = this.height =		                    this.center[2] * pick(this.sector, 1) / 2;		            }		        },		        /* *		         * Returns the x, y coordinate of a point given by a value and a pixel		         * distance from center		         */		        getPosition: function (value, length) {		            return this.postTranslate(		                this.isCircular ?		                    this.translate(value) :		                    this.angleRad, // #2848		                pick(		                    this.isCircular ? length : this.translate(value),		                    this.center[2] / 2		                ) - this.offset		            );		        },		        /* *		         * Translate from intermediate plotX (angle), plotY (axis.len - radius)		         * to final chart coordinates.		         */		        postTranslate: function (angle, radius) {		            var chart = this.chart,		                center = this.center;		            angle = this.startAngleRad + angle;		            return {		                x: chart.plotLeft + center[0] + Math.cos(angle) * radius,		                y: chart.plotTop + center[1] + Math.sin(angle) * radius		            };		        },		        /* *		         * Find the path for plot bands along the radial axis		         */		        getPlotBandPath: function (from, to, options) {		            var center = this.center,		                startAngleRad = this.startAngleRad,		                fullRadius = center[2] / 2,		                radii = [		                    pick(options.outerRadius, '100%'),		                    options.innerRadius,		                    pick(options.thickness, 10)		                ],		                offset = Math.min(this.offset, 0),		                percentRegex = /%$/,		                start,		                end,		                open,		                isCircular = this.isCircular, // X axis in a polar chart		                ret;		            // Polygonal plot bands		            if (this.options.gridLineInterpolation === 'polygon') {		                ret = this.getPlotLinePath(from).concat(		                    this.getPlotLinePath(to, true)		                );		            // Circular grid bands		            } else {		                // Keep within bounds		                from = Math.max(from, this.min);		                to = Math.min(to, this.max);		                // Plot bands on Y axis (radial axis) - inner and outer radius		                // depend on to and from		                if (!isCircular) {		                    radii[0] = this.translate(from);		                    radii[1] = this.translate(to);		                }		                // Convert percentages to pixel values		                radii = radii.map(function (radius) {		                    if (percentRegex.test(radius)) {		                        radius = (pInt(radius, 10) * fullRadius) / 100;		                    }		                    return radius;		                });		                // Handle full circle		                if (options.shape === 'circle' || !isCircular) {		                    start = -Math.PI / 2;		                    end = Math.PI * 1.5;		                    open = true;		                } else {		                    start = startAngleRad + this.translate(from);		                    end = startAngleRad + this.translate(to);		                }		                radii[0] -= offset; // #5283		                radii[2] -= offset; // #5283		                ret = this.chart.renderer.symbols.arc(		                    this.left + center[0],		                    this.top + center[1],		                    radii[0],		                    radii[0],		                    {		                        // Math is for reversed yAxis (#3606)		                        start: Math.min(start, end),		                        end: Math.max(start, end),		                        innerR: pick(radii[1], radii[0] - radii[2]),		                        open: open		                    }		                );		            }		            return ret;		        },		        /* *		         * Find the path for plot lines perpendicular to the radial axis.		         */		        getPlotLinePath: function (value, reverse) {		            var axis = this,		                center = axis.center,		                chart = axis.chart,		                end = axis.getPosition(value),		                xAxis,		                xy,		                tickPositions,		                ret;		            // Spokes		            if (axis.isCircular) {		                ret = [		                    'M',		                    center[0] + chart.plotLeft,		                    center[1] + chart.plotTop,		                    'L',		                    end.x,		                    end.y		                ];		            // Concentric circles		            } else if (axis.options.gridLineInterpolation === 'circle') {		                value = axis.translate(value);		                // a value of 0 is in the center, so it won't be visible,		                // but draw it anyway for update and animation (#2366)		                ret = axis.getLinePath(0, value);		            // Concentric polygons		            } else {		                // Find the X axis in the same pane		                chart.xAxis.forEach(function (a) {		                    if (a.pane === axis.pane) {		                        xAxis = a;		                    }		                });		                ret = [];		                value = axis.translate(value);		                tickPositions = xAxis.tickPositions;		                if (xAxis.autoConnect) {		                    tickPositions = tickPositions.concat([tickPositions[0]]);		                }		                // Reverse the positions for concatenation of polygonal plot		                // bands		                if (reverse) {		                    tickPositions = [].concat(tickPositions).reverse();		                }		                tickPositions.forEach(function (pos, i) {		                    xy = xAxis.getPosition(pos, value);		                    ret.push(i ? 'L' : 'M', xy.x, xy.y);		                });		            }		            return ret;		        },		        /* *		         * Find the position for the axis title, by default inside the gauge		         */		        getTitlePosition: function () {		            var center = this.center,		                chart = this.chart,		                titleOptions = this.options.title;		            return {		                x: chart.plotLeft + center[0] + (titleOptions.x || 0),		                y: (		                    chart.plotTop +		                    center[1] -		                    (		                        {		                            high: 0.5,		                            middle: 0.25,		                            low: 0		                        }[titleOptions.align] * center[2]		                    ) +		                    (titleOptions.y || 0)		                )		            };		        }		    };		    // Actions before axis init.		    addEvent(Axis, 'init', function (e) {		        var axis = this,		            chart = this.chart,		            angular = chart.angular,		            polar = chart.polar,		            isX = this.isXAxis,		            isHidden = angular && isX,		            isCircular,		            chartOptions = chart.options,		            paneIndex = e.userOptions.pane || 0,		            pane = this.pane = chart.pane && chart.pane[paneIndex];		        // Before prototype.init		        if (angular) {		            extend(this, isHidden ? hiddenAxisMixin : radialAxisMixin);		            isCircular = !isX;		            if (isCircular) {		                this.defaultRadialOptions = this.defaultRadialGaugeOptions;		            }		        } else if (polar) {		            extend(this, radialAxisMixin);		            isCircular = isX;		            this.defaultRadialOptions = isX ?		                this.defaultRadialXOptions :		                merge(this.defaultYAxisOptions, this.defaultRadialYOptions);		        }		        // Disable certain features on angular and polar axes		        if (angular || polar) {		            this.isRadial = true;		            chart.inverted = false;		            chartOptions.chart.zoomType = null;		            // Prevent overlapping axis labels (#9761)		            chart.labelCollectors.push(function () {		                if (		                    axis.isRadial &&		                    axis.tickPositions &&		                    // undocumented option for now, but working		                    axis.options.labels.allowOverlap !== true		                ) {		                    return axis.tickPositions		                        .map(function (pos) {		                            return axis.ticks[pos] && axis.ticks[pos].label;		                        })		                        .filter(function (label) {		                            return Boolean(label);		                        });		                }		            });		        } else {		            this.isRadial = false;		        }		        // A pointer back to this axis to borrow geometry		        if (pane && isCircular) {		            pane.axis = this;		        }		        this.isCircular = isCircular;		    });		    addEvent(Axis, 'afterInit', function () {		        var chart = this.chart,		            options = this.options,		            isHidden = chart.angular && this.isXAxis,		            pane = this.pane,		            paneOptions = pane && pane.options;		        if (!isHidden && pane && (chart.angular || chart.polar)) {		            // Start and end angle options are		            // given in degrees relative to top, while internal computations are		            // in radians relative to right (like SVG).		            // Y axis in polar charts		            this.angleRad = (options.angle || 0) * Math.PI / 180;		            // Gauges		            this.startAngleRad = (paneOptions.startAngle - 90) * Math.PI / 180;		            this.endAngleRad = (		                pick(paneOptions.endAngle, paneOptions.startAngle + 360) - 90		            ) * Math.PI / 180; // Gauges		            this.offset = options.offset || 0;		        }		    });		    // Wrap auto label align to avoid setting axis-wide rotation on radial axes		    // (#4920)		    addEvent(Axis, 'autoLabelAlign', function (e) {		        if (this.isRadial) {		            e.align = undefined;		            e.preventDefault();		        }		    });		    // Add special cases within the Tick class' methods for radial axes.		    addEvent(Tick, 'afterGetPosition', function (e) {		        if (this.axis.getPosition) {		            extend(e.pos, this.axis.getPosition(this.pos));		        }		    });		    // Find the center position of the label based on the distance option.		    addEvent(Tick, 'afterGetLabelPosition', function (e) {		        var axis = this.axis,		            label = this.label,		            labelOptions = axis.options.labels,		            optionsY = labelOptions.y,		            ret,		            centerSlot = 20, // 20 degrees to each side at the top and bottom		            align = labelOptions.align,		            angle = (		                (axis.translate(this.pos) + axis.startAngleRad + Math.PI / 2) /		                Math.PI * 180		            ) % 360;		        if (axis.isRadial) { // Both X and Y axes in a polar chart		            ret = axis.getPosition(this.pos, (axis.center[2] / 2) +		                pick(labelOptions.distance, -25));		            // Automatically rotated		            if (labelOptions.rotation === 'auto') {		                label.attr({		                    rotation: angle		                });		            // Vertically centered		            } else if (optionsY === null) {		                optionsY = (		                    axis.chart.renderer		                        .fontMetrics(label.styles && label.styles.fontSize).b -		                    label.getBBox().height / 2		                );		            }		            // Automatic alignment		            if (align === null) {		                if (axis.isCircular) { // Y axis		                    if (		                        this.label.getBBox().width >		                        axis.len * axis.tickInterval / (axis.max - axis.min)		                    ) { // #3506		                        centerSlot = 0;		                    }		                    if (angle > centerSlot && angle < 180 - centerSlot) {		                        align = 'left'; // right hemisphere		                    } else if (		                        angle > 180 + centerSlot &&		                        angle < 360 - centerSlot		                    ) {		                        align = 'right'; // left hemisphere		                    } else {		                        align = 'center'; // top or bottom		                    }		                } else {		                    align = 'center';		                }		                label.attr({		                    align: align		                });		            }		            e.pos.x = ret.x + labelOptions.x;		            e.pos.y = ret.y + optionsY;		        }		    });		    // Wrap the getMarkPath function to return the path of the radial marker		    wrap(tickProto, 'getMarkPath', function (		        proceed,		        x,		        y,		        tickLength,		        tickWidth,		        horiz,		        renderer		    ) {		        var axis = this.axis,		            endPoint,		            ret;		        if (axis.isRadial) {		            endPoint = axis.getPosition(		                this.pos,		                axis.center[2] / 2 + tickLength		            );		            ret = [		                'M',		                x,		                y,		                'L',		                endPoint.x,		                endPoint.y		            ];		        } else {		            ret = proceed.call(		                this,		                x,		                y,		                tickLength,		                tickWidth,		                horiz,		                renderer		            );		        }		        return ret;		    });		}	}(Highcharts));	(function (H) {		/* *		 * (c) 2010-2019 Torstein Honsi		 *		 * License: www.highcharts.com/license		 */		var noop = H.noop,		    pick = H.pick,		    extend = H.extend,		    isArray = H.isArray,		    defined = H.defined,		    Series = H.Series,		    seriesType = H.seriesType,		    seriesTypes = H.seriesTypes,		    seriesProto = Series.prototype,		    pointProto = H.Point.prototype;		/**		 * The area range series is a carteseian series with higher and lower values for		 * each point along an X axis, where the area between the values is shaded.		 * Requires `highcharts-more.js`.		 *		 * @sample {highcharts} highcharts/demo/arearange/		 *         Area range chart		 * @sample {highstock} stock/demo/arearange/		 *         Area range chart		 *		 * @extends      plotOptions.area		 * @product      highcharts highstock		 * @excluding    stack, stacking		 * @optionparent plotOptions.arearange		 */		seriesType('arearange', 'area', {		    /**		     * Whether to apply a drop shadow to the graph line. Since 2.3 the shadow		     * can be an object configuration containing `color`, `offsetX`, `offsetY`,		     * `opacity` and `width`.		     *		     * @type      {boolean|Highcharts.ShadowOptionsObject}		     * @product   highcharts		     * @apioption plotOptions.arearange.shadow		     */		    /**		     * Pixel width of the arearange graph line.		     *		     * @since   2.3.0		     * @product highcharts highstock		     */		    lineWidth: 1,		    threshold: null,		    tooltip: {		        pointFormat: '<span style="color:{series.color}">\u25CF</span> ' +		            '{series.name}: <b>{point.low}</b> - <b>{point.high}</b><br/>'		    },		    /**		     * Whether the whole area or just the line should respond to mouseover		     * tooltips and other mouse or touch events.		     *		     * @since   2.3.0		     * @product highcharts highstock		     */		    trackByArea: true,		    /**		     * Extended data labels for range series types. Range series data labels		     * have no `x` and `y` options. Instead, they have `xLow`, `xHigh`, `yLow`		     * and `yHigh` options to allow the higher and lower data label sets		     * individually.		     *		     * @extends   plotOptions.series.dataLabels		     * @since     2.3.0		     * @excluding x, y		     * @product   highcharts highstock		     */		    dataLabels: {		        /**		         * @type {Highcharts.AlignType|null}		         */		        align: null,		        /**		         * @type {Highcharts.VerticalAlignType|null}		         */		        verticalAlign: null,		        /**		         * X offset of the lower data labels relative to the point value.		         *		         * @sample {highcharts} highcharts/plotoptions/arearange-datalabels/		         *         Data labels on range series		         * @sample {highstock} highcharts/plotoptions/arearange-datalabels/		         *         Data labels on range series		         *		         * @since   2.3.0		         * @product highcharts highstock		         */		        xLow: 0,		        /**		         * X offset of the higher data labels relative to the point value.		         *		         * @sample {highcharts|highstock} highcharts/plotoptions/arearange-datalabels/		         *         Data labels on range series		         *		         * @since   2.3.0		         * @product highcharts highstock		         */		        xHigh: 0,		        /**		         * Y offset of the lower data labels relative to the point value.		         *		         * @sample {highcharts|highstock} highcharts/plotoptions/arearange-datalabels/		         *         Data labels on range series		         *		         * @since   2.3.0		         * @product highcharts highstock		         */		        yLow: 0,		        /**		         * Y offset of the higher data labels relative to the point value.		         *		         * @sample {highcharts|highstock} highcharts/plotoptions/arearange-datalabels/		         *         Data labels on range series		         *		         * @since   2.3.0		         * @product highcharts highstock		         */		        yHigh: 0		    }		// Prototype members		}, {		    pointArrayMap: ['low', 'high'],		    toYData: function (point) {		        return [point.low, point.high];		    },		    pointValKey: 'low',		    deferTranslatePolar: true,		    // Translate a point's plotHigh from the internal angle and radius measures		    // to true plotHigh coordinates. This is an addition of the toXY method		    // found in Polar.js, because it runs too early for arearanges to be		    // considered (#3419).		    highToXY: function (point) {		        // Find the polar plotX and plotY		        var chart = this.chart,		            xy = this.xAxis.postTranslate(		                point.rectPlotX,		                this.yAxis.len - point.plotHigh		            );		        point.plotHighX = xy.x - chart.plotLeft;		        point.plotHigh = xy.y - chart.plotTop;		        point.plotLowX = point.plotX;		    },		    // Translate data points from raw values x and y to plotX and plotY.		    translate: function () {		        var series = this,		            yAxis = series.yAxis,		            hasModifyValue = !!series.modifyValue;		        seriesTypes.area.prototype.translate.apply(series);		        // Set plotLow and plotHigh		        series.points.forEach(function (point) {		            var low = point.low,		                high = point.high,		                plotY = point.plotY;		            if (high === null || low === null) {		                point.isNull = true;		                point.plotY = null;		            } else {		                point.plotLow = plotY;		                point.plotHigh = yAxis.translate(		                    hasModifyValue ? series.modifyValue(high, point) : high,		                    0,		                    1,		                    0,		                    1		                );		                if (hasModifyValue) {		                    point.yBottom = point.plotHigh;		                }		            }		        });		        // Postprocess plotHigh		        if (this.chart.polar) {		            this.points.forEach(function (point) {		                series.highToXY(point);		                point.tooltipPos = [		                    (point.plotHighX + point.plotLowX) / 2,		                    (point.plotHigh + point.plotLow) / 2		                ];		            });		        }		    },		    // Extend the line series' getSegmentPath method by applying the segment		    // path to both lower and higher values of the range.		    getGraphPath: function (points) {		        var highPoints = [],		            highAreaPoints = [],		            i,		            getGraphPath = seriesTypes.area.prototype.getGraphPath,		            point,		            pointShim,		            linePath,		            lowerPath,		            options = this.options,		            connectEnds = this.chart.polar && options.connectEnds !== false,		            connectNulls = options.connectNulls,		            step = options.step,		            higherPath,		            higherAreaPath;		        points = points || this.points;		        i = points.length;		        // Create the top line and the top part of the area fill. The area fill		        // compensates for null points by drawing down to the lower graph,		        // moving across the null gap and starting again at the lower graph.		        i = points.length;		        while (i--) {		            point = points[i];		            if (		                !point.isNull &&		                !connectEnds &&		                !connectNulls &&		                (!points[i + 1] || points[i + 1].isNull)		            ) {		                highAreaPoints.push({		                    plotX: point.plotX,		                    plotY: point.plotY,		                    doCurve: false // #5186, gaps in areasplinerange fill		                });		            }		            pointShim = {		                polarPlotY: point.polarPlotY,		                rectPlotX: point.rectPlotX,		                yBottom: point.yBottom,		                // plotHighX is for polar charts		                plotX: pick(point.plotHighX, point.plotX),		                plotY: point.plotHigh,		                isNull: point.isNull		            };		            highAreaPoints.push(pointShim);		            highPoints.push(pointShim);		            if (		                !point.isNull &&		                !connectEnds &&		                !connectNulls &&		                (!points[i - 1] || points[i - 1].isNull)		            ) {		                highAreaPoints.push({		                    plotX: point.plotX,		                    plotY: point.plotY,		                    doCurve: false // #5186, gaps in areasplinerange fill		                });		            }		        }		        // Get the paths		        lowerPath = getGraphPath.call(this, points);		        if (step) {		            if (step === true) {		                step = 'left';		            }		            options.step = {		                left: 'right',		                center: 'center',		                right: 'left'		            }[step]; // swap for reading in getGraphPath		        }		        higherPath = getGraphPath.call(this, highPoints);		        higherAreaPath = getGraphPath.call(this, highAreaPoints);		        options.step = step;		        // Create a line on both top and bottom of the range		        linePath = [].concat(lowerPath, higherPath);		        // For the area path, we need to change the 'move' statement		        // into 'lineTo' or 'curveTo'		        if (!this.chart.polar && higherAreaPath[0] === 'M') {		            higherAreaPath[0] = 'L'; // this probably doesn't work for spline		        }		        this.graphPath = linePath;		        this.areaPath = lowerPath.concat(higherAreaPath);		        // Prepare for sideways animation		        linePath.isArea = true;		        linePath.xMap = lowerPath.xMap;		        this.areaPath.xMap = lowerPath.xMap;		        return linePath;		    },		    // Extend the basic drawDataLabels method by running it for both lower and		    // higher values.		    drawDataLabels: function () {		        var data = this.points,		            length = data.length,		            i,		            originalDataLabels = [],		            dataLabelOptions = this.options.dataLabels,		            point,		            up,		            inverted = this.chart.inverted,		            upperDataLabelOptions,		            lowerDataLabelOptions;		        // Split into upper and lower options. If data labels is an array, the		        // first element is the upper label, the second is the lower.		        //		        // TODO: We want to change this and allow multiple labels for both upper		        // and lower values in the future - introducing some options for which		        // point value to use as Y for the dataLabel, so that this could be		        // handled in Series.drawDataLabels. This would also improve performance		        // since we now have to loop over all the points multiple times to work		        // around the data label logic.		        if (isArray(dataLabelOptions)) {		            if (dataLabelOptions.length > 1) {		                upperDataLabelOptions = dataLabelOptions[0];		                lowerDataLabelOptions = dataLabelOptions[1];		            } else {		                upperDataLabelOptions = dataLabelOptions[0];		                lowerDataLabelOptions = { enabled: false };		            }		        } else {		            upperDataLabelOptions = extend({}, dataLabelOptions); // Make copy;		            upperDataLabelOptions.x = dataLabelOptions.xHigh;		            upperDataLabelOptions.y = dataLabelOptions.yHigh;		            lowerDataLabelOptions = extend({}, dataLabelOptions); // Make copy		            lowerDataLabelOptions.x = dataLabelOptions.xLow;		            lowerDataLabelOptions.y = dataLabelOptions.yLow;		        }		        // Draw upper labels		        if (upperDataLabelOptions.enabled || this._hasPointLabels) {		            // Set preliminary values for plotY and dataLabel		            // and draw the upper labels		            i = length;		            while (i--) {		                point = data[i];		                if (point) {		                    up = upperDataLabelOptions.inside ?		                        point.plotHigh < point.plotLow :		                        point.plotHigh > point.plotLow;		                    point.y = point.high;		                    point._plotY = point.plotY;		                    point.plotY = point.plotHigh;		                    // Store original data labels and set preliminary label		                    // objects to be picked up in the uber method		                    originalDataLabels[i] = point.dataLabel;		                    point.dataLabel = point.dataLabelUpper;		                    // Set the default offset		                    point.below = up;		                    if (inverted) {		                        if (!upperDataLabelOptions.align) {		                            upperDataLabelOptions.align = up ? 'right' : 'left';		                        }		                    } else {		                        if (!upperDataLabelOptions.verticalAlign) {		                            upperDataLabelOptions.verticalAlign = up ?		                                'top' :		                                'bottom';		                        }		                    }		                }		            }		            this.options.dataLabels = upperDataLabelOptions;		            if (seriesProto.drawDataLabels) {		                seriesProto.drawDataLabels.apply(this, arguments); // #1209		            }		            // Reset state after the upper labels were created. Move		            // it to point.dataLabelUpper and reassign the originals.		            // We do this here to support not drawing a lower label.		            i = length;		            while (i--) {		                point = data[i];		                if (point) {		                    point.dataLabelUpper = point.dataLabel;		                    point.dataLabel = originalDataLabels[i];		                    delete point.dataLabels;		                    point.y = point.low;		                    point.plotY = point._plotY;		                }		            }		        }		        // Draw lower labels		        if (lowerDataLabelOptions.enabled || this._hasPointLabels) {		            i = length;		            while (i--) {		                point = data[i];		                if (point) {		                    up = lowerDataLabelOptions.inside ?		                        point.plotHigh < point.plotLow :		                        point.plotHigh > point.plotLow;		                    // Set the default offset		                    point.below = !up;		                    if (inverted) {		                        if (!lowerDataLabelOptions.align) {		                            lowerDataLabelOptions.align = up ? 'left' : 'right';		                        }		                    } else {		                        if (!lowerDataLabelOptions.verticalAlign) {		                            lowerDataLabelOptions.verticalAlign = up ?		                                'bottom' :		                                'top';		                        }		                    }		                }		            }		            this.options.dataLabels = lowerDataLabelOptions;		            if (seriesProto.drawDataLabels) {		                seriesProto.drawDataLabels.apply(this, arguments);		            }		        }		        // Merge upper and lower into point.dataLabels for later destroying		        if (upperDataLabelOptions.enabled) {		            i = length;		            while (i--) {		                point = data[i];		                if (point) {		                    point.dataLabels = [point.dataLabelUpper, point.dataLabel]		                        .filter(function (label) {		                            return !!label;		                        });		                }		            }		        }		        // Reset options		        this.options.dataLabels = dataLabelOptions;		    },		    alignDataLabel: function () {		        seriesTypes.column.prototype.alignDataLabel.apply(this, arguments);		    },		    drawPoints: function () {		        var series = this,		            pointLength = series.points.length,		            point,		            i;		        // Draw bottom points		        seriesProto.drawPoints.apply(series, arguments);		        // Prepare drawing top points		        i = 0;		        while (i < pointLength) {		            point = series.points[i];		            // Save original props to be overridden by temporary props for top		            // points		            point.origProps = {		                plotY: point.plotY,		                plotX: point.plotX,		                isInside: point.isInside,		                negative: point.negative,		                zone: point.zone,		                y: point.y		            };		            point.lowerGraphic = point.graphic;		            point.graphic = point.upperGraphic;		            point.plotY = point.plotHigh;		            if (defined(point.plotHighX)) {		                point.plotX = point.plotHighX;		            }		            point.y = point.high;		            point.negative = point.high < (series.options.threshold || 0);		            point.zone = series.zones.length && point.getZone();		            if (!series.chart.polar) {		                point.isInside = point.isTopInside = (		                    point.plotY !== undefined &&		                    point.plotY >= 0 &&		                    point.plotY <= series.yAxis.len && // #3519		                    point.plotX >= 0 &&		                    point.plotX <= series.xAxis.len		                );		            }		            i++;		        }		        // Draw top points		        seriesProto.drawPoints.apply(series, arguments);		        // Reset top points preliminary modifications		        i = 0;		        while (i < pointLength) {		            point = series.points[i];		            point.upperGraphic = point.graphic;		            point.graphic = point.lowerGraphic;		            H.extend(point, point.origProps);		            delete point.origProps;		            i++;		        }		    },		    setStackedPoints: noop		}, {		    setState: function () {		        var prevState = this.state,		            series = this.series,		            isPolar = series.chart.polar;		        if (!defined(this.plotHigh)) {		            // Boost doesn't calculate plotHigh		            this.plotHigh = series.yAxis.toPixels(this.high, true);		        }		        if (!defined(this.plotLow)) {		            // Boost doesn't calculate plotLow		            this.plotLow = this.plotY = series.yAxis.toPixels(this.low, true);		        }		        if (series.stateMarkerGraphic) {		            series.lowerStateMarkerGraphic = series.stateMarkerGraphic;		            series.stateMarkerGraphic = series.upperStateMarkerGraphic;		        }		        // Change state also for the top marker		        this.graphic = this.upperGraphic;		        this.plotY = this.plotHigh;		        if (isPolar) {		            this.plotX = this.plotHighX;		        }		        // Top state:		        pointProto.setState.apply(this, arguments);		        this.state = prevState;		        // Now restore defaults		        this.plotY = this.plotLow;		        this.graphic = this.lowerGraphic;		        if (isPolar) {		            this.plotX = this.plotLowX;		        }		        if (series.stateMarkerGraphic) {		            series.upperStateMarkerGraphic = series.stateMarkerGraphic;		            series.stateMarkerGraphic = series.lowerStateMarkerGraphic;		            // Lower marker is stored at stateMarkerGraphic		            // to avoid reference duplication (#7021)		            series.lowerStateMarkerGraphic = undefined;		        }		        pointProto.setState.apply(this, arguments);		    },		    haloPath: function () {		        var isPolar = this.series.chart.polar,		            path = [];		        // Bottom halo		        this.plotY = this.plotLow;		        if (isPolar) {		            this.plotX = this.plotLowX;		        }		        if (this.isInside) {		            path = pointProto.haloPath.apply(this, arguments);		        }		        // Top halo		        this.plotY = this.plotHigh;		        if (isPolar) {		            this.plotX = this.plotHighX;		        }		        if (this.isTopInside) {		            path = path.concat(		                pointProto.haloPath.apply(this, arguments)		            );		        }		        return path;		    },		    destroyElements: function () {		        var graphics = ['lowerGraphic', 'upperGraphic'];		        graphics.forEach(function (graphicName) {		            if (this[graphicName]) {		                this[graphicName] = this[graphicName].destroy();		            }		        }, this);		        // Clear graphic for states, removed in the above each:		        this.graphic = null;		        return pointProto.destroyElements.apply(this, arguments);		    }		});		/**		 * A `arearange` series. If the [type](#series.arearange.type) option is not		 * specified, it is inherited from [chart.type](#chart.type).		 *		 *		 * @extends   series,plotOptions.arearange		 * @excluding dataParser, dataURL, stack, stacking		 * @product   highcharts highstock		 * @apioption series.arearange		 */		/**		 * An array of data points for the series. For the `arearange` series type,		 * points can be given in the following ways:		 *		 * 1.  An array of arrays with 3 or 2 values. In this case, the values		 *     correspond to `x,low,high`. If the first value is a string, it is		 *     applied as the name of the point, and the `x` value is inferred.		 *     The `x` value can also be omitted, in which case the inner arrays		 *     should be of length 2\. Then the `x` value is automatically calculated,		 *     either starting at 0 and incremented by 1, or from `pointStart`		 *     and `pointInterval` given in the series options.		 *     ```js		 *     data: [		 *         [0, 8, 3],		 *         [1, 1, 1],		 *         [2, 6, 8]		 *     ]		 *     ```		 *		 * 2.  An array of objects with named values. The following snippet shows only a		 *     few settings, see the complete options set below. If the total number of		 *     data points exceeds the series'		 *     [turboThreshold](#series.arearange.turboThreshold),		 *     this option is not available.		 *     ```js		 *     data: [{		 *         x: 1,		 *         low: 9,		 *         high: 0,		 *         name: "Point2",		 *         color: "#00FF00"		 *     }, {		 *         x: 1,		 *         low: 3,		 *         high: 4,		 *         name: "Point1",		 *         color: "#FF00FF"		 *     }]		 *     ```		 *		 * @sample {highcharts} highcharts/series/data-array-of-arrays/		 *         Arrays of numeric x and y		 * @sample {highcharts} highcharts/series/data-array-of-arrays-datetime/		 *         Arrays of datetime x and y		 * @sample {highcharts} highcharts/series/data-array-of-name-value/		 *         Arrays of point.name and y		 * @sample {highcharts} highcharts/series/data-array-of-objects/		 *         Config objects		 *		 * @type      {Array<Array<(number|string),number>|Array<(number|string),number,number>|*>}		 * @extends   series.line.data		 * @excluding marker, y		 * @product   highcharts highstock		 * @apioption series.arearange.data		 */		/**		 * The high or maximum value for each data point.		 *		 * @type      {number}		 * @product   highcharts highstock		 * @apioption series.arearange.data.high		 */		/**		 * The low or minimum value for each data point.		 *		 * @type      {number}		 * @product   highcharts highstock		 * @apioption series.arearange.data.low		 */		/**		 * @excluding x, y		 * @product   highcharts highstock		 * @apioption series.arearange.dataLabels		 */	}(Highcharts));	(function (H) {		/* *		 * (c) 2010-2019 Torstein Honsi		 *		 * License: www.highcharts.com/license		 */		var seriesType = H.seriesType,		    seriesTypes = H.seriesTypes;		/**		 * The area spline range is a cartesian series type with higher and		 * lower Y values along an X axis. The area inside the range is colored, and		 * the graph outlining the area is a smoothed spline. Requires		 * `highcharts-more.js`.		 *		 * @sample {highstock|highstock} stock/demo/areasplinerange/		 *         Area spline range		 *		 * @extends   plotOptions.arearange		 * @since     2.3.0		 * @excluding step		 * @product   highcharts highstock		 * @apioption plotOptions.areasplinerange		 */		seriesType('areasplinerange', 'arearange', null, {		    getPointSpline: seriesTypes.spline.prototype.getPointSpline		});		/**		 * A `areasplinerange` series. If the [type](#series.areasplinerange.type)		 * option is not specified, it is inherited from [chart.type](#chart.type).		 *		 * @extends   series,plotOptions.areasplinerange		 * @excluding dataParser, dataURL, stack		 * @product   highcharts highstock		 * @apioption series.areasplinerange		 */		/**		 * An array of data points for the series. For the `areasplinerange`		 * series type, points can be given in the following ways:		 *		 * 1. An array of arrays with 3 or 2 values. In this case, the values correspond		 *    to `x,low,high`. If the first value is a string, it is applied as the name		 *    of the point, and the `x` value is inferred. The `x` value can also be		 *    omitted, in which case the inner arrays should be of length 2\. Then the		 *    `x` value is automatically calculated, either starting at 0 and		 *    incremented by 1, or from `pointStart` and `pointInterval` given in the		 *    series options.		 *    ```js		 *    data: [		 *        [0, 0, 5],		 *        [1, 9, 1],		 *        [2, 5, 2]		 *    ]		 *    ```		 *		 * 2. An array of objects with named values. The following snippet shows only a		 *    few settings, see the complete options set below. If the total number of		 *    data points exceeds the series'		 *    [turboThreshold](#series.areasplinerange.turboThreshold), this option is		 *    not available.		 *    ```js		 *    data: [{		 *        x: 1,		 *        low: 5,		 *        high: 0,		 *        name: "Point2",		 *        color: "#00FF00"		 *    }, {		 *        x: 1,		 *        low: 4,		 *        high: 1,		 *        name: "Point1",		 *        color: "#FF00FF"		 *    }]		 *    ```		 *		 * @sample {highcharts} highcharts/series/data-array-of-arrays/		 *         Arrays of numeric x and y		 * @sample {highcharts} highcharts/series/data-array-of-arrays-datetime/		 *         Arrays of datetime x and y		 * @sample {highcharts} highcharts/series/data-array-of-name-value/		 *         Arrays of point.name and y		 * @sample {highcharts} highcharts/series/data-array-of-objects/		 *         Config objects		 *		 * @type      {Array<Array<(number|string),number>|Array<(number|string),number,number>|*>}		 * @extends   series.arearange.data		 * @product   highcharts highstock		 * @apioption series.areasplinerange.data		 */	}(Highcharts));	(function (H) {		/* *		 * (c) 2010-2019 Torstein Honsi		 *		 * License: www.highcharts.com/license		 */		var defaultPlotOptions = H.defaultPlotOptions,		    merge = H.merge,		    noop = H.noop,		    pick = H.pick,		    seriesType = H.seriesType,		    seriesTypes = H.seriesTypes;		var colProto = seriesTypes.column.prototype;		/**		 * The column range is a cartesian series type with higher and lower		 * Y values along an X axis. Requires `highcharts-more.js`. To display		 * horizontal bars, set [chart.inverted](#chart.inverted) to `true`.		 *		 * @sample {highcharts|highstock} highcharts/demo/columnrange/		 *         Inverted column range		 *		 * @extends      plotOptions.column		 * @since        2.3.0		 * @excluding    negativeColor, stacking, softThreshold, threshold		 * @product      highcharts highstock		 * @optionparent plotOptions.columnrange		 */		var columnRangeOptions = {		    /**		     * Extended data labels for range series types. Range series data labels		     * have no `x` and `y` options. Instead, they have `xLow`, `xHigh`,		     * `yLow` and `yHigh` options to allow the higher and lower data label		     * sets individually.		     *		     * @extends   plotOptions.arearange.dataLabels		     * @since     2.3.0		     * @excluding x, y		     * @product   highcharts highstock		     * @apioption plotOptions.columnrange.dataLabels		     */		    pointRange: null,		    /** @ignore-option */		    marker: null,		    states: {		        hover: {		            /** @ignore-option */		            halo: false		        }		    }		};		/**		 * The ColumnRangeSeries class		 *		 * @private		 * @class		 * @name Highcharts.seriesTypes.columnrange		 *		 * @augments Highcharts.Series		 */		seriesType('columnrange', 'arearange', merge(		    defaultPlotOptions.column,		    defaultPlotOptions.arearange,		    columnRangeOptions		), {		    // Translate data points from raw values x and y to plotX and plotY		    translate: function () {		        var series = this,		            yAxis = series.yAxis,		            xAxis = series.xAxis,		            startAngleRad = xAxis.startAngleRad,		            start,		            chart = series.chart,		            isRadial = series.xAxis.isRadial,		            safeDistance = Math.max(chart.chartWidth, chart.chartHeight) + 999,		            plotHigh;		        // Don't draw too far outside plot area (#6835)		        function safeBounds(pixelPos) {		            return Math.min(Math.max(		                -safeDistance,		                pixelPos		            ), safeDistance);		        }		        colProto.translate.apply(series);		        // Set plotLow and plotHigh		        series.points.forEach(function (point) {		            var shapeArgs = point.shapeArgs,		                minPointLength = series.options.minPointLength,		                heightDifference,		                height,		                y;		            point.plotHigh = plotHigh = safeBounds(		                yAxis.translate(point.high, 0, 1, 0, 1)		            );		            point.plotLow = safeBounds(point.plotY);		            // adjust shape		            y = plotHigh;		            height = pick(point.rectPlotY, point.plotY) - plotHigh;		            // Adjust for minPointLength		            if (Math.abs(height) < minPointLength) {		                heightDifference = (minPointLength - height);		                height += heightDifference;		                y -= heightDifference / 2;		            // Adjust for negative ranges or reversed Y axis (#1457)		            } else if (height < 0) {		                height *= -1;		                y -= height;		            }		            if (isRadial) {		                start = point.barX + startAngleRad;		                point.shapeType = 'path';		                point.shapeArgs = {		                    d: series.polarArc(		                        y + height,		                        y,		                        start,		                        start + point.pointWidth		                    )		                };		            } else {		                shapeArgs.height = height;		                shapeArgs.y = y;		                point.tooltipPos = chart.inverted ?		                    [		                        yAxis.len + yAxis.pos - chart.plotLeft - y - height / 2,		                        xAxis.len + xAxis.pos - chart.plotTop - shapeArgs.x -		                        shapeArgs.width / 2,		                        height		                    ] : [		                        xAxis.left - chart.plotLeft + shapeArgs.x +		                        shapeArgs.width / 2,		                        yAxis.pos - chart.plotTop + y + height / 2,		                        height		                    ]; // don't inherit from column tooltip position - #3372		            }		        });		    },		    directTouch: true,		    trackerGroups: ['group', 'dataLabelsGroup'],		    drawGraph: noop,		    getSymbol: noop,		    // Overrides from modules that may be loaded after this module		    crispCol: function () {		        return colProto.crispCol.apply(this, arguments);		    },		    drawPoints: function () {		        return colProto.drawPoints.apply(this, arguments);		    },		    drawTracker: function () {		        return colProto.drawTracker.apply(this, arguments);		    },		    getColumnMetrics: function () {		        return colProto.getColumnMetrics.apply(this, arguments);		    },		    pointAttribs: function () {		        return colProto.pointAttribs.apply(this, arguments);		    },		    animate: function () {		        return colProto.animate.apply(this, arguments);		    },		    polarArc: function () {		        return colProto.polarArc.apply(this, arguments);		    },		    translate3dPoints: function () {		        return colProto.translate3dPoints.apply(this, arguments);		    },		    translate3dShapes: function () {		        return colProto.translate3dShapes.apply(this, arguments);		    }		}, {		    setState: colProto.pointClass.prototype.setState		});		/**		 * A `columnrange` series. If the [type](#series.columnrange.type)		 * option is not specified, it is inherited from		 * [chart.type](#chart.type).		 *		 * @extends   series,plotOptions.columnrange		 * @excluding dataParser, dataURL, stack, stacking		 * @product   highcharts highstock		 * @apioption series.columnrange		 */		/**		 * An array of data points for the series. For the `columnrange` series		 * type, points can be given in the following ways:		 *		 * 1. An array of arrays with 3 or 2 values. In this case, the values correspond		 *    to `x,low,high`. If the first value is a string, it is applied as the name		 *    of the point, and the `x` value is inferred. The `x` value can also be		 *    omitted, in which case the inner arrays should be of length 2\. Then the		 *    `x` value is automatically calculated, either starting at 0 and		 *    incremented by 1, or from `pointStart` and `pointInterval` given in the		 *    series options.		 *    ```js		 *    data: [		 *        [0, 4, 2],		 *        [1, 2, 1],		 *        [2, 9, 10]		 *    ]		 *    ```		 *		 * 2. An array of objects with named values. The following snippet shows only a		 *    few settings, see the complete options set below. If the total number of		 *    data points exceeds the series'		 *    [turboThreshold](#series.columnrange.turboThreshold), this option is not		 *    available.		 *    ```js		 *    data: [{		 *        x: 1,		 *        low: 0,		 *        high: 4,		 *        name: "Point2",		 *        color: "#00FF00"		 *    }, {		 *        x: 1,		 *        low: 5,		 *        high: 3,		 *        name: "Point1",		 *        color: "#FF00FF"		 *    }]		 *    ```		 *		 * @sample {highcharts} highcharts/series/data-array-of-arrays/		 *         Arrays of numeric x and y		 * @sample {highcharts} highcharts/series/data-array-of-arrays-datetime/		 *         Arrays of datetime x and y		 * @sample {highcharts} highcharts/series/data-array-of-name-value/		 *         Arrays of point.name and y		 * @sample {highcharts} highcharts/series/data-array-of-objects/		 *         Config objects		 *		 * @type      {Array<Array<(number|string),number>|Array<(number|string),number,number>|*>}		 * @extends   series.arearange.data		 * @excluding marker		 * @product   highcharts highstock		 * @apioption series.columnrange.data		 */		/**		 * @excluding halo, lineWidth, lineWidthPlus, marker		 * @product   highcharts highstock		 * @apioption series.columnrange.states.hover		 */		/**		 * @excluding halo, lineWidth, lineWidthPlus, marker		 * @product   highcharts highstock		 * @apioption series.columnrange.states.select		 */	}(Highcharts));	(function (H) {		/* *		 * (c) 2010-2019 Sebastian Bochan		 *		 * License: www.highcharts.com/license		 */		var pick = H.pick,		    seriesType = H.seriesType,		    seriesTypes = H.seriesTypes;		var colProto = seriesTypes.column.prototype;		/**		 * The ColumnPyramidSeries class		 *		 * @private		 * @class		 * @name Highcharts.seriesTypes.columnpyramid		 *		 * @augments Highcharts.Series		 */		seriesType('columnpyramid', 'column'		    /**		 * Column pyramid series display one pyramid per value along an X axis.		 * Requires `highcharts-more.js`. To display horizontal pyramids,		 * set [chart.inverted](#chart.inverted) to `true`.		 *		 * @sample {highcharts|highstock} highcharts/demo/column-pyramid/		 *         Column pyramid		 * @sample {highcharts|highstock} highcharts/plotoptions/columnpyramid-stacked/		 *         Column pyramid stacked		 * @sample {highcharts|highstock} highcharts/plotoptions/columnpyramid-inverted/		 *         Column pyramid inverted		 *		 * @extends      plotOptions.column		 * @since        7.0.0		 * @product      highcharts highstock		 * @excluding    boostThreshold, borderRadius, crisp, depth, edgeColor,		 *               edgeWidth, groupZPadding, negativeColor, softThreshold,		 *               threshold, zoneAxis, zones		 * @optionparent plotOptions.columnpyramid		 */		    , {}, {		    // Overrides the column translate method		        translate: function () {		            var series = this,		                chart = series.chart,		                options = series.options,		                dense = series.dense =		            series.closestPointRange * series.xAxis.transA < 2,		                borderWidth = series.borderWidth = pick(		                    options.borderWidth,		                    dense ? 0 : 1 // #3635		                ),		                yAxis = series.yAxis,		                threshold = options.threshold,		                translatedThreshold = series.translatedThreshold =		            yAxis.getThreshold(threshold),		                minPointLength = pick(options.minPointLength, 5),		                metrics = series.getColumnMetrics(),		                pointWidth = metrics.width,		                // postprocessed for border width		                seriesBarW = series.barW =		            Math.max(pointWidth, 1 + 2 * borderWidth),		                pointXOffset = series.pointXOffset = metrics.offset;		            if (chart.inverted) {		                translatedThreshold -= 0.5; // #3355		            }		            // When the pointPadding is 0,		            // we want the pyramids to be packed tightly,		            // so we allow individual pyramids to have individual sizes.		            // When pointPadding is greater,		            // we strive for equal-width columns (#2694).		            if (options.pointPadding) {		                seriesBarW = Math.ceil(seriesBarW);		            }		            colProto.translate.apply(series);		            // Record the new values		            series.points.forEach(function (point) {		                var yBottom = pick(point.yBottom, translatedThreshold),		                    safeDistance = 999 + Math.abs(yBottom),		                    plotY = Math.min(		                        Math.max(-safeDistance, point.plotY),		                        yAxis.len + safeDistance		                    ),		                    // Don't draw too far outside plot area		                    // (#1303, #2241, #4264)		                    barX = point.plotX + pointXOffset,		                    barW = seriesBarW / 2,		                    barY = Math.min(plotY, yBottom),		                    barH = Math.max(plotY, yBottom) - barY,		                    stackTotal, stackHeight, topPointY, topXwidth, bottomXwidth,		                    invBarPos,		                    x1, x2, x3, x4, y1, y2;		                point.barX = barX;		                point.pointWidth = pointWidth;		                // Fix the tooltip on center of grouped pyramids		                // (#1216, #424, #3648)		                point.tooltipPos = chart.inverted ? [		                    yAxis.len + yAxis.pos - chart.plotLeft - plotY,		                    series.xAxis.len - barX - barW, barH		                ] : [barX + barW, plotY + yAxis.pos - chart.plotTop, barH];		                stackTotal = threshold + (point.total || point.y);		                // overwrite stacktotal (always 100 / -100)		                if (options.stacking === 'percent') {		                    stackTotal = threshold + (point.y < 0) ? -100 : 100;		                }		                // get the highest point (if stack, extract from total)		                topPointY = yAxis.toPixels((stackTotal), true);		                // calculate height of stack (in pixels)		                stackHeight = chart.plotHeight - topPointY -		                            (chart.plotHeight - translatedThreshold);		                // topXwidth and bottomXwidth = width of lines from the center		                // calculated from tanges proportion.		                topXwidth = (barW * (barY - topPointY)) / stackHeight;		                // like topXwidth, but with height of point		                bottomXwidth = (barW * (barY + barH - topPointY)) / stackHeight;		                /*		                        /\		                        /  \		                x1,y1,------ x2,y1		                    /      \		                    ----------		                x4,y2        x3,y2		             */		                x1 = barX - topXwidth + barW;		                x2 = barX + topXwidth + barW;		                x3 = barX + bottomXwidth + barW;		                x4 = barX - bottomXwidth + barW;		                y1 = barY - minPointLength;		                y2 = barY + barH;		                if (point.y < 0) {		                    y1 = barY;		                    y2 = barY + barH + minPointLength;		                }		                // inverted chart		                if (chart.inverted) {		                    invBarPos = chart.plotWidth - barY;		                    stackHeight = (topPointY -		                    (chart.plotWidth - translatedThreshold));		                    // proportion tanges		                    topXwidth = (barW *		                    (topPointY - invBarPos)) / stackHeight;		                    bottomXwidth = (barW *		                    (topPointY - (invBarPos - barH))) / stackHeight;		                    x1 = barX + barW + topXwidth; // top bottom		                    x2 = x1 - 2 * topXwidth; // top top		                    x3 = barX - bottomXwidth + barW; // bottom top		                    x4 = barX + bottomXwidth + barW; // bottom bottom		                    y1 = barY;		                    y2 = barY + barH - minPointLength;		                    if (point.y < 0) {		                        y2 = barY + barH + minPointLength;		                    }		                }		                // Register shape type and arguments to be used in drawPoints		                point.shapeType = 'path';		                point.shapeArgs = {		                // args for datalabels positioning		                    x: x1,		                    y: y1,		                    width: x2 - x1,		                    height: barH,		                    // path of pyramid		                    d: ['M',		                        x1, y1,		                        'L',		                        x2, y1,		                        x3, y2,		                        x4, y2,		                        'Z'		                    ]		                };		            });		        }		    });		/**		 * A `columnpyramid` series. If the [type](#series.columnpyramid.type) option is		 * not specified, it is inherited from [chart.type](#chart.type).		 *		 * @extends   series,plotOptions.columnpyramid		 * @excluding connectEnds, connectNulls, dashStyle, dataParser, dataURL,		 *            gapSize, gapUnit, linecap, lineWidth, marker, step		 * @product   highcharts highstock		 * @apioption series.columnpyramid		 */		/**		 * @excluding halo, lineWidth, lineWidthPlus, marker		 * @product   highcharts highstock		 * @apioption series.columnpyramid.states.hover		 */		/**		 * @excluding halo, lineWidth, lineWidthPlus, marker		 * @product   highcharts highstock		 * @apioption series.columnpyramid.states.select		 */		/**		 * An array of data points for the series. For the `columnpyramid` series type,		 * points can be given in the following ways:		 *		 * 1. An array of numerical values. In this case, the numerical values will be		 *    interpreted as `y` options. The `x` values will be automatically		 *    calculated, either starting at 0 and incremented by 1, or from		 *    `pointStart` and `pointInterval` given in the series options. If the axis		 *    has categories, these will be used. Example:		 *    ```js		 *    data: [0, 5, 3, 5]		 *    ```		 *		 * 2. An array of arrays with 2 values. In this case, the values correspond to		 *    `x,y`. If the first value is a string, it is applied as the name of the		 *    point, and the `x` value is inferred.		 *    ```js		 *    data: [		 *        [0, 6],		 *        [1, 2],		 *        [2, 6]		 *    ]		 *    ```		 *		 * 3. An array of objects with named values. The objects are point configuration		 *    objects as seen below. If the total number of data points exceeds the		 *    series' [turboThreshold](#series.columnpyramid.turboThreshold), this		 *    option is not available.		 *    ```js		 *    data: [{		 *        x: 1,		 *        y: 9,		 *        name: "Point2",		 *        color: "#00FF00"		 *    }, {		 *        x: 1,		 *        y: 6,		 *        name: "Point1",		 *        color: "#FF00FF"		 *    }]		 *    ```		 *		 * @sample {highcharts} highcharts/chart/reflow-true/		 *         Numerical values		 * @sample {highcharts} highcharts/series/data-array-of-arrays/		 *         Arrays of numeric x and y		 * @sample {highcharts} highcharts/series/data-array-of-arrays-datetime/		 *         Arrays of datetime x and y		 * @sample {highcharts} highcharts/series/data-array-of-name-value/		 *         Arrays of point.name and y		 * @sample {highcharts} highcharts/series/data-array-of-objects/		 *         Config objects		 *		 * @type      {Array<number|Array<(number|string),number>|*>}		 * @extends   series.line.data		 * @excluding marker		 * @product   highcharts highstock		 * @apioption series.columnpyramid.data		 */	}(Highcharts));	(function (H) {		/* *		 * (c) 2010-2019 Torstein Honsi		 *		 * License: www.highcharts.com/license		 */		var isNumber = H.isNumber,		    merge = H.merge,		    noop = H.noop,		    pick = H.pick,		    pInt = H.pInt,		    Series = H.Series,		    seriesType = H.seriesType,		    TrackerMixin = H.TrackerMixin;		/**		 * Gauges are circular plots displaying one or more values with a dial pointing		 * to values along the perimeter.		 *		 * @sample highcharts/demo/gauge-speedometer/		 *         Gauge chart		 *		 * @extends      plotOptions.line		 * @excluding    animationLimit, boostThreshold, connectEnds, connectNulls,		 *               cropThreshold, dashStyle, findNearestPointBy,		 *               getExtremesFromAll, marker, negativeColor, pointPlacement,		 *               shadow, softThreshold, stacking, states, step, threshold,		 *               turboThreshold, xAxis, zoneAxis, zones		 * @product      highcharts		 * @optionparent plotOptions.gauge		 */		seriesType('gauge', 'line', {		    /**		     * When this option is `true`, the dial will wrap around the axes. For		     * instance, in a full-range gauge going from 0 to 360, a value of 400		     * will point to 40\. When `wrap` is `false`, the dial stops at 360.		     *		     * @see [overshoot](#plotOptions.gauge.overshoot)		     *		     * @type      {boolean}		     * @default   true		     * @since     3.0		     * @product   highcharts		     * @apioption plotOptions.gauge.wrap		     */		    /**		     * Data labels for the gauge. For gauges, the data labels are enabled		     * by default and shown in a bordered box below the point.		     *		     * @extends plotOptions.series.dataLabels		     * @since   2.3.0		     * @product highcharts		     */		    dataLabels: {		        /**		         * Enable or disable the data labels.		         *		         * @since   2.3.0		         * @product highcharts highmaps		         */		        enabled: true,		        defer: false,		        /**		         * The y position offset of the label relative to the center of the		         * gauge.		         *		         * @since   2.3.0		         * @product highcharts highmaps		         */		        y: 15,		        /**		         * The border radius in pixels for the gauge's data label.		         *		         * @since   2.3.0		         * @product highcharts highmaps		         */		        borderRadius: 3,		        crop: false,		        /**		         * The vertical alignment of the data label.		         *		         * @product highcharts highmaps		         */		        verticalAlign: 'top',		        /**		         * The Z index of the data labels. A value of 2 display them behind		         * the dial.		         *		         * @since   2.1.5		         * @product highcharts highmaps		         */		        zIndex: 2,		        /**		         * The border width in pixels for the gauge data label.		         *		         * @since   2.3.0		         * @product highcharts highmaps		         */		        borderWidth: 1,		        /**		         * The border color for the data label.		         *		         * @type    {Highcharts.ColorString}		         * @default #cccccc		         * @since   2.3.0		         * @product highcharts highmaps		         */		        borderColor: '#cccccc'		    },		    /**		     * Options for the dial or arrow pointer of the gauge.		     *		     * In styled mode, the dial is styled with the		     * `.highcharts-gauge-series .highcharts-dial` rule.		     *		     * @sample {highcharts} highcharts/css/gauge/		     *         Styled mode		     *		     * @since   2.3.0		     * @product highcharts		     */		    dial: {},		    /**		     * The length of the dial's base part, relative to the total radius		     * or length of the dial.		     *		     * @sample {highcharts} highcharts/plotoptions/gauge-dial/		     *         Dial options demonstrated		     *		     * @type      {string}		     * @default   70%		     * @since     2.3.0		     * @product   highcharts		     * @apioption plotOptions.gauge.dial.baseLength		     */		    /**		     * The pixel width of the base of the gauge dial. The base is the part		     * closest to the pivot, defined by baseLength.		     *		     * @sample {highcharts} highcharts/plotoptions/gauge-dial/		     *         Dial options demonstrated		     *		     * @type      {number}		     * @default   3		     * @since     2.3.0		     * @product   highcharts		     * @apioption plotOptions.gauge.dial.baseWidth		     */		    /**		     * The radius or length of the dial, in percentages relative to the		     * radius of the gauge itself.		     *		     * @sample {highcharts} highcharts/plotoptions/gauge-dial/		     *         Dial options demonstrated		     *		     * @type      {string}		     * @default   80%		     * @since     2.3.0		     * @product   highcharts		     * @apioption plotOptions.gauge.dial.radius		     */		    /**		     * The length of the dial's rear end, the part that extends out on the		     * other side of the pivot. Relative to the dial's length.		     *		     * @sample {highcharts} highcharts/plotoptions/gauge-dial/		     *         Dial options demonstrated		     *		     * @type      {string}		     * @default   10%		     * @since     2.3.0		     * @product   highcharts		     * @apioption plotOptions.gauge.dial.rearLength		     */		    /**		     * The width of the top of the dial, closest to the perimeter. The pivot		     * narrows in from the base to the top.		     *		     * @sample {highcharts} highcharts/plotoptions/gauge-dial/		     *         Dial options demonstrated		     *		     * @type      {number}		     * @default   1		     * @since     2.3.0		     * @product   highcharts		     * @apioption plotOptions.gauge.dial.topWidth		     */		    /**		     * The background or fill color of the gauge's dial.		     *		     * @sample {highcharts} highcharts/plotoptions/gauge-dial/		     *         Dial options demonstrated		     *		     * @type      {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}		     * @default   #000000		     * @since     2.3.0		     * @product   highcharts		     * @apioption plotOptions.gauge.dial.backgroundColor		     */		    /**		     * The border color or stroke of the gauge's dial. By default, the		     * borderWidth is 0, so this must be set in addition to a custom border		     * color.		     *		     * @sample {highcharts} highcharts/plotoptions/gauge-dial/		     *         Dial options demonstrated		     *		     * @type      {Highcharts.ColorString}		     * @default   #cccccc		     * @since     2.3.0		     * @product   highcharts		     * @apioption plotOptions.gauge.dial.borderColor		     */		    /**		     * The width of the gauge dial border in pixels.		     *		     * @sample {highcharts} highcharts/plotoptions/gauge-dial/		     *         Dial options demonstrated		     *		     * @type      {number}		     * @default   0		     * @since     2.3.0		     * @product   highcharts		     * @apioption plotOptions.gauge.dial.borderWidth		     */		    /**		     * Allow the dial to overshoot the end of the perimeter axis by this		     * many degrees. Say if the gauge axis goes from 0 to 60, a value of		     * 100, or 1000, will show 5 degrees beyond the end of the axis when this		     * option is set to 5.		     *		     * @see [wrap](#plotOptions.gauge.wrap)		     *		     * @sample {highcharts} highcharts/plotoptions/gauge-overshoot/		     *         Allow 5 degrees overshoot		     *		     * @type      {number}		     * @default   0		     * @since     3.0.10		     * @product   highcharts		     * @apioption plotOptions.gauge.overshoot		     */		    /**		     * Options for the pivot or the center point of the gauge.		     *		     * In styled mode, the pivot is styled with the		     * `.highcharts-gauge-series .highcharts-pivot` rule.		     *		     * @sample {highcharts} highcharts/css/gauge/		     *         Styled mode		     *		     * @since   2.3.0		     * @product highcharts		     */		    pivot: {},		    /**		     * The pixel radius of the pivot.		     *		     * @sample {highcharts} highcharts/plotoptions/gauge-pivot/		     *         Pivot options demonstrated		     *		     * @type      {number}		     * @default   5		     * @since     2.3.0		     * @product   highcharts		     * @apioption plotOptions.gauge.pivot.radius		     */		    /**		     * The border or stroke width of the pivot.		     *		     * @sample {highcharts} highcharts/plotoptions/gauge-pivot/		     *         Pivot options demonstrated		     *		     * @type      {number}		     * @default   0		     * @since     2.3.0		     * @product   highcharts		     * @apioption plotOptions.gauge.pivot.borderWidth		     */		    /**		     * The border or stroke color of the pivot. In able to change this,		     * the borderWidth must also be set to something other than the default		     * 0.		     *		     * @sample {highcharts} highcharts/plotoptions/gauge-pivot/		     *         Pivot options demonstrated		     *		     * @type      {Highcharts.ColorString}		     * @default   #cccccc		     * @since     2.3.0		     * @product   highcharts		     * @apioption plotOptions.gauge.pivot.borderColor		     */		    /**		     * The background color or fill of the pivot.		     *		     * @sample {highcharts} highcharts/plotoptions/gauge-pivot/		     *         Pivot options demonstrated		     *		     * @type      {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}		     * @default   #000000		     * @since     2.3.0		     * @product   highcharts		     * @apioption plotOptions.gauge.pivot.backgroundColor		     */		    tooltip: {		        headerFormat: ''		    },		    /**		     * Whether to display this particular series or series type in the		     * legend. Defaults to false for gauge series.		     *		     * @since   2.3.0		     * @product highcharts		     */		    showInLegend: false		// Prototype members		}, {		    // chart.angular will be set to true when a gauge series is present,		    // and this will be used on the axes		    angular: true,		    directTouch: true, // #5063		    drawGraph: noop,		    fixedBox: true,		    forceDL: true,		    noSharedTooltip: true,		    trackerGroups: ['group', 'dataLabelsGroup'],		    // Calculate paths etc		    translate: function () {		        var series = this,		            yAxis = series.yAxis,		            options = series.options,		            center = yAxis.center;		        series.generatePoints();		        series.points.forEach(function (point) {		            var dialOptions = merge(options.dial, point.dial),		                radius = (pInt(pick(dialOptions.radius, 80)) * center[2]) /		                    200,		                baseLength = (pInt(pick(dialOptions.baseLength, 70)) * radius) /		                    100,		                rearLength = (pInt(pick(dialOptions.rearLength, 10)) * radius) /		                    100,		                baseWidth = dialOptions.baseWidth || 3,		                topWidth = dialOptions.topWidth || 1,		                overshoot = options.overshoot,		                rotation = yAxis.startAngleRad +		                    yAxis.translate(point.y, null, null, null, true);		            // Handle the wrap and overshoot options		            if (isNumber(overshoot)) {		                overshoot = overshoot / 180 * Math.PI;		                rotation = Math.max(		                    yAxis.startAngleRad - overshoot,		                    Math.min(yAxis.endAngleRad + overshoot, rotation)		                );		            } else if (options.wrap === false) {		                rotation = Math.max(		                    yAxis.startAngleRad,		                    Math.min(yAxis.endAngleRad, rotation)		                );		            }		            rotation = rotation * 180 / Math.PI;		            point.shapeType = 'path';		            point.shapeArgs = {		                d: dialOptions.path || [		                    'M',		                    -rearLength, -baseWidth / 2,		                    'L',		                    baseLength, -baseWidth / 2,		                    radius, -topWidth / 2,		                    radius, topWidth / 2,		                    baseLength, baseWidth / 2,		                    -rearLength, baseWidth / 2,		                    'z'		                ],		                translateX: center[0],		                translateY: center[1],		                rotation: rotation		            };		            // Positions for data label		            point.plotX = center[0];		            point.plotY = center[1];		        });		    },		    // Draw the points where each point is one needle		    drawPoints: function () {		        var series = this,		            chart = series.chart,		            center = series.yAxis.center,		            pivot = series.pivot,		            options = series.options,		            pivotOptions = options.pivot,		            renderer = chart.renderer;		        series.points.forEach(function (point) {		            var graphic = point.graphic,		                shapeArgs = point.shapeArgs,		                d = shapeArgs.d,		                dialOptions = merge(options.dial, point.dial); // #1233		            if (graphic) {		                graphic.animate(shapeArgs);		                shapeArgs.d = d; // animate alters it		            } else {		                point.graphic = renderer[point.shapeType](shapeArgs)		                    .attr({		                        // required by VML when animation is false		                        rotation: shapeArgs.rotation,		                        zIndex: 1		                    })		                    .addClass('highcharts-dial')		                    .add(series.group);		                // Presentational attributes		                if (!chart.styledMode) {		                    point.graphic.attr({		                        stroke: dialOptions.borderColor || 'none',		                        'stroke-width': dialOptions.borderWidth || 0,		                        fill: dialOptions.backgroundColor ||		                            '#000000'		                    });		                }		            }		        });		        // Add or move the pivot		        if (pivot) {		            pivot.animate({ // #1235		                translateX: center[0],		                translateY: center[1]		            });		        } else {		            series.pivot = renderer.circle(0, 0, pick(pivotOptions.radius, 5))		                .attr({		                    zIndex: 2		                })		                .addClass('highcharts-pivot')		                .translate(center[0], center[1])		                .add(series.group);		            // Presentational attributes		            if (!chart.styledMode) {		                series.pivot.attr({		                    'stroke-width': pivotOptions.borderWidth || 0,		                    stroke: pivotOptions.borderColor ||		                        '#cccccc',		                    fill: pivotOptions.backgroundColor ||		                        '#000000'		                });		            }		        }		    },		    // Animate the arrow up from startAngle		    animate: function (init) {		        var series = this;		        if (!init) {		            series.points.forEach(function (point) {		                var graphic = point.graphic;		                if (graphic) {		                    // start value		                    graphic.attr({		                        rotation: series.yAxis.startAngleRad * 180 / Math.PI		                    });		                    // animate		                    graphic.animate({		                        rotation: point.shapeArgs.rotation		                    }, series.options.animation);		                }		            });		            // delete this function to allow it only once		            series.animate = null;		        }		    },		    render: function () {		        this.group = this.plotGroup(		            'group',		            'series',		            this.visible ? 'visible' : 'hidden',		            this.options.zIndex,		            this.chart.seriesGroup		        );		        Series.prototype.render.call(this);		        this.group.clip(this.chart.clipRect);		    },		    // Extend the basic setData method by running processData and generatePoints		    // immediately, in order to access the points from the legend.		    setData: function (data, redraw) {		        Series.prototype.setData.call(this, data, false);		        this.processData();		        this.generatePoints();		        if (pick(redraw, true)) {		            this.chart.redraw();		        }		    },		    // If the tracking module is loaded, add the point tracker		    drawTracker: TrackerMixin && TrackerMixin.drawTrackerPoint		// Point members		}, {		    // Don't do any hover colors or anything		    setState: function (state) {		        this.state = state;		    }		});		/**		 * A `gauge` series. If the [type](#series.gauge.type) option is not		 * specified, it is inherited from [chart.type](#chart.type).		 *		 * @extends   series,plotOptions.gauge		 * @excluding animationLimit, boostThreshold, connectEnds, connectNulls,		 *            cropThreshold, dashStyle, dataParser, dataURL, findNearestPointBy,		 *            getExtremesFromAll, marker, negativeColor, pointPlacement, shadow,		 *            softThreshold, stack, stacking, states, step, threshold,		 *            turboThreshold, zoneAxis, zones		 * @product   highcharts		 * @apioption series.gauge		 */		/**		 * An array of data points for the series. For the `gauge` series type,		 * points can be given in the following ways:		 *		 * 1. An array of numerical values. In this case, the numerical values will be		 *    interpreted as `y` options. Example:		 *    ```js		 *    data: [0, 5, 3, 5]		 *    ```		 *		 * 2. An array of objects with named values. The following snippet shows only a		 *    few settings, see the complete options set below. If the total number of		 *    data points exceeds the series'		 *    [turboThreshold](#series.gauge.turboThreshold), this option is not		 *    available.		 *    ```js		 *    data: [{		 *        y: 6,		 *        name: "Point2",		 *        color: "#00FF00"		 *    }, {		 *        y: 8,		 *        name: "Point1",		 *       color: "#FF00FF"		 *    }]		 *    ```		 *		 * The typical gauge only contains a single data value.		 *		 * @sample {highcharts} highcharts/chart/reflow-true/		 *         Numerical values		 * @sample {highcharts} highcharts/series/data-array-of-objects/		 *         Config objects		 *		 * @type      {Array<number|*>}		 * @extends   series.line.data		 * @excluding drilldown, marker, x		 * @product   highcharts		 * @apioption series.gauge.data		 */	}(Highcharts));	(function (H) {		/* *		 * (c) 2010-2019 Torstein Honsi		 *		 * License: www.highcharts.com/license		 */		var noop = H.noop,		    pick = H.pick,		    seriesType = H.seriesType,		    seriesTypes = H.seriesTypes;		/**		 * The boxplot series type.		 *		 * @private		 * @class		 * @name Highcharts.seriesTypes#boxplot		 *		 * @augments Highcharts.Series		 */		/**		 * A box plot is a convenient way of depicting groups of data through their		 * five-number summaries: the smallest observation (sample minimum), lower		 * quartile (Q1), median (Q2), upper quartile (Q3), and largest observation		 * (sample maximum).		 *		 * @sample highcharts/demo/box-plot/		 *         Box plot		 *		 * @extends      plotOptions.column		 * @excluding    borderColor, borderRadius, borderWidth, groupZPadding, states		 * @product      highcharts		 * @optionparent plotOptions.boxplot		 */		seriesType('boxplot', 'column', {		    threshold: null,		    tooltip: {		        pointFormat:		            '<span style="color:{point.color}">\u25CF</span> <b> ' +		            '{series.name}</b><br/>' +		            'Maximum: {point.high}<br/>' +		            'Upper quartile: {point.q3}<br/>' +		            'Median: {point.median}<br/>' +		            'Lower quartile: {point.q1}<br/>' +		            'Minimum: {point.low}<br/>'		    },		    /**		     * The length of the whiskers, the horizontal lines marking low and		     * high values. It can be a numerical pixel value, or a percentage		     * value of the box width. Set `0` to disable whiskers.		     *		     * @sample {highcharts} highcharts/plotoptions/box-plot-styling/		     *         True by default		     *		     * @type    {number|string}		     * @since   3.0		     * @product highcharts		     */		    whiskerLength: '50%',		    /**		     * The fill color of the box.		     *		     * In styled mode, the fill color can be set with the		     * `.highcharts-boxplot-box` class.		     *		     * @sample {highcharts} highcharts/plotoptions/box-plot-styling/		     *         Box plot styling		     *		     * @type    {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}		     * @default #ffffff		     * @since   3.0		     * @product highcharts		     */		    fillColor: '#ffffff',		    /**		     * The width of the line surrounding the box. If any of		     * [stemWidth](#plotOptions.boxplot.stemWidth),		     * [medianWidth](#plotOptions.boxplot.medianWidth)		     * or [whiskerWidth](#plotOptions.boxplot.whiskerWidth) are `null`,		     * the lineWidth also applies to these lines.		     *		     * @sample {highcharts} highcharts/plotoptions/box-plot-styling/		     *         Box plot styling		     * @sample {highcharts} highcharts/plotoptions/error-bar-styling/		     *         Error bar styling		     *		     * @since   3.0		     * @product highcharts		     */		    lineWidth: 1,		    /**		     * The color of the median line. If `undefined`, the general series color		     * applies.		     *		     * In styled mode, the median stroke width can be set with the		     * `.highcharts-boxplot-median` class.		     *		     * @sample {highcharts} highcharts/plotoptions/box-plot-styling/		     *         Box plot styling		     * @sample {highcharts} highcharts/css/boxplot/		     *         Box plot in styled mode		     * @sample {highcharts} highcharts/plotoptions/error-bar-styling/		     *         Error bar styling		     *		     * @type      {Highcharts.ColorString|Highcharts.GradientColorObject}		     * @since     3.0		     * @product   highcharts		     * @apioption plotOptions.boxplot.medianColor		     */		    /**		     * The pixel width of the median line. If `null`, the		     * [lineWidth](#plotOptions.boxplot.lineWidth) is used.		     *		     * In styled mode, the median stroke width can be set with the		     * `.highcharts-boxplot-median` class.		     *		     * @sample {highcharts} highcharts/plotoptions/box-plot-styling/		     *         Box plot styling		     * @sample {highcharts} highcharts/css/boxplot/		     *         Box plot in styled mode		     *		     * @since   3.0		     * @product highcharts		     */		    medianWidth: 2,		    /*		    // States are not working and are removed from docs.		    // Refer to: #2340		    states: {		        hover: {		            brightness: -0.3		        }		    },		    /**		     * The color of the stem, the vertical line extending from the box to		     * the whiskers. If `undefined`, the series color is used.		     *		     * In styled mode, the stem stroke can be set with the		     * `.highcharts-boxplot-stem` class.		     *		     * @sample {highcharts} highcharts/plotoptions/box-plot-styling/		     *         Box plot styling		     * @sample {highcharts} highcharts/css/boxplot/		     *         Box plot in styled mode		     * @sample {highcharts} highcharts/plotoptions/error-bar-styling/		     *         Error bar styling		     *		     * @type      {Highcharts.ColorString}		     * @since     3.0		     * @product   highcharts		     * @apioption plotOptions.boxplot.stemColor		     */		    /**		     * The dash style of the stem, the vertical line extending from the		     * box to the whiskers.		     *		     * @sample {highcharts} highcharts/plotoptions/box-plot-styling/		     *         Box plot styling		     * @sample {highcharts} highcharts/css/boxplot/		     *         Box plot in styled mode		     * @sample {highcharts} highcharts/plotoptions/error-bar-styling/		     *         Error bar styling		     *		     * @type      {Highcharts.DashStyleType}		     * @default   Solid		     * @since     3.0		     * @product   highcharts		     * @apioption plotOptions.boxplot.stemDashStyle		     */		    /**		     * The width of the stem, the vertical line extending from the box to		     * the whiskers. If `undefined`, the width is inherited from the		     * [lineWidth](#plotOptions.boxplot.lineWidth) option.		     *		     * In styled mode, the stem stroke width can be set with the		     * `.highcharts-boxplot-stem` class.		     *		     * @sample {highcharts} highcharts/plotoptions/box-plot-styling/		     *         Box plot styling		     * @sample {highcharts} highcharts/css/boxplot/		     *         Box plot in styled mode		     * @sample {highcharts} highcharts/plotoptions/error-bar-styling/		     *         Error bar styling		     *		     * @type      {number}		     * @since     3.0		     * @product   highcharts		     * @apioption plotOptions.boxplot.stemWidth		     */		    /**		     * The color of the whiskers, the horizontal lines marking low and high		     * values. When `undefined`, the general series color is used.		     *		     * In styled mode, the whisker stroke can be set with the		     * `.highcharts-boxplot-whisker` class .		     *		     * @sample {highcharts} highcharts/plotoptions/box-plot-styling/		     *         Box plot styling		     * @sample {highcharts} highcharts/css/boxplot/		     *         Box plot in styled mode		     *		     * @type      {Highcharts.ColorString}		     * @since     3.0		     * @product   highcharts		     * @apioption plotOptions.boxplot.whiskerColor		     */		    /**		     * The line width of the whiskers, the horizontal lines marking low and		     * high values. When `undefined`, the general		     * [lineWidth](#plotOptions.boxplot.lineWidth) applies.		     *		     * In styled mode, the whisker stroke width can be set with the		     * `.highcharts-boxplot-whisker` class.		     *		     * @sample {highcharts} highcharts/plotoptions/box-plot-styling/		     *         Box plot styling		     * @sample {highcharts} highcharts/css/boxplot/		     *         Box plot in styled mode		     *		     * @since   3.0		     * @product highcharts		     */		    whiskerWidth: 2		}, /** @lends Highcharts.seriesTypes.boxplot */ {		    // array point configs are mapped to this		    pointArrayMap: ['low', 'q1', 'median', 'q3', 'high'],		    toYData: function (point) { // return a plain array for speedy calculation		        return [point.low, point.q1, point.median, point.q3, point.high];		    },		    // defines the top of the tracker		    pointValKey: 'high',		    // Get presentational attributes		    pointAttribs: function () {		        // No attributes should be set on point.graphic which is the group		        return {};		    },		    // Disable data labels for box plot		    drawDataLabels: noop,		    // Translate data points from raw values x and y to plotX and plotY		    translate: function () {		        var series = this,		            yAxis = series.yAxis,		            pointArrayMap = series.pointArrayMap;		        seriesTypes.column.prototype.translate.apply(series);		        // do the translation on each point dimension		        series.points.forEach(function (point) {		            pointArrayMap.forEach(function (key) {		                if (point[key] !== null) {		                    point[key + 'Plot'] = yAxis.translate(		                        point[key], 0, 1, 0, 1		                    );		                }		            });		        });		    },		    // Draw the data points		    drawPoints: function () {		        var series = this,		            points = series.points,		            options = series.options,		            chart = series.chart,		            renderer = chart.renderer,		            q1Plot,		            q3Plot,		            highPlot,		            lowPlot,		            medianPlot,		            medianPath,		            crispCorr,		            crispX = 0,		            boxPath,		            width,		            left,		            right,		            halfWidth,		            // error bar inherits this series type but doesn't do quartiles		            doQuartiles = series.doQuartiles !== false,		            pointWiskerLength,		            whiskerLength = series.options.whiskerLength;		        points.forEach(function (point) {		            var graphic = point.graphic,		                verb = graphic ? 'animate' : 'attr',		                shapeArgs = point.shapeArgs,		                boxAttr = {},		                stemAttr = {},		                whiskersAttr = {},		                medianAttr = {},		                color = point.color || series.color;		            if (point.plotY !== undefined) {		                // crisp vector coordinates		                width = shapeArgs.width;		                left = Math.floor(shapeArgs.x);		                right = left + width;		                halfWidth = Math.round(width / 2);		                q1Plot = Math.floor(doQuartiles ? point.q1Plot : point.lowPlot);		                q3Plot = Math.floor(doQuartiles ? point.q3Plot : point.lowPlot);		                highPlot = Math.floor(point.highPlot);		                lowPlot = Math.floor(point.lowPlot);		                if (!graphic) {		                    point.graphic = graphic = renderer.g('point')		                        .add(series.group);		                    point.stem = renderer.path()		                        .addClass('highcharts-boxplot-stem')		                        .add(graphic);		                    if (whiskerLength) {		                        point.whiskers = renderer.path()		                            .addClass('highcharts-boxplot-whisker')		                            .add(graphic);		                    }		                    if (doQuartiles) {		                        point.box = renderer.path(boxPath)		                            .addClass('highcharts-boxplot-box')		                            .add(graphic);		                    }		                    point.medianShape = renderer.path(medianPath)		                        .addClass('highcharts-boxplot-median')		                        .add(graphic);		                }		                if (!chart.styledMode) {		                    // Stem attributes		                    stemAttr.stroke =		                        point.stemColor || options.stemColor || color;		                    stemAttr['stroke-width'] = pick(		                        point.stemWidth,		                        options.stemWidth,		                        options.lineWidth		                    );		                    stemAttr.dashstyle =		                        point.stemDashStyle || options.stemDashStyle;		                    point.stem.attr(stemAttr);		                    // Whiskers attributes		                    if (whiskerLength) {		                        whiskersAttr.stroke =		                            point.whiskerColor || options.whiskerColor || color;		                        whiskersAttr['stroke-width'] = pick(		                            point.whiskerWidth,		                            options.whiskerWidth,		                            options.lineWidth		                        );		                        point.whiskers.attr(whiskersAttr);		                    }		                    if (doQuartiles) {		                        boxAttr.fill = (		                            point.fillColor ||		                            options.fillColor ||		                            color		                        );		                        boxAttr.stroke = options.lineColor || color;		                        boxAttr['stroke-width'] = options.lineWidth || 0;		                        point.box.attr(boxAttr);		                    }		                    // Median attributes		                    medianAttr.stroke =		                        point.medianColor || options.medianColor || color;		                    medianAttr['stroke-width'] = pick(		                        point.medianWidth,		                        options.medianWidth,		                        options.lineWidth		                    );		                    point.medianShape.attr(medianAttr);		                }		                // The stem		                crispCorr = (point.stem.strokeWidth() % 2) / 2;		                crispX = left + halfWidth + crispCorr;		                point.stem[verb]({		                    d: [		                    // stem up		                        'M',		                        crispX, q3Plot,		                        'L',		                        crispX, highPlot,		                        // stem down		                        'M',		                        crispX, q1Plot,		                        'L',		                        crispX, lowPlot		                    ]		                });		                // The box		                if (doQuartiles) {		                    crispCorr = (point.box.strokeWidth() % 2) / 2;		                    q1Plot = Math.floor(q1Plot) + crispCorr;		                    q3Plot = Math.floor(q3Plot) + crispCorr;		                    left += crispCorr;		                    right += crispCorr;		                    point.box[verb]({		                        d: [		                            'M',		                            left, q3Plot,		                            'L',		                            left, q1Plot,		                            'L',		                            right, q1Plot,		                            'L',		                            right, q3Plot,		                            'L',		                            left, q3Plot,		                            'z'		                        ]		                    });		                }		                // The whiskers		                if (whiskerLength) {		                    crispCorr = (point.whiskers.strokeWidth() % 2) / 2;		                    highPlot = highPlot + crispCorr;		                    lowPlot = lowPlot + crispCorr;		                    pointWiskerLength = (/%$/).test(whiskerLength) ?		                        halfWidth * parseFloat(whiskerLength) / 100 :		                        whiskerLength / 2;		                    point.whiskers[verb]({		                        d: [		                        // High whisker		                            'M',		                            crispX - pointWiskerLength,		                            highPlot,		                            'L',		                            crispX + pointWiskerLength,		                            highPlot,		                            // Low whisker		                            'M',		                            crispX - pointWiskerLength,		                            lowPlot,		                            'L',		                            crispX + pointWiskerLength,		                            lowPlot		                        ]		                    });		                }		                // The median		                medianPlot = Math.round(point.medianPlot);		                crispCorr = (point.medianShape.strokeWidth() % 2) / 2;		                medianPlot = medianPlot + crispCorr;		                point.medianShape[verb]({		                    d: [		                        'M',		                        left,		                        medianPlot,		                        'L',		                        right,		                        medianPlot		                    ]		                });		            }		        });		    },		    setStackedPoints: noop // #3890		});		/**		 * A `boxplot` series. If the [type](#series.boxplot.type) option is		 * not specified, it is inherited from [chart.type](#chart.type).		 *		 * @extends   series,plotOptions.boxplot		 * @excluding dataParser, dataURL, marker, stack, stacking, states		 * @product   highcharts		 * @apioption series.boxplot		 */		/**		 * An array of data points for the series. For the `boxplot` series		 * type, points can be given in the following ways:		 *		 * 1. An array of arrays with 6 or 5 values. In this case, the values correspond		 *    to `x,low,q1,median,q3,high`. If the first value is a string, it is		 *    applied as the name of the point, and the `x` value is inferred. The `x`		 *    value can also be omitted, in which case the inner arrays should be of		 *    length 5. Then the `x` value is automatically calculated, either starting		 *    at 0 and incremented by 1, or from `pointStart` and `pointInterval` given		 *    in the series options.		 *    ```js		 *    data: [		 *        [0, 3, 0, 10, 3, 5],		 *        [1, 7, 8, 7, 2, 9],		 *        [2, 6, 9, 5, 1, 3]		 *    ]		 *    ```		 *		 * 2. An array of objects with named values. The following snippet shows only a		 *    few settings, see the complete options set below. If the total number of		 *    data points exceeds the series'		 *    [turboThreshold](#series.boxplot.turboThreshold), this option is not		 *    available.		 *    ```js		 *    data: [{		 *        x: 1,		 *        low: 4,		 *        q1: 9,		 *        median: 9,		 *        q3: 1,		 *        high: 10,		 *        name: "Point2",		 *        color: "#00FF00"		 *    }, {		 *        x: 1,		 *        low: 5,		 *        q1: 7,		 *        median: 3,		 *        q3: 6,		 *        high: 2,		 *        name: "Point1",		 *        color: "#FF00FF"		 *    }]		 *    ```		 *		 * @sample {highcharts} highcharts/series/data-array-of-arrays/		 *         Arrays of numeric x and y		 * @sample {highcharts} highcharts/series/data-array-of-arrays-datetime/		 *         Arrays of datetime x and y		 * @sample {highcharts} highcharts/series/data-array-of-name-value/		 *         Arrays of point.name and y		 * @sample {highcharts} highcharts/series/data-array-of-objects/		 *         Config objects		 *		 * @type      {Array<Array<(number|string),number,number,number,number>|Array<(number|string),number,number,number,number,number>|*>}		 * @extends   series.line.data		 * @excluding marker		 * @product   highcharts		 * @apioption series.boxplot.data		 */		/**		 * The `high` value for each data point, signifying the highest value		 * in the sample set. The top whisker is drawn here.		 *		 * @type      {number}		 * @product   highcharts		 * @apioption series.boxplot.data.high		 */		/**		 * The `low` value for each data point, signifying the lowest value		 * in the sample set. The bottom whisker is drawn here.		 *		 * @type      {number}		 * @product   highcharts		 * @apioption series.boxplot.data.low		 */		/**		 * The median for each data point. This is drawn as a line through the		 * middle area of the box.		 *		 * @type      {number}		 * @product   highcharts		 * @apioption series.boxplot.data.median		 */		/**		 * The lower quartile for each data point. This is the bottom of the		 * box.		 *		 * @type      {number}		 * @product   highcharts		 * @apioption series.boxplot.data.q1		 */		/**		 * The higher quartile for each data point. This is the top of the box.		 *		 * @type      {number}		 * @product   highcharts		 * @apioption series.boxplot.data.q3		 */	}(Highcharts));	(function (H) {		/* *		 * (c) 2010-2019 Torstein Honsi		 *		 * License: www.highcharts.com/license		 */		var noop = H.noop,		    seriesType = H.seriesType,		    seriesTypes = H.seriesTypes;		/**		 * Error bars are a graphical representation of the variability of data and are		 * used on graphs to indicate the error, or uncertainty in a reported		 * measurement.		 *		 * @sample highcharts/demo/error-bar/		 *         Error bars on a column series		 * @sample highcharts/series-errorbar/on-scatter/		 *         Error bars on a scatter series		 *		 * @extends      plotOptions.boxplot		 * @product      highcharts highstock		 * @optionparent plotOptions.errorbar		 */		seriesType('errorbar', 'boxplot', {		    /**		     * The main color of the bars. This can be overridden by		     * [stemColor](#plotOptions.errorbar.stemColor) and		     * [whiskerColor](#plotOptions.errorbar.whiskerColor) individually.		     *		     * @sample {highcharts} highcharts/plotoptions/error-bar-styling/		     *         Error bar styling		     *		     * @type    {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}		     * @default #000000		     * @since   3.0		     * @product highcharts		     */		    color: '#000000',		    grouping: false,		    /**		     * The parent series of the error bar. The default value links it to		     * the previous series. Otherwise, use the id of the parent series.		     *		     * @since   3.0		     * @product highcharts		     */		    linkedTo: ':previous',		    tooltip: {		        pointFormat: '<span style="color:{point.color}">\u25CF</span> {series.name}: <b>{point.low}</b> - <b>{point.high}</b><br/>'		    },		    /**		     * The line width of the whiskers, the horizontal lines marking low		     * and high values. When `null`, the general		     * [lineWidth](#plotOptions.errorbar.lineWidth) applies.		     *		     * @sample {highcharts} highcharts/plotoptions/error-bar-styling/		     *         Error bar styling		     *		     * @type    {number}		     * @since   3.0		     * @product highcharts		     */		    whiskerWidth: null		// Prototype members		}, {		    type: 'errorbar',		    pointArrayMap: ['low', 'high'], // array point configs are mapped to this		    toYData: function (point) { // return a plain array for speedy calculation		        return [point.low, point.high];		    },		    pointValKey: 'high', // defines the top of the tracker		    doQuartiles: false,		    drawDataLabels: seriesTypes.arearange ?		        function () {		            var valKey = this.pointValKey;		            seriesTypes.arearange.prototype.drawDataLabels.call(this);		            // Arearange drawDataLabels does not reset point.y to high,		            // but to low after drawing (#4133)		            this.data.forEach(function (point) {		                point.y = point[valKey];		            });		        } :		        noop,		    // Get the width and X offset, either on top of the linked series column or		    // standalone		    getColumnMetrics: function () {		        return (this.linkedParent && this.linkedParent.columnMetrics) ||		            seriesTypes.column.prototype.getColumnMetrics.call(this);		    }		});		/**		 * A `errorbar` series. If the [type](#series.errorbar.type) option		 * is not specified, it is inherited from [chart.type](#chart.type).		 *		 * @extends   series,plotOptions.errorbar		 * @excluding dataParser, dataURL, stack, stacking		 * @product   highcharts		 * @apioption series.errorbar		 */		/**		 * An array of data points for the series. For the `errorbar` series		 * type, points can be given in the following ways:		 *		 * 1. An array of arrays with 3 or 2 values. In this case, the values correspond		 *    to `x,low,high`. If the first value is a string, it is applied as the name		 *    of the point, and the `x` value is inferred. The `x` value can also be		 *    omitted, in which case the inner arrays should be of length 2\. Then the		 *    `x` value is automatically calculated, either starting at 0 and		 *    incremented by 1, or from `pointStart` and `pointInterval` given in the		 *    series options.		 *    ```js		 *    data: [		 *        [0, 10, 2],		 *        [1, 1, 8],		 *        [2, 4, 5]		 *    ]		 *    ```		 *		 * 2. An array of objects with named values. The following snippet shows only a		 *    few settings, see the complete options set below. If the total number of		 *    data points exceeds the series'		 *    [turboThreshold](#series.errorbar.turboThreshold), this option is not		 *    available.		 *    ```js		 *    data: [{		 *        x: 1,		 *        low: 0,		 *        high: 0,		 *        name: "Point2",		 *        color: "#00FF00"		 *    }, {		 *        x: 1,		 *        low: 5,		 *        high: 5,		 *        name: "Point1",		 *        color: "#FF00FF"		 *    }]		 *    ```		 *		 * @sample {highcharts} highcharts/series/data-array-of-arrays/		 *         Arrays of numeric x and y		 * @sample {highcharts} highcharts/series/data-array-of-arrays-datetime/		 *         Arrays of datetime x and y		 * @sample {highcharts} highcharts/series/data-array-of-name-value/		 *         Arrays of point.name and y		 * @sample {highcharts} highcharts/series/data-array-of-objects/		 *         Config objects		 *		 * @type      {Array<Array<(number|string),number>|Array<(number|string),number,number>|*>}		 * @extends   series.arearange.data		 * @excluding dataLabels, drilldown, marker, states		 * @product   highcharts		 * @apioption series.errorbar.data		 */	}(Highcharts));	(function (H) {		/* *		 * (c) 2010-2019 Torstein Honsi		 *		 * License: www.highcharts.com/license		 */		var correctFloat = H.correctFloat,		    isNumber = H.isNumber,		    pick = H.pick,		    objectEach = H.objectEach,		    arrayMin = H.arrayMin,		    arrayMax = H.arrayMax,		    addEvent = H.addEvent,		    Axis = H.Axis,		    Chart = H.Chart,		    Point = H.Point,		    Series = H.Series,		    seriesType = H.seriesType,		    seriesTypes = H.seriesTypes;		addEvent(Axis, 'afterInit', function () {		    if (!this.isXAxis) {		        this.waterfallStacks = {};		    }		});		addEvent(Chart, 'beforeRedraw', function () {		    var axes = this.axes,		        series = this.series,		        i = series.length;		    while (i--) {		        if (series[i].options.stacking) {		            axes.forEach(function (axis) {		                if (!axis.isXAxis) {		                    axis.waterfallStacks = {};		                }		            });		            i = 0;		        }		    }		});		/**		 * A waterfall chart displays sequentially introduced positive or negative		 * values in cumulative columns.		 *		 * @sample highcharts/demo/waterfall/		 *         Waterfall chart		 * @sample highcharts/plotoptions/waterfall-inverted/		 *         Horizontal (inverted) waterfall		 * @sample highcharts/plotoptions/waterfall-stacked/		 *         Stacked waterfall chart		 *		 * @extends      plotOptions.column		 * @product      highcharts		 * @optionparent plotOptions.waterfall		 */		seriesType('waterfall', 'column', {		    /**		     * @type      {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}		     * @apioption plotOptions.waterfall.color		     */		    /**		     * The color used specifically for positive point columns. When not		     * specified, the general series color is used.		     *		     * In styled mode, the waterfall colors can be set with the		     * `.highcharts-point-negative`, `.highcharts-sum` and		     * `.highcharts-intermediate-sum` classes.		     *		     * @sample {highcharts} highcharts/demo/waterfall/		     *         Waterfall		     *		     * @type      {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}		     * @product   highcharts		     * @apioption plotOptions.waterfall.upColor		     */		    dataLabels: {		        inside: true		    },		    /**		     * The width of the line connecting waterfall columns.		     *		     * @product highcharts		     */		    lineWidth: 1,		    /**		     * The color of the line that connects columns in a waterfall series.		     *		     * In styled mode, the stroke can be set with the `.highcharts-graph` class.		     *		     * @type    {Highcharts.ColorString}		     * @since   3.0		     * @product highcharts		     */		    lineColor: '#333333',		    /**		     * A name for the dash style to use for the line connecting the columns		     * of the waterfall series. Possible values: Dash, DashDot, Dot, LongDash,		     * LongDashDot, LongDashDotDot, ShortDash, ShortDashDot, ShortDashDotDot,		     * ShortDot, Solid		     *		     * In styled mode, the stroke dash-array can be set with the		     * `.highcharts-graph` class.		     *		     * @type    {Highcharts.DashStyleType}		     * @since   3.0		     * @product highcharts		     */		    dashStyle: 'Dot',		    /**		     * The color of the border of each waterfall column.		     *		     * In styled mode, the border stroke can be set with the		     * `.highcharts-point` class.		     *		     * @type    {Highcharts.ColorString}		     * @since   3.0		     * @product highcharts		     */		    borderColor: '#333333',		    states: {		        hover: {		            lineWidthPlus: 0 // #3126		        }		    }		// Prototype members		}, {		    pointValKey: 'y',		    // Property needed to prevent lines between the columns from disappearing		    // when negativeColor is used.		    showLine: true,		    // After generating points, set y-values for all sums.		    generatePoints: function () {		        var point,		            len,		            i,		            y;		        // Parent call:		        seriesTypes.column.prototype.generatePoints.apply(this);		        for (i = 0, len = this.points.length; i < len; i++) {		            point = this.points[i];		            y = this.processedYData[i];		            // override point value for sums		            // #3710 Update point does not propagate to sum		            if (point.isIntermediateSum || point.isSum) {		                point.y = correctFloat(y);		            }		        }		    },		    // Translate data points from raw values		    translate: function () {		        var series = this,		            options = series.options,		            yAxis = series.yAxis,		            len,		            i,		            points,		            point,		            shapeArgs,		            y,		            yValue,		            previousY,		            previousIntermediate,		            range,		            minPointLength = pick(options.minPointLength, 5),		            halfMinPointLength = minPointLength / 2,		            threshold = options.threshold,		            stacking = options.stacking,		            tooltipY,		            actualStack = yAxis.waterfallStacks[series.stackKey],		            actualStackX,		            total,		            pointY,		            yPos,		            hPos;		        // run column series translate		        seriesTypes.column.prototype.translate.apply(series);		        previousY = previousIntermediate = threshold;		        points = series.points;		        for (i = 0, len = points.length; i < len; i++) {		            // cache current point object		            point = points[i];		            yValue = series.processedYData[i];		            shapeArgs = point.shapeArgs;		            range = [0, yValue];		            pointY = point.y;		            // code responsible for correct positions of stacked points		            // starts here		            if (stacking) {		                if (actualStack) {		                    actualStackX = actualStack[i];		                    if (stacking === 'overlap') {		                        total = actualStackX.threshold + actualStackX.total;		                        actualStackX.total -= pointY;		                        y = pointY >= 0 ? total : total - pointY;		                    } else {		                        if (pointY >= 0) {		                            total = actualStackX.threshold +		                                actualStackX.posTotal;		                            actualStackX.posTotal -= pointY;		                            y = total;		                        } else {		                            total = actualStackX.threshold +		                                actualStackX.negTotal;		                            actualStackX.negTotal -= pointY;		                            y = total - pointY;		                        }		                    }		                    if (!point.isSum) {		                        // the connectorThreshold property is later used in		                        // getCrispPath function to draw a connector line in a		                        // correct place		                        actualStackX.connectorThreshold =		                            actualStackX.threshold + actualStackX.stackTotal;		                    }		                    if (yAxis.reversed) {		                        yPos = (pointY >= 0) ? (y - pointY) : (y + pointY);		                        hPos = y;		                    } else {		                        yPos = y;		                        hPos = y - pointY;		                    }		                    point.below = yPos <= pick(threshold, 0);		                    shapeArgs.y = yAxis.translate(yPos, 0, 1, 0, 1);		                    shapeArgs.height = Math.abs(shapeArgs.y -		                        yAxis.translate(hPos, 0, 1, 0, 1));		                }		            } else {		                // up points		                y = Math.max(previousY, previousY + pointY) + range[0];		                shapeArgs.y = yAxis.translate(y, 0, 1, 0, 1);		                // sum points		                if (point.isSum) {		                    shapeArgs.y = yAxis.translate(range[1], 0, 1, 0, 1);		                    shapeArgs.height = Math.min(		                        yAxis.translate(range[0], 0, 1, 0, 1),		                        yAxis.len		                    ) - shapeArgs.y; // #4256		                } else if (point.isIntermediateSum) {		                    if (pointY >= 0) {		                        yPos = range[1] + previousIntermediate;		                        hPos = previousIntermediate;		                    } else {		                        yPos = previousIntermediate;		                        hPos = range[1] + previousIntermediate;		                    }		                    if (yAxis.reversed) {		                        // swapping values		                        yPos ^= hPos;		                        hPos ^= yPos;		                        yPos ^= hPos;		                    }		                    shapeArgs.y = yAxis.translate(yPos, 0, 1, 0, 1);		                    shapeArgs.height = Math.abs(shapeArgs.y - Math.min(		                        yAxis.translate(hPos, 0, 1, 0, 1),		                        yAxis.len		                    ));		                    previousIntermediate += range[1];		                // If it's not the sum point, update previous stack end position		                // and get shape height (#3886)		                } else {		                    shapeArgs.height = yValue > 0 ?		                        yAxis.translate(previousY, 0, 1, 0, 1) - shapeArgs.y :		                        yAxis.translate(previousY, 0, 1, 0, 1) -		                            yAxis.translate(previousY - yValue, 0, 1, 0, 1);		                    previousY += yValue;		                    point.below = previousY < pick(threshold, 0);		                }		                // #3952 Negative sum or intermediate sum not rendered correctly		                if (shapeArgs.height < 0) {		                    shapeArgs.y += shapeArgs.height;		                    shapeArgs.height *= -1;		                }		            }		            point.plotY = shapeArgs.y = Math.round(shapeArgs.y) -		                (series.borderWidth % 2) / 2;		            // #3151		            shapeArgs.height = Math.max(Math.round(shapeArgs.height), 0.001);		            point.yBottom = shapeArgs.y + shapeArgs.height;		            if (shapeArgs.height <= minPointLength && !point.isNull) {		                shapeArgs.height = minPointLength;		                shapeArgs.y -= halfMinPointLength;		                point.plotY = shapeArgs.y;		                if (point.y < 0) {		                    point.minPointLengthOffset = -halfMinPointLength;		                } else {		                    point.minPointLengthOffset = halfMinPointLength;		                }		            } else {		                if (point.isNull) {		                    shapeArgs.width = 0;		                }		                point.minPointLengthOffset = 0;		            }		            // Correct tooltip placement (#3014)		            tooltipY = point.plotY + (point.negative ? shapeArgs.height : 0);		            if (series.chart.inverted) {		                point.tooltipPos[0] = yAxis.len - tooltipY;		            } else {		                point.tooltipPos[1] = tooltipY;		            }		        }		    },		    // Call default processData then override yData to reflect waterfall's		    // extremes on yAxis		    processData: function (force) {		        var series = this,		            options = series.options,		            yData = series.yData,		            // #3710 Update point does not propagate to sum		            points = options.data,		            point,		            dataLength = yData.length,		            threshold = options.threshold || 0,		            subSum,		            sum,		            dataMin,		            dataMax,		            y,		            i;		        sum = subSum = dataMin = dataMax = 0;		        for (i = 0; i < dataLength; i++) {		            y = yData[i];		            point = points && points[i] ? points[i] : {};		            if (y === 'sum' || point.isSum) {		                yData[i] = correctFloat(sum);		            } else if (y === 'intermediateSum' || point.isIntermediateSum) {		                yData[i] = correctFloat(subSum);		                subSum = 0;		            } else {		                sum += y;		                subSum += y;		            }		            dataMin = Math.min(sum, dataMin);		            dataMax = Math.max(sum, dataMax);		        }		        Series.prototype.processData.call(this, force);		        // Record extremes only if stacking was not set:		        if (!options.stacking) {		            series.dataMin = dataMin + threshold;		            series.dataMax = dataMax;		        }		    },		    // Return y value or string if point is sum		    toYData: function (pt) {		        if (pt.isSum) {		            // #3245 Error when first element is Sum or Intermediate Sum		            return (pt.x === 0 ? null : 'sum');		        }		        if (pt.isIntermediateSum) {		            return (pt.x === 0 ? null : 'intermediateSum'); // #3245		        }		        return pt.y;		    },		    // Postprocess mapping between options and SVG attributes		    pointAttribs: function (point, state) {		        var upColor = this.options.upColor,		            attr;		        // Set or reset up color (#3710, update to negative)		        if (upColor && !point.options.color) {		            point.color = point.y > 0 ? upColor : null;		        }		        attr = seriesTypes.column.prototype.pointAttribs.call(		            this,		            point,		            state		        );		        // The dashStyle option in waterfall applies to the graph, not		        // the points		        delete attr.dashstyle;		        return attr;		    },		    // Return an empty path initially, because we need to know the stroke-width		    // in order to set the final path.		    getGraphPath: function () {		        return ['M', 0, 0];		    },		    // Draw columns' connector lines		    getCrispPath: function () {		        var data = this.data,		            yAxis = this.yAxis,		            length = data.length,		            graphNormalizer = Math.round(this.graph.strokeWidth()) % 2 / 2,		            borderNormalizer = Math.round(this.borderWidth) % 2 / 2,		            reversedXAxis = this.xAxis.reversed,		            reversedYAxis = this.yAxis.reversed,		            stacking = this.options.stacking,		            path = [],		            connectorThreshold,		            prevStack,		            prevStackX,		            prevPoint,		            yPos,		            isPos,		            prevArgs,		            pointArgs,		            i,		            d;		        for (i = 1; i < length; i++) {		            pointArgs = data[i].shapeArgs;		            prevPoint = data[i - 1];		            prevArgs = data[i - 1].shapeArgs;		            prevStack = yAxis.waterfallStacks[this.stackKey];		            isPos = prevPoint.y > 0 ? -prevArgs.height : 0;		            if (prevStack) {		                prevStackX = prevStack[i - 1];		                // y position of the connector is different when series are		                // stacked, yAxis is reversed and it also depends on point's		                // value		                if (stacking) {		                    connectorThreshold = prevStackX.connectorThreshold;		                    yPos = Math.round(		                        (yAxis.translate(connectorThreshold, 0, 1, 0, 1) +		                        (reversedYAxis ? isPos : 0))		                    ) - graphNormalizer;		                } else {		                    yPos = prevArgs.y + prevPoint.minPointLengthOffset +		                        borderNormalizer - graphNormalizer;		                }		                d = [		                    'M',		                    prevArgs.x + (reversedXAxis ? 0 : prevArgs.width),		                    yPos,		                    'L',		                    pointArgs.x + (reversedXAxis ? pointArgs.width : 0),		                    yPos		                ];		            }		            if (		                !stacking &&		                (prevPoint.y < 0 && !reversedYAxis) ||		                (prevPoint.y > 0 && reversedYAxis)		            ) {		                d[2] += prevArgs.height;		                d[5] += prevArgs.height;		            }		            path = path.concat(d);		        }		        return path;		    },		    // The graph is initially drawn with an empty definition, then updated with		    // crisp rendering.		    drawGraph: function () {		        Series.prototype.drawGraph.call(this);		        this.graph.attr({		            d: this.getCrispPath()		        });		    },		    // Waterfall has stacking along the x-values too.		    setStackedPoints: function () {		        var series = this,		            options = series.options,		            waterfallStacks = series.yAxis.waterfallStacks,		            seriesThreshold = options.threshold,		            stackThreshold = seriesThreshold || 0,		            interSum = seriesThreshold || 0,		            stackKey = series.stackKey,		            xData = series.xData,		            xLength = xData.length,		            actualStack,		            actualStackX,		            posTotal,		            negTotal,		            xPoint,		            yVal,		            x;		        // code responsible for creating stacks for waterfall series		        if (series.visible || !series.chart.options.chart.ignoreHiddenSeries) {		            if (!waterfallStacks[stackKey]) {		                waterfallStacks[stackKey] = {};		            }		            actualStack = waterfallStacks[stackKey];		            for (var i = 0; i < xLength; i++) {		                x = xData[i];		                if (!actualStack[x]) {		                    actualStack[x] = {		                        negTotal: 0,		                        posTotal: 0,		                        total: 0,		                        stackTotal: 0,		                        threshold: 0,		                        stackState: [stackThreshold]		                    };		                }		                actualStackX = actualStack[x];		                yVal = series.yData[i];		                if (yVal >= 0) {		                    actualStackX.posTotal += yVal;		                } else {		                    actualStackX.negTotal += yVal;		                }		                // points do not exist yet, so raw data is used		                xPoint = options.data[i];		                posTotal = actualStackX.posTotal;		                negTotal = actualStackX.negTotal;		                if (xPoint && xPoint.isIntermediateSum) {		                    // swapping values		                    stackThreshold ^= interSum;		                    interSum ^= stackThreshold;		                    stackThreshold ^= interSum;		                } else if (xPoint && xPoint.isSum) {		                    stackThreshold = seriesThreshold;		                }		                actualStackX.stackTotal = posTotal + negTotal;		                actualStackX.total = actualStackX.stackTotal;		                actualStackX.threshold = stackThreshold;		                actualStackX.stackState[0] = stackThreshold;		                actualStackX.stackState.push(actualStackX.stackTotal);		                stackThreshold += actualStackX.stackTotal;		            }		        }		    },		    // Extremes for a non-stacked series are recorded in processData.		    // In case of stacking, use Series.stackedYData to calculate extremes.		    getExtremes: function () {		        var stacking = this.options.stacking,		            yAxis,		            waterfallStacks,		            stackedYNeg,		            stackedYPos,		            states,		            firstState;		        if (stacking) {		            yAxis = this.yAxis;		            waterfallStacks = yAxis.waterfallStacks;		            stackedYNeg = this.stackedYNeg = [];		            stackedYPos = this.stackedYPos = [];		            // the visible y range can be different when stacking is set to		            // overlap and different when it's set to normal		            if (stacking === 'overlap') {		                objectEach(waterfallStacks[this.stackKey], function (stackX) {		                    states = [];		                    stackX.stackState.forEach(function (state, stateIndex) {		                        firstState = stackX.stackState[0];		                        if (stateIndex) {		                            states.push(state + firstState);		                        } else {		                            states.push(firstState);		                        }		                    });		                    stackedYNeg.push(arrayMin(states));		                    stackedYPos.push(arrayMax(states));		                });		            } else {		                objectEach(waterfallStacks[this.stackKey], function (stackX) {		                    stackedYNeg.push(stackX.negTotal + stackX.threshold);		                    stackedYPos.push(stackX.posTotal + stackX.threshold);		                });		            }		            this.dataMin = arrayMin(stackedYNeg);		            this.dataMax = arrayMax(stackedYPos);		        }		    }		// Point members		}, {		    getClassName: function () {		        var className = Point.prototype.getClassName.call(this);		        if (this.isSum) {		            className += ' highcharts-sum';		        } else if (this.isIntermediateSum) {		            className += ' highcharts-intermediate-sum';		        }		        return className;		    },		    // Pass the null test in ColumnSeries.translate.		    isValid: function () {		        return isNumber(this.y, true) || this.isSum || this.isIntermediateSum;		    }		});		/**		 * A `waterfall` series. If the [type](#series.waterfall.type) option		 * is not specified, it is inherited from [chart.type](#chart.type).		 *		 * @extends   series,plotOptions.waterfall		 * @excluding dataParser, dataURL		 * @product   highcharts		 * @apioption series.waterfall		 */		/**		 * An array of data points for the series. For the `waterfall` series		 * type, points can be given in the following ways:		 *		 * 1. An array of numerical values. In this case, the numerical values will be		 *    interpreted as `y` options. The `x` values will be automatically		 *    calculated, either starting at 0 and incremented by 1, or from		 *    `pointStart` and `pointInterval` given in the series options. If the axis		 *    has categories, these will be used. Example:		 *    ```js		 *    data: [0, 5, 3, 5]		 *    ```		 *		 * 2. An array of arrays with 2 values. In this case, the values correspond to		 *    `x,y`. If the first value is a string, it is applied as the name of the		 *    point, and the `x` value is inferred.		 *    ```js		 *    data: [		 *        [0, 7],		 *        [1, 8],		 *        [2, 3]		 *    ]		 *    ```		 *		 * 3. An array of objects with named values. The following snippet shows only a		 *    few settings, see the complete options set below. If the total number of		 *    data points exceeds the series'		 *    [turboThreshold](#series.waterfall.turboThreshold), this option is not		 *    available.		 *    ```js		 *    data: [{		 *        x: 1,		 *        y: 8,		 *        name: "Point2",		 *        color: "#00FF00"		 *    }, {		 *        x: 1,		 *        y: 8,		 *        name: "Point1",		 *        color: "#FF00FF"		 *    }]		 *    ```		 *		 * @sample {highcharts} highcharts/chart/reflow-true/		 *         Numerical values		 * @sample {highcharts} highcharts/series/data-array-of-arrays/		 *         Arrays of numeric x and y		 * @sample {highcharts} highcharts/series/data-array-of-arrays-datetime/		 *         Arrays of datetime x and y		 * @sample {highcharts} highcharts/series/data-array-of-name-value/		 *         Arrays of point.name and y		 * @sample {highcharts} highcharts/series/data-array-of-objects/		 *         Config objects		 *		 * @type      {Array<number|Array<(number|string),number>|*>}		 * @extends   series.line.data		 * @excluding marker		 * @product   highcharts		 * @apioption series.waterfall.data		 */		/**		 * When this property is true, the points acts as a summary column for		 * the values added or substracted since the last intermediate sum,		 * or since the start of the series. The `y` value is ignored.		 *		 * @sample {highcharts} highcharts/demo/waterfall/		 *         Waterfall		 *		 * @type      {boolean}		 * @default   false		 * @product   highcharts		 * @apioption series.waterfall.data.isIntermediateSum		 */		/**		 * When this property is true, the point display the total sum across		 * the entire series. The `y` value is ignored.		 *		 * @sample {highcharts} highcharts/demo/waterfall/		 *         Waterfall		 *		 * @type      {boolean}		 * @default   false		 * @product   highcharts		 * @apioption series.waterfall.data.isSum		 */	}(Highcharts));	(function (H) {		/* *		 * (c) 2010-2019 Torstein Honsi		 *		 * License: www.highcharts.com/license		 */		var LegendSymbolMixin = H.LegendSymbolMixin,		    noop = H.noop,		    Series = H.Series,		    seriesType = H.seriesType,		    seriesTypes = H.seriesTypes;		/**		 * A polygon series can be used to draw any freeform shape in the cartesian		 * coordinate system. A fill is applied with the `color` option, and		 * stroke is applied through `lineWidth` and `lineColor` options. Requires		 * the `highcharts-more.js` file.		 *		 * @sample {highcharts} highcharts/demo/polygon/		 *         Polygon		 * @sample {highstock} highcharts/demo/polygon/		 *         Polygon		 *		 * @extends      plotOptions.scatter		 * @since        4.1.0		 * @excluding    jitter, softThreshold, threshold		 * @product      highcharts highstock		 * @optionparent plotOptions.polygon		 */		seriesType('polygon', 'scatter', {		    marker: {		        enabled: false,		        states: {		            hover: {		                enabled: false		            }		        }		    },		    stickyTracking: false,		    tooltip: {		        followPointer: true,		        pointFormat: ''		    },		    trackByArea: true		// Prototype members		}, {		    type: 'polygon',		    getGraphPath: function () {		        var graphPath = Series.prototype.getGraphPath.call(this),		            i = graphPath.length + 1;		        // Close all segments		        while (i--) {		            if ((i === graphPath.length || graphPath[i] === 'M') && i > 0) {		                graphPath.splice(i, 0, 'z');		            }		        }		        this.areaPath = graphPath;		        return graphPath;		    },		    drawGraph: function () {		        // Hack into the fill logic in area.drawGraph		        this.options.fillColor = this.color;		        seriesTypes.area.prototype.drawGraph.call(this);		    },		    drawLegendSymbol: LegendSymbolMixin.drawRectangle,		    drawTracker: Series.prototype.drawTracker,		    setStackedPoints: noop // No stacking points on polygons (#5310)		});		/**		 * A `polygon` series. If the [type](#series.polygon.type) option is		 * not specified, it is inherited from [chart.type](#chart.type).		 *		 * @extends   series,plotOptions.polygon		 * @excluding dataParser, dataURL, stack		 * @product   highcharts highstock		 * @apioption series.polygon		 */		/**		 * An array of data points for the series. For the `polygon` series		 * type, points can be given in the following ways:		 *		 * 1. An array of numerical values. In this case, the numerical values will be		 *    interpreted as `y` options. The `x` values will be automatically		 *    calculated, either starting at 0 and incremented by 1, or from		 *    `pointStart` and `pointInterval` given in the series options. If the axis		 *    has categories, these will be used. Example:		 *    ```js		 *    data: [0, 5, 3, 5]		 *    ```		 *		 * 2. An array of arrays with 2 values. In this case, the values correspond to		 *    `x,y`. If the first value is a string, it is applied as the name of the		 *    point, and the `x` value is inferred.		 *    ```js		 *    data: [		 *        [0, 10],		 *        [1, 3],		 *        [2, 1]		 *    ]		 *    ```		 *		 * 3. An array of objects with named values. The following snippet shows only a		 *    few settings, see the complete options set below. If the total number of		 *    data points exceeds the series'		 *    [turboThreshold](#series.polygon.turboThreshold), this option is not		 *    available.		 *    ```js		 *    data: [{		 *        x: 1,		 *        y: 1,		 *        name: "Point2",		 *        color: "#00FF00"		 *    }, {		 *        x: 1,		 *        y: 8,		 *        name: "Point1",		 *        color: "#FF00FF"		 *    }]		 *    ```		 *		 * @sample {highcharts} highcharts/chart/reflow-true/		 *         Numerical values		 * @sample {highcharts} highcharts/series/data-array-of-arrays/		 *         Arrays of numeric x and y		 * @sample {highcharts} highcharts/series/data-array-of-arrays-datetime/		 *         Arrays of datetime x and y		 * @sample {highcharts} highcharts/series/data-array-of-name-value/		 *         Arrays of point.name and y		 * @sample {highcharts} highcharts/series/data-array-of-objects/		 *         Config objects		 *		 * @type      {Array<number|Array<(number|string),number>|*>}		 * @extends   series.line.data		 * @product   highcharts highstock		 * @apioption series.polygon.data		 */	}(Highcharts));	(function (H) {		/* *		 * (c) 2010-2019 Highsoft AS		 *		 * Author: Paweł Potaczek		 *		 * License: www.highcharts.com/license		 */		/**		 * @interface Highcharts.LegendBubbleLegendFormatterContextObject		 *//**		 * The center y position of the range.		 * @name Highcharts.LegendBubbleLegendFormatterContextObject#center		 * @type {number}		 *//**		 * The radius of the bubble range.		 * @name Highcharts.LegendBubbleLegendFormatterContextObject#radius		 * @type {number}		 *//**		 * The bubble value.		 * @name Highcharts.LegendBubbleLegendFormatterContextObject#value		 * @type {number}		 */		var Series = H.Series,		    Legend = H.Legend,		    Chart = H.Chart,		    addEvent = H.addEvent,		    wrap = H.wrap,		    color = H.color,		    isNumber = H.isNumber,		    numberFormat = H.numberFormat,		    objectEach = H.objectEach,		    merge = H.merge,		    noop = H.noop,		    pick = H.pick,		    stableSort = H.stableSort,		    setOptions = H.setOptions,		    arrayMin = H.arrayMin,		    arrayMax = H.arrayMax;		setOptions({ // Set default bubble legend options		    legend: {		        /**		         * The bubble legend is an additional element in legend which presents		         * the scale of the bubble series. Individual bubble ranges can be		         * defined by user or calculated from series. In the case of		         * automatically calculated ranges, a 1px margin of error is permitted.		         * Requires `highcharts-more.js`.		         *		         * @since        7.0.0		         * @product      highcharts highstock highmaps		         * @optionparent legend.bubbleLegend		         */		        bubbleLegend: {		            /**		             * The color of the ranges borders, can be also defined for an		             * individual range.		             *		             * @sample highcharts/bubble-legend/similartoseries/		             *         Similat look to the bubble series		             * @sample highcharts/bubble-legend/bordercolor/		             *         Individual bubble border color		             *		             * @type {Highcharts.ColorString}		             */		            borderColor: undefined,		            /**		             * The width of the ranges borders in pixels, can be also defined		             * for an individual range.		             */		            borderWidth: 2,		            /**		             * An additional class name to apply to the bubble legend' circle		             * graphical elements. This option does not replace default class		             * names of the graphical element.		             *		             * @sample {highcharts} highcharts/css/bubble-legend/		             *         Styling by CSS		             *		             * @type {string}		             */		            className: undefined,		            /**		             * The main color of the bubble legend. Applies to ranges, if		             * individual color is not defined.		             *		             * @sample highcharts/bubble-legend/similartoseries/		             *         Similat look to the bubble series		             * @sample highcharts/bubble-legend/color/		             *         Individual bubble color		             *		             * @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}		             */		            color: undefined,		            /**		             * An additional class name to apply to the bubble legend's		             * connector graphical elements. This option does not replace		             * default class names of the graphical element.		             *		             * @sample {highcharts} highcharts/css/bubble-legend/		             *         Styling by CSS		             *		             * @type {string}		             */		            connectorClassName: undefined,		            /**		             * The color of the connector, can be also defined		             * for an individual range.		             *		             * @type {Highcharts.ColorString}		             */		            connectorColor: undefined,		            /**		             * The length of the connectors in pixels. If labels are centered,		             * the distance is reduced to 0.		             *		             * @sample highcharts/bubble-legend/connectorandlabels/		             *         Increased connector length		             */		            connectorDistance: 60,		            /**		             * The width of the connectors in pixels.		             *		             * @sample highcharts/bubble-legend/connectorandlabels/		             *         Increased connector width		             */		            connectorWidth: 1,		            /**		             * Enable or disable the bubble legend.		             */		            enabled: false,		            /**		             * Options for the bubble legend labels.		             */		            labels: {		                /**		                 * An additional class name to apply to the bubble legend		                 * label graphical elements. This option does not replace		                 * default class names of the graphical element.		                 *		                 * @sample {highcharts} highcharts/css/bubble-legend/		                 *         Styling by CSS		                 *		                 * @type {string}		                 */		                className: undefined,		                /**		                 * Whether to allow data labels to overlap.		                 */		                allowOverlap: false,		                /**		                 * A [format string](http://docs.highcharts.com/#formatting)		                 * for the bubble legend labels. Available variables are the		                 * same as for `formatter`.		                 *		                 * @sample highcharts/bubble-legend/format/		                 *         Add a unit		                 *		                 * @type {string}		                 */		                format: '',		                /**		                 * Available `this` properties are:		                 *		                 * - `this.value`: The bubble value.		                 *		                 * - `this.radius`: The radius of the bubble range.		                 *		                 * - `this.center`: The center y position of the range.		                 *		                 * @type {Highcharts.FormatterCallbackFunction<Highcharts.LegendBubbleLegendFormatterContextObject>}		                 */		                formatter: undefined,		                /**		                 * The alignment of the labels compared to the bubble legend.		                 * Can be one of `left`, `center` or `right`.		                 * @validvalue ["left", "center", "right"]		                 *		                 * @sample highcharts/bubble-legend/connectorandlabels/		                 *         Labels on left		                 *		                 * @validvalue ["left", "center", "right"]		                 */		                align: 'right',		                /**		                 * CSS styles for the labels.		                 *		                 * @type {Highcharts.CSSObject}		                 */		                style: {		                    /** @ignore-option */		                    fontSize: 10,		                    /** @ignore-option */		                    color: undefined		                },		                /**		                 * The x position offset of the label relative to the		                 * connector.		                 */		                x: 0,		                /**		                 * The y position offset of the label relative to the		                 * connector.		                 */		                y: 0		            },		            /**		             * Miximum bubble legend range size. If values for ranges are not		             * specified, the `minSize` and the `maxSize` are calculated from		             * bubble series.		             */		            maxSize: 60, // Number		            /**		             * Minimum bubble legend range size. If values for ranges are not		             * specified, the `minSize` and the `maxSize` are calculated from		             * bubble series.		             */		            minSize: 10, // Number		            /**		             * The position of the bubble legend in the legend.		             * @sample highcharts/bubble-legend/connectorandlabels/		             *         Bubble legend as last item in legend		             */		            legendIndex: 0, // Number		            /**		             * Options for specific range. One range consists of bubble, label		             * and connector.		             *		             * @sample highcharts/bubble-legend/ranges/		             *         Manually defined ranges		             * @sample highcharts/bubble-legend/autoranges/		             *         Auto calculated ranges		             *		             * @type {Array<*>}		             */		            ranges: {		                /**		                 * Range size value, similar to bubble Z data.		                 */		                value: undefined,		                /**		                 * The color of the border for individual range.		                 * @type {Highcharts.ColorString}		                 */		                borderColor: undefined,		                /**		                 * The color of the bubble for individual range.		                 * @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}		                 */		                color: undefined,		                /**		                 * The color of the connector for individual range.		                 * @type {Highcharts.ColorString}		                 */		                connectorColor: undefined		            },		            /**		             * Whether the bubble legend range value should be represented by		             * the area or the width of the bubble. The default, area,		             * corresponds best to the human perception of the size of each		             * bubble.		             *		             * @sample highcharts/bubble-legend/ranges/		             *         Size by width		             *		             * @validvalue ["area", "width"]		             */		            sizeBy: 'area',		            /**		             * When this is true, the absolute value of z determines the size of		             * the bubble. This means that with the default zThreshold of 0, a		             * bubble of value -1 will have the same size as a bubble of value		             * 1, while a bubble of value 0 will have a smaller size according		             * to minSize.		             */		            sizeByAbsoluteValue: false,		            /**		             * Define the visual z index of the bubble legend.		             */		            zIndex: 1,		            /**		             * Ranges with with lower value than zThreshold, are skipped.		             */		            zThreshold: 0		        }		    }		});		/**		 * BubbleLegend class.		 *		 * @private		 * @class		 * @name Highcharts.BubbleLegend		 *		 * @param {Highcharts.LegendBubbleLegendOptions} config		 *        Bubble legend options		 *		 * @param {Highcharts.LegendOptions} config		 *        Legend options		 */		H.BubbleLegend = function (options, legend) {		    this.init(options, legend);		};		H.BubbleLegend.prototype = {		    /**		     * Create basic bubbleLegend properties similar to item in legend.		     *		     * @private		     * @function Highcharts.BubbleLegend#init		     *		     * @param {Highcharts.LegendBubbleLegendOptions} config		     *        Bubble legend options		     *		     * @param {Highcharts.LegendOptions} config		     *        Legend options		     */		    init: function (options, legend) {		        this.options = options;		        this.visible = true;		        this.chart = legend.chart;		        this.legend = legend;		    },		    setState: noop,		    /**		     * Depending on the position option, add bubbleLegend to legend items.		     *		     * @private		     * @function Highcharts.BubbleLegend#addToLegend		     *		     * @param {Array<*>}		     *        All legend items		     */		    addToLegend: function (items) {		        // Insert bubbleLegend into legend items		        items.splice(this.options.legendIndex, 0, this);		    },		    /**		     * Calculate ranges, sizes and call the next steps of bubbleLegend creation.		     *		     * @private		     * @function Highcharts.BubbleLegend#drawLegendSymbol		     *		     * @param {Highcharts.Legend} legend		     *        Legend instance		     */		    drawLegendSymbol: function (legend) {		        var bubbleLegend = this,		            chart = bubbleLegend.chart,		            options = bubbleLegend.options,		            size,		            itemDistance = pick(legend.options.itemDistance, 20),		            connectorSpace,		            ranges = options.ranges,		            radius,		            maxLabel,		            connectorDistance = options.connectorDistance;		        // Predict label dimensions		        bubbleLegend.fontMetrics = chart.renderer.fontMetrics(		            options.labels.style.fontSize.toString() + 'px'		        );		        // Do not create bubbleLegend now if ranges or ranges valeus are not		        // specified or if are empty array.		        if (!ranges || !ranges.length || !isNumber(ranges[0].value)) {		            legend.options.bubbleLegend.autoRanges = true;		            return;		        }		        // Sort ranges to right render order		        stableSort(ranges, function (a, b) {		            return b.value - a.value;		        });		        bubbleLegend.ranges = ranges;		        bubbleLegend.setOptions();		        bubbleLegend.render();		        // Get max label size		        maxLabel = bubbleLegend.getMaxLabelSize();		        radius = bubbleLegend.ranges[0].radius;		        size = radius * 2;		        // Space for connectors and labels.		        connectorSpace = connectorDistance - radius + maxLabel.width;		        connectorSpace = connectorSpace > 0 ? connectorSpace : 0;		        bubbleLegend.maxLabel = maxLabel;		        bubbleLegend.movementX = options.labels.align === 'left' ?		            connectorSpace : 0;		        bubbleLegend.legendItemWidth = size + connectorSpace + itemDistance;		        bubbleLegend.legendItemHeight = size + bubbleLegend.fontMetrics.h / 2;		    },		    /**		     * Set style options for each bubbleLegend range.		     *		     * @private		     * @function Highcharts.BubbleLegend#setOptions		     */		    setOptions: function () {		        var bubbleLegend = this,		            ranges = bubbleLegend.ranges,		            options = bubbleLegend.options,		            series = bubbleLegend.chart.series[options.seriesIndex],		            baseline = bubbleLegend.legend.baseline,		            bubbleStyle = {		                'z-index': options.zIndex,		                'stroke-width': options.borderWidth		            },		            connectorStyle = {		                'z-index': options.zIndex,		                'stroke-width': options.connectorWidth		            },		            labelStyle = bubbleLegend.getLabelStyles(),		            fillOpacity = series.options.marker.fillOpacity,		            styledMode = bubbleLegend.chart.styledMode;		        // Allow to parts of styles be used individually for range		        ranges.forEach(function (range, i) {		            if (!styledMode) {		                bubbleStyle.stroke = pick(		                    range.borderColor,		                    options.borderColor,		                    series.color		                );		                bubbleStyle.fill = pick(		                    range.color,		                    options.color,		                    fillOpacity !== 1 ?		                        color(series.color).setOpacity(fillOpacity)		                            .get('rgba') :		                        series.color		                );		                connectorStyle.stroke = pick(		                    range.connectorColor,		                    options.connectorColor,		                    series.color		                );		            }		            // Set options needed for rendering each range		            ranges[i].radius = bubbleLegend.getRangeRadius(range.value);		            ranges[i] = merge(ranges[i], {		                center: ranges[0].radius - ranges[i].radius + baseline		            });		            if (!styledMode) {		                merge(true, ranges[i], {		                    bubbleStyle: merge(false, bubbleStyle),		                    connectorStyle: merge(false, connectorStyle),		                    labelStyle: labelStyle		                });		            }		        });		    },		    /**		     * Merge options for bubbleLegend labels.		     *		     * @private		     * @function Highcharts.BubbleLegend#getLabelStyles		     */		    getLabelStyles: function () {		        var options = this.options,		            additionalLabelsStyle = {},		            labelsOnLeft = options.labels.align === 'left',		            rtl = this.legend.options.rtl;		        // To separate additional style options		        objectEach(options.labels.style, function (value, key) {		            if (key !== 'color' && key !== 'fontSize' && key !== 'z-index') {		                additionalLabelsStyle[key] = value;		            }		        });		        return merge(false, additionalLabelsStyle, {		            'font-size': options.labels.style.fontSize,		            fill: pick(		                options.labels.style.color,		                '#000000'		            ),		            'z-index': options.zIndex,		            align: rtl || labelsOnLeft ? 'right' : 'left'		        });		    },		    /**		     * Calculate radius for each bubble range,		     * used code from BubbleSeries.js 'getRadius' method.		     *		     * @private		     * @function Highcharts.BubbleLegend#getRangeRadius		     *		     * @param {number} value		     *        Range value		     *		     * @return {number}		     *         Radius for one range		     */		    getRangeRadius: function (value) {		        var bubbleLegend = this,		            options = bubbleLegend.options,		            seriesIndex = bubbleLegend.options.seriesIndex,		            bubbleSeries = bubbleLegend.chart.series[seriesIndex],		            zMax = options.ranges[0].value,		            zMin = options.ranges[options.ranges.length - 1].value,		            minSize = options.minSize,		            maxSize = options.maxSize;		        return bubbleSeries.getRadius.call(		            this,		            zMin,		            zMax,		            minSize,		            maxSize,		            value		        );		    },		    /**		     * Render the legendSymbol group.		     *		     * @private		     * @function Highcharts.BubbleLegend#render		     */		    render: function () {		        var bubbleLegend = this,		            renderer = bubbleLegend.chart.renderer,		            zThreshold = bubbleLegend.options.zThreshold;		        if (!bubbleLegend.symbols) {		            bubbleLegend.symbols = {		                connectors: [],		                bubbleItems: [],		                labels: []		            };		        }		        // Nesting SVG groups to enable handleOverflow		        bubbleLegend.legendSymbol = renderer.g('bubble-legend');		        bubbleLegend.legendItem = renderer.g('bubble-legend-item');		        // To enable default 'hideOverlappingLabels' method		        bubbleLegend.legendSymbol.translateX = 0;		        bubbleLegend.legendSymbol.translateY = 0;		        bubbleLegend.ranges.forEach(function (range) {		            if (range.value >= zThreshold) {		                bubbleLegend.renderRange(range);		            }		        });		        // To use handleOverflow method		        bubbleLegend.legendSymbol.add(bubbleLegend.legendItem);		        bubbleLegend.legendItem.add(bubbleLegend.legendGroup);		        bubbleLegend.hideOverlappingLabels();		    },		    /**		     * Render one range, consisting of bubble symbol, connector and label.		     *		     * @private		     * @function Highcharts.BubbleLegend#renderRange		     *		     * @param {Highcharts.LegendBubbleLegendRangesOptions} config		     *        Range options		     *		     * @private		     */		    renderRange: function (range) {		        var bubbleLegend = this,		            mainRange = bubbleLegend.ranges[0],		            legend = bubbleLegend.legend,		            options = bubbleLegend.options,		            labelsOptions = options.labels,		            chart = bubbleLegend.chart,		            renderer = chart.renderer,		            symbols = bubbleLegend.symbols,		            labels = symbols.labels,		            label,		            elementCenter = range.center,		            absoluteRadius = Math.abs(range.radius),		            connectorDistance = options.connectorDistance,		            labelsAlign = labelsOptions.align,		            rtl = legend.options.rtl,		            fontSize = labelsOptions.style.fontSize,		            connectorLength = rtl || labelsAlign === 'left' ?		                -connectorDistance : connectorDistance,		            borderWidth = options.borderWidth,		            connectorWidth = options.connectorWidth,		            posX = mainRange.radius,		            posY = elementCenter - absoluteRadius - borderWidth / 2 +		                connectorWidth / 2,		            labelY,		            labelX,		            fontMetrics = bubbleLegend.fontMetrics,		            labelMovement = fontSize / 2 - (fontMetrics.h - fontSize) / 2,		            crispMovement = (posY % 1 ? 1 : 0.5) -		                (connectorWidth % 2 ? 0 : 0.5),		            styledMode = renderer.styledMode;		        // Set options for centered labels		        if (labelsAlign === 'center') {		            connectorLength = 0; // do not use connector		            options.connectorDistance = 0;		            range.labelStyle.align = 'center';		        }		        labelY = posY + options.labels.y;		        labelX = posX + connectorLength + options.labels.x;		        // Render bubble symbol		        symbols.bubbleItems.push(		            renderer		                .circle(		                    posX,		                    elementCenter + crispMovement,		                    absoluteRadius		                )		                .attr(		                    styledMode ? {} : range.bubbleStyle		                )		                .addClass(		                    (		                        styledMode ?		                            'highcharts-color-' +		                                bubbleLegend.options.seriesIndex + ' ' :		                            ''		                    ) +		                    'highcharts-bubble-legend-symbol ' +		                    (options.className || '')		                ).add(		                    bubbleLegend.legendSymbol		                )		        );		        // Render connector		        symbols.connectors.push(		            renderer		                .path(renderer.crispLine(		                    ['M', posX, posY, 'L', posX + connectorLength, posY],		                    options.connectorWidth		                ))		                .attr(		                    styledMode ? {} : range.connectorStyle		                )		                .addClass(		                    (		                        styledMode ?		                            'highcharts-color-' +		                                bubbleLegend.options.seriesIndex + ' ' :		                            ''		                    ) +		                    'highcharts-bubble-legend-connectors ' +		                    (options.connectorClassName || '')		                ).add(		                    bubbleLegend.legendSymbol		                )		        );		        // Render label		        label = renderer		            .text(		                bubbleLegend.formatLabel(range),		                labelX,		                labelY + labelMovement		            )		            .attr(		                styledMode ? {} : range.labelStyle		            )		            .addClass(		                'highcharts-bubble-legend-labels ' +		                (options.labels.className || '')		            ).add(		                bubbleLegend.legendSymbol		            );		        labels.push(label);		        // To enable default 'hideOverlappingLabels' method		        label.placed = true;		        label.alignAttr = {		            x: labelX,		            y: labelY + labelMovement		        };		    },		    /**		     * Get the label which takes up the most space.		     *		     * @private		     * @function Highcharts.BubbleLegend#getMaxLabelSize		     */		    getMaxLabelSize: function () {		        var labels = this.symbols.labels,		            maxLabel,		            labelSize;		        labels.forEach(function (label) {		            labelSize = label.getBBox(true);		            if (maxLabel) {		                maxLabel = labelSize.width > maxLabel.width ?		                    labelSize : maxLabel;		            } else {		                maxLabel = labelSize;		            }		        });		        return maxLabel || {};		    },		    /**		     * Get formatted label for range.		     *		     * @private		     * @function Highcharts.BubbleLegend#formatLabel		     *		     * @param {Highcharts.LegendBubbleLegendRangesOptions} range		     *        Range options		     *		     * @return {string}		     *         Range label text		     */		    formatLabel: function (range) {		        var options = this.options,		            formatter = options.labels.formatter,		            format = options.labels.format;		        return format ? H.format(format, range) :		            formatter ? formatter.call(range) :		                numberFormat(range.value, 1);		    },		    /**		     * By using default chart 'hideOverlappingLabels' method, hide or show		     * labels and connectors.		     *		     * @private		     * @function Highcharts.BubbleLegend#hideOverlappingLabels		     */		    hideOverlappingLabels: function () {		        var bubbleLegend = this,		            chart = this.chart,		            allowOverlap = bubbleLegend.options.labels.allowOverlap,		            symbols = bubbleLegend.symbols;		        if (!allowOverlap && symbols) {		            chart.hideOverlappingLabels(symbols.labels);		            // Hide or show connectors		            symbols.labels.forEach(function (label, index) {		                if (!label.newOpacity) {		                    symbols.connectors[index].hide();		                } else if (label.newOpacity !== label.oldOpacity) {		                    symbols.connectors[index].show();		                }		            });		        }		    },		    /**		     * Calculate ranges from created series.		     *		     * @private		     * @function Highcharts.BubbleLegend#getRanges		     *		     * @return {Array<Highcharts.LegendBubbleLegendRangesOptions>}		     *         Array of range objects		     */		    getRanges: function () {		        var bubbleLegend = this.legend.bubbleLegend,		            series = bubbleLegend.chart.series,		            ranges,		            rangesOptions = bubbleLegend.options.ranges,		            zData,		            minZ = Number.MAX_VALUE,		            maxZ = -Number.MAX_VALUE;		        series.forEach(function (s) {		            // Find the min and max Z, like in bubble series		            if (s.isBubble && !s.ignoreSeries) {		                zData = s.zData.filter(isNumber);		                if (zData.length) {		                    minZ = pick(s.options.zMin, Math.min(		                        minZ,		                        Math.max(		                            arrayMin(zData),		                            s.options.displayNegative === false ?		                                s.options.zThreshold :		                                -Number.MAX_VALUE		                        )		                    ));		                    maxZ = pick(		                        s.options.zMax,		                        Math.max(maxZ, arrayMax(zData))		                    );		                }		            }		        });		        // Set values for ranges		        if (minZ === maxZ) {		            // Only one range if min and max values are the same.		            ranges = [{ value: maxZ }];		        } else {		            ranges = [		                { value: minZ },		                { value: (minZ + maxZ) / 2 },		                { value: maxZ, autoRanges: true }		            ];		        }		        // Prevent reverse order of ranges after redraw		        if (rangesOptions.length && rangesOptions[0].radius) {		            ranges.reverse();		        }		        // Merge ranges values with user options		        ranges.forEach(function (range, i) {		            if (rangesOptions && rangesOptions[i]) {		                ranges[i] = merge(false, rangesOptions[i], range);		            }		        });		        return ranges;		    },		    /**		     * Calculate bubble legend sizes from rendered series.		     *		     * @private		     * @function Highcharts.BubbleLegend#predictBubbleSizes		     *		     * @return {Array<number,number>}		     *         Calculated min and max bubble sizes		     */		    predictBubbleSizes: function () {		        var chart = this.chart,		            fontMetrics = this.fontMetrics,		            legendOptions = chart.legend.options,		            floating = legendOptions.floating,		            horizontal = legendOptions.layout === 'horizontal',		            lastLineHeight = horizontal ? chart.legend.lastLineHeight : 0,		            plotSizeX = chart.plotSizeX,		            plotSizeY = chart.plotSizeY,		            bubbleSeries = chart.series[this.options.seriesIndex],		            minSize = Math.ceil(bubbleSeries.minPxSize),		            maxPxSize = Math.ceil(bubbleSeries.maxPxSize),		            maxSize = bubbleSeries.options.maxSize,		            plotSize = Math.min(plotSizeY, plotSizeX),		            calculatedSize;		        // Calculate prediceted max size of bubble		        if (floating || !(/%$/.test(maxSize))) {		            calculatedSize = maxPxSize;		        } else {		            maxSize = parseFloat(maxSize);		            calculatedSize = ((plotSize + lastLineHeight - fontMetrics.h / 2) *		               maxSize / 100) / (maxSize / 100 + 1);		            // Get maxPxSize from bubble series if calculated bubble legend		            // size will not affect to bubbles series.		            if (		                (horizontal && plotSizeY - calculatedSize >=		               plotSizeX) || (!horizontal && plotSizeX -		               calculatedSize >= plotSizeY)		            ) {		                calculatedSize = maxPxSize;		            }		        }		        return [minSize, Math.ceil(calculatedSize)];		    },		    /**		     * Correct ranges with calculated sizes.		     *		     * @private		     * @function Highcharts.BubbleLegend#updateRanges		     *		     * @param {number} min		     *		     * @param {number} max		     */		    updateRanges: function (min, max) {		        var bubbleLegendOptions = this.legend.options.bubbleLegend;		        bubbleLegendOptions.minSize = min;		        bubbleLegendOptions.maxSize = max;		        bubbleLegendOptions.ranges = this.getRanges();		    },		    /**		     * Because of the possibility of creating another legend line, predicted		     * bubble legend sizes may differ by a few pixels, so it is necessary to		     * correct them.		     *		     * @private		     * @function Highcharts.BubbleLegend#correctSizes		     */		    correctSizes: function () {		        var legend = this.legend,		            chart = this.chart,		            bubbleSeries = chart.series[this.options.seriesIndex],		            bubbleSeriesSize = bubbleSeries.maxPxSize,		            bubbleLegendSize = this.options.maxSize;		        if (Math.abs(Math.ceil(bubbleSeriesSize) - bubbleLegendSize) > 1) {		            this.updateRanges(this.options.minSize, bubbleSeries.maxPxSize);		            legend.render();		        }		    }		};		// Start the bubble legend creation process.		addEvent(H.Legend, 'afterGetAllItems', function (e) {		    var legend = this,		        bubbleLegend = legend.bubbleLegend,		        legendOptions = legend.options,		        options = legendOptions.bubbleLegend,		        bubbleSeriesIndex = legend.chart.getVisibleBubbleSeriesIndex();		    // Remove unnecessary element		    if (bubbleLegend && bubbleLegend.ranges && bubbleLegend.ranges.length) {		        // Allow change the way of calculating ranges in update		        if (options.ranges.length) {		            options.autoRanges = !!options.ranges[0].autoRanges;		        }		        // Update bubbleLegend dimensions in each redraw		        legend.destroyItem(bubbleLegend);		    }		    // Create bubble legend		    if (bubbleSeriesIndex >= 0 &&		            legendOptions.enabled &&		            options.enabled		    ) {		        options.seriesIndex = bubbleSeriesIndex;		        legend.bubbleLegend = new H.BubbleLegend(options, legend);		        legend.bubbleLegend.addToLegend(e.allItems);		    }		});		/**		 * Check if there is at least one visible bubble series.		 *		 * @private		 * @function Highcharts.Chart#getVisibleBubbleSeriesIndex		 *		 * @return {number}		 *         First visible bubble series index		 */		Chart.prototype.getVisibleBubbleSeriesIndex = function () {		    var series = this.series,		        i = 0;		    while (i < series.length) {		        if (		            series[i] &&		            series[i].isBubble &&		            series[i].visible &&		            series[i].zData.length		        ) {		            return i;		        }		        i++;		    }		    return -1;		};		/**		 * Calculate height for each row in legend.		 *		 * @private		 * @function Highcharts.Legend#getLinesHeights		 *		 * @return {Array<object>}		 *         Informations about line height and items amount		 */		Legend.prototype.getLinesHeights = function () {		    var items = this.allItems,		        lines = [],		        lastLine,		        length = items.length,		        i = 0,		        j = 0;		    for (i = 0; i < length; i++) {		        if (items[i].legendItemHeight) {		            // for bubbleLegend		            items[i].itemHeight = items[i].legendItemHeight;		        }		        if ( // Line break		            items[i] === items[length - 1] ||		            items[i + 1] &&		            items[i]._legendItemPos[1] !==		            items[i + 1]._legendItemPos[1]		        ) {		            lines.push({ height: 0 });		            lastLine = lines[lines.length - 1];		            // Find the highest item in line		            for (j; j <= i; j++) {		                if (items[j].itemHeight > lastLine.height) {		                    lastLine.height = items[j].itemHeight;		                }		            }		            lastLine.step = i;		        }		    }		    return lines;		};		/**		 * Correct legend items translation in case of different elements heights.		 *		 * @private		 * @function Highcharts.Legend#retranslateItems		 *		 * @param {Array<object>} lines		 *        Informations about line height and items amount		 */		Legend.prototype.retranslateItems = function (lines) {		    var items = this.allItems,		        orgTranslateX,		        orgTranslateY,		        movementX,		        rtl = this.options.rtl,		        actualLine = 0;		    items.forEach(function (item, index) {		        orgTranslateX = item.legendGroup.translateX;		        orgTranslateY = item._legendItemPos[1];		        movementX = item.movementX;		        if (movementX || (rtl && item.ranges)) {		            movementX = rtl ? orgTranslateX - item.options.maxSize / 2 :		                orgTranslateX + movementX;		            item.legendGroup.attr({ translateX: movementX });		        }		        if (index > lines[actualLine].step) {		            actualLine++;		        }		        item.legendGroup.attr({		            translateY: Math.round(		                orgTranslateY + lines[actualLine].height / 2		            )		        });		        item._legendItemPos[1] = orgTranslateY + lines[actualLine].height / 2;		    });		};		// Hide or show bubble legend depending on the visible status of bubble series.		addEvent(Series, 'legendItemClick', function () {		    var series = this,		        chart = series.chart,		        visible = series.visible,		        legend = series.chart.legend,		        status;		    if (legend && legend.bubbleLegend) {		        // Visible property is not set correctly yet, so temporary correct it		        series.visible = !visible;		        // Save future status for getRanges method		        series.ignoreSeries = visible;		        // Check if at lest one bubble series is visible		        status = chart.getVisibleBubbleSeriesIndex() >= 0;		        // Hide bubble legend if all bubble series are disabled		        if (legend.bubbleLegend.visible !== status) {		            // Show or hide bubble legend		            legend.update({		                bubbleLegend: { enabled: status }		            });		            legend.bubbleLegend.visible = status; // Restore default status		        }		        series.visible = visible;		    }		});		// If ranges are not specified, determine ranges from rendered bubble series and		// render legend again.		wrap(Chart.prototype, 'drawChartBox', function (proceed, options, callback) {		    var chart = this,		        legend = chart.legend,		        bubbleSeries = chart.getVisibleBubbleSeriesIndex() >= 0,		        bubbleLegendOptions,		        bubbleSizes;		    if (		        legend && legend.options.enabled && legend.bubbleLegend &&		        legend.options.bubbleLegend.autoRanges && bubbleSeries		    ) {		        bubbleLegendOptions = legend.bubbleLegend.options;		        bubbleSizes = legend.bubbleLegend.predictBubbleSizes();		        legend.bubbleLegend.updateRanges(bubbleSizes[0], bubbleSizes[1]);		        // Disable animation on init		        if (!bubbleLegendOptions.placed) {		            legend.group.placed = false;		            legend.allItems.forEach(function (item) {		                item.legendGroup.translateY = null;		            });		        }		        // Create legend with bubbleLegend		        legend.render();		        chart.getMargins();		        chart.axes.forEach(function (axis) {		            axis.render();		            if (!bubbleLegendOptions.placed) {		                axis.setScale();		                axis.updateNames();		                // Disable axis animation on init		                objectEach(axis.ticks, function (tick) {		                    tick.isNew = true;		                    tick.isNewLabel = true;		                });		            }		        });		        bubbleLegendOptions.placed = true;		        // After recalculate axes, calculate margins again.		        chart.getMargins();		        // Call default 'drawChartBox' method.		        proceed.call(chart, options, callback);		        // Check bubble legend sizes and correct them if necessary.		        legend.bubbleLegend.correctSizes();		        // Correct items positions with different dimensions in legend.		        legend.retranslateItems(legend.getLinesHeights());		    } else {		        proceed.call(chart, options, callback);		        if (legend && legend.options.enabled && legend.bubbleLegend) {		            // Allow color change after click in legend on static bubble legend		            legend.render();		            legend.retranslateItems(legend.getLinesHeights());		        }		    }		});	}(Highcharts));	(function (H) {		/* *		 * (c) 2010-2019 Torstein Honsi		 *		 * License: www.highcharts.com/license		 */		var arrayMax = H.arrayMax,		    arrayMin = H.arrayMin,		    Axis = H.Axis,		    color = H.color,		    isNumber = H.isNumber,		    noop = H.noop,		    pick = H.pick,		    pInt = H.pInt,		    Point = H.Point,		    Series = H.Series,		    seriesType = H.seriesType,		    seriesTypes = H.seriesTypes;		/**		 * A bubble series is a three dimensional series type where each point renders		 * an X, Y and Z value. Each points is drawn as a bubble where the position		 * along the X and Y axes mark the X and Y values, and the size of the bubble		 * relates to the Z value. Requires `highcharts-more.js`.		 *		 * @sample {highcharts} highcharts/demo/bubble/		 *         Bubble chart		 *		 * @extends      plotOptions.scatter		 * @product      highcharts highstock		 * @optionparent plotOptions.bubble		 */		seriesType('bubble', 'scatter', {		    dataLabels: {		        formatter: function () { // #2945		            return this.point.z;		        },		        inside: true,		        verticalAlign: 'middle'		    },		    /**		     * If there are more points in the series than the `animationLimit`, the		     * animation won't run. Animation affects overall performance and doesn't		     * work well with heavy data series.		     *		     * @since 6.1.0		     */		    animationLimit: 250,		    /**		     * Whether to display negative sized bubbles. The threshold is given		     * by the [zThreshold](#plotOptions.bubble.zThreshold) option, and negative		     * bubbles can be visualized by setting		     * [negativeColor](#plotOptions.bubble.negativeColor).		     *		     * @sample {highcharts} highcharts/plotoptions/bubble-negative/		     *         Negative bubbles		     *		     * @type      {boolean}		     * @default   true		     * @since     3.0		     * @apioption plotOptions.bubble.displayNegative		     */		    /**		     * @extends   plotOptions.series.marker		     * @excluding enabled, enabledThreshold, height, radius, width		     */		    marker: {		        lineColor: null, // inherit from series.color		        lineWidth: 1,		        /**		         * The fill opacity of the bubble markers.		         */		        fillOpacity: 0.5,		        /**		         * In bubble charts, the radius is overridden and determined based on		         * the point's data value.		         *		         * @ignore		         */		        radius: null,		        states: {		            hover: {		                radiusPlus: 0		            }		        },		        /**		         * A predefined shape or symbol for the marker. Possible values are		         * "circle", "square", "diamond", "triangle" and "triangle-down".		         *		         * Additionally, the URL to a graphic can be given on the form		         * `url(graphic.png)`. Note that for the image to be applied to exported		         * charts, its URL needs to be accessible by the export server.		         *		         * Custom callbacks for symbol path generation can also be added to		         * `Highcharts.SVGRenderer.prototype.symbols`. The callback is then		         * used by its method name, as shown in the demo.		         *		         * @sample     {highcharts} highcharts/plotoptions/bubble-symbol/		         *             Bubble chart with various symbols		         * @sample     {highcharts} highcharts/plotoptions/series-marker-symbol/		         *             General chart with predefined, graphic and custom markers		         *		         * @since      5.0.11		         * @validvalue ["circle", "square", "diamond", "triangle",		         *             "triangle-down"]		         */		        symbol: 'circle'		    },		    /**		     * Minimum bubble size. Bubbles will automatically size between the		     * `minSize` and `maxSize` to reflect the `z` value of each bubble.		     * Can be either pixels (when no unit is given), or a percentage of		     * the smallest one of the plot width and height.		     *		     * @sample {highcharts} highcharts/plotoptions/bubble-size/		     *         Bubble size		     *		     * @type    {number|string}		     * @since   3.0		     * @product highcharts highstock		     */		    minSize: 8,		    /**		     * Maximum bubble size. Bubbles will automatically size between the		     * `minSize` and `maxSize` to reflect the `z` value of each bubble.		     * Can be either pixels (when no unit is given), or a percentage of		     * the smallest one of the plot width and height.		     *		     * @sample {highcharts} highcharts/plotoptions/bubble-size/		     *         Bubble size		     *		     * @type    {number|string}		     * @since   3.0		     * @product highcharts highstock		     */		    maxSize: '20%',		    /**		     * When a point's Z value is below the		     * [zThreshold](#plotOptions.bubble.zThreshold) setting, this color is used.		     *		     * @sample {highcharts} highcharts/plotoptions/bubble-negative/		     *         Negative bubbles		     *		     * @type      {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}		     * @since     3.0		     * @product   highcharts		     * @apioption plotOptions.bubble.negativeColor		     */		    /**		     * Whether the bubble's value should be represented by the area or the		     * width of the bubble. The default, `area`, corresponds best to the		     * human perception of the size of each bubble.		     *		     * @sample {highcharts} highcharts/plotoptions/bubble-sizeby/		     *         Comparison of area and size		     *		     * @type       {string}		     * @default    area		     * @since      3.0.7		     * @validvalue ["area", "width"]		     * @apioption  plotOptions.bubble.sizeBy		     */		    /**		     * When this is true, the absolute value of z determines the size of		     * the bubble. This means that with the default `zThreshold` of 0, a		     * bubble of value -1 will have the same size as a bubble of value 1,		     * while a bubble of value 0 will have a smaller size according to		     * `minSize`.		     *		     * @sample    {highcharts} highcharts/plotoptions/bubble-sizebyabsolutevalue/		     *            Size by absolute value, various thresholds		     *		     * @type      {boolean}		     * @default   false		     * @since     4.1.9		     * @product   highcharts		     * @apioption plotOptions.bubble.sizeByAbsoluteValue		     */		    /**		     * When this is true, the series will not cause the Y axis to cross		     * the zero plane (or [threshold](#plotOptions.series.threshold) option)		     * unless the data actually crosses the plane.		     *		     * For example, if `softThreshold` is `false`, a series of 0, 1, 2,		     * 3 will make the Y axis show negative values according to the `minPadding`		     * option. If `softThreshold` is `true`, the Y axis starts at 0.		     *		     * @since   4.1.9		     * @product highcharts		     */		    softThreshold: false,		    states: {		        hover: {		            halo: {		                size: 5		            }		        }		    },		    tooltip: {		        pointFormat: '({point.x}, {point.y}), Size: {point.z}'		    },		    turboThreshold: 0,		    /**		     * The minimum for the Z value range. Defaults to the highest Z value		     * in the data.		     *		     * @see [zMin](#plotOptions.bubble.zMin)		     *		     * @sample {highcharts} highcharts/plotoptions/bubble-zmin-zmax/		     *         Z has a possible range of 0-100		     *		     * @type      {number}		     * @since     4.0.3		     * @product   highcharts		     * @apioption plotOptions.bubble.zMax		     */		    /**		     * The minimum for the Z value range. Defaults to the lowest Z value		     * in the data.		     *		     * @see [zMax](#plotOptions.bubble.zMax)		     *		     * @sample {highcharts} highcharts/plotoptions/bubble-zmin-zmax/		     *         Z has a possible range of 0-100		     *		     * @type      {number}		     * @since     4.0.3		     * @product   highcharts		     * @apioption plotOptions.bubble.zMin		     */		    /**		     * When [displayNegative](#plotOptions.bubble.displayNegative) is `false`,		     * bubbles with lower Z values are skipped. When `displayNegative`		     * is `true` and a [negativeColor](#plotOptions.bubble.negativeColor)		     * is given, points with lower Z is colored.		     *		     * @sample {highcharts} highcharts/plotoptions/bubble-negative/		     *         Negative bubbles		     *		     * @since   3.0		     * @product highcharts		     */		    zThreshold: 0,		    zoneAxis: 'z'		// Prototype members		}, {		    pointArrayMap: ['y', 'z'],		    parallelArrays: ['x', 'y', 'z'],		    trackerGroups: ['group', 'dataLabelsGroup'],		    specialGroup: 'group', // To allow clipping (#6296)		    bubblePadding: true,		    zoneAxis: 'z',		    directTouch: true,		    isBubble: true,		    pointAttribs: function (point, state) {		        var markerOptions = this.options.marker,		            fillOpacity = markerOptions.fillOpacity,		            attr = Series.prototype.pointAttribs.call(this, point, state);		        if (fillOpacity !== 1) {		            attr.fill = color(attr.fill).setOpacity(fillOpacity).get('rgba');		        }		        return attr;		    },		    // Get the radius for each point based on the minSize, maxSize and each		    // point's Z value. This must be done prior to Series.translate because		    // the axis needs to add padding in accordance with the point sizes.		    getRadii: function (zMin, zMax, series) {		        var len,		            i,		            zData = this.zData,		            minSize = series.minPxSize,		            maxSize = series.maxPxSize,		            radii = [],		            value;		        // Set the shape type and arguments to be picked up in drawPoints		        for (i = 0, len = zData.length; i < len; i++) {		            value = zData[i];		            // Separate method to get individual radius for bubbleLegend		            radii.push(this.getRadius(zMin, zMax, minSize, maxSize, value));		        }		        this.radii = radii;		    },		    // Get the individual radius for one point.		    getRadius: function (zMin, zMax, minSize, maxSize, value) {		        var options = this.options,		            sizeByArea = options.sizeBy !== 'width',		            zThreshold = options.zThreshold,		            pos,		            zRange = zMax - zMin,		            radius;		        // When sizing by threshold, the absolute value of z determines		        // the size of the bubble.		        if (options.sizeByAbsoluteValue && value !== null) {		            value = Math.abs(value - zThreshold);		            zMax = zRange = Math.max(		                zMax - zThreshold,		                Math.abs(zMin - zThreshold)		            );		            zMin = 0;		        }		        if (!isNumber(value)) {		            radius = null;		        // Issue #4419 - if value is less than zMin, push a radius that's		        // always smaller than the minimum size		        } else if (value < zMin) {		            radius = minSize / 2 - 1;		        } else {		            // Relative size, a number between 0 and 1		            pos = zRange > 0 ? (value - zMin) / zRange : 0.5;		            if (sizeByArea && pos >= 0) {		                pos = Math.sqrt(pos);		            }		            radius = Math.ceil(minSize + pos * (maxSize - minSize)) / 2;		        }		        return radius;		    },		    // Perform animation on the bubbles		    animate: function (init) {		        if (		            !init &&		            this.points.length < this.options.animationLimit // #8099		        ) {		            this.points.forEach(function (point) {		                var graphic = point.graphic,		                    animationTarget;		                if (graphic && graphic.width) { // URL symbols don't have width		                    animationTarget = {		                        x: graphic.x,		                        y: graphic.y,		                        width: graphic.width,		                        height: graphic.height		                    };		                    // Start values		                    graphic.attr({		                        x: point.plotX,		                        y: point.plotY,		                        width: 1,		                        height: 1		                    });		                    // Run animation		                    graphic.animate(animationTarget, this.options.animation);		                }		            }, this);		            // delete this function to allow it only once		            this.animate = null;		        }		    },		    // Extend the base translate method to handle bubble size		    translate: function () {		        var i,		            data = this.data,		            point,		            radius,		            radii = this.radii;		        // Run the parent method		        seriesTypes.scatter.prototype.translate.call(this);		        // Set the shape type and arguments to be picked up in drawPoints		        i = data.length;		        while (i--) {		            point = data[i];		            radius = radii ? radii[i] : 0; // #1737		            if (isNumber(radius) && radius >= this.minPxSize / 2) {		                // Shape arguments		                point.marker = H.extend(point.marker, {		                    radius: radius,		                    width: 2 * radius,		                    height: 2 * radius		                });		                // Alignment box for the data label		                point.dlBox = {		                    x: point.plotX - radius,		                    y: point.plotY - radius,		                    width: 2 * radius,		                    height: 2 * radius		                };		            } else { // below zThreshold		                // #1691		                point.shapeArgs = point.plotY = point.dlBox = undefined;		            }		        }		    },		    alignDataLabel: seriesTypes.column.prototype.alignDataLabel,		    buildKDTree: noop,		    applyZones: noop		// Point class		}, {		    haloPath: function (size) {		        return Point.prototype.haloPath.call(		            this,		            // #6067		            size === 0 ? 0 : (this.marker ? this.marker.radius || 0 : 0) + size		        );		    },		    ttBelow: false		});		// Add logic to pad each axis with the amount of pixels necessary to avoid the		// bubbles to overflow.		Axis.prototype.beforePadding = function () {		    var axis = this,		        axisLength = this.len,		        chart = this.chart,		        pxMin = 0,		        pxMax = axisLength,		        isXAxis = this.isXAxis,		        dataKey = isXAxis ? 'xData' : 'yData',		        min = this.min,		        extremes = {},		        smallestSize = Math.min(chart.plotWidth, chart.plotHeight),		        zMin = Number.MAX_VALUE,		        zMax = -Number.MAX_VALUE,		        range = this.max - min,		        transA = axisLength / range,		        activeSeries = [];		    // Handle padding on the second pass, or on redraw		    this.series.forEach(function (series) {		        var seriesOptions = series.options,		            zData;		        if (		            series.bubblePadding &&		            (series.visible || !chart.options.chart.ignoreHiddenSeries)		        ) {		            // Correction for #1673		            axis.allowZoomOutside = true;		            // Cache it		            activeSeries.push(series);		            if (isXAxis) { // because X axis is evaluated first		                // For each series, translate the size extremes to pixel values		                ['minSize', 'maxSize'].forEach(function (prop) {		                    var length = seriesOptions[prop],		                        isPercent = /%$/.test(length);		                    length = pInt(length);		                    extremes[prop] = isPercent ?		                        smallestSize * length / 100 :		                        length;		                });		                series.minPxSize = extremes.minSize;		                // Prioritize min size if conflict to make sure bubbles are		                // always visible. #5873		                series.maxPxSize = Math.max(extremes.maxSize, extremes.minSize);		                // Find the min and max Z		                zData = series.zData.filter(H.isNumber);		                if (zData.length) { // #1735		                    zMin = pick(seriesOptions.zMin, Math.min(		                        zMin,		                        Math.max(		                            arrayMin(zData),		                            seriesOptions.displayNegative === false ?		                                seriesOptions.zThreshold :		                                -Number.MAX_VALUE		                        )		                    ));		                    zMax = pick(		                        seriesOptions.zMax,		                        Math.max(zMax, arrayMax(zData))		                    );		                }		            }		        }		    });		    activeSeries.forEach(function (series) {		        var data = series[dataKey],		            i = data.length,		            radius;		        if (isXAxis) {		            series.getRadii(zMin, zMax, series);		        }		        if (range > 0) {		            while (i--) {		                if (		                    isNumber(data[i]) &&		                    axis.dataMin <= data[i] &&		                    data[i] <= axis.dataMax		                ) {		                    radius = series.radii[i];		                    pxMin = Math.min(		                        ((data[i] - min) * transA) - radius,		                        pxMin		                    );		                    pxMax = Math.max(		                        ((data[i] - min) * transA) + radius,		                        pxMax		                    );		                }		            }		        }		    });		    // Apply the padding to the min and max properties		    if (activeSeries.length && range > 0 && !this.isLog) {		        pxMax -= axisLength;		        transA *= (		            axisLength +		            Math.max(0, pxMin) - // #8901		            Math.min(pxMax, axisLength)		        ) / axisLength;		        [['min', 'userMin', pxMin], ['max', 'userMax', pxMax]].forEach(		            function (keys) {		                if (pick(axis.options[keys[0]], axis[keys[1]]) === undefined) {		                    axis[keys[0]] += keys[2] / transA;		                }		            }		        );		    }		};		/**		 * A `bubble` series. If the [type](#series.bubble.type) option is		 * not specified, it is inherited from [chart.type](#chart.type).		 *		 * @extends   series,plotOptions.bubble		 * @excluding dataParser, dataURL, stack		 * @product   highcharts highstock		 * @apioption series.bubble		 */		/**		 * An array of data points for the series. For the `bubble` series type,		 * points can be given in the following ways:		 *		 * 1. An array of arrays with 3 or 2 values. In this case, the values correspond		 *    to `x,y,z`. If the first value is a string, it is applied as the name of		 *    the point, and the `x` value is inferred. The `x` value can also be		 *    omitted, in which case the inner arrays should be of length 2\. Then the		 *    `x` value is automatically calculated, either starting at 0 and		 *    incremented by 1, or from `pointStart` and `pointInterval` given in the		 *    series options.		 *    ```js		 *    data: [		 *        [0, 1, 2],		 *        [1, 5, 5],		 *        [2, 0, 2]		 *    ]		 *    ```		 *		 * 2. An array of objects with named values. The following snippet shows only a		 *    few settings, see the complete options set below. If the total number of		 *    data points exceeds the series'		 *    [turboThreshold](#series.bubble.turboThreshold), this option is not		 *    available.		 *    ```js		 *    data: [{		 *        x: 1,		 *        y: 1,		 *        z: 1,		 *        name: "Point2",		 *        color: "#00FF00"		 *    }, {		 *        x: 1,		 *        y: 5,		 *        z: 4,		 *        name: "Point1",		 *        color: "#FF00FF"		 *    }]		 *    ```		 *		 * @sample {highcharts} highcharts/series/data-array-of-arrays/		 *         Arrays of numeric x and y		 * @sample {highcharts} highcharts/series/data-array-of-arrays-datetime/		 *         Arrays of datetime x and y		 * @sample {highcharts} highcharts/series/data-array-of-name-value/		 *         Arrays of point.name and y		 * @sample {highcharts} highcharts/series/data-array-of-objects/		 *         Config objects		 *		 * @type      {Array<Array<(number|string),number>|Array<(number|string),number,number>|*>}		 * @extends   series.line.data		 * @excluding marker		 * @product   highcharts		 * @apioption series.bubble.data		 */		/**		 * The size value for each bubble. The bubbles' diameters are computed		 * based on the `z`, and controlled by series options like `minSize`,		 * `maxSize`, `sizeBy`, `zMin` and `zMax`.		 *		 * @type      {number}		 * @product   highcharts		 * @apioption series.bubble.data.z		 */		/**		 * @excluding enabled, enabledThreshold, height, radius, width		 * @apioption series.bubble.marker		 */	}(Highcharts));	(function (H) {		/* *		 * (c) 2010-2019 Grzegorz Blachlinski, Sebastian Bochan		 *		 * License: www.highcharts.com/license		 */		var seriesType = H.seriesType,		    defined = H.defined;		/**		 * Packed bubble series		 *		 * @private		 * @class		 * @name Highcharts.seriesTypes.packedbubble		 *		 * @augments Highcharts.Series		 *		 * @requires modules:highcharts-more		 */		seriesType(		    'packedbubble',		    'bubble',		    /**		     * A packed bubble series is a two dimensional series type, where each point		     * renders a value in X, Y position. Each point is drawn as a bubble where		     * the bubbles don't overlap with each other and the radius of the bubble		     * related to the value. Requires `highcharts-more.js`.		     *		     * @sample {highcharts} highcharts/demo/packed-bubble/		     *         Packed-bubble chart		     *		     * @extends      plotOptions.bubble		     * @since        7.0.0		     * @product      highcharts		     * @excluding    connectEnds, connectNulls, jitter, keys,		     *               sizeByAbsoluteValue, step, zMax, zMin		     * @optionparent plotOptions.packedbubble		     */		    {		        /**		         * Minimum bubble size. Bubbles will automatically size between the		         * `minSize` and `maxSize` to reflect the value of each bubble.		         * Can be either pixels (when no unit is given), or a percentage of		         * the smallest one of the plot width and height.		         *		         * @sample {highcharts} highcharts/plotoptions/bubble-size/		         *         Bubble size		         *		         * @type    {number|string}		         */		        minSize: '10%',		        /**		         * Maximum bubble size. Bubbles will automatically size between the		         * `minSize` and `maxSize` to reflect the value of each bubble.		         * Can be either pixels (when no unit is given), or a percentage of		         * the smallest one of the plot width and height.		         *		         * @sample {highcharts} highcharts/plotoptions/bubble-size/		         *         Bubble size		         *		         * @type    {number|string}		         */		        maxSize: '100%',		        sizeBy: 'radius',		        zoneAxis: 'y',		        tooltip: {		            pointFormat: 'Value: {point.value}'		        }		    }, {		        pointArrayMap: ['value'],		        pointValKey: 'value',		        isCartesian: false,		        axisTypes: [],		        /**		         * Create a single array of all points from all series		         * @private		         * @param {Array} Array of all series objects		         * @return {Array} Returns the array of all points.		         */		        accumulateAllPoints: function (series) {		            var chart = series.chart,		                allDataPoints = [],		                i, j;		            for (i = 0; i < chart.series.length; i++) {		                series = chart.series[i];		                if (series.visible || !chart.options.chart.ignoreHiddenSeries) {		                    // add data to array only if series is visible		                    for (j = 0; j < series.yData.length; j++) {		                        allDataPoints.push([		                            null, null,		                            series.yData[j],		                            series.index,		                            j		                        ]);		                    }		                }		            }		            return allDataPoints;		        },		        // Extend the base translate method to handle bubble size, and correct		        // positioning them.		        translate: function () {		            var positions, // calculated positions of bubbles in bubble array		                series = this,		                chart = series.chart,		                data = series.data,		                index = series.index,		                point,		                radius,		                i;		            this.processedXData = this.xData;		            this.generatePoints();		            // merged data is an array with all of the data from all series		            if (!defined(chart.allDataPoints)) {		                chart.allDataPoints = series.accumulateAllPoints(series);		                // calculate radius for all added data		                series.getPointRadius();		            }		            // after getting initial radius, calculate bubble positions		            positions = this.placeBubbles(chart.allDataPoints);		            // Set the shape type and arguments to be picked up in drawPoints		            for (i = 0; i < positions.length; i++) {		                if (positions[i][3] === index) {		                    // update the series points with the values from positions		                    // array		                    point = data[positions[i][4]];		                    radius = positions[i][2];		                    point.plotX = positions[i][0] - chart.plotLeft +		                      chart.diffX;		                    point.plotY = positions[i][1] - chart.plotTop +		                      chart.diffY;		                    point.marker = H.extend(point.marker, {		                        radius: radius,		                        width: 2 * radius,		                        height: 2 * radius		                    });		                }		            }		        },		        /**		         * Check if two bubbles overlaps.		         * @private		         * @param {Array} bubble1 first bubble		         * @param {Array} bubble2 second bubble		         * @return {boolean} overlap or not		         */		        checkOverlap: function (bubble1, bubble2) {		            var diffX = bubble1[0] - bubble2[0], // diff of X center values		                diffY = bubble1[1] - bubble2[1], // diff of Y center values		                sumRad = bubble1[2] + bubble2[2]; // sum of bubble radius		            return (		                Math.sqrt(diffX * diffX + diffY * diffY) -		                Math.abs(sumRad)		            ) < -0.001;		        },		        /**		         * Function that is adding one bubble based on positions and sizes		         * of two other bubbles, lastBubble is the last added bubble,		         * newOrigin is the bubble for positioning new bubbles.		         * nextBubble is the curently added bubble for which we are		         * calculating positions		         * @private		         * @param {Array} lastBubble The closest last bubble		         * @param {Array} newOrigin New bubble		         * @param {Array} nextBubble The closest next bubble		         * @return {Array} Bubble with correct positions		         */		        positionBubble: function (lastBubble, newOrigin, nextBubble) {		            var sqrt = Math.sqrt,		                asin = Math.asin,		                acos = Math.acos,		                pow = Math.pow,		                abs = Math.abs,		                distance = sqrt( // dist between lastBubble and newOrigin		                    pow((lastBubble[0] - newOrigin[0]), 2) +		                  pow((lastBubble[1] - newOrigin[1]), 2)		                ),		                alfa = acos(		                    // from cosinus theorem: alfa is an angle used for		                    // calculating correct position		                    (		                        pow(distance, 2) +		                    pow(nextBubble[2] + newOrigin[2], 2) -		                    pow(nextBubble[2] + lastBubble[2], 2)		                    ) / (2 * (nextBubble[2] + newOrigin[2]) * distance)		                ),		                beta = asin( // from sinus theorem.		                    abs(lastBubble[0] - newOrigin[0]) /		                  distance		                ),		                // providing helping variables, related to angle between		                // lastBubble and newOrigin		                gamma = (lastBubble[1] - newOrigin[1]) < 0 ? 0 : Math.PI,		                // if new origin y is smaller than last bubble y value		                // (2 and 3 quarter),		                // add Math.PI to final angle		                delta = (lastBubble[0] - newOrigin[0]) *		                (lastBubble[1] - newOrigin[1]) < 0 ?		                    1 : -1, // (1st and 3rd quarter)		                finalAngle = gamma + alfa + beta * delta,		                cosA = Math.cos(finalAngle),		                sinA = Math.sin(finalAngle),		                posX = newOrigin[0] + (newOrigin[2] + nextBubble[2]) * sinA,		                // center of new origin + (radius1 + radius2) * sinus A		                posY = newOrigin[1] - (newOrigin[2] + nextBubble[2]) * cosA;		            return [		                posX,		                posY,		                nextBubble[2],		                nextBubble[3],		                nextBubble[4]		            ]; // the same as described before		        },		        /**		         * This is the main function responsible for positioning all of the		         * bubbles.		         * allDataPoints - bubble array, in format [pixel x value,		         * pixel y value, radius, related series index, related point index]		         * @private		         * @param {Array} allDataPoints All points from all series		         * @return {Array} Positions of all bubbles		         */		        placeBubbles: function (allDataPoints) {		            var series = this,		                checkOverlap = series.checkOverlap,		                positionBubble = series.positionBubble,		                bubblePos = [],		                stage = 1,		                j = 0,		                k = 0,		                calculatedBubble,		                sortedArr,		                i;		            // sort all points		            sortedArr = allDataPoints.sort(function (a, b) {		                return b[2] - a[2];		            });		            // if length is 0, return empty array		            if (!sortedArr.length) {		                return [];		            }		            if (sortedArr.length < 2) {		                // if length is 1,return only one bubble		                return [		                    0, 0,		                    sortedArr[0][0],		                    sortedArr[0][1],		                    sortedArr[0][2]		                ];		            }		            // create first bubble in the middle of the chart		            bubblePos.push([		                [		                    0, // starting in 0,0 coordinates		                    0,		                    sortedArr[0][2], // radius		                    sortedArr[0][3], // series index		                    sortedArr[0][4]		                ] // point index		            ]); // 0 level bubble		            bubblePos.push([		                [		                    0,		                    0 - sortedArr[1][2] - sortedArr[0][2],		                    // move bubble above first one		                    sortedArr[1][2],		                    sortedArr[1][3],		                    sortedArr[1][4]		                ]		            ]); // 1 level 1st bubble		            // first two already positioned so starting from 2		            for (i = 2; i < sortedArr.length; i++) {		                sortedArr[i][2] = sortedArr[i][2] || 1;		                // in case if radius is calculated as 0.		                calculatedBubble = positionBubble(		                    bubblePos[stage][j],		                    bubblePos[stage - 1][k],		                    sortedArr[i]		                ); // calculate initial bubble position		                if (checkOverlap(calculatedBubble, bubblePos[stage][0])) {		                    // if new bubble is overlapping with first bubble in		                    // current level (stage)		                    bubblePos.push([]);		                    k = 0;		                    // reset index of bubble, used for positioning the bubbles		                    // around it, we are starting from first bubble in next		                    // stage because we are changing level to higher		                    bubblePos[stage + 1].push(		                        positionBubble(		                            bubblePos[stage][j],		                            bubblePos[stage][0],		                            sortedArr[i]		                        )		                    );		                    // (last added bubble, 1st. bbl from cur stage, new bubble)		                    stage++; // the new level is created, above current one		                    j = 0; // set the index of bubble in current level to 0		                } else if (		                    stage > 1 && bubblePos[stage - 1][k + 1] &&		                    checkOverlap(calculatedBubble, bubblePos[stage - 1][k + 1])		                ) {		                    // If new bubble is overlapping with one of the previous		                    // stage bubbles, it means that - bubble, used for		                    // positioning the bubbles around it has changed so we need		                    // to recalculate it.		                    k++;		                    bubblePos[stage].push(		                        positionBubble(		                            bubblePos[stage][j],		                            bubblePos[stage - 1][k],		                            sortedArr[i]		                        )		                    );		                    // (last added bubble, previous stage bubble, new bubble)		                    j++;		                } else { // simply add calculated bubble		                    j++;		                    bubblePos[stage].push(calculatedBubble);		                }		            }		            series.chart.stages = bubblePos;		            // it may not be necessary but adding it just in case -		            // it is containing all of the bubble levels		            series.chart.rawPositions = [].concat.apply([], bubblePos);		            // bubble positions merged into one array		            series.resizeRadius();		            return series.chart.rawPositions;		        },		        /**		         * The function responsible for resizing the bubble radius.		         * In shortcut: it is taking the initially		         * calculated positions of bubbles. Then it is calculating the min max		         * of both dimensions, creating something in shape of bBox.		         * The comparison of bBox and the size of plotArea		         * (later it may be also the size set by customer) is giving the		         * value how to recalculate the radius so it will match the size		         * @private		         */		        resizeRadius: function () {		            var chart = this.chart,		                positions = chart.rawPositions,		                min = Math.min,		                max = Math.max,		                plotLeft = chart.plotLeft,		                plotTop = chart.plotTop,		                chartHeight = chart.plotHeight,		                chartWidth = chart.plotWidth,		                minX, maxX, minY, maxY,		                radius,		                bBox,		                spaceRatio,		                smallerDimension,		                i;		            minX = minY = Number.POSITIVE_INFINITY; // set initial values		            maxX = maxY = Number.NEGATIVE_INFINITY;		            for (i = 0; i < positions.length; i++) {		                radius = positions[i][2];		                minX = min(minX, positions[i][0] - radius);		                // (x center-radius) is the min x value used by specific bubble		                maxX = max(maxX, positions[i][0] + radius);		                minY = min(minY, positions[i][1] - radius);		                maxY = max(maxY, positions[i][1] + radius);		            }		            bBox = [maxX - minX, maxY - minY];		            spaceRatio = [		                (chartWidth - plotLeft) / bBox[0],		                (chartHeight - plotTop) / bBox[1]		            ];		            smallerDimension = min.apply([], spaceRatio);		            if (Math.abs(smallerDimension - 1) > 1e-10) {		                // if bBox is considered not the same width as possible size		                for (i = 0; i < positions.length; i++) {		                    positions[i][2] *= smallerDimension;		                }		                this.placeBubbles(positions);		            } else {		                // If no radius recalculation is needed, we need to position the		                // whole bubbles in center of chart plotarea for this, we are		                // adding two parameters, diffY and diffX, that are related to		                // differences between the initial center and the bounding box.		                chart.diffY = chartHeight / 2 +		                    plotTop - minY - (maxY - minY) / 2;		                chart.diffX = chartWidth / 2 +		                    plotLeft - minX - (maxX - minX) / 2;		            }		        },		        // Calculate radius of bubbles in series.		        getPointRadius: function () { // bubbles array		            var series = this,		                chart = series.chart,		                plotWidth = chart.plotWidth,		                plotHeight = chart.plotHeight,		                seriesOptions = series.options,		                smallestSize = Math.min(plotWidth, plotHeight),		                extremes = {},		                radii = [],		                allDataPoints = chart.allDataPoints,		                minSize,		                maxSize,		                value,		                radius;		            ['minSize', 'maxSize'].forEach(function (prop) {		                var length = parseInt(seriesOptions[prop], 10),		                    isPercent = /%$/.test(length);		                extremes[prop] = isPercent ?		                    smallestSize * length / 100 :		                    length;		            });		            chart.minRadius = minSize = extremes.minSize;		            chart.maxRadius = maxSize = extremes.maxSize;		            (allDataPoints || []).forEach(function (point, i) {		                value = point[2];		                radius = series.getRadius(		                    minSize,		                    maxSize,		                    minSize,		                    maxSize,		                    value		                );		                if (value === 0) {		                    radius = null;		                }		                allDataPoints[i][2] = radius;		                radii.push(radius);		            });		            this.radii = radii;		        },		        alignDataLabel: H.Series.prototype.alignDataLabel		    }		);		// When one series is modified, the others need to be recomputed		H.addEvent(H.seriesTypes.packedbubble, 'updatedData', function () {		    var self = this;		    this.chart.series.forEach(function (s) {		        if (s.type === self.type) {		            s.isDirty = true;		        }		    });		});		// Remove accumulated data points to redistribute all of them again		// (i.e after hiding series by legend)		H.addEvent(H.Chart, 'beforeRedraw', function () {		    if (this.allDataPoints) {		        delete this.allDataPoints;		    }		});		/**		 * A `packedbubble` series. If the [type](#series.packedbubble.type) option is		 * not specified, it is inherited from [chart.type](#chart.type).		 *		 * @extends   series,plotOptions.packedbubble		 * @excluding dataParser, dataURL, stack		 * @product   highcharts highstock		 * @apioption series.packedbubble		 */		/**		 * An array of data points for the series. For the `packedbubble` series type,		 * points can be given in the following ways:		 *		 * 1. An array of `value` values.		 *    ```js		 *    data: [5, 1, 20]		 *    ```		 *		 * 2. An array of objects with named values. The objects are point configuration		 *    objects as seen below. If the total number of data points exceeds the		 *    series' [turboThreshold](#series.packedbubble.turboThreshold), this option		 *    is not available.		 *    ```js		 *    data: [{		 *        value: 1,		 *        name: "Point2",		 *        color: "#00FF00"		 *    }, {		 *        value: 5,		 *        name: "Point1",		 *        color: "#FF00FF"		 *    }]		 *    ```		 *		 * @sample {highcharts} highcharts/series/data-array-of-objects/		 *         Config objects		 *		 * @type      {Array<number|*>}		 * @extends   series.line.data		 * @excluding marker,x,y		 * @product   highcharts		 * @apioption series.packedbubble.data		 */		/**		 * The value of a bubble. The bubble's size proportional to its `value`.		 *		 * @type      {number}		 * @product   highcharts		 * @apioption series.packedbubble.data.weight		 */		/**		 * @excluding enabled, enabledThreshold, height, radius, width		 * @apioption series.packedbubble.marker		 */	}(Highcharts));	(function (H) {		/* *		 * (c) 2010-2019 Torstein Honsi		 *		 * License: www.highcharts.com/license		 */		// Extensions for polar charts. Additionally, much of the geometry required for		// polar charts is gathered in RadialAxes.js.		var pick = H.pick,		    Pointer = H.Pointer,		    Series = H.Series,		    seriesTypes = H.seriesTypes,		    wrap = H.wrap,		    seriesProto = Series.prototype,		    pointerProto = Pointer.prototype,		    colProto;		if (!H.polarExtended) {		    H.polarExtended = true;		    /**		     * Search a k-d tree by the point angle, used for shared tooltips in polar		     * charts		     */		    seriesProto.searchPointByAngle = function (e) {		        var series = this,		            chart = series.chart,		            xAxis = series.xAxis,		            center = xAxis.pane.center,		            plotX = e.chartX - center[0] - chart.plotLeft,		            plotY = e.chartY - center[1] - chart.plotTop;		        return this.searchKDTree({		            clientX: 180 + (Math.atan2(plotX, plotY) * (-180 / Math.PI))		        });		    };		    /**		     * #6212 Calculate connectors for spline series in polar chart.		     * @param {boolean} calculateNeighbours		     *        Check if connectors should be calculated for neighbour points as		     *        well allows short recurence		     */		    seriesProto.getConnectors = function (		        segment,		        index,		        calculateNeighbours,		        connectEnds		    ) {		        var i,		            prevPointInd,		            nextPointInd,		            previousPoint,		            nextPoint,		            previousX,		            previousY,		            nextX,		            nextY,		            plotX,		            plotY,		            ret,		            // 1 means control points midway between points, 2 means 1/3 from		            // the point, 3 is 1/4 etc;		            smoothing = 1.5,		            denom = smoothing + 1,		            leftContX,		            leftContY,		            rightContX,		            rightContY,		            dLControlPoint, // distance left control point		            dRControlPoint,		            leftContAngle,		            rightContAngle,		            jointAngle,		            addedNumber = connectEnds ? 1 : 0;		        // Calculate final index of points depending on the initial index value.		        // Because of calculating neighbours, index may be outisde segment		        // array.		        if (index >= 0 && index <= segment.length - 1) {		            i = index;		        } else if (index < 0) {		            i = segment.length - 1 + index;		        } else {		            i = 0;		        }		        prevPointInd = (i - 1 < 0) ? segment.length - (1 + addedNumber) : i - 1;		        nextPointInd = (i + 1 > segment.length - 1) ? addedNumber : i + 1;		        previousPoint = segment[prevPointInd];		        nextPoint = segment[nextPointInd];		        previousX = previousPoint.plotX;		        previousY = previousPoint.plotY;		        nextX = nextPoint.plotX;		        nextY = nextPoint.plotY;		        plotX = segment[i].plotX; // actual point		        plotY = segment[i].plotY;		        leftContX = (smoothing * plotX + previousX) / denom;		        leftContY = (smoothing * plotY + previousY) / denom;		        rightContX = (smoothing * plotX + nextX) / denom;		        rightContY = (smoothing * plotY + nextY) / denom;		        dLControlPoint = Math.sqrt(		            Math.pow(leftContX - plotX, 2) + Math.pow(leftContY - plotY, 2)		        );		        dRControlPoint = Math.sqrt(		            Math.pow(rightContX - plotX, 2) + Math.pow(rightContY - plotY, 2)		        );		        leftContAngle = Math.atan2(leftContY - plotY, leftContX - plotX);		        rightContAngle = Math.atan2(rightContY - plotY, rightContX - plotX);		        jointAngle = (Math.PI / 2) + ((leftContAngle + rightContAngle) / 2);		        // Ensure the right direction, jointAngle should be in the same quadrant		        // as leftContAngle		        if (Math.abs(leftContAngle - jointAngle) > Math.PI / 2) {		            jointAngle -= Math.PI;		        }		        // Find the corrected control points for a spline straight through the		        // point		        leftContX = plotX + Math.cos(jointAngle) * dLControlPoint;		        leftContY = plotY + Math.sin(jointAngle) * dLControlPoint;		        rightContX = plotX + Math.cos(Math.PI + jointAngle) * dRControlPoint;		        rightContY = plotY + Math.sin(Math.PI + jointAngle) * dRControlPoint;		        // push current point's connectors into returned object		        ret = {		            rightContX: rightContX,		            rightContY: rightContY,		            leftContX: leftContX,		            leftContY: leftContY,		            plotX: plotX,		            plotY: plotY		        };		        // calculate connectors for previous and next point and push them inside		        // returned object		        if (calculateNeighbours) {		            ret.prevPointCont = this.getConnectors(		                segment,		                prevPointInd,		                false,		                connectEnds		            );		        }		        return ret;		    };		    /**		     * Translate a point's plotX and plotY from the internal angle and radius		     * measures to true plotX, plotY coordinates		     */		    seriesProto.toXY = function (point) {		        var xy,		            chart = this.chart,		            plotX = point.plotX,		            plotY = point.plotY,		            clientX;		        // Save rectangular plotX, plotY for later computation		        point.rectPlotX = plotX;		        point.rectPlotY = plotY;		        // Find the polar plotX and plotY		        xy = this.xAxis.postTranslate(point.plotX, this.yAxis.len - plotY);		        point.plotX = point.polarPlotX = xy.x - chart.plotLeft;		        point.plotY = point.polarPlotY = xy.y - chart.plotTop;		        // If shared tooltip, record the angle in degrees in order to align X		        // points. Otherwise, use a standard k-d tree to get the nearest point		        // in two dimensions.		        if (this.kdByAngle) {		            clientX = (		                (plotX / Math.PI * 180) + this.xAxis.pane.options.startAngle		            ) % 360;		            if (clientX < 0) { // #2665		                clientX += 360;		            }		            point.clientX = clientX;		        } else {		            point.clientX = point.plotX;		        }		    };		    if (seriesTypes.spline) {		        /**		         * Overridden method for calculating a spline from one point to the next		         */		        wrap(		            seriesTypes.spline.prototype,		            'getPointSpline',		            function (proceed, segment, point, i) {		                var ret,		                    connectors;		                if (this.chart.polar) {		                    // moveTo or lineTo		                    if (!i) {		                        ret = ['M', point.plotX, point.plotY];		                    } else { // curve from last point to this		                        connectors = this.getConnectors(		                            segment,		                            i,		                            true,		                            this.connectEnds		                        );		                        ret = [		                            'C',		                            connectors.prevPointCont.rightContX,		                            connectors.prevPointCont.rightContY,		                            connectors.leftContX,		                            connectors.leftContY,		                            connectors.plotX,		                            connectors.plotY		                        ];		                    }		                } else {		                    ret = proceed.call(this, segment, point, i);		                }		                return ret;		            }		        );		        // #6430 Areasplinerange series use unwrapped getPointSpline method, so		        // we need to set this method again.		        if (seriesTypes.areasplinerange) {		            seriesTypes.areasplinerange.prototype.getPointSpline =		                seriesTypes.spline.prototype.getPointSpline;		        }		    }		    /**		     * Extend translate. The plotX and plotY values are computed as if the polar		     * chart were a cartesian plane, where plotX denotes the angle in radians		     * and (yAxis.len - plotY) is the pixel distance from center.		     */		    H.addEvent(Series, 'afterTranslate', function () {		        var chart = this.chart,		            points,		            i;		        if (chart.polar) {		            // Prepare k-d-tree handling. It searches by angle (clientX) in		            // case of shared tooltip, and by two dimensional distance in case		            // of non-shared.		            this.kdByAngle = chart.tooltip && chart.tooltip.shared;		            if (this.kdByAngle) {		                this.searchPoint = this.searchPointByAngle;		            } else {		                this.options.findNearestPointBy = 'xy';		            }		            // Postprocess plot coordinates		            if (!this.preventPostTranslate) {		                points = this.points;		                i = points.length;		                while (i--) {		                    // Translate plotX, plotY from angle and radius to true plot		                    // coordinates		                    this.toXY(points[i]);		                }		            }		            // Perform clip after render		            if (!this.hasClipCircleSetter) {		                this.hasClipCircleSetter = Boolean(		                    H.addEvent(this, 'afterRender', function () {		                        var circ;		                        if (chart.polar) {		                            circ = this.yAxis.center;		                            this.group.clip(		                                chart.renderer.clipCircle(		                                    circ[0],		                                    circ[1],		                                    circ[2] / 2		                                )		                            );		                            this.setClip = H.noop;		                        }		                    })		                );		            }		        }		    }, { order: 2 }); // Run after translation of ||-coords		    /**		     * Extend getSegmentPath to allow connecting ends across 0 to provide a		     * closed circle in line-like series.		     */		    wrap(seriesProto, 'getGraphPath', function (proceed, points) {		        var series = this,		            i,		            firstValid,		            popLastPoint;		        // Connect the path		        if (this.chart.polar) {		            points = points || this.points;		            // Append first valid point in order to connect the ends		            for (i = 0; i < points.length; i++) {		                if (!points[i].isNull) {		                    firstValid = i;		                    break;		                }		            }		            /**		             * Polar charts only. Whether to connect the ends of a line series		             * plot across the extremes.		             *		             * @sample {highcharts} highcharts/plotoptions/line-connectends-false/		             *         Do not connect		             *		             * @type      {boolean}		             * @since     2.3.0		             * @product   highcharts		             * @apioption plotOptions.series.connectEnds		             */		            if (this.options.connectEnds !== false &&		                firstValid !== undefined		            ) {		                this.connectEnds = true; // re-used in splines		                points.splice(points.length, 0, points[firstValid]);		                popLastPoint = true;		            }		            // For area charts, pseudo points are added to the graph, now we		            // need to translate these		            points.forEach(function (point) {		                if (point.polarPlotY === undefined) {		                    series.toXY(point);		                }		            });		        }		        // Run uber method		        var ret = proceed.apply(this, [].slice.call(arguments, 1));		        // #6212 points.splice method is adding points to an array. In case of		        // areaspline getGraphPath method is used two times and in both times		        // points are added to an array. That is why points.pop is used, to get		        // unmodified points.		        if (popLastPoint) {		            points.pop();		        }		        return ret;		    });		    var polarAnimate = function (proceed, init) {		        var chart = this.chart,		            animation = this.options.animation,		            group = this.group,		            markerGroup = this.markerGroup,		            center = this.xAxis.center,		            plotLeft = chart.plotLeft,		            plotTop = chart.plotTop,		            attribs;		        // Specific animation for polar charts		        if (chart.polar) {		            // Enable animation on polar charts only in SVG. In VML, the scaling		            // is different, plus animation would be so slow it would't matter.		            if (chart.renderer.isSVG) {		                if (animation === true) {		                    animation = {};		                }		                // Initialize the animation		                if (init) {		                    // Scale down the group and place it in the center		                    attribs = {		                        translateX: center[0] + plotLeft,		                        translateY: center[1] + plotTop,		                        scaleX: 0.001, // #1499		                        scaleY: 0.001		                    };		                    group.attr(attribs);		                    if (markerGroup) {		                        markerGroup.attr(attribs);		                    }		                // Run the animation		                } else {		                    attribs = {		                        translateX: plotLeft,		                        translateY: plotTop,		                        scaleX: 1,		                        scaleY: 1		                    };		                    group.animate(attribs, animation);		                    if (markerGroup) {		                        markerGroup.animate(attribs, animation);		                    }		                    // Delete this function to allow it only once		                    this.animate = null;		                }		            }		        // For non-polar charts, revert to the basic animation		        } else {		            proceed.call(this, init);		        }		    };		    // Define the animate method for regular series		    wrap(seriesProto, 'animate', polarAnimate);		    if (seriesTypes.column) {		        colProto = seriesTypes.column.prototype;		        colProto.polarArc = function (low, high, start, end) {		            var center = this.xAxis.center,		                len = this.yAxis.len;		            return this.chart.renderer.symbols.arc(		                center[0],		                center[1],		                len - high,		                null,		                {		                    start: start,		                    end: end,		                    innerR: len - pick(low, len)		                }		            );		        };		        /**		        * Define the animate method for columnseries		        */		        wrap(colProto, 'animate', polarAnimate);		        /**		         * Extend the column prototype's translate method		         */		        wrap(colProto, 'translate', function (proceed) {		            var xAxis = this.xAxis,		                startAngleRad = xAxis.startAngleRad,		                start,		                points,		                point,		                i;		            this.preventPostTranslate = true;		            // Run uber method		            proceed.call(this);		            // Postprocess plot coordinates		            if (xAxis.isRadial) {		                points = this.points;		                i = points.length;		                while (i--) {		                    point = points[i];		                    start = point.barX + startAngleRad;		                    point.shapeType = 'path';		                    point.shapeArgs = {		                        d: this.polarArc(		                            point.yBottom,		                            point.plotY,		                            start,		                            start + point.pointWidth		                        )		                    };		                    // Provide correct plotX, plotY for tooltip		                    this.toXY(point);		                    point.tooltipPos = [point.plotX, point.plotY];		                    point.ttBelow = point.plotY > xAxis.center[1];		                }		            }		        });		        /**		         * Align column data labels outside the columns. #1199.		         */		        wrap(colProto, 'alignDataLabel', function (		            proceed,		            point,		            dataLabel,		            options,		            alignTo,		            isNew		        ) {		            if (this.chart.polar) {		                var angle = point.rectPlotX / Math.PI * 180,		                    align,		                    verticalAlign;		                // Align nicely outside the perimeter of the columns		                if (options.align === null) {		                    if (angle > 20 && angle < 160) {		                        align = 'left'; // right hemisphere		                    } else if (angle > 200 && angle < 340) {		                        align = 'right'; // left hemisphere		                    } else {		                        align = 'center'; // top or bottom		                    }		                    options.align = align;		                }		                if (options.verticalAlign === null) {		                    if (angle < 45 || angle > 315) {		                        verticalAlign = 'bottom'; // top part		                    } else if (angle > 135 && angle < 225) {		                        verticalAlign = 'top'; // bottom part		                    } else {		                        verticalAlign = 'middle'; // left or right		                    }		                    options.verticalAlign = verticalAlign;		                }		                seriesProto.alignDataLabel.call(		                    this,		                    point,		                    dataLabel,		                    options,		                    alignTo,		                    isNew		                );		            } else {		                proceed.call(this, point, dataLabel, options, alignTo, isNew);		            }		        });		    }		    /**		     * Extend getCoordinates to prepare for polar axis values		     */		    wrap(pointerProto, 'getCoordinates', function (proceed, e) {		        var chart = this.chart,		            ret = {		                xAxis: [],		                yAxis: []		            };		        if (chart.polar) {		            chart.axes.forEach(function (axis) {		                var isXAxis = axis.isXAxis,		                    center = axis.center,		                    x = e.chartX - center[0] - chart.plotLeft,		                    y = e.chartY - center[1] - chart.plotTop;		                ret[isXAxis ? 'xAxis' : 'yAxis'].push({		                    axis: axis,		                    value: axis.translate(		                        isXAxis ?		                            Math.PI - Math.atan2(x, y) : // angle		                            // distance from center		                            Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)),		                        true		                    )		                });		            });		        } else {		            ret = proceed.call(this, e);		        }		        return ret;		    });		    H.SVGRenderer.prototype.clipCircle = function (x, y, r) {		        var wrapper,		            id = H.uniqueKey(),		            clipPath = this.createElement('clipPath').attr({		                id: id		            }).add(this.defs);		        wrapper = this.circle(x, y, r).add(clipPath);		        wrapper.id = id;		        wrapper.clipPath = clipPath;		        return wrapper;		    };		    H.addEvent(H.Chart, 'getAxes', function () {		        if (!this.pane) {		            this.pane = [];		        }		        H.splat(this.options.pane).forEach(function (paneOptions) {		            new H.Pane( // eslint-disable-line no-new		                paneOptions,		                this		            );		        }, this);		    });		    H.addEvent(H.Chart, 'afterDrawChartBox', function () {		        this.pane.forEach(function (pane) {		            pane.render();		        });		    });		    /**		     * Extend chart.get to also search in panes. Used internally in		     * responsiveness and chart.update.		     */		    wrap(H.Chart.prototype, 'get', function (proceed, id) {		        return H.find(this.pane, function (pane) {		            return pane.options.id === id;		        }) || proceed.call(this, id);		    });		}	}(Highcharts));	return (function () {	}());}));
 |