1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668 |
- ;(function() {
-
-
-
-
- var canvasAvailable = !!document.createElement('canvas').getContext,
- svgAvailable = !!window.SVGAngle || document.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1"),
-
- vmlAvailable = !(canvasAvailable | svgAvailable);
-
- var _findWithFunction = function(a, f) {
- if (a)
- for (var i = 0; i < a.length; i++) if (f(a[i])) return i;
- return -1;
- },
- _indexOf = function(l, v) {
- return _findWithFunction(l, function(_v) { return _v == v; });
- },
- _removeWithFunction = function(a, f) {
- var idx = _findWithFunction(a, f);
- if (idx > -1) a.splice(idx, 1);
- return idx != -1;
- },
- _remove = function(l, v) {
- var idx = _indexOf(l, v);
- if (idx > -1) l.splice(idx, 1);
- return idx != -1;
- },
-
- _addWithFunction = function(list, item, hashFunction) {
- if (_findWithFunction(list, hashFunction) == -1) list.push(item);
- },
- _addToList = function(map, key, value) {
- var l = map[key];
- if (l == null) {
- l = [], map[key] = l;
- }
- l.push(value);
- return l;
- };
-
-
- if (!window.console)
- window.console = { time:function(){}, timeEnd:function(){}, group:function(){}, groupEnd:function(){}, log:function(){} };
-
-
- var _connectionBeingDragged = null,
- _getAttribute = function(el, attName) { return jsPlumb.CurrentLibrary.getAttribute(_getElementObject(el), attName); },
- _setAttribute = function(el, attName, attValue) { jsPlumb.CurrentLibrary.setAttribute(_getElementObject(el), attName, attValue); },
- _addClass = function(el, clazz) { jsPlumb.CurrentLibrary.addClass(_getElementObject(el), clazz); },
- _hasClass = function(el, clazz) { return jsPlumb.CurrentLibrary.hasClass(_getElementObject(el), clazz); },
- _removeClass = function(el, clazz) { jsPlumb.CurrentLibrary.removeClass(_getElementObject(el), clazz); },
- _getElementObject = function(el) { return jsPlumb.CurrentLibrary.getElementObject(el); },
- _getOffset = function(el) { return jsPlumb.CurrentLibrary.getOffset(_getElementObject(el)); },
- _getSize = function(el) { return jsPlumb.CurrentLibrary.getSize(_getElementObject(el)); },
- _logEnabled = true,
- _log = function() {
- if (_logEnabled && typeof console != "undefined") {
- try {
- var msg = arguments[arguments.length - 1];
- console.log(msg);
- }
- catch (e) {}
- }
- },
- _group = function(g) { if (_logEnabled && typeof console != "undefined") console.group(g); },
- _groupEnd = function(g) { if (_logEnabled && typeof console != "undefined") console.groupEnd(g); },
- _time = function(t) { if (_logEnabled && typeof console != "undefined") console.time(t); },
- _timeEnd = function(t) { if (_logEnabled && typeof console != "undefined") console.timeEnd(t); };
-
-
- EventGenerator = function() {
- var _listeners = {}, self = this;
-
-
-
-
-
-
- var eventsToDieOn = [ "ready" ];
-
-
- this.bind = function(event, listener) {
- _addToList(_listeners, event, listener);
- };
-
-
- this.fire = function(event, value, originalEvent) {
- if (_listeners[event]) {
- for ( var i = 0; i < _listeners[event].length; i++) {
-
-
-
- if (_findWithFunction(eventsToDieOn, function(e) { return e === event}) != -1)
- _listeners[event][i](value, originalEvent);
- else {
-
- try {
- _listeners[event][i](value, originalEvent);
- } catch (e) {
- _log("jsPlumb: fire failed for event " + event + " : " + e);
- }
- }
- }
- }
- };
-
- this.clearListeners = function(event) {
- if (event)
- delete _listeners[event];
- else {
- delete _listeners;
- _listeners = {};
- }
- };
-
- this.getListener = function(forEvent) {
- return _listeners[forEvent];
- };
- },
-
-
- _timestamp = function() { return "" + (new Date()).getTime(); },
-
-
- jsPlumbUIComponent = function(params) {
- var self = this, a = arguments, _hover = false, parameters = params.parameters || {}, idPrefix = self.idPrefix,
- id = idPrefix + (new Date()).getTime();
- self._jsPlumb = params["_jsPlumb"];
- self.getId = function() { return id; };
- self.tooltip = params.tooltip;
- self.hoverClass = params.hoverClass;
-
-
- EventGenerator.apply(this);
-
-
-
-
-
-
- this.clone = function() {
- var o = new Object();
- self.constructor.apply(o, a);
- return o;
- };
-
- this.getParameter = function(name) { return parameters[name]; },
- this.getParameters = function() { return parameters; },
- this.setParameter = function(name, value) { parameters[name] = value; },
- this.setParameters = function(p) { parameters = p; },
- this.overlayPlacements = [],
- this.paintStyle = null,
- this.hoverPaintStyle = null;
-
-
-
- var beforeDetach = params.beforeDetach;
- this.isDetachAllowed = function(connection) {
- var r = self._jsPlumb.checkCondition("beforeDetach", connection );
- if (beforeDetach) {
- try {
- r = beforeDetach(connection);
- }
- catch (e) { _log("jsPlumb: beforeDetach callback failed", e); }
- }
- return r;
- };
-
-
-
- var beforeDrop = params.beforeDrop;
- this.isDropAllowed = function(sourceId, targetId, scope) {
- var r = self._jsPlumb.checkCondition("beforeDrop", { sourceId:sourceId, targetId:targetId, scope:scope });
- if (beforeDrop) {
- try {
- r = beforeDrop({ sourceId:sourceId, targetId:targetId, scope:scope });
- }
- catch (e) { _log("jsPlumb: beforeDrop callback failed", e); }
- }
- return r;
- };
-
-
-
-
- var _updateHoverStyle = function() {
- if (self.paintStyle && self.hoverPaintStyle) {
- var mergedHoverStyle = {};
- jsPlumb.extend(mergedHoverStyle, self.paintStyle);
- jsPlumb.extend(mergedHoverStyle, self.hoverPaintStyle);
- delete self["hoverPaintStyle"];
-
- if (mergedHoverStyle.gradient && self.paintStyle.fillStyle)
- delete mergedHoverStyle["gradient"];
- self.hoverPaintStyle = mergedHoverStyle;
- }
- };
-
-
- this.setPaintStyle = function(style, doNotRepaint) {
- self.paintStyle = style;
- self.paintStyleInUse = self.paintStyle;
- _updateHoverStyle();
- if (!doNotRepaint) self.repaint();
- };
-
-
- this.setHoverPaintStyle = function(style, doNotRepaint) {
- self.hoverPaintStyle = style;
- _updateHoverStyle();
- if (!doNotRepaint) self.repaint();
- };
-
-
- this.setHover = function(hover, ignoreAttachedElements, timestamp) {
-
-
- if (!self._jsPlumb.currentlyDragging && !self._jsPlumb.isHoverSuspended()) {
-
- _hover = hover;
- if (self.hoverClass != null && self.canvas != null) {
- if (hover)
- jpcl.addClass(self.canvas, self.hoverClass);
- else
- jpcl.removeClass(self.canvas, self.hoverClass);
- }
- if (self.hoverPaintStyle != null) {
- self.paintStyleInUse = hover ? self.hoverPaintStyle : self.paintStyle;
- timestamp = timestamp || _timestamp();
- self.repaint({timestamp:timestamp, recalc:false});
- }
-
-
- if (self.getAttachedElements && !ignoreAttachedElements)
- _updateAttachedElements(hover, _timestamp(), self);
- }
- };
-
- this.isHover = function() { return _hover; };
- var jpcl = jsPlumb.CurrentLibrary,
- events = [ "click", "dblclick", "mouseenter", "mouseout", "mousemove", "mousedown", "mouseup", "contextmenu" ],
- eventFilters = { "mouseout":"mouseexit" },
- bindOne = function(o, c, evt) {
- var filteredEvent = eventFilters[evt] || evt;
- jpcl.bind(o, evt, function(ee) {
- c.fire(filteredEvent, c, ee);
- });
- },
- unbindOne = function(o, evt) {
- var filteredEvent = eventFilters[evt] || evt;
- jpcl.unbind(o, evt);
- };
-
- this.attachListeners = function(o, c) {
- for (var i = 0; i < events.length; i++) {
- bindOne(o, c, events[i]);
- }
- };
-
- var _updateAttachedElements = function(state, timestamp, sourceElement) {
- var affectedElements = self.getAttachedElements();
- if (affectedElements) {
- for (var i = 0; i < affectedElements.length; i++) {
- if (!sourceElement || sourceElement != affectedElements[i])
- affectedElements[i].setHover(state, true, timestamp);
- }
- }
- };
-
- this.reattachListenersForElement = function(o) {
- if (arguments.length > 1) {
- for (var i = 0; i < events.length; i++)
- unbindOne(o, events[i]);
- for (var i = 1; i < arguments.length; i++)
- self.attachListeners(o, arguments[i]);
- }
- };
- },
- overlayCapableJsPlumbUIComponent = function(params) {
- jsPlumbUIComponent.apply(this, arguments);
- var self = this;
-
- this.overlays = [];
- var processOverlay = function(o) {
- var _newOverlay = null;
- if (o.constructor == Array) {
-
-
-
- var type = o[0],
-
- p = jsPlumb.extend({component:self, _jsPlumb:self._jsPlumb}, o[1]);
- if (o.length == 3) jsPlumb.extend(p, o[2]);
- _newOverlay = new jsPlumb.Overlays[self._jsPlumb.getRenderMode()][type](p);
- if (p.events) {
- for (var evt in p.events) {
- _newOverlay.bind(evt, p.events[evt]);
- }
- }
- } else if (o.constructor == String) {
- _newOverlay = new jsPlumb.Overlays[self._jsPlumb.getRenderMode()][o]({component:self, _jsPlumb:self._jsPlumb});
- } else {
- _newOverlay = o;
- }
-
- self.overlays.push(_newOverlay);
- },
- calculateOverlaysToAdd = function(params) {
- var defaultKeys = self.defaultOverlayKeys || [],
- o = params.overlays,
- checkKey = function(k) {
- return self._jsPlumb.Defaults[k] || jsPlumb.Defaults[k] || [];
- };
-
- if (!o) o = [];
- for (var i = 0; i < defaultKeys.length; i++)
- o.unshift.apply(o, checkKey(defaultKeys[i]));
-
- return o;
- }
- var _overlays = calculateOverlaysToAdd(params);
- if (_overlays) {
- for (var i = 0; i < _overlays.length; i++) {
- processOverlay(_overlays[i]);
- }
- }
-
- var _getOverlayIndex = function(id) {
- var idx = -1;
- for (var i = 0; i < self.overlays.length; i++) {
- if (id === self.overlays[i].id) {
- idx = i;
- break;
- }
- }
- return idx;
- };
-
-
- this.addOverlay = function(overlay) {
- processOverlay(overlay);
- self.repaint();
- };
-
-
- this.getOverlay = function(id) {
- var idx = _getOverlayIndex(id);
- return idx >= 0 ? self.overlays[idx] : null;
- };
-
- this.getOverlays = function() {
- return self.overlays;
- };
-
-
- this.hideOverlay = function(id) {
- var o = self.getOverlay(id);
- if (o) o.hide();
- };
- this.hideOverlays = function() {
- for (var i = 0; i < self.overlays.length; i++)
- self.overlays[i].hide();
- };
-
-
- this.showOverlay = function(id) {
- var o = self.getOverlay(id);
- if (o) o.show();
- };
- this.showOverlays = function() {
- for (var i = 0; i < self.overlays.length; i++)
- self.overlays[i].show();
- };
-
-
- this.removeAllOverlays = function() {
- self.overlays.splice(0, self.overlays.length);
- self.repaint();
- };
-
-
- this.removeOverlay = function(overlayId) {
- var idx = _getOverlayIndex(overlayId);
- if (idx != -1) {
- var o = self.overlays[idx];
- o.cleanup();
- self.overlays.splice(idx, 1);
- }
- };
-
-
- this.removeOverlays = function() {
- for (var i = 0; i < arguments.length; i++)
- self.removeOverlay(arguments[i]);
- };
-
-
- var _internalLabelOverlayId = "__label",
- _makeLabelOverlay = function(params) {
- var _params = {
- cssClass:params.cssClass,
- labelStyle : this.labelStyle,
- id:_internalLabelOverlayId,
- component:self,
- _jsPlumb:self._jsPlumb
- },
- mergedParams = jsPlumb.extend(_params, params);
- return new jsPlumb.Overlays[self._jsPlumb.getRenderMode()].Label( mergedParams );
- };
- if (params.label) {
- var loc = params.labelLocation || self.defaultLabelLocation || 0.5,
- labelStyle = params.labelStyle || self._jsPlumb.Defaults.LabelStyle || jsPlumb.Defaults.LabelStyle;
- this.overlays.push(_makeLabelOverlay({
- label:params.label,
- location:loc,
- labelStyle:labelStyle
- }));
- }
-
- this.setLabel = function(l) {
- var lo = self.getOverlay(_internalLabelOverlayId);
- if (!lo) {
- var params = l.constructor == String || l.constructor == Function ? { label:l } : l;
- lo = _makeLabelOverlay(params);
- this.overlays.push(lo);
- }
- else {
- if (l.constructor == String || l.constructor == Function) lo.setLabel(l);
- else {
- if (l.label) lo.setLabel(l.label);
- if (l.location) lo.setLocation(l.location);
- }
- }
-
- self.repaint();
- };
-
- this.getLabel = function() {
- var lo = self.getOverlay(_internalLabelOverlayId);
- return lo != null ? lo.getLabel() : null;
- };
-
- this.getLabelOverlay = function() {
- return self.getOverlay(_internalLabelOverlayId);
- }
- },
-
- _bindListeners = function(obj, _self, _hoverFunction) {
- obj.bind("click", function(ep, e) { _self.fire("click", _self, e); });
- obj.bind("dblclick", function(ep, e) { _self.fire("dblclick", _self, e); });
- obj.bind("contextmenu", function(ep, e) { _self.fire("contextmenu", _self, e); });
- obj.bind("mouseenter", function(ep, e) {
- if (!_self.isHover()) {
- _hoverFunction(true);
- _self.fire("mouseenter", _self, e);
- }
- });
- obj.bind("mouseexit", function(ep, e) {
- if (_self.isHover()) {
- _hoverFunction(false);
- _self.fire("mouseexit", _self, e);
- }
- });
- };
-
- var _jsPlumbInstanceIndex = 0,
- getInstanceIndex = function() {
- var i = _jsPlumbInstanceIndex + 1;
- _jsPlumbInstanceIndex++;
- return i;
- };
- var jsPlumbInstance = function(_defaults) {
-
-
- this.Defaults = {
- Anchor : "BottomCenter",
- Anchors : [ null, null ],
- ConnectionsDetachable : true,
- ConnectionOverlays : [ ],
- Connector : "Bezier",
- Container : null,
- DragOptions : { },
- DropOptions : { },
- Endpoint : "Dot",
- EndpointOverlays : [ ],
- Endpoints : [ null, null ],
- EndpointStyle : { fillStyle : "#456" },
- EndpointStyles : [ null, null ],
- EndpointHoverStyle : null,
- EndpointHoverStyles : [ null, null ],
- HoverPaintStyle : null,
- LabelStyle : { color : "black" },
- LogEnabled : false,
- Overlays : [ ],
- MaxConnections : 1,
- PaintStyle : { lineWidth : 8, strokeStyle : "#456" },
-
- RenderMode : "svg",
- Scope : "jsPlumb_DefaultScope"
- };
- if (_defaults) jsPlumb.extend(this.Defaults, _defaults);
-
- this.logEnabled = this.Defaults.LogEnabled;
- EventGenerator.apply(this);
- var _currentInstance = this,
- _instanceIndex = getInstanceIndex(),
- _bb = _currentInstance.bind,
- _initialDefaults = {};
- for (var i in this.Defaults)
- _initialDefaults[i] = this.Defaults[i];
- this.bind = function(event, fn) {
- if ("ready" === event && initialized) fn();
- else _bb.apply(_currentInstance,[event, fn]);
- };
-
- _currentInstance.importDefaults = function(d) {
- for (var i in d) {
- _currentInstance.Defaults[i] = d[i];
- }
- };
-
- _currentInstance.restoreDefaults = function() {
- _currentInstance.Defaults = jsPlumb.extend({}, _initialDefaults);
- };
- var log = null,
- repaintFunction = function() {
- jsPlumb.repaintEverything();
- },
- automaticRepaint = true,
- repaintEverything = function() {
- if (automaticRepaint)
- repaintFunction();
- },
- resizeTimer = null,
- initialized = false,
- connectionsByScope = {},
-
- endpointsByElement = {},
- endpointsByUUID = {},
- offsets = {},
- offsetTimestamps = {},
- floatingConnections = {},
- draggableStates = {},
- canvasList = [],
- sizes = [],
-
- DEFAULT_SCOPE = this.Defaults.Scope,
- renderMode = null,
-
- _addToList = function(map, key, value) {
- var l = map[key];
- if (l == null) {
- l = [];
- map[key] = l;
- }
- l.push(value);
- return l;
- },
-
- _appendElement = function(el, parent) {
- if (_currentInstance.Defaults.Container)
- jsPlumb.CurrentLibrary.appendElement(el, _currentInstance.Defaults.Container);
- else if (!parent)
- document.body.appendChild(el);
- else
- jsPlumb.CurrentLibrary.appendElement(el, parent);
- },
- _curIdStamp = 1,
- _idstamp = function() { return "" + _curIdStamp++; },
-
-
- _convertYUICollection = function(c) {
- return c._nodes ? c._nodes : c;
- },
- _suspendDrawing = false,
-
- _setSuspendDrawing = function(val, repaintAfterwards) {
- _suspendDrawing = val;
- if (repaintAfterwards) _currentInstance.repaintEverything();
- },
-
- _draw = function(element, ui, timestamp) {
- if (!_suspendDrawing) {
- var id = _getAttribute(element, "id"),
- repaintEls = _currentInstance.dragManager.getElementsForDraggable(id);
- if (timestamp == null) timestamp = _timestamp();
- _currentInstance.anchorManager.redraw(id, ui, timestamp);
- if (repaintEls) {
- for (var i in repaintEls) {
- _currentInstance.anchorManager.redraw(repaintEls[i].id, ui, timestamp, repaintEls[i].offset);
- }
- }
- }
- },
-
- _elementProxy = function(element, fn) {
- var retVal = null;
- if (element.constructor == Array) {
- retVal = [];
- for ( var i = 0; i < element.length; i++) {
- var el = _getElementObject(element[i]), id = _getAttribute(el, "id");
- retVal.push(fn(el, id));
- }
- } else {
- var el = _getElementObject(element), id = _getAttribute(el, "id");
- retVal = fn(el, id);
- }
- return retVal;
- },
-
- _getEndpoint = function(uuid) { return endpointsByUUID[uuid]; },
-
- _initDraggableIfNecessary = function(element, isDraggable, dragOptions) {
- var draggable = isDraggable == null ? false : isDraggable,
- jpcl = jsPlumb.CurrentLibrary;
- if (draggable) {
- if (jpcl.isDragSupported(element) && !jpcl.isAlreadyDraggable(element)) {
- var options = dragOptions || _currentInstance.Defaults.DragOptions || jsPlumb.Defaults.DragOptions;
- options = jsPlumb.extend( {}, options);
- var dragEvent = jpcl.dragEvents["drag"],
- stopEvent = jpcl.dragEvents["stop"],
- startEvent = jpcl.dragEvents["start"];
- options[dragEvent] = _wrap(options[dragEvent], function() {
- var ui = jpcl.getUIPosition(arguments);
- _draw(element, ui);
- _addClass(element, "jsPlumb_dragged");
- });
- options[stopEvent] = _wrap(options[stopEvent], function() {
- var ui = jpcl.getUIPosition(arguments);
- _draw(element, ui);
- _removeClass(element, "jsPlumb_dragged");
- });
- draggableStates[_getId(element)] = true;
- var draggable = draggableStates[_getId(element)];
- options.disabled = draggable == null ? false : !draggable;
- jpcl.initDraggable(element, options, false);
- _currentInstance.dragManager.register(element);
- }
- }
- },
-
-
- _prepareConnectionParams = function(params, referenceParams) {
- var _p = jsPlumb.extend( {}, params);
- if (referenceParams) jsPlumb.extend(_p, referenceParams);
-
-
- if (_p.source && _p.source.endpoint) _p.sourceEndpoint = _p.source;
- if (_p.source && _p.target.endpoint) _p.targetEndpoint = _p.target;
-
-
- if (params.uuids) {
- _p.sourceEndpoint = _getEndpoint(params.uuids[0]);
- _p.targetEndpoint = _getEndpoint(params.uuids[1]);
- }
-
-
- if (_p.sourceEndpoint && _p.sourceEndpoint.isFull()) {
- _log(_currentInstance, "could not add connection; source endpoint is full");
- return;
- }
-
- if (_p.targetEndpoint && _p.targetEndpoint.isFull()) {
- _log(_currentInstance, "could not add connection; target endpoint is full");
- return;
- }
-
-
-
- if (_p.sourceEndpoint && _p.sourceEndpoint.connectorOverlays) {
- _p.overlays = _p.overlays || [];
- for (var i = 0; i < _p.sourceEndpoint.connectorOverlays.length; i++) {
- _p.overlays.push(_p.sourceEndpoint.connectorOverlays[i]);
- }
- }
-
-
- _p.tooltip = params.tooltip;
- if (!_p.tooltip && _p.sourceEndpoint && _p.sourceEndpoint.connectorTooltip)
- _p.tooltip = _p.sourceEndpoint.connectorTooltip;
-
-
-
-
-
-
- if (_p.target && !_p.target.endpoint && !_p.targetEndpoint && !_p.newConnection) {
- var tid = _getId(_p.target),
- tep =_targetEndpointDefinitions[tid],
- existingUniqueEndpoint = _targetEndpoints[tid];
- if (tep) {
-
- var newEndpoint = existingUniqueEndpoint != null ? existingUniqueEndpoint : _currentInstance.addEndpoint(_p.target, tep);
- if (_targetEndpointsUnique[tid]) _targetEndpoints[tid] = newEndpoint;
- _p.targetEndpoint = newEndpoint;
- }
- }
-
- if (_p.source && !_p.source.endpoint && !_p.sourceEndpoint && !_p.newConnection) {
- var tid = _getId(_p.source),
- tep = _sourceEndpointDefinitions[tid],
- existingUniqueEndpoint = _sourceEndpoints[tid];
- if (tep) {
-
- var newEndpoint = existingUniqueEndpoint != null ? existingUniqueEndpoint : _currentInstance.addEndpoint(_p.source, tep);
- if (_sourceEndpointsUnique[tid]) _sourceEndpoints[tid] = newEndpoint;
- _p.sourceEndpoint = newEndpoint;
- }
- }
-
- return _p;
- },
-
- _newConnection = function(params) {
- var connectionFunc = _currentInstance.Defaults.ConnectionType || _currentInstance.getDefaultConnectionType(),
- endpointFunc = _currentInstance.Defaults.EndpointType || Endpoint,
- parent = jsPlumb.CurrentLibrary.getParent;
-
- if (params.container)
- params["parent"] = params.container;
- else {
- if (params.sourceEndpoint)
- params["parent"] = params.sourceEndpoint.parent;
- else if (params.source.constructor == endpointFunc)
- params["parent"] = params.source.parent;
- else params["parent"] = parent(params.source);
- }
-
- params["_jsPlumb"] = _currentInstance;
- var con = new connectionFunc(params);
- con.id = "con_" + _idstamp();
- _eventFireProxy("click", "click", con);
- _eventFireProxy("dblclick", "dblclick", con);
- _eventFireProxy("contextmenu", "contextmenu", con);
- return con;
- },
-
-
- _finaliseConnection = function(jpc, params, originalEvent) {
- params = params || {};
-
- if (!jpc.suspendedEndpoint)
- _addToList(connectionsByScope, jpc.scope, jpc);
-
- if (!params.doNotFireConnectionEvent && params.fireEvent !== false) {
- _currentInstance.fire("jsPlumbConnection", {
- connection:jpc,
- source : jpc.source, target : jpc.target,
- sourceId : jpc.sourceId, targetId : jpc.targetId,
- sourceEndpoint : jpc.endpoints[0], targetEndpoint : jpc.endpoints[1]
- }, originalEvent);
- }
-
-
-
-
- _currentInstance.anchorManager.newConnection(jpc);
-
- _draw(jpc.source);
- },
-
- _eventFireProxy = function(event, proxyEvent, obj) {
- obj.bind(event, function(originalObject, originalEvent) {
- _currentInstance.fire(proxyEvent, obj, originalEvent);
- });
- },
-
-
- _getParentFromParams = function(params) {
- if (params.container)
- return params.container;
- else {
- var tag = jsPlumb.CurrentLibrary.getTagName(params.source),
- p = jsPlumb.CurrentLibrary.getParent(params.source);
- if (tag && tag.toLowerCase() === "td")
- return jsPlumb.CurrentLibrary.getParent(p);
- else return p;
- }
- },
-
-
- _newEndpoint = function(params) {
- var endpointFunc = _currentInstance.Defaults.EndpointType || Endpoint;
- params.parent = _getParentFromParams(params);
- params["_jsPlumb"] = _currentInstance;
- var ep = new endpointFunc(params);
- ep.id = "ep_" + _idstamp();
- _eventFireProxy("click", "endpointClick", ep);
- _eventFireProxy("dblclick", "endpointDblClick", ep);
- _eventFireProxy("contextmenu", "contextmenu", ep);
- return ep;
- },
-
-
- _operation = function(elId, func, endpointFunc) {
- var endpoints = endpointsByElement[elId];
- if (endpoints && endpoints.length) {
- for ( var i = 0; i < endpoints.length; i++) {
- for ( var j = 0; j < endpoints[i].connections.length; j++) {
- var retVal = func(endpoints[i].connections[j]);
-
-
- if (retVal) return;
- }
- if (endpointFunc) endpointFunc(endpoints[i]);
- }
- }
- },
-
- _operationOnAll = function(func) {
- for ( var elId in endpointsByElement) {
- _operation(elId, func);
- }
- },
-
-
- _removeElement = function(element, parent) {
- if (element != null && element.parentNode != null) {
- element.parentNode.removeChild(element);
- }
- },
-
- _removeElements = function(elements, parent) {
- for ( var i = 0; i < elements.length; i++)
- _removeElement(elements[i], parent);
- },
-
- _setDraggable = function(element, draggable) {
- return _elementProxy(element, function(el, id) {
- draggableStates[id] = draggable;
- if (jsPlumb.CurrentLibrary.isDragSupported(el)) {
- jsPlumb.CurrentLibrary.setDraggable(el, draggable);
- }
- });
- },
-
- _setVisible = function(el, state, alsoChangeEndpoints) {
- state = state === "block";
- var endpointFunc = null;
- if (alsoChangeEndpoints) {
- if (state) endpointFunc = function(ep) {
- ep.setVisible(true, true, true);
- };
- else endpointFunc = function(ep) {
- ep.setVisible(false, true, true);
- };
- }
- var id = _getAttribute(el, "id");
- _operation(id, function(jpc) {
- if (state && alsoChangeEndpoints) {
-
-
- var oidx = jpc.sourceId === id ? 1 : 0;
- if (jpc.endpoints[oidx].isVisible()) jpc.setVisible(true);
- }
- else
- jpc.setVisible(state);
- }, endpointFunc);
- },
-
- _toggleDraggable = function(el) {
- return _elementProxy(el, function(el, elId) {
- var state = draggableStates[elId] == null ? false : draggableStates[elId];
- state = !state;
- draggableStates[elId] = state;
- jsPlumb.CurrentLibrary.setDraggable(el, state);
- return state;
- });
- },
-
- _toggleVisible = function(elId, changeEndpoints) {
- var endpointFunc = null;
- if (changeEndpoints) {
- endpointFunc = function(ep) {
- var state = ep.isVisible();
- ep.setVisible(!state);
- };
- }
- _operation(elId, function(jpc) {
- var state = jpc.isVisible();
- jpc.setVisible(!state);
- }, endpointFunc);
-
-
-
- },
-
- _updateOffset = function(params) {
- var timestamp = params.timestamp, recalc = params.recalc, offset = params.offset, elId = params.elId;
- if (!recalc) {
- if (timestamp && timestamp === offsetTimestamps[elId])
- return offsets[elId];
- }
- if (recalc || !offset) {
-
-
- var s = _getElementObject(elId);
- if (s != null) {
- sizes[elId] = _getSize(s);
- offsets[elId] = _getOffset(s);
- offsetTimestamps[elId] = timestamp;
- }
- } else {
- offsets[elId] = offset;
- if (sizes[elId] == null) {
- var s = _getElementObject(elId);
- if (s != null)
- sizes[elId] = _getSize(s);
- }
- }
-
- if(offsets[elId] && !offsets[elId].right) {
- offsets[elId].right = offsets[elId].left + sizes[elId][0];
- offsets[elId].bottom = offsets[elId].top + sizes[elId][1];
- offsets[elId].width = sizes[elId][0];
- offsets[elId].height = sizes[elId][1];
- offsets[elId].centerx = offsets[elId].left + (offsets[elId].width / 2);
- offsets[elId].centery = offsets[elId].top + (offsets[elId].height / 2);
- }
- return offsets[elId];
- },
-
- _getCachedData = function(elId) {
- var o = offsets[elId];
- if (!o) o = _updateOffset({elId:elId});
- return {o:o, s:sizes[elId]};
- },
-
- _getId = function(element, uuid) {
- var ele = _getElementObject(element);
- var id = _getAttribute(ele, "id");
- if (!id || id == "undefined") {
-
- if (arguments.length == 2 && arguments[1] != undefined)
- id = uuid;
- else
- id = "jsPlumb_" + _instanceIndex + "_" + _idstamp();
- _setAttribute(ele, "id", id);
- }
- return id;
- },
-
- _wrap = function(wrappedFunction, newFunction, returnOnThisValue) {
- wrappedFunction = wrappedFunction || function() { };
- newFunction = newFunction || function() { };
- return function() {
- var r = null;
- try {
- r = newFunction.apply(this, arguments);
- } catch (e) {
- _log(_currentInstance, "jsPlumb function failed : " + e);
- }
- if (returnOnThisValue == null || (r !== returnOnThisValue)) {
- try {
- wrappedFunction.apply(this, arguments);
- } catch (e) {
- _log(_currentInstance, "wrapped function failed : " + e);
- }
- }
- return r;
- };
- };
-
- this.connectorClass = "_jsPlumb_connector";
-
- this.endpointClass = "_jsPlumb_endpoint";
-
- this.overlayClass = "_jsPlumb_overlay";
-
- this.Anchors = {};
-
- this.Connectors = {
- "canvas":{},
- "svg":{},
- "vml":{}
- };
- this.Endpoints = {
- "canvas":{},
- "svg":{},
- "vml":{}
- };
- this.Overlays = {
- "canvas":{},
- "svg":{},
- "vml":{}
- };
-
-
-
-
-
-
-
-
- this.addClass = function(el, clazz) {
- return jsPlumb.CurrentLibrary.addClass(el, clazz);
- };
-
-
- this.removeClass = function(el, clazz) {
- return jsPlumb.CurrentLibrary.removeClass(el, clazz);
- };
-
-
- this.hasClass = function(el, clazz) {
- return jsPlumb.CurrentLibrary.hasClass(el, clazz);
- };
-
-
- this.addEndpoint = function(el, params, referenceParams) {
- referenceParams = referenceParams || {};
- var p = jsPlumb.extend({}, referenceParams);
- jsPlumb.extend(p, params);
- p.endpoint = p.endpoint || _currentInstance.Defaults.Endpoint || jsPlumb.Defaults.Endpoint;
- p.paintStyle = p.paintStyle || _currentInstance.Defaults.EndpointStyle || jsPlumb.Defaults.EndpointStyle;
-
- el = _convertYUICollection(el);
-
- var results = [], inputs = el.length && el.constructor != String ? el : [ el ];
-
- for (var i = 0; i < inputs.length; i++) {
- var _el = _getElementObject(inputs[i]), id = _getId(_el);
- p.source = _el;
- _updateOffset({ elId : id });
- var e = _newEndpoint(p);
- if (p.parentAnchor) e.parentAnchor = p.parentAnchor;
- _addToList(endpointsByElement, id, e);
- var myOffset = offsets[id], myWH = sizes[id];
- var anchorLoc = e.anchor.compute( { xy : [ myOffset.left, myOffset.top ], wh : myWH, element : e });
- e.paint({ anchorLoc : anchorLoc });
- results.push(e);
- _currentInstance.dragManager.endpointAdded(_el);
- }
-
- return results.length == 1 ? results[0] : results;
- };
-
-
- this.addEndpoints = function(el, endpoints, referenceParams) {
- var results = [];
- for ( var i = 0; i < endpoints.length; i++) {
- var e = _currentInstance.addEndpoint(el, endpoints[i], referenceParams);
- if (e.constructor == Array)
- Array.prototype.push.apply(results, e);
- else results.push(e);
- }
- return results;
- };
-
- this.animate = function(el, properties, options) {
- var ele = _getElementObject(el), id = _getAttribute(el, "id");
- options = options || {};
- var stepFunction = jsPlumb.CurrentLibrary.dragEvents['step'];
- var completeFunction = jsPlumb.CurrentLibrary.dragEvents['complete'];
- options[stepFunction] = _wrap(options[stepFunction], function() {
- _currentInstance.repaint(id);
- });
-
- options[completeFunction] = _wrap(options[completeFunction],
- function() {
- _currentInstance.repaint(id);
- });
- jsPlumb.CurrentLibrary.animate(ele, properties, options);
- };
-
-
- this.checkCondition = function(conditionName, value) {
- var l = _currentInstance.getListener(conditionName);
- var r = true;
- if (l && l.length > 0) {
- try {
- for (var i = 0 ; i < l.length; i++) {
- r = r && l[i](value);
- }
- }
- catch (e) {
- _log(_currentInstance, "cannot check condition [" + conditionName + "]" + e);
- }
- }
- return r;
- };
-
- this.connect = function(params, referenceParams) {
-
- var _p = _prepareConnectionParams(params, referenceParams);
-
-
-
- if (_p) {
-
-
-
- if (_p.deleteEndpointsOnDetach == null)
- _p.deleteEndpointsOnDetach = true;
-
- var jpc = _newConnection(_p);
-
- _finaliseConnection(jpc, _p);
- return jpc;
- }
- };
-
-
- this.deleteEndpoint = function(object) {
- var endpoint = (typeof object == "string") ? endpointsByUUID[object] : object;
- if (endpoint) {
- var uuid = endpoint.getUuid();
- if (uuid) endpointsByUUID[uuid] = null;
- endpoint.detachAll();
- _removeElements(endpoint.endpoint.getDisplayElements());
- _currentInstance.anchorManager.deleteEndpoint(endpoint);
- for (var e in endpointsByElement) {
- var endpoints = endpointsByElement[e];
- if (endpoints) {
- var newEndpoints = [];
- for (var i = 0; i < endpoints.length; i++)
- if (endpoints[i] != endpoint) newEndpoints.push(endpoints[i]);
-
- endpointsByElement[e] = newEndpoints;
- }
- }
- _currentInstance.dragManager.endpointDeleted(endpoint);
- }
- };
-
-
- this.deleteEveryEndpoint = function() {
- for ( var id in endpointsByElement) {
- var endpoints = endpointsByElement[id];
- if (endpoints && endpoints.length) {
- for ( var i = 0; i < endpoints.length; i++) {
- _currentInstance.deleteEndpoint(endpoints[i]);
- }
- }
- }
- delete endpointsByElement;
- endpointsByElement = {};
- delete endpointsByUUID;
- endpointsByUUID = {};
- };
- var fireDetachEvent = function(jpc, doFireEvent, originalEvent) {
-
- var connType = _currentInstance.Defaults.ConnectionType || _currentInstance.getDefaultConnectionType(),
- argIsConnection = jpc.constructor == connType,
- params = argIsConnection ? {
- connection:jpc,
- source : jpc.source, target : jpc.target,
- sourceId : jpc.sourceId, targetId : jpc.targetId,
- sourceEndpoint : jpc.endpoints[0], targetEndpoint : jpc.endpoints[1]
- } : jpc;
- if (doFireEvent) _currentInstance.fire("jsPlumbConnectionDetached", params, originalEvent);
- _currentInstance.anchorManager.connectionDetached(params);
- },
-
- fireConnectionDraggingEvent = function(jpc) {
- _currentInstance.fire("connectionDrag", jpc);
- },
- fireConnectionDragStopEvent = function(jpc) {
- _currentInstance.fire("connectionDragStop", jpc);
- };
-
- this.detach = function() {
- if (arguments.length == 0) return;
- var connType = _currentInstance.Defaults.ConnectionType || _currentInstance.getDefaultConnectionType(),
- firstArgIsConnection = arguments[0].constructor == connType,
- params = arguments.length == 2 ? firstArgIsConnection ? (arguments[1] || {}) : arguments[0] : arguments[0],
- fireEvent = (params.fireEvent !== false),
- forceDetach = params.forceDetach,
- connection = firstArgIsConnection ? arguments[0] : params.connection;
- if (connection) {
- if (forceDetach || (connection.isDetachAllowed(connection)
- && connection.endpoints[0].isDetachAllowed(connection)
- && connection.endpoints[1].isDetachAllowed(connection))) {
- if (forceDetach || _currentInstance.checkCondition("beforeDetach", connection))
- connection.endpoints[0].detach(connection, false, true, fireEvent);
- }
- }
- else {
- var _p = jsPlumb.extend( {}, params);
-
- if (_p.uuids) {
- _getEndpoint(_p.uuids[0]).detachFrom(_getEndpoint(_p.uuids[1]), fireEvent);
- } else if (_p.sourceEndpoint && _p.targetEndpoint) {
- _p.sourceEndpoint.detachFrom(_p.targetEndpoint);
- } else {
- var sourceId = _getId(_p.source),
- targetId = _getId(_p.target);
- _operation(sourceId, function(jpc) {
- if ((jpc.sourceId == sourceId && jpc.targetId == targetId) || (jpc.targetId == sourceId && jpc.sourceId == targetId)) {
- if (_currentInstance.checkCondition("beforeDetach", jpc)) {
- jpc.endpoints[0].detach(jpc, false, true, fireEvent);
- }
- }
- });
- }
- }
- };
-
- this.detachAllConnections = function(el, params) {
- params = params || {};
- el = _getElementObject(el);
- var id = _getAttribute(el, "id"),
- endpoints = endpointsByElement[id];
- if (endpoints && endpoints.length) {
- for ( var i = 0; i < endpoints.length; i++) {
- endpoints[i].detachAll(params.fireEvent);
- }
- }
- };
-
- this.detachEveryConnection = function(params) {
- params = params || {};
- for ( var id in endpointsByElement) {
- var endpoints = endpointsByElement[id];
- if (endpoints && endpoints.length) {
- for ( var i = 0; i < endpoints.length; i++) {
- endpoints[i].detachAll(params.fireEvent);
- }
- }
- }
- delete connectionsByScope;
- connectionsByScope = {};
- };
-
-
- this.draggable = function(el, options) {
- if (typeof el == 'object' && el.length) {
- for ( var i = 0; i < el.length; i++) {
- var ele = _getElementObject(el[i]);
- if (ele) _initDraggableIfNecessary(ele, true, options);
- }
- }
- else if (el._nodes) {
-
- for ( var i = 0; i < el._nodes.length; i++) {
- var ele = _getElementObject(el._nodes[i]);
- if (ele) _initDraggableIfNecessary(ele, true, options);
- }
- }
- else {
- var ele = _getElementObject(el);
- if (ele) _initDraggableIfNecessary(ele, true, options);
- }
- };
-
- this.extend = function(o1, o2) {
- return jsPlumb.CurrentLibrary.extend(o1, o2);
- };
-
-
- this.getDefaultEndpointType = function() {
- return Endpoint;
- };
-
-
- this.getDefaultConnectionType = function() {
- return Connection;
- };
-
- var _setOperation = function(list, func, args, selector) {
- for (var i = 0; i < list.length; i++) {
- list[i][func].apply(list[i], args);
- }
- return selector(list);
- },
- _getOperation = function(list, func, args) {
- var out = [];
- for (var i = 0; i < list.length; i++) {
- out.push([ list[i][func].apply(list[i], args), list[i] ]);
- }
- return out;
- },
- setter = function(list, func, selector) {
- return function() {
- return _setOperation(list, func, arguments, selector);
- };
- },
- getter = function(list, func) {
- return function() {
- return _getOperation(list, func, arguments);
- };
- };
-
- this.getConnections = function(options, flat) {
- if (!options) {
- options = {};
- } else if (options.constructor == String) {
- options = { "scope": options };
- }
- var prepareList = function(input) {
- var r = [];
- if (input) {
- if (typeof input == 'string') {
- if (input === "*") return input;
- r.push(input);
- }
- else
- r = input;
- }
- return r;
- },
- scope = options.scope || _currentInstance.getDefaultScope(),
- scopes = prepareList(scope),
- sources = prepareList(options.source),
- targets = prepareList(options.target),
- filter = function(list, value) {
- if (list === "*") return true;
- return list.length > 0 ? _indexOf(list, value) != -1 : true;
- },
- results = (!flat && scopes.length > 1) ? {} : [],
- _addOne = function(scope, obj) {
- if (!flat && scopes.length > 1) {
- var ss = results[scope];
- if (ss == null) {
- ss = []; results[scope] = ss;
- }
- ss.push(obj);
- } else results.push(obj);
- };
- for ( var i in connectionsByScope) {
- if (filter(scopes, i)) {
- for ( var j = 0; j < connectionsByScope[i].length; j++) {
- var c = connectionsByScope[i][j];
- if (filter(sources, c.sourceId) && filter(targets, c.targetId))
- _addOne(i, c);
- }
- }
- }
- return results;
- };
-
- var _makeConnectionSelectHandler = function(list) {
-
- return {
-
- setHover:setter(list, "setHover", _makeConnectionSelectHandler),
- removeAllOverlays:setter(list, "removeAllOverlays", _makeConnectionSelectHandler),
- setLabel:setter(list, "setLabel", _makeConnectionSelectHandler),
- addOverlay:setter(list, "addOverlay", _makeConnectionSelectHandler),
- removeOverlay:setter(list, "removeOverlay", _makeConnectionSelectHandler),
- removeOverlays:setter(list, "removeOverlays", _makeConnectionSelectHandler),
- showOverlay:setter(list, "showOverlay", _makeConnectionSelectHandler),
- hideOverlay:setter(list, "hideOverlay", _makeConnectionSelectHandler),
- showOverlays:setter(list, "showOverlays", _makeConnectionSelectHandler),
- hideOverlays:setter(list, "hideOverlays", _makeConnectionSelectHandler),
- setPaintStyle:setter(list, "setPaintStyle", _makeConnectionSelectHandler),
- setHoverPaintStyle:setter(list, "setHoverPaintStyle", _makeConnectionSelectHandler),
- setDetachable:setter(list, "setDetachable", _makeConnectionSelectHandler),
- setConnector:setter(list, "setConnector", _makeConnectionSelectHandler),
- setParameter:setter(list, "setParameter", _makeConnectionSelectHandler),
- setParameters:setter(list, "setParameters", _makeConnectionSelectHandler),
-
- detach:function() {
- for (var i = 0; i < list.length; i++)
- _currentInstance.detach(list[i]);
- },
-
- getLabel:getter(list, "getLabel"),
- getOverlay:getter(list, "getOverlay"),
- isHover:getter(list, "isHover"),
- isDetachable:getter(list, "isDetachable"),
- getParameter:getter(list, "getParameter"),
- getParameters:getter(list, "getParameters"),
-
- length:list.length,
- each:function(f) {
- for (var i = 0; i < list.length; i++) {
- f(list[i]);
- }
- return _makeConnectionSelectHandler(list);
- },
- get:function(idx) {
- return list[idx];
- }
- };
- };
-
- this.select = function(params) {
- params = params || {};
- params.scope = params.scope || "*";
- var c = _currentInstance.getConnections(params, true);
- return _makeConnectionSelectHandler(c);
- };
-
- this.getAllConnections = function() {
- return connectionsByScope;
- };
-
- this.getDefaultScope = function() {
- return DEFAULT_SCOPE;
- };
-
- this.getEndpoint = _getEndpoint;
-
-
- this.getEndpoints = function(el) {
- return endpointsByElement[_getId(el)];
- };
-
- this.getId = _getId;
- this.getOffset = function(id) {
- var o = offsets[id];
- return _updateOffset({elId:id});
- };
-
- this.getSelector = function(spec) {
- return jsPlumb.CurrentLibrary.getSelector(spec);
- };
-
- this.getSize = function(id) {
- var s = sizes[id];
- if (!s) _updateOffset({elId:id});
- return sizes[id];
- };
-
- this.appendElement = _appendElement;
-
- var _hoverSuspended = false;
- this.isHoverSuspended = function() { return _hoverSuspended; };
- this.setHoverSuspended = function(s) { _hoverSuspended = s; };
-
- this.hide = function(el, changeEndpoints) {
- _setVisible(el, "none", changeEndpoints);
- };
-
-
- this.idstamp = _idstamp;
-
-
- this.init = function() {
- if (!initialized) {
- _currentInstance.setRenderMode(_currentInstance.Defaults.RenderMode);
-
- var bindOne = function(event) {
- jsPlumb.CurrentLibrary.bind(document, event, function(e) {
- if (!_currentInstance.currentlyDragging && renderMode == jsPlumb.CANVAS) {
-
- for (var scope in connectionsByScope) {
- var c = connectionsByScope[scope];
- for (var i = 0; i < c.length; i++) {
- var t = c[i].connector[event](e);
- if (t) return;
- }
- }
- for (var el in endpointsByElement) {
- var ee = endpointsByElement[el];
- for (var i = 0; i < ee.length; i++) {
- if (ee[i].endpoint[event](e)) return;
- }
- }
- }
- });
- };
- bindOne("click");bindOne("dblclick");bindOne("mousemove");bindOne("mousedown");bindOne("mouseup");bindOne("contextmenu");
-
- initialized = true;
- _currentInstance.fire("ready");
- }
- };
-
- this.log = log;
- this.jsPlumbUIComponent = jsPlumbUIComponent;
- this.EventGenerator = EventGenerator;
-
- this.makeAnchor = function() {
- if (arguments.length == 0) return null;
- var specimen = arguments[0], elementId = arguments[1], jsPlumbInstance = arguments[2], newAnchor = null;
- if (!jsPlumbInstance)
- throw "NO JSPLUMB SET";
-
- if (specimen.compute && specimen.getOrientation) return specimen;
-
- else if (typeof specimen == "string") {
- newAnchor = jsPlumb.Anchors[arguments[0]]({elementId:elementId, jsPlumbInstance:_currentInstance});
- }
-
-
-
-
- else if (specimen.constructor == Array) {
- if (specimen[0].constructor == Array || specimen[0].constructor == String) {
- if (specimen.length == 2 && specimen[0].constructor == String && specimen[1].constructor == Object) {
- var pp = jsPlumb.extend({elementId:elementId, jsPlumbInstance:_currentInstance}, specimen[1]);
- newAnchor = jsPlumb.Anchors[specimen[0]](pp);
- }
- else
- newAnchor = new DynamicAnchor(specimen, null, elementId);
- }
- else {
- var anchorParams = {
- x:specimen[0], y:specimen[1],
- orientation : (specimen.length >= 4) ? [ specimen[2], specimen[3] ] : [0,0],
- offsets : (specimen.length == 6) ? [ specimen[4], specimen[5] ] : [ 0, 0 ],
- elementId:elementId
- };
- newAnchor = new Anchor(anchorParams);
- newAnchor.clone = function() { return new Anchor(anchorParams); };
- }
- }
-
- if (!newAnchor.id) newAnchor.id = "anchor_" + _idstamp();
- return newAnchor;
- };
-
- this.makeAnchors = function(types, elementId, jsPlumbInstance) {
- var r = [];
- for ( var i = 0; i < types.length; i++) {
- if (typeof types[i] == "string")
- r.push(jsPlumb.Anchors[types[i]]({elementId:elementId, jsPlumbInstance:jsPlumbInstance}));
- else if (types[i].constructor == Array)
- r.push(_currentInstance.makeAnchor(types[i], elementId, jsPlumbInstance));
- }
- return r;
- };
-
- this.makeDynamicAnchor = function(anchors, anchorSelector) {
- return new DynamicAnchor(anchors, anchorSelector);
- };
-
-
- var _targetEndpointDefinitions = {},
- _targetEndpoints = {},
- _targetEndpointsUnique = {},
- _setEndpointPaintStylesAndAnchor = function(ep, epIndex) {
- ep.paintStyle = ep.paintStyle ||
- _currentInstance.Defaults.EndpointStyles[epIndex] ||
- _currentInstance.Defaults.EndpointStyle ||
- jsPlumb.Defaults.EndpointStyles[epIndex] ||
- jsPlumb.Defaults.EndpointStyle;
- ep.hoverPaintStyle = ep.hoverPaintStyle ||
- _currentInstance.Defaults.EndpointHoverStyles[epIndex] ||
- _currentInstance.Defaults.EndpointHoverStyle ||
- jsPlumb.Defaults.EndpointHoverStyles[epIndex] ||
- jsPlumb.Defaults.EndpointHoverStyle;
- ep.anchor = ep.anchor ||
- _currentInstance.Defaults.Anchors[epIndex] ||
- _currentInstance.Defaults.Anchor ||
- jsPlumb.Defaults.Anchors[epIndex] ||
- jsPlumb.Defaults.Anchor;
-
- ep.endpoint = ep.endpoint ||
- _currentInstance.Defaults.Endpoints[epIndex] ||
- _currentInstance.Defaults.Endpoint ||
- jsPlumb.Defaults.Endpoints[epIndex] ||
- jsPlumb.Defaults.Endpoint;
- };
- this.makeTarget = function(el, params, referenceParams) {
-
- var p = jsPlumb.extend({_jsPlumb:_currentInstance}, referenceParams);
- jsPlumb.extend(p, params);
- _setEndpointPaintStylesAndAnchor(p, 1);
- var jpcl = jsPlumb.CurrentLibrary,
- targetScope = p.scope || _currentInstance.Defaults.Scope,
- deleteEndpointsOnDetach = !(p.deleteEndpointsOnDetach === false),
- _doOne = function(_el) {
-
-
-
- var elid = _getId(_el);
- _targetEndpointDefinitions[elid] = p;
- _targetEndpointsUnique[elid] = p.uniqueEndpoint,
- proxyComponent = new jsPlumbUIComponent(p);
-
- var dropOptions = jsPlumb.extend({}, p.dropOptions || {}),
- _drop = function() {
- var originalEvent = jsPlumb.CurrentLibrary.getDropEvent(arguments);
- _currentInstance.currentlyDragging = false;
- var draggable = _getElementObject(jpcl.getDragObject(arguments)),
- id = _getAttribute(draggable, "dragId"),
-
- scope = _getAttribute(draggable, "originalScope"),
- jpc = floatingConnections[id],
- source = jpc.endpoints[0],
- _endpoint = p.endpoint ? jsPlumb.extend({}, p.endpoint) : {};
-
- source.anchor.locked = false;
-
- if (scope) jpcl.setDragScope(draggable, scope);
-
-
-
- var _continue = proxyComponent.isDropAllowed(jpc.sourceId, _getId(_el), jpc.scope);
-
-
-
-
-
-
-
- if (jpc.endpointsToDeleteOnDetach) {
- if (source === jpc.endpointsToDeleteOnDetach[0])
- jpc.endpointsToDeleteOnDetach[0] = null;
- else if (source === jpc.endpointsToDeleteOnDetach[1])
- jpc.endpointsToDeleteOnDetach[1] = null;
- }
-
-
-
-
- if (jpc.suspendedEndpoint) {
- jpc.targetId = jpc.suspendedEndpoint.elementId;
- jpc.target = jpcl.getElementObject(jpc.suspendedEndpoint.elementId);
- jpc.endpoints[1] = jpc.suspendedEndpoint;
- }
-
- if (_continue) {
-
-
- source.detach(jpc, false, true, false);
-
-
-
-
- var newEndpoint = _targetEndpoints[elid] || _currentInstance.addEndpoint(_el, p);
- if (p.uniqueEndpoint) _targetEndpoints[elid] = newEndpoint;
-
-
-
- if (newEndpoint.anchor.positionFinder != null) {
- var dropPosition = jpcl.getUIPosition(arguments),
- elPosition = jpcl.getOffset(_el),
- elSize = jpcl.getSize(_el),
- ap = newEndpoint.anchor.positionFinder(dropPosition, elPosition, elSize, newEndpoint.anchor.constructorParams);
- newEndpoint.anchor.x = ap[0];
- newEndpoint.anchor.y = ap[1];
-
-
-
-
-
- }
- var c = _currentInstance.connect({
- source:source,
- target:newEndpoint,
- scope:scope,
- previousConnection:jpc,
- container:jpc.parent,
- deleteEndpointsOnDetach:deleteEndpointsOnDetach,
-
-
-
-
-
- doNotFireConnectionEvent:source.endpointWillMoveAfterConnection
- });
- if (deleteEndpointsOnDetach)
- c.endpointsToDeleteOnDetach = [ source, newEndpoint ];
- c.repaint();
- }
-
- else {
-
-
-
- if (jpc.suspendedEndpoint) {
- if (source.isReattach) {
- jpc.setHover(false);
- jpc.floatingAnchorIndex = null;
- jpc.suspendedEndpoint.addConnection(jpc);
- _currentInstance.repaint(source.elementId);
- }
- else
- source.detach(jpc, false, true, true, originalEvent);
- }
-
- }
- };
-
- var dropEvent = jpcl.dragEvents['drop'];
- dropOptions["scope"] = dropOptions["scope"] || targetScope;
- dropOptions[dropEvent] = _wrap(dropOptions[dropEvent], _drop);
-
- jpcl.initDroppable(_el, dropOptions, true);
- };
-
- el = _convertYUICollection(el);
-
- var inputs = el.length && el.constructor != String ? el : [ el ];
-
- for (var i = 0; i < inputs.length; i++) {
- _doOne(_getElementObject(inputs[i]));
- }
- };
-
-
- this.makeTargets = function(els, params, referenceParams) {
- for ( var i = 0; i < els.length; i++) {
- _currentInstance.makeTarget(els[i], params, referenceParams);
- }
- };
-
-
- var _sourceEndpointDefinitions = {},
- _sourceEndpoints = {},
- _sourceEndpointsUnique = {};
- this.makeSource = function(el, params, referenceParams) {
- var p = jsPlumb.extend({}, referenceParams);
- jsPlumb.extend(p, params);
- _setEndpointPaintStylesAndAnchor(p, 0);
- var jpcl = jsPlumb.CurrentLibrary,
- _doOne = function(_el) {
-
-
- var elid = _getId(_el),
- parent = p.parent,
- idToRegisterAgainst = parent != null ? _currentInstance.getId(jpcl.getElementObject(parent)) : elid;
-
- _sourceEndpointDefinitions[idToRegisterAgainst] = p;
- _sourceEndpointsUnique[idToRegisterAgainst] = p.uniqueEndpoint;
- var stopEvent = jpcl.dragEvents["stop"],
- dragEvent = jpcl.dragEvents["drag"],
- dragOptions = jsPlumb.extend({ }, p.dragOptions || {}),
- existingDrag = dragOptions.drag,
- existingStop = dragOptions.stop,
- ep = null,
- endpointAddedButNoDragYet = false;
-
- dragOptions["scope"] = dragOptions["scope"] || p.scope;
- dragOptions[dragEvent] = _wrap(dragOptions[dragEvent], function() {
- if (existingDrag) existingDrag.apply(this, arguments);
- endpointAddedButNoDragYet = false;
- });
-
- dragOptions[stopEvent] = function() {
- if (existingStop) existingStop.apply(this, arguments);
-
- _currentInstance.currentlyDragging = false;
-
- if (ep.connections.length == 0)
- _currentInstance.deleteEndpoint(ep);
- else {
-
- jpcl.unbind(ep.canvas, "mousedown");
-
-
-
-
- var anchorDef = p.anchor || _currentInstance.Defaults.Anchor,
- oldAnchor = ep.anchor;
- ep.anchor = _currentInstance.makeAnchor(anchorDef, elid, _currentInstance);
-
-
- if (p.parent) {
- var parent = jpcl.getElementObject(p.parent);
- if (parent) {
- var currentId = ep.elementId;
- ep.setElement(parent);
- ep.endpointWillMoveAfterConnection = false;
- _currentInstance.anchorManager.rehomeEndpoint(currentId, parent);
- ep.connections[0].previousConnection = null;
- _currentInstance.anchorManager.connectionDetached({
- sourceId:ep.connections[0].sourceId,
- targetId:ep.connections[0].targetId,
- connection:ep.connections[0]
- });
- _finaliseConnection(ep.connections[0]);
- }
- }
-
- ep.repaint();
- _currentInstance.repaint(ep.elementId);
- _currentInstance.repaint(ep.connections[0].targetId);
- }
- };
-
- var mouseDownListener = function(e) {
-
- var myOffsetInfo = _updateOffset({elId:elid});
- var x = ((e.pageX || e.page.x) - myOffsetInfo.left) / myOffsetInfo.width,
- y = ((e.pageY || e.page.y) - myOffsetInfo.top) / myOffsetInfo.height,
- parentX = x,
- parentY = y;
-
-
-
-
-
- if (p.parent) {
- var pEl = jsPlumb.CurrentLibrary.getElementObject(p.parent),
- pId = _getId(pEl);
- myOffsetInfo = _updateOffset({elId:pId});
- parentX = ((e.pageX || e.page.x) - myOffsetInfo.left) / myOffsetInfo.width,
- parentY = ((e.pageY || e.page.y) - myOffsetInfo.top) / myOffsetInfo.height;
- }
-
-
-
-
- var tempEndpointParams = {};
- jsPlumb.extend(tempEndpointParams, p);
- tempEndpointParams.isSource = true;
- tempEndpointParams.anchor = [x,y,0,0];
- tempEndpointParams.parentAnchor = [ parentX, parentY, 0, 0 ];
- tempEndpointParams.dragOptions = dragOptions;
-
-
-
-
- if (p.parent) {
- var potentialParent = tempEndpointParams.container || _currentInstance.Defaults.Container;
- if (potentialParent)
- tempEndpointParams.container = potentialParent;
- else
- tempEndpointParams.container = jsPlumb.CurrentLibrary.getParent(p.parent);
- }
-
- ep = _currentInstance.addEndpoint(elid, tempEndpointParams);
- endpointAddedButNoDragYet = true;
-
-
- ep.endpointWillMoveAfterConnection = p.parent != null;
- ep.endpointWillMoveTo = p.parent ? jpcl.getElementObject(p.parent) : null;
- var _delTempEndpoint = function() {
-
-
-
-
- if(endpointAddedButNoDragYet) {
- _currentInstance.deleteEndpoint(ep);
- }
- };
- _currentInstance.registerListener(ep.canvas, "mouseup", _delTempEndpoint);
- _currentInstance.registerListener(_el, "mouseup", _delTempEndpoint);
-
-
-
- jpcl.trigger(ep.canvas, "mousedown", e);
- };
-
-
- _currentInstance.registerListener(_el, "mousedown", mouseDownListener);
- };
-
- el = _convertYUICollection(el);
-
- var inputs = el.length && el.constructor != String ? el : [ el ];
-
- for (var i = 0; i < inputs.length; i++) {
- _doOne(_getElementObject(inputs[i]));
- }
- };
-
-
- this.makeSources = function(els, params, referenceParams) {
- for ( var i = 0; i < els.length; i++) {
- _currentInstance.makeSource(els[i], params, referenceParams);
- }
- };
-
-
- this.ready = function(fn) {
- _currentInstance.bind("ready", fn);
- },
-
- this.repaint = function(el) {
- var _processElement = function(el) { _draw(_getElementObject(el)); };
-
- if (typeof el == 'object')
- for ( var i = 0; i < el.length; i++) _processElement(el[i]);
- else
- _processElement(el);
- };
-
- this.repaintEverything = function() {
- var timestamp = _timestamp();
- for ( var elId in endpointsByElement) {
- _draw(_getElementObject(elId), null, timestamp);
- }
- };
-
- this.removeAllEndpoints = function(el) {
- var elId = _getAttribute(el, "id"),
- ebe = endpointsByElement[elId];
- if (ebe) {
- for ( var i = 0; i < ebe.length; i++)
- _currentInstance.deleteEndpoint(ebe[i]);
- }
- endpointsByElement[elId] = [];
- };
-
- this.removeEveryEndpoint = this.deleteEveryEndpoint;
-
-
- this.removeEndpoint = function(el, endpoint) {
- _currentInstance.deleteEndpoint(endpoint);
- };
- var _registeredListeners = {},
- _unbindRegisteredListeners = function() {
- for (var i in _registeredListeners) {
- for (var j = 0; j < _registeredListeners[i].length; j++) {
- var info = _registeredListeners[i][j];
- jsPlumb.CurrentLibrary.unbind(info.el, info.event, info.listener);
- }
- }
- _registeredListeners = {};
- };
-
-
- this.registerListener = function(el, type, listener) {
- jsPlumb.CurrentLibrary.bind(el, type, listener);
- _addToList(_registeredListeners, type, {el:el, event:type, listener:listener});
- };
-
- this.reset = function() {
- _currentInstance.deleteEveryEndpoint();
- _currentInstance.clearListeners();
- _targetEndpointDefinitions = {};
- _targetEndpoints = {};
- _targetEndpointsUnique = {};
- _sourceEndpointDefinitions = {};
- _sourceEndpoints = {};
- _sourceEndpointsUnique = {};
- _unbindRegisteredListeners();
- _currentInstance.anchorManager.reset();
- _currentInstance.dragManager.reset();
- };
-
-
- this.setDefaultScope = function(scope) {
- DEFAULT_SCOPE = scope;
- };
-
- this.setDraggable = _setDraggable;
-
- this.setId = function(el, newId, doNotSetAttribute) {
-
- var id = el.constructor == String ? el : _currentInstance.getId(el),
- sConns = _currentInstance.getConnections({source:id, scope:'*'}, true),
- tConns = _currentInstance.getConnections({target:id, scope:'*'}, true);
- newId = "" + newId;
-
- if (!doNotSetAttribute) {
- el = jsPlumb.CurrentLibrary.getElementObject(id);
- jsPlumb.CurrentLibrary.setAttribute(el, "id", newId);
- }
-
- el = jsPlumb.CurrentLibrary.getElementObject(newId);
-
- endpointsByElement[newId] = endpointsByElement[id] || [];
- for (var i = 0; i < endpointsByElement[newId].length; i++) {
- endpointsByElement[newId][i].elementId = newId;
- endpointsByElement[newId][i].element = el;
- endpointsByElement[newId][i].anchor.elementId = newId;
- }
- delete endpointsByElement[id];
- _currentInstance.anchorManager.changeId(id, newId);
- var _conns = function(list, epIdx, type) {
- for (var i = 0; i < list.length; i++) {
- list[i].endpoints[epIdx].elementId = newId;
- list[i].endpoints[epIdx].element = el;
- list[i][type + "Id"] = newId;
- list[i][type] = el;
- }
- };
- _conns(sConns, 0, "source");
- _conns(tConns, 1, "target");
- };
-
- this.setIdChanged = function(oldId, newId) {
- _currentInstance.setId(oldId, newId, true);
- };
- this.setDebugLog = function(debugLog) {
- log = debugLog;
- };
-
- this.setRepaintFunction = function(f) {
- repaintFunction = f;
- };
-
- this.setSuspendDrawing = _setSuspendDrawing;
-
-
- this.CANVAS = "canvas";
-
-
- this.SVG = "svg";
-
- this.VML = "vml";
-
-
- this.setRenderMode = function(mode) {
- if (mode)
- mode = mode.toLowerCase();
- else
- return;
- if (mode !== jsPlumb.CANVAS && mode !== jsPlumb.SVG && mode !== jsPlumb.VML) throw new Error("render mode must be one of jsPlumb.CANVAS, jsPlumb.SVG or jsPlumb.VML");
-
- if (mode === jsPlumb.CANVAS && canvasAvailable)
- renderMode = jsPlumb.CANVAS;
- else if (mode === jsPlumb.SVG && svgAvailable)
- renderMode = jsPlumb.SVG;
- else if (vmlAvailable)
- renderMode = jsPlumb.VML;
-
- return renderMode;
- };
-
- this.getRenderMode = function() { return renderMode; };
-
- this.show = function(el, changeEndpoints) {
- _setVisible(el, "block", changeEndpoints);
- };
-
- this.sizeCanvas = function(canvas, x, y, w, h) {
- if (canvas) {
- canvas.style.height = h + "px";
- canvas.height = h;
- canvas.style.width = w + "px";
- canvas.width = w;
- canvas.style.left = x + "px";
- canvas.style.top = y + "px";
- }
- };
-
- this.getTestHarness = function() {
- return {
- endpointsByElement : endpointsByElement,
- endpointCount : function(elId) {
- var e = endpointsByElement[elId];
- return e ? e.length : 0;
- },
- connectionCount : function(scope) {
- scope = scope || DEFAULT_SCOPE;
- var c = connectionsByScope[scope];
- return c ? c.length : 0;
- },
-
- getId : _getId,
- makeAnchor:self.makeAnchor,
- makeDynamicAnchor:self.makeDynamicAnchor
- };
- };
-
- this.toggle = _toggleVisible;
-
-
- this.toggleVisible = _toggleVisible;
-
- this.toggleDraggable = _toggleDraggable;
-
- this.unload = function() {
-
-
- };
-
- this.wrap = _wrap;
- this.addListener = this.bind;
-
- var adjustForParentOffsetAndScroll = function(xy, el) {
- var offsetParent = null, result = xy;
- if (el.tagName.toLowerCase() === "svg" && el.parentNode) {
- offsetParent = el.parentNode;
- }
- else if (el.offsetParent) {
- offsetParent = el.offsetParent;
- }
- if (offsetParent != null) {
- var po = offsetParent.tagName.toLowerCase() === "body" ? {left:0,top:0} : _getOffset(offsetParent),
- so = offsetParent.tagName.toLowerCase() === "body" ? {left:0,top:0} : {left:offsetParent.scrollLeft, top:offsetParent.scrollTop};
-
-
-
-
-
-
- result[0] = xy[0] - po.left + so.left;
- result[1] = xy[1] - po.top + so.top;
- }
-
- return result;
-
- };
-
- var Anchor = function(params) {
- var self = this;
- this.x = params.x || 0;
- this.y = params.y || 0;
- this.elementId = params.elementId;
- var orientation = params.orientation || [ 0, 0 ];
- var lastTimestamp = null, lastReturnValue = null;
- this.offsets = params.offsets || [ 0, 0 ];
- self.timestamp = null;
- this.compute = function(params) {
- var xy = params.xy, wh = params.wh, element = params.element, timestamp = params.timestamp;
-
- if (timestamp && timestamp === self.timestamp)
- return lastReturnValue;
-
- lastReturnValue = [ xy[0] + (self.x * wh[0]) + self.offsets[0], xy[1] + (self.y * wh[1]) + self.offsets[1] ];
-
-
- lastReturnValue = adjustForParentOffsetAndScroll(lastReturnValue, element.canvas);
-
- self.timestamp = timestamp;
- return lastReturnValue;
- };
- this.getOrientation = function(_endpoint) { return orientation; };
- this.equals = function(anchor) {
- if (!anchor) return false;
- var ao = anchor.getOrientation();
- var o = this.getOrientation();
- return this.x == anchor.x && this.y == anchor.y
- && this.offsets[0] == anchor.offsets[0]
- && this.offsets[1] == anchor.offsets[1]
- && o[0] == ao[0] && o[1] == ao[1];
- };
- this.getCurrentLocation = function() { return lastReturnValue; };
- };
-
- var FloatingAnchor = function(params) {
-
-
- var ref = params.reference,
-
- refCanvas = params.referenceCanvas,
- size = _getSize(_getElementObject(refCanvas)),
-
-
-
-
-
- xDir = 0, yDir = 0,
-
-
- orientation = null,
- _lastResult = null;
-
-
-
- this.x = 0; this.y = 0;
- this.isFloating = true;
- this.compute = function(params) {
- var xy = params.xy, element = params.element,
- result = [ xy[0] + (size[0] / 2), xy[1] + (size[1] / 2) ];
-
-
- result = adjustForParentOffsetAndScroll(result, element.canvas);
-
- _lastResult = result;
- return result;
- };
- this.getOrientation = function(_endpoint) {
- if (orientation) return orientation;
- else {
- var o = ref.getOrientation(_endpoint);
-
-
-
- return [ Math.abs(o[0]) * xDir * -1,
- Math.abs(o[1]) * yDir * -1 ];
- }
- };
-
- this.over = function(anchor) {
- orientation = anchor.getOrientation();
- };
-
- this.out = function() { orientation = null; };
- this.getCurrentLocation = function() { return _lastResult; };
- };
-
- var DynamicAnchor = function(anchors, anchorSelector, elementId) {
- this.isSelective = true;
- this.isDynamic = true;
- var _anchors = [], self = this,
- _convert = function(anchor) {
- return anchor.constructor == Anchor ? anchor: _currentInstance.makeAnchor(anchor, elementId, _currentInstance);
- };
- for (var i = 0; i < anchors.length; i++)
- _anchors[i] = _convert(anchors[i]);
- this.addAnchor = function(anchor) { _anchors.push(_convert(anchor)); };
- this.getAnchors = function() { return _anchors; };
- this.locked = false;
- var _curAnchor = _anchors.length > 0 ? _anchors[0] : null,
- _curIndex = _anchors.length > 0 ? 0 : -1,
- self = this,
-
-
- _distance = function(anchor, cx, cy, xy, wh) {
- var ax = xy[0] + (anchor.x * wh[0]), ay = xy[1] + (anchor.y * wh[1]);
- return Math.sqrt(Math.pow(cx - ax, 2) + Math.pow(cy - ay, 2));
- },
-
-
-
-
-
-
-
-
- _anchorSelector = anchorSelector || function(xy, wh, txy, twh, anchors) {
- var cx = txy[0] + (twh[0] / 2), cy = txy[1] + (twh[1] / 2);
- var minIdx = -1, minDist = Infinity;
- for ( var i = 0; i < anchors.length; i++) {
- var d = _distance(anchors[i], cx, cy, xy, wh);
- if (d < minDist) {
- minIdx = i + 0;
- minDist = d;
- }
- }
- return anchors[minIdx];
- };
-
- this.compute = function(params) {
- var xy = params.xy, wh = params.wh, timestamp = params.timestamp, txy = params.txy, twh = params.twh;
-
-
-
- if (self.locked || txy == null || twh == null)
- return _curAnchor.compute(params);
- else
- params.timestamp = null;
-
- _curAnchor = _anchorSelector(xy, wh, txy, twh, _anchors);
- self.x = _curAnchor.x;
- self.y = _curAnchor.y;
-
- return _curAnchor.compute(params);
- };
- this.getCurrentLocation = function() {
- return _curAnchor != null ? _curAnchor.getCurrentLocation() : null;
- };
- this.getOrientation = function(_endpoint) { return _curAnchor != null ? _curAnchor.getOrientation(_endpoint) : [ 0, 0 ]; };
- this.over = function(anchor) { if (_curAnchor != null) _curAnchor.over(anchor); };
- this.out = function() { if (_curAnchor != null) _curAnchor.out(); };
- };
-
-
-
-
-
-
-
-
- var continuousAnchors = {},
- continuousAnchorLocations = {},
- continuousAnchorOrientations = {},
- Orientation = { HORIZONTAL : "horizontal", VERTICAL : "vertical", DIAGONAL : "diagonal", IDENTITY:"identity" },
-
-
-
-
- calculateOrientation = function(sourceId, targetId, sd, td) {
- if (sourceId === targetId) return {
- orientation:Orientation.IDENTITY,
- a:["top", "top"]
- };
- var theta = Math.atan2((td.centery - sd.centery) , (td.centerx - sd.centerx)),
- theta2 = Math.atan2((sd.centery - td.centery) , (sd.centerx - td.centerx)),
- h = ((sd.left <= td.left && sd.right >= td.left) || (sd.left <= td.right && sd.right >= td.right) ||
- (sd.left <= td.left && sd.right >= td.right) || (td.left <= sd.left && td.right >= sd.right)),
- v = ((sd.top <= td.top && sd.bottom >= td.top) || (sd.top <= td.bottom && sd.bottom >= td.bottom) ||
- (sd.top <= td.top && sd.bottom >= td.bottom) || (td.top <= sd.top && td.bottom >= sd.bottom));
- if (! (h || v)) {
- var a = null, rls = false, rrs = false, sortValue = null;
- if (td.left > sd.left && td.top > sd.top)
- a = ["right", "top"];
- else if (td.left > sd.left && sd.top > td.top)
- a = [ "top", "left"];
- else if (td.left < sd.left && td.top < sd.top)
- a = [ "top", "right"];
- else if (td.left < sd.left && td.top > sd.top)
- a = ["left", "top" ];
- return { orientation:Orientation.DIAGONAL, a:a, theta:theta, theta2:theta2 };
- }
- else if (h) return {
- orientation:Orientation.HORIZONTAL,
- a:sd.top < td.top ? ["bottom", "top"] : ["top", "bottom"],
- theta:theta, theta2:theta2
- }
- else return {
- orientation:Orientation.VERTICAL,
- a:sd.left < td.left ? ["right", "left"] : ["left", "right"],
- theta:theta, theta2:theta2
- }
- },
- placeAnchorsOnLine = function(desc, elementDimensions, elementPosition,
- connections, horizontal, otherMultiplier, reverse) {
- var a = [], step = elementDimensions[horizontal ? 0 : 1] / (connections.length + 1);
- for (var i = 0; i < connections.length; i++) {
- var val = (i + 1) * step, other = otherMultiplier * elementDimensions[horizontal ? 1 : 0];
- if (reverse)
- val = elementDimensions[horizontal ? 0 : 1] - val;
- var dx = (horizontal ? val : other), x = elementPosition[0] + dx, xp = dx / elementDimensions[0],
- dy = (horizontal ? other : val), y = elementPosition[1] + dy, yp = dy / elementDimensions[1];
- a.push([ x, y, xp, yp, connections[i][1], connections[i][2] ]);
- }
- return a;
- },
- standardEdgeSort = function(a, b) { return a[0] > b[0] ? 1 : -1 },
- currySort = function(reverseAngles) {
- return function(a,b) {
- var r = true;
- if (reverseAngles) {
- if (a[0][0] < b[0][0])
- r = true;
- else
- r = a[0][1] > b[0][1];
- }
- else {
- if (a[0][0] > b[0][0])
- r= true;
- else
- r =a[0][1] > b[0][1];
- }
- return r === false ? -1 : 1;
- };
- },
- leftSort = function(a,b) {
-
- var p1 = a[0][0] < 0 ? -Math.PI - a[0][0] : Math.PI - a[0][0],
- p2 = b[0][0] < 0 ? -Math.PI - b[0][0] : Math.PI - b[0][0];
- if (p1 > p2) return 1;
- else return a[0][1] > b[0][1] ? 1 : -1;
- },
- edgeSortFunctions = {
- "top":standardEdgeSort,
- "right":currySort(true),
- "bottom":currySort(true),
- "left":leftSort
- },
- _sortHelper = function(_array, _fn) {
- return _array.sort(_fn);
- },
- placeAnchors = function(elementId, _anchorLists) {
- var sS = sizes[elementId], sO = offsets[elementId],
- placeSomeAnchors = function(desc, elementDimensions, elementPosition, unsortedConnections, isHorizontal, otherMultiplier, orientation) {
- if (unsortedConnections.length > 0) {
- var sc = _sortHelper(unsortedConnections, edgeSortFunctions[desc]),
- reverse = desc === "right" || desc === "top",
- anchors = placeAnchorsOnLine(desc, elementDimensions,
- elementPosition, sc,
- isHorizontal, otherMultiplier, reverse );
-
- var _setAnchorLocation = function(endpoint, anchorPos) {
- var a = adjustForParentOffsetAndScroll([anchorPos[0], anchorPos[1]], endpoint.canvas);
- continuousAnchorLocations[endpoint.id] = [ a[0], a[1], anchorPos[2], anchorPos[3] ];
- continuousAnchorOrientations[endpoint.id] = orientation;
- };
- for (var i = 0; i < anchors.length; i++) {
- var c = anchors[i][4], weAreSource = c.endpoints[0].elementId === elementId, weAreTarget = c.endpoints[1].elementId === elementId;
- if (weAreSource)
- _setAnchorLocation(c.endpoints[0], anchors[i]);
- else if (weAreTarget)
- _setAnchorLocation(c.endpoints[1], anchors[i]);
- }
- }
- };
- placeSomeAnchors("bottom", sS, [sO.left,sO.top], _anchorLists.bottom, true, 1, [0,1]);
- placeSomeAnchors("top", sS, [sO.left,sO.top], _anchorLists.top, true, 0, [0,-1]);
- placeSomeAnchors("left", sS, [sO.left,sO.top], _anchorLists.left, false, 0, [-1,0]);
- placeSomeAnchors("right", sS, [sO.left,sO.top], _anchorLists.right, false, 1, [1,0]);
- },
- AnchorManager = function() {
- var _amEndpoints = {},
- connectionsByElementId = {},
- self = this,
- anchorLists = {};
- this.reset = function() {
- _amEndpoints = {};
- connectionsByElementId = {};
- anchorLists = {};
- };
- this.newConnection = function(conn) {
- var sourceId = conn.sourceId, targetId = conn.targetId,
- ep = conn.endpoints,
- doRegisterTarget = true,
- registerConnection = function(otherIndex, otherEndpoint, otherAnchor, elId, c) {
- if ((sourceId == targetId) && otherAnchor.isContinuous){
-
- jsPlumb.CurrentLibrary.removeElement(ep[1].canvas);
- doRegisterTarget = false;
- }
- _addToList(connectionsByElementId, elId, [c, otherEndpoint, otherAnchor.constructor == DynamicAnchor]);
- };
- registerConnection(0, ep[0], ep[0].anchor, targetId, conn);
- if (doRegisterTarget)
- registerConnection(1, ep[1], ep[1].anchor, sourceId, conn);
- };
- this.connectionDetached = function(connInfo) {
- var connection = connInfo.connection || connInfo;
- var sourceId = connection.sourceId,
- targetId = connection.targetId,
- ep = connection.endpoints,
- removeConnection = function(otherIndex, otherEndpoint, otherAnchor, elId, c) {
- if (otherAnchor.constructor == FloatingAnchor) {
-
- }
- else {
- _removeWithFunction(connectionsByElementId[elId], function(_c) {
- return _c[0].id == c.id;
- });
- }
- };
-
- removeConnection(1, ep[1], ep[1].anchor, sourceId, connection);
- removeConnection(0, ep[0], ep[0].anchor, targetId, connection);
-
- var sEl = connection.sourceId,
- tEl = connection.targetId,
- sE = connection.endpoints[0].id,
- tE = connection.endpoints[1].id,
- _remove = function(list, eId) {
- if (list) {
- var f = function(e) { return e[4] == eId; };
- _removeWithFunction(list["top"], f);
- _removeWithFunction(list["left"], f);
- _removeWithFunction(list["bottom"], f);
- _removeWithFunction(list["right"], f);
- }
- };
-
- _remove(anchorLists[sEl], sE);
- _remove(anchorLists[tEl], tE);
- self.redraw(sEl);
- self.redraw(tEl);
- };
- this.add = function(endpoint, elementId) {
- _addToList(_amEndpoints, elementId, endpoint);
- };
- this.changeId = function(oldId, newId) {
- connectionsByElementId[newId] = connectionsByElementId[oldId];
- _amEndpoints[newId] = _amEndpoints[oldId];
- delete connectionsByElementId[oldId];
- delete _amEndpoints[oldId];
- };
- this.getConnectionsFor = function(elementId) {
- return connectionsByElementId[elementId] || [];
- };
- this.getEndpointsFor = function(elementId) {
- return _amEndpoints[elementId] || [];
- };
- this.deleteEndpoint = function(endpoint) {
- _removeWithFunction(_amEndpoints[endpoint.elementId], function(e) {
- return e.id == endpoint.id;
- });
- };
- this.clearFor = function(elementId) {
- delete _amEndpoints[elementId];
- _amEndpoints[elementId] = [];
- };
-
-
-
-
-
- var _updateAnchorList = function(lists, theta, order, conn, aBoolean, otherElId, idx, reverse, edgeId, elId, connsToPaint, endpointsToPaint) {
-
- var exactIdx = -1,
- firstMatchingElIdx = -1,
- endpoint = conn.endpoints[idx],
- endpointId = endpoint.id,
- oIdx = [1,0][idx],
- values = [ [ theta, order ], conn, aBoolean, otherElId, endpointId ],
- listToAddTo = lists[edgeId],
- listToRemoveFrom = endpoint._continuousAnchorEdge ? lists[endpoint._continuousAnchorEdge] : null;
- if (listToRemoveFrom) {
- var rIdx = _findWithFunction(listToRemoveFrom, function(e) { return e[4] == endpointId });
- if (rIdx != -1) {
- listToRemoveFrom.splice(rIdx, 1);
-
- for (var i = 0; i < listToRemoveFrom.length; i++) {
- _addWithFunction(connsToPaint, listToRemoveFrom[i][1], function(c) { return c.id == listToRemoveFrom[i][1].id });
- _addWithFunction(endpointsToPaint, listToRemoveFrom[i][1].endpoints[idx], function(e) { return e.id == listToRemoveFrom[i][1].endpoints[idx].id });
- }
- }
- }
- for (var i = 0; i < listToAddTo.length; i++) {
- if (idx == 1 && listToAddTo[i][3] === otherElId && firstMatchingElIdx == -1)
- firstMatchingElIdx = i;
- _addWithFunction(connsToPaint, listToAddTo[i][1], function(c) { return c.id == listToAddTo[i][1].id });
- _addWithFunction(endpointsToPaint, listToAddTo[i][1].endpoints[idx], function(e) { return e.id == listToAddTo[i][1].endpoints[idx].id });
- }
- if (exactIdx != -1) {
- listToAddTo[exactIdx] = values;
- }
- else {
- var insertIdx = reverse ? firstMatchingElIdx != -1 ? firstMatchingElIdx : 0 : listToAddTo.length;
- listToAddTo.splice(insertIdx, 0, values);
- }
-
- endpoint._continuousAnchorEdge = edgeId;
- };
- this.redraw = function(elementId, ui, timestamp, offsetToUI) {
-
- var ep = _amEndpoints[elementId] || [],
- endpointConnections = connectionsByElementId[elementId] || [],
- connectionsToPaint = [],
- endpointsToPaint = [],
- anchorsToUpdate = [];
-
- timestamp = timestamp || _timestamp();
-
-
-
- offsetToUI = offsetToUI || {left:0, top:0};
- if (ui) {
- ui = {
- left:ui.left + offsetToUI.left,
- top:ui.top + offsetToUI.top
- }
- }
-
- _updateOffset( { elId : elementId, offset : ui, recalc : false, timestamp : timestamp });
-
- var myOffset = offsets[elementId],
- myWH = sizes[elementId],
- orientationCache = {};
-
-
-
-
-
- for (var i = 0; i < endpointConnections.length; i++) {
- var conn = endpointConnections[i][0],
- sourceId = conn.sourceId,
- targetId = conn.targetId,
- sourceContinuous = conn.endpoints[0].anchor.isContinuous,
- targetContinuous = conn.endpoints[1].anchor.isContinuous;
- if (sourceContinuous || targetContinuous) {
- var oKey = sourceId + "_" + targetId,
- oKey2 = targetId + "_" + sourceId,
- o = orientationCache[oKey],
- oIdx = conn.sourceId == elementId ? 1 : 0;
- if (sourceContinuous && !anchorLists[sourceId]) anchorLists[sourceId] = { top:[], right:[], bottom:[], left:[] };
- if (targetContinuous && !anchorLists[targetId]) anchorLists[targetId] = { top:[], right:[], bottom:[], left:[] };
- if (elementId != targetId) _updateOffset( { elId : targetId, timestamp : timestamp });
- if (elementId != sourceId) _updateOffset( { elId : sourceId, timestamp : timestamp });
- var td = _getCachedData(targetId),
- sd = _getCachedData(sourceId);
- if (targetId == sourceId && (sourceContinuous || targetContinuous)) {
-
-
-
-
- _updateAnchorList(anchorLists[sourceId], -Math.PI / 2, 0, conn, false, targetId, 0, false, "top", sourceId, connectionsToPaint, endpointsToPaint)
- }
- else {
- if (!o) {
- o = calculateOrientation(sourceId, targetId, sd.o, td.o);
- orientationCache[oKey] = o;
-
-
-
- }
- if (sourceContinuous) _updateAnchorList(anchorLists[sourceId], o.theta, 0, conn, false, targetId, 0, false, o.a[0], sourceId, connectionsToPaint, endpointsToPaint);
- if (targetContinuous) _updateAnchorList(anchorLists[targetId], o.theta2, -1, conn, true, sourceId, 1, true, o.a[1], targetId, connectionsToPaint, endpointsToPaint);
- }
- if (sourceContinuous) _addWithFunction(anchorsToUpdate, sourceId, function(a) { return a === sourceId; });
- if (targetContinuous) _addWithFunction(anchorsToUpdate, targetId, function(a) { return a === targetId; });
- _addWithFunction(connectionsToPaint, conn, function(c) { return c.id == conn.id; });
- if ((sourceContinuous && oIdx == 0) || (targetContinuous && oIdx == 1))
- _addWithFunction(endpointsToPaint, conn.endpoints[oIdx], function(e) { return e.id == conn.endpoints[oIdx].id; });
- }
- }
-
- for (var i = 0; i < anchorsToUpdate.length; i++) {
- placeAnchors(anchorsToUpdate[i], anchorLists[anchorsToUpdate[i]]);
- }
-
-
-
-
- for (var i = 0; i < ep.length; i++) {
- ep[i].paint( { timestamp : timestamp, offset : myOffset, dimensions : myWH });
- }
-
- for (var i = 0; i < endpointsToPaint.length; i++) {
- endpointsToPaint[i].paint( { timestamp : timestamp, offset : myOffset, dimensions : myWH });
- }
-
-
-
- for (var i = 0; i < endpointConnections.length; i++) {
- var otherEndpoint = endpointConnections[i][1];
- if (otherEndpoint.anchor.constructor == DynamicAnchor) {
- otherEndpoint.paint({ elementWithPrecedence:elementId });
- _addWithFunction(connectionsToPaint, endpointConnections[i][0], function(c) { return c.id == endpointConnections[i][0].id; });
-
- for (var k = 0; k < otherEndpoint.connections.length; k++) {
- if (otherEndpoint.connections[k] !== endpointConnections[i][0])
- _addWithFunction(connectionsToPaint, otherEndpoint.connections[k], function(c) { return c.id == otherEndpoint.connections[k].id; });
- }
- } else if (otherEndpoint.anchor.constructor == Anchor) {
- _addWithFunction(connectionsToPaint, endpointConnections[i][0], function(c) { return c.id == endpointConnections[i][0].id; });
- }
- }
-
- var fc = floatingConnections[elementId];
- if (fc)
- fc.paint({timestamp:timestamp, recalc:false, elId:elementId});
-
-
- for (var i = 0; i < connectionsToPaint.length; i++) {
- connectionsToPaint[i].paint({elId:elementId, timestamp:timestamp, recalc:false});
- }
- };
- this.rehomeEndpoint = function(currentId, element) {
- var eps = _amEndpoints[currentId] || [],
- elementId = _currentInstance.getId(element);
- for (var i = 0; i < eps.length; i++) {
- self.add(eps[i], elementId);
- }
- eps.splice(0, eps.length);
- };
- };
- _currentInstance.anchorManager = new AnchorManager();
- _currentInstance.continuousAnchorFactory = {
- get:function(params) {
- var existing = continuousAnchors[params.elementId];
- if (!existing) {
- existing = {
- type:"Continuous",
- compute : function(params) {
- return continuousAnchorLocations[params.element.id] || [0,0];
- },
- getCurrentLocation : function(endpoint) {
- return continuousAnchorLocations[endpoint.id] || [0,0];
- },
- getOrientation : function(endpoint) {
- return continuousAnchorOrientations[endpoint.id] || [0,0];
- },
- isDynamic : true,
- isContinuous : true
- };
- continuousAnchors[params.elementId] = existing;
- }
- return existing;
- }
- };
-
- var DragManager = function() {
-
- var _draggables = {}, _dlist = [], _delements = {}, _elementsWithEndpoints = {};
-
- this.register = function(el) {
- el = jsPlumb.CurrentLibrary.getElementObject(el);
- var id = _currentInstance.getId(el),
- domEl = jsPlumb.CurrentLibrary.getDOMElement(el);
- if (!_draggables[id]) {
- _draggables[id] = el;
- _dlist.push(el);
- _delements[id] = {};
- }
-
-
- var _oneLevel = function(p) {
- var pEl = jsPlumb.CurrentLibrary.getElementObject(p),
- pOff = jsPlumb.CurrentLibrary.getOffset(pEl);
- for (var i = 0; i < p.childNodes.length; i++) {
- if (p.childNodes[i].nodeType != 3) {
- var cEl = jsPlumb.CurrentLibrary.getElementObject(p.childNodes[i]),
- cid = _currentInstance.getId(cEl);
- if (_elementsWithEndpoints[cid] && _elementsWithEndpoints[cid] > 0) {
- var cOff = jsPlumb.CurrentLibrary.getOffset(cEl);
- _delements[id][cid] = {
- id:cid,
- offset:{
- left:cOff.left - pOff.left,
- top:cOff.top - pOff.top
- }
- };
- }
- }
- }
- };
- _oneLevel(domEl);
- };
-
- this.endpointAdded = function(el) {
- var jpcl = jsPlumb.CurrentLibrary, b = document.body, id = _currentInstance.getId(el), c = jpcl.getDOMElement(el),
- p = c.parentNode, done = p == b;
- _elementsWithEndpoints[id] = _elementsWithEndpoints[id] ? _elementsWithEndpoints[id] + 1 : 1;
- while (p != b) {
- var pid = _currentInstance.getId(p);
- if (_draggables[pid]) {
- var idx = -1, pEl = jpcl.getElementObject(p), pLoc = jsPlumb.CurrentLibrary.getOffset(pEl);
-
- if (_delements[pid][id] == null) {
- var cLoc = jsPlumb.CurrentLibrary.getOffset(el);
- _delements[pid][id] = {
- id:id,
- offset:{
- left:cLoc.left - pLoc.left,
- top:cLoc.top - pLoc.top
- }
- };
- }
- break;
- }
- p = p.parentNode;
- }
- };
- this.endpointDeleted = function(endpoint) {
- if (_elementsWithEndpoints[endpoint.elementId]) {
- _elementsWithEndpoints[endpoint.elementId]--;
- if (_elementsWithEndpoints[endpoint.elementId] <= 0) {
- for (var i in _delements) {
- delete _delements[i][endpoint.elementId];
- }
- }
- }
- };
- this.getElementsForDraggable = function(id) {
- return _delements[id];
- };
- this.reset = function() {
- _draggables = {};
- _dlist = [];
- _delements = {};
- _elementsWithEndpoints = {};
- };
-
- };
- _currentInstance.dragManager = new DragManager();
-
-
-
- var Connection = function(params) {
- var self = this, visible = true;
- self.idPrefix = "_jsplumb_c_";
- self.defaultLabelLocation = 0.5;
- self.defaultOverlayKeys = ["Overlays", "ConnectionOverlays"];
- this.parent = params.parent;
- overlayCapableJsPlumbUIComponent.apply(this, arguments);
-
-
-
- this.isVisible = function() { return visible; };
-
- this.setVisible = function(v) {
- visible = v;
- self[v ? "showOverlays" : "hideOverlays"]();
- if (self.connector && self.connector.canvas) self.connector.canvas.style.display = v ? "block" : "none";
- };
-
-
- this.source = _getElementObject(params.source);
-
- this.target = _getElementObject(params.target);
-
-
-
- if (params.sourceEndpoint) {
- this.source = params.sourceEndpoint.endpointWillMoveTo || params.sourceEndpoint.getElement();
- }
- if (params.targetEndpoint) this.target = params.targetEndpoint.getElement();
-
-
-
-
- self.previousConnection = params.previousConnection;
-
- var _cost = params.cost;
- self.getCost = function() { return _cost; };
- self.setCost = function(c) { _cost = c; };
-
- var _bidirectional = params.bidirectional === false ? false : true;
- self.isBidirectional = function() { return _bidirectional; };
-
-
- this.sourceId = _getAttribute(this.source, "id");
-
- this.targetId = _getAttribute(this.target, "id");
-
-
- this.getAttachedElements = function() {
- return self.endpoints;
- };
-
-
- this.scope = params.scope;
-
- this.endpoints = [];
- this.endpointStyles = [];
-
- var _makeAnchor = function(anchorParams, elementId) {
- if (anchorParams)
- return _currentInstance.makeAnchor(anchorParams, elementId, _currentInstance);
- },
- prepareEndpoint = function(existing, index, params, element, elementId, connectorPaintStyle, connectorHoverPaintStyle) {
- if (existing) {
- self.endpoints[index] = existing;
- existing.addConnection(self);
- } else {
- if (!params.endpoints) params.endpoints = [ null, null ];
- var ep = params.endpoints[index]
- || params.endpoint
- || _currentInstance.Defaults.Endpoints[index]
- || jsPlumb.Defaults.Endpoints[index]
- || _currentInstance.Defaults.Endpoint
- || jsPlumb.Defaults.Endpoint;
- if (!params.endpointStyles) params.endpointStyles = [ null, null ];
- if (!params.endpointHoverStyles) params.endpointHoverStyles = [ null, null ];
- var es = params.endpointStyles[index] || params.endpointStyle || _currentInstance.Defaults.EndpointStyles[index] || jsPlumb.Defaults.EndpointStyles[index] || _currentInstance.Defaults.EndpointStyle || jsPlumb.Defaults.EndpointStyle;
-
- if (es.fillStyle == null && connectorPaintStyle != null)
- es.fillStyle = connectorPaintStyle.strokeStyle;
-
-
-
- if (es.outlineColor == null && connectorPaintStyle != null)
- es.outlineColor = connectorPaintStyle.outlineColor;
- if (es.outlineWidth == null && connectorPaintStyle != null)
- es.outlineWidth = connectorPaintStyle.outlineWidth;
-
-
- var ehs = params.endpointHoverStyles[index] || params.endpointHoverStyle || _currentInstance.Defaults.EndpointHoverStyles[index] || jsPlumb.Defaults.EndpointHoverStyles[index] || _currentInstance.Defaults.EndpointHoverStyle || jsPlumb.Defaults.EndpointHoverStyle;
-
- if (connectorHoverPaintStyle != null) {
- if (ehs == null) ehs = {};
- if (ehs.fillStyle == null) {
- ehs.fillStyle = connectorHoverPaintStyle.strokeStyle;
- }
- }
- var a = params.anchors ? params.anchors[index] :
- params.anchor ? params.anchor :
- _makeAnchor(_currentInstance.Defaults.Anchors[index], elementId) ||
- _makeAnchor(jsPlumb.Defaults.Anchors[index], elementId) ||
- _makeAnchor(_currentInstance.Defaults.Anchor, elementId) ||
- _makeAnchor(jsPlumb.Defaults.Anchor, elementId),
- u = params.uuids ? params.uuids[index] : null,
- e = _newEndpoint({
- paintStyle : es,
- hoverPaintStyle:ehs,
- endpoint : ep,
- connections : [ self ],
- uuid : u,
- anchor : a,
- source : element,
- scope : params.scope,
- container:params.container,
- reattach:params.reattach,
- detachable:params.detachable
- });
- self.endpoints[index] = e;
-
-
- if (params.drawEndpoints === false) e.setVisible(false, true, true);
-
- return e;
- }
- };
- var eS = prepareEndpoint(params.sourceEndpoint,
- 0,
- params,
- self.source,
- self.sourceId,
- params.paintStyle,
- params.hoverPaintStyle);
- if (eS) _addToList(endpointsByElement, this.sourceId, eS);
-
-
-
- var existingTargetEndpoint = ((self.sourceId == self.targetId) && params.targetEndpoint == null) ? eS : params.targetEndpoint,
- eT = prepareEndpoint(existingTargetEndpoint,
- 1,
- params,
- self.target,
- self.targetId,
- params.paintStyle,
- params.hoverPaintStyle);
- if (eT) _addToList(endpointsByElement, this.targetId, eT);
-
- if (!this.scope) this.scope = this.endpoints[0].scope;
-
-
- if (params.deleteEndpointsOnDetach)
- self.endpointsToDeleteOnDetach = [eS, eT];
- var _detachable = _currentInstance.Defaults.ConnectionsDetachable;
- if (params.detachable === false) _detachable = false;
- if(self.endpoints[0].connectionsDetachable === false) _detachable = false;
- if(self.endpoints[1].connectionsDetachable === false) _detachable = false;
-
-
- if (_cost == null) _cost = self.endpoints[0].getConnectionCost();
-
- if (params.bidirectional == null) _bidirectional = self.endpoints[0].areConnectionsBidirectional();
-
-
- this.isDetachable = function() {
- return _detachable === true;
- };
-
- this.setDetachable = function(detachable) {
- _detachable = detachable === true;
- };
-
-
-
-
-
-
- var _p = jsPlumb.extend({}, this.endpoints[0].getParameters());
- jsPlumb.extend(_p, this.endpoints[1].getParameters());
- jsPlumb.extend(_p, self.getParameters());
- self.setParameters(_p);
-
-
- var _sh = self.setHover;
- self.setHover = function() {
- self.connector.setHover.apply(self.connector, arguments);
- _sh.apply(self, arguments);
- };
-
- var _internalHover = function(state) {
- if (_connectionBeingDragged == null) {
- self.setHover(state, false);
- }
- };
-
- this.setConnector = function(connector, doNotRepaint) {
- if (self.connector != null) _removeElements(self.connector.getDisplayElements(), self.parent);
- var connectorArgs = {
- _jsPlumb:self._jsPlumb,
- parent:params.parent,
- cssClass:params.cssClass,
- container:params.container,
- tooltip:self.tooltip
- };
- if (connector.constructor == String)
- this.connector = new jsPlumb.Connectors[renderMode][connector](connectorArgs);
- else if (connector.constructor == Array)
- this.connector = new jsPlumb.Connectors[renderMode][connector[0]](jsPlumb.extend(connector[1], connectorArgs));
- self.canvas = self.connector.canvas;
-
- _bindListeners(self.connector, self, _internalHover);
- if (!doNotRepaint) self.repaint();
- };
-
-
-
- self.setConnector(this.endpoints[0].connector ||
- this.endpoints[1].connector ||
- params.connector ||
- _currentInstance.Defaults.Connector ||
- jsPlumb.Defaults.Connector, true);
-
-
- this.setPaintStyle(this.endpoints[0].connectorStyle ||
- this.endpoints[1].connectorStyle ||
- params.paintStyle ||
- _currentInstance.Defaults.PaintStyle ||
- jsPlumb.Defaults.PaintStyle, true);
-
- this.setHoverPaintStyle(this.endpoints[0].connectorHoverStyle ||
- this.endpoints[1].connectorHoverStyle ||
- params.hoverPaintStyle ||
- _currentInstance.Defaults.HoverPaintStyle ||
- jsPlumb.Defaults.HoverPaintStyle, true);
-
- this.paintStyleInUse = this.paintStyle;
-
-
- this.moveParent = function(newParent) {
- var jpcl = jsPlumb.CurrentLibrary, curParent = jpcl.getParent(self.connector.canvas);
- jpcl.removeElement(self.connector.canvas, curParent);
- jpcl.appendElement(self.connector.canvas, newParent);
- if (self.connector.bgCanvas) {
- jpcl.removeElement(self.connector.bgCanvas, curParent);
- jpcl.appendElement(self.connector.bgCanvas, newParent);
- }
-
- for (var i = 0; i < self.overlays.length; i++) {
- if (self.overlays[i].isAppendedAtTopLevel) {
- jpcl.removeElement(self.overlays[i].canvas, curParent);
- jpcl.appendElement(self.overlays[i].canvas, newParent);
- if (self.overlays[i].reattachListeners)
- self.overlays[i].reattachListeners(self.connector);
- }
- }
- if (self.connector.reattachListeners)
- self.connector.reattachListeners();
- };
-
-
-
-
-
-
-
-
-
- _updateOffset( { elId : this.sourceId });
- _updateOffset( { elId : this.targetId });
-
-
- var myOffset = offsets[this.sourceId], myWH = sizes[this.sourceId],
- otherOffset = offsets[this.targetId],
- otherWH = sizes[this.targetId],
- initialTimestamp = _timestamp(),
- anchorLoc = this.endpoints[0].anchor.compute( {
- xy : [ myOffset.left, myOffset.top ], wh : myWH, element : this.endpoints[0],
- elementId:this.endpoints[0].elementId,
- txy : [ otherOffset.left, otherOffset.top ], twh : otherWH, tElement : this.endpoints[1],
- timestamp:initialTimestamp
- });
- this.endpoints[0].paint( { anchorLoc : anchorLoc, timestamp:initialTimestamp });
- anchorLoc = this.endpoints[1].anchor.compute( {
- xy : [ otherOffset.left, otherOffset.top ], wh : otherWH, element : this.endpoints[1],
- elementId:this.endpoints[1].elementId,
- txy : [ myOffset.left, myOffset.top ], twh : myWH, tElement : this.endpoints[0],
- timestamp:initialTimestamp
- });
- this.endpoints[1].paint({ anchorLoc : anchorLoc, timestamp:initialTimestamp });
-
-
- this.paint = function(params) {
- params = params || {};
- var elId = params.elId, ui = params.ui, recalc = params.recalc, timestamp = params.timestamp,
-
- swap = false,
- tId = swap ? this.sourceId : this.targetId, sId = swap ? this.targetId : this.sourceId,
- tIdx = swap ? 0 : 1, sIdx = swap ? 1 : 0;
- var sourceInfo = _updateOffset( { elId : elId, offset : ui, recalc : recalc, timestamp : timestamp }),
- targetInfo = _updateOffset( { elId : tId, timestamp : timestamp });
-
- var sE = this.endpoints[sIdx], tE = this.endpoints[tIdx],
- sAnchorP = sE.anchor.getCurrentLocation(sE),
- tAnchorP = tE.anchor.getCurrentLocation(tE);
-
- var maxSize = 0;
- for ( var i = 0; i < self.overlays.length; i++) {
- var o = self.overlays[i];
- if (o.isVisible()) maxSize = Math.max(maxSize, o.computeMaxSize(self.connector));
- }
- var dim = this.connector.compute(sAnchorP, tAnchorP,
- this.endpoints[sIdx], this.endpoints[tIdx],
- this.endpoints[sIdx].anchor, this.endpoints[tIdx].anchor,
- self.paintStyleInUse.lineWidth, maxSize,
- sourceInfo,
- targetInfo);
-
- self.connector.paint(dim, self.paintStyleInUse);
-
- for ( var i = 0; i < self.overlays.length; i++) {
- var o = self.overlays[i];
- if (o.isVisible) self.overlayPlacements[i] = o.draw(self.connector, self.paintStyleInUse, dim);
- }
- };
-
- this.repaint = function(params) {
- params = params || {};
- var recalc = !(params.recalc === false);
- this.paint({ elId : this.sourceId, recalc : recalc, timestamp:params.timestamp });
- };
-
- };
-
- var _makeConnectionDragHandler = function(placeholder) {
- var stopped = false;
- return {
- drag : function() {
- if (stopped) {
- stopped = false;
- return true;
- }
- var _ui = jsPlumb.CurrentLibrary.getUIPosition(arguments),
- el = placeholder.element;
- if (el) {
- jsPlumb.CurrentLibrary.setOffset(el, _ui);
- _draw(_getElementObject(el), _ui);
- }
- },
- stopDrag : function() {
- stopped = true;
- }
- };
- };
-
- var _makeFloatingEndpoint = function(paintStyle, referenceAnchor, endpoint, referenceCanvas, sourceElement) {
- var floatingAnchor = new FloatingAnchor( { reference : referenceAnchor, referenceCanvas : referenceCanvas });
-
-
-
- return _newEndpoint({ paintStyle : paintStyle, endpoint : endpoint, anchor : floatingAnchor, source : sourceElement, scope:"__floating" });
- };
-
-
- var _makeDraggablePlaceholder = function(placeholder, parent) {
- var n = document.createElement("div");
- n.style.position = "absolute";
- var placeholderDragElement = _getElementObject(n);
- _appendElement(n, parent);
- var id = _getId(placeholderDragElement);
- _updateOffset( { elId : id });
-
- placeholder.id = id;
- placeholder.element = placeholderDragElement;
- };
-
-
- var Endpoint = function(params) {
- var self = this;
- self.idPrefix = "_jsplumb_e_";
- self.defaultLabelLocation = [ 0.5, 0.5 ];
- self.defaultOverlayKeys = ["Overlays", "EndpointOverlays"];
- this.parent = params.parent;
- overlayCapableJsPlumbUIComponent.apply(this, arguments);
- params = params || {};
-
-
-
-
-
-
-
-
-
- var visible = true, __enabled = !(params.enabled === false);
-
- this.isVisible = function() { return visible; };
-
- this.setVisible = function(v, doNotChangeConnections, doNotNotifyOtherEndpoint) {
- visible = v;
- if (self.canvas) self.canvas.style.display = v ? "block" : "none";
- self[v ? "showOverlays" : "hideOverlays"]();
- if (!doNotChangeConnections) {
- for (var i = 0; i < self.connections.length; i++) {
- self.connections[i].setVisible(v);
- if (!doNotNotifyOtherEndpoint) {
- var oIdx = self === self.connections[i].endpoints[0] ? 1 : 0;
-
- if (self.connections[i].endpoints[oIdx].connections.length == 1) self.connections[i].endpoints[oIdx].setVisible(v, true, true);
- }
- }
- }
- };
-
- this.isEnabled = function() { return __enabled; };
-
- this.setEnabled = function(e) { __enabled = e; };
- var _element = params.source, _uuid = params.uuid, floatingEndpoint = null, inPlaceCopy = null;
- if (_uuid) endpointsByUUID[_uuid] = self;
- var _elementId = _getAttribute(_element, "id");
- this.elementId = _elementId;
- this.element = _element;
-
- var _connectionCost = params.connectionCost;
- this.getConnectionCost = function() { return _connectionCost; };
- this.setConnectionCost = function(c) {
- _connectionCost = c;
- };
-
- var _connectionsBidirectional = params.connectionsBidirectional === false ? false : true;
- this.areConnectionsBidirectional = function() { return _connectionsBidirectional; };
- this.setConnectionsBidirectional = function(b) { _connectionsBidirectional = b; };
-
- self.anchor = params.anchor ? _currentInstance.makeAnchor(params.anchor, _elementId, _currentInstance) : params.anchors ? _currentInstance.makeAnchor(params.anchors, _elementId, _currentInstance) : _currentInstance.makeAnchor("TopCenter", _elementId, _currentInstance);
-
-
- if (!params._transient)
- _currentInstance.anchorManager.add(self, _elementId);
-
- var _endpoint = params.endpoint || _currentInstance.Defaults.Endpoint || jsPlumb.Defaults.Endpoint || "Dot",
- endpointArgs = {
- _jsPlumb:self._jsPlumb,
- parent:params.parent,
- container:params.container,
- tooltip:params.tooltip,
- connectorTooltip:params.connectorTooltip,
- endpoint:self
- };
- if (_endpoint.constructor == String)
- _endpoint = new jsPlumb.Endpoints[renderMode][_endpoint](endpointArgs);
- else if (_endpoint.constructor == Array) {
- endpointArgs = jsPlumb.extend(_endpoint[1], endpointArgs);
- _endpoint = new jsPlumb.Endpoints[renderMode][_endpoint[0]](endpointArgs);
- }
- else {
- _endpoint = _endpoint.clone();
- }
-
-
-
-
- var argsForClone = jsPlumb.extend({}, endpointArgs);
- _endpoint.clone = function() {
- var o = new Object();
- _endpoint.constructor.apply(o, [argsForClone]);
- return o;
- };
-
- self.endpoint = _endpoint;
- self.type = self.endpoint.type;
-
- var _sh = self.setHover;
- self.setHover = function() {
- self.endpoint.setHover.apply(self.endpoint, arguments);
- _sh.apply(self, arguments);
- };
-
- var internalHover = function(state) {
- if (self.connections.length > 0)
- self.connections[0].setHover(state, false);
- else
- self.setHover(state);
- };
-
-
- _bindListeners(self.endpoint, self, internalHover);
-
- this.setPaintStyle(params.paintStyle ||
- params.style ||
- _currentInstance.Defaults.EndpointStyle ||
- jsPlumb.Defaults.EndpointStyle, true);
- this.setHoverPaintStyle(params.hoverPaintStyle ||
- _currentInstance.Defaults.EndpointHoverStyle ||
- jsPlumb.Defaults.EndpointHoverStyle, true);
- this.paintStyleInUse = this.paintStyle;
- this.connectorStyle = params.connectorStyle;
- this.connectorHoverStyle = params.connectorHoverStyle;
- this.connectorOverlays = params.connectorOverlays;
- this.connector = params.connector;
- this.connectorTooltip = params.connectorTooltip;
- this.isSource = params.isSource || false;
- this.isTarget = params.isTarget || false;
-
- var _maxConnections = params.maxConnections || _currentInstance.Defaults.MaxConnections;
-
- this.getAttachedElements = function() {
- return self.connections;
- };
-
-
- this.canvas = this.endpoint.canvas;
-
- this.connections = params.connections || [];
-
- this.scope = params.scope || DEFAULT_SCOPE;
- this.timestamp = null;
- self.isReattach = params.reattach || false;
- self.connectionsDetachable = _currentInstance.Defaults.ConnectionsDetachable;
- if (params.connectionsDetachable === false || params.detachable === false)
- self.connectionsDetachable = false;
- var dragAllowedWhenFull = params.dragAllowedWhenFull || true;
- this.computeAnchor = function(params) {
- return self.anchor.compute(params);
- };
-
- this.addConnection = function(connection) {
- self.connections.push(connection);
- };
-
- this.detach = function(connection, ignoreTarget, forceDetach, fireEvent, originalEvent) {
- var idx = _findWithFunction(self.connections, function(c) { return c.id == connection.id}),
- actuallyDetached = false;
- fireEvent = (fireEvent !== false);
- if (idx >= 0) {
-
-
- if (forceDetach || connection._forceDetach || connection.isDetachable() || connection.isDetachAllowed(connection)) {
-
- var t = connection.endpoints[0] == self ? connection.endpoints[1] : connection.endpoints[0];
-
-
-
-
-
-
-
- if (forceDetach || connection._forceDetach || (self.isDetachAllowed(connection) )) {
-
- self.connections.splice(idx, 1);
-
-
- if (!ignoreTarget) {
-
- t.detach(connection, true, forceDetach);
-
-
-
-
-
- if (connection.endpointsToDeleteOnDetach){
- for (var i = 0; i < connection.endpointsToDeleteOnDetach.length; i++) {
- var cde = connection.endpointsToDeleteOnDetach[i];
- if (cde && cde.connections.length == 0)
- _currentInstance.deleteEndpoint(cde);
- }
- }
- }
- _removeElements(connection.connector.getDisplayElements(), connection.parent);
- _removeWithFunction(connectionsByScope[connection.scope], function(c) {
- return c.id == connection.id;
- });
- actuallyDetached = true;
- var doFireEvent = (!ignoreTarget && fireEvent)
- fireDetachEvent(connection, doFireEvent, originalEvent);
- }
- }
- }
- return actuallyDetached;
- };
-
- this.detachAll = function(fireEvent, originalEvent) {
- while (self.connections.length > 0) {
- self.detach(self.connections[0], false, true, fireEvent, originalEvent);
- }
- };
-
- this.detachFrom = function(targetEndpoint, fireEvent, originalEvent) {
- var c = [];
- for ( var i = 0; i < self.connections.length; i++) {
- if (self.connections[i].endpoints[1] == targetEndpoint
- || self.connections[i].endpoints[0] == targetEndpoint) {
- c.push(self.connections[i]);
- }
- }
- for ( var i = 0; i < c.length; i++) {
- if (self.detach(c[i], false, true, fireEvent, originalEvent))
- c[i].setHover(false, false);
- }
- };
-
- this.detachFromConnection = function(connection) {
- var idx = _findWithFunction(self.connections, function(c) { return c.id == connection.id});
- if (idx >= 0) {
- self.connections.splice(idx, 1);
- }
- };
-
- this.getElement = function() {
- return _element;
- };
-
-
- this.setElement = function(el) {
-
-
-
- var parentId = _getId(el);
-
- _removeWithFunction(endpointsByElement[_elementId], function(e) {
- return e.id == self.id;
- });
- _element = _getElementObject(el);
- _elementId = _getId(_element);
- self.elementId = _elementId;
-
- var newParentElement = _getParentFromParams({source:parentId}),
- curParent = jpcl.getParent(self.canvas);
- jpcl.removeElement(self.canvas, curParent);
- jpcl.appendElement(self.canvas, newParentElement);
-
-
- for (var i = 0; i < self.connections.length; i++) {
- self.connections[i].moveParent(newParentElement);
- self.connections[i].sourceId = _elementId;
- self.connections[i].source = _element;
- }
- _addToList(endpointsByElement, parentId, self);
-
-
- };
-
- this.getUuid = function() {
- return _uuid;
- };
-
- this.makeInPlaceCopy = function() {
- return _newEndpoint( {
- anchor : self.anchor,
- source : _element,
- paintStyle : this.paintStyle,
- endpoint : _endpoint,
- _transient:true,
- scope:self.scope
- });
- };
-
- this.isConnectedTo = function(endpoint) {
- var found = false;
- if (endpoint) {
- for ( var i = 0; i < self.connections.length; i++) {
- if (self.connections[i].endpoints[1] == endpoint) {
- found = true;
- break;
- }
- }
- }
- return found;
- };
-
- this.isFloating = function() {
- return floatingEndpoint != null;
- };
-
-
- this.connectorSelector = function() {
- var candidate = self.connections[0];
- if (self.isTarget && candidate) return candidate;
- else {
- return (self.connections.length < _maxConnections) || _maxConnections == -1 ? null : candidate;
- }
- };
-
- this.isFull = function() {
- return !(self.isFloating() || _maxConnections < 1 || self.connections.length < _maxConnections);
- };
-
- this.setDragAllowedWhenFull = function(allowed) {
- dragAllowedWhenFull = allowed;
- };
-
- this.setStyle = self.setPaintStyle;
-
- this.equals = function(endpoint) {
- return this.anchor.equals(endpoint.anchor);
- };
-
-
-
- var findConnectionToUseForDynamicAnchor = function(elementWithPrecedence) {
- var idx = 0;
- if (elementWithPrecedence != null) {
- for (var i = 0; i < self.connections.length; i++) {
- if (self.connections[i].sourceId == elementWithPrecedence || self.connections[i].targetId == elementWithPrecedence) {
- idx = i;
- break;
- }
- }
- }
-
- return self.connections[idx];
- };
-
- this.paint = function(params) {
- params = params || {};
- var timestamp = params.timestamp,
- recalc = !(params.recalc === false);
- if (!timestamp || self.timestamp !== timestamp) {
- _updateOffset({ elId:_elementId, timestamp:timestamp, recalc:recalc });
- var xy = params.offset || offsets[_elementId];
- if(xy) {
- var ap = params.anchorPoint,connectorPaintStyle = params.connectorPaintStyle;
- if (ap == null) {
- var wh = params.dimensions || sizes[_elementId];
- if (xy == null || wh == null) {
- _updateOffset( { elId : _elementId, timestamp : timestamp });
- xy = offsets[_elementId];
- wh = sizes[_elementId];
- }
- var anchorParams = { xy : [ xy.left, xy.top ], wh : wh, element : self, timestamp : timestamp };
- if (recalc && self.anchor.isDynamic && self.connections.length > 0) {
- var c = findConnectionToUseForDynamicAnchor(params.elementWithPrecedence),
- oIdx = c.endpoints[0] == self ? 1 : 0,
- oId = oIdx == 0 ? c.sourceId : c.targetId,
- oOffset = offsets[oId], oWH = sizes[oId];
- anchorParams.txy = [ oOffset.left, oOffset.top ];
- anchorParams.twh = oWH;
- anchorParams.tElement = c.endpoints[oIdx];
- }
- ap = self.anchor.compute(anchorParams);
- }
-
- var d = _endpoint.compute(ap, self.anchor.getOrientation(_endpoint), self.paintStyleInUse, connectorPaintStyle || self.paintStyleInUse);
- _endpoint.paint(d, self.paintStyleInUse, self.anchor);
- self.timestamp = timestamp;
-
- for ( var i = 0; i < self.overlays.length; i++) {
- var o = self.overlays[i];
- if (o.isVisible) self.overlayPlacements[i] = o.draw(self.endpoint, self.paintStyleInUse, d);
- }
- }
- }
- };
- this.repaint = this.paint;
-
- this.removeConnection = this.detach;
-
-
- if (jsPlumb.CurrentLibrary.isDragSupported(_element)) {
- var placeholderInfo = { id:null, element:null },
- jpc = null,
- existingJpc = false,
- existingJpcParams = null,
- _dragHandler = _makeConnectionDragHandler(placeholderInfo);
- var start = function() {
-
-
- jpc = self.connectorSelector();
- var _continue = true;
-
- if (!self.isEnabled()) _continue = false;
-
- if (jpc == null && !params.isSource) _continue = false;
-
- if (params.isSource && self.isFull() && !dragAllowedWhenFull) _continue = false;
-
-
-
- if (jpc != null && !jpc.isDetachable()) _continue = false;
- if (_continue === false) {
-
-
-
- if (jsPlumb.CurrentLibrary.stopDrag) jsPlumb.CurrentLibrary.stopDrag();
- _dragHandler.stopDrag();
- return false;
- }
-
- if (jpc && !self.isFull() && params.isSource) jpc = null;
- _updateOffset( { elId : _elementId });
- inPlaceCopy = self.makeInPlaceCopy();
- inPlaceCopy.paint();
-
- _makeDraggablePlaceholder(placeholderInfo, self.parent);
-
-
-
-
- var ipcoel = _getElementObject(inPlaceCopy.canvas),
- ipco = jsPlumb.CurrentLibrary.getOffset(ipcoel),
- po = adjustForParentOffsetAndScroll([ipco.left, ipco.top], inPlaceCopy.canvas);
- jsPlumb.CurrentLibrary.setOffset(placeholderInfo.element, {left:po[0], top:po[1]});
-
-
-
-
- if (self.parentAnchor) self.anchor = _currentInstance.makeAnchor(self.parentAnchor, self.elementId, _currentInstance);
-
- _setAttribute(_getElementObject(self.canvas), "dragId", placeholderInfo.id);
- _setAttribute(_getElementObject(self.canvas), "elId", _elementId);
-
- floatingEndpoint = _makeFloatingEndpoint(self.paintStyle, self.anchor, _endpoint, self.canvas, placeholderInfo.element);
-
- if (jpc == null) {
- self.anchor.locked = true;
- self.setHover(false, false);
-
-
-
- jpc = _newConnection({
- sourceEndpoint : self,
- targetEndpoint : floatingEndpoint,
- source : self.endpointWillMoveTo || _getElementObject(_element),
- target : placeholderInfo.element,
- anchors : [ self.anchor, floatingEndpoint.anchor ],
- paintStyle : params.connectorStyle,
- hoverPaintStyle:params.connectorHoverStyle,
- connector : params.connector,
- overlays : params.connectorOverlays
- });
- } else {
- existingJpc = true;
- jpc.connector.setHover(false, false);
-
- _initDropTarget(_getElementObject(inPlaceCopy.canvas), false, true);
-
- var anchorIdx = jpc.endpoints[0].id == self.id ? 0 : 1;
- jpc.floatingAnchorIndex = anchorIdx;
- self.detachFromConnection(jpc);
-
-
- var c = _getElementObject(self.canvas),
- dragScope = jsPlumb.CurrentLibrary.getDragScope(c);
- _setAttribute(c, "originalScope", dragScope);
-
-
- var dropScope = jsPlumb.CurrentLibrary.getDropScope(c);
- jsPlumb.CurrentLibrary.setDragScope(c, dropScope);
-
-
- if (anchorIdx == 0) {
- existingJpcParams = [ jpc.source, jpc.sourceId, i, dragScope ];
- jpc.source = placeholderInfo.element;
- jpc.sourceId = placeholderInfo.id;
- } else {
- existingJpcParams = [ jpc.target, jpc.targetId, i, dragScope ];
- jpc.target = placeholderInfo.element;
- jpc.targetId = placeholderInfo.id;
- }
-
- jpc.endpoints[anchorIdx == 0 ? 1 : 0].anchor.locked = true;
-
- jpc.suspendedEndpoint = jpc.endpoints[anchorIdx];
- jpc.suspendedEndpoint.setHover(false);
- jpc.endpoints[anchorIdx] = floatingEndpoint;
-
- fireConnectionDraggingEvent(jpc);
- }
-
- floatingConnections[placeholderInfo.id] = jpc;
- floatingEndpoint.addConnection(jpc);
-
-
- _addToList(endpointsByElement, placeholderInfo.id, floatingEndpoint);
-
- _currentInstance.currentlyDragging = true;
- };
- var jpcl = jsPlumb.CurrentLibrary,
- dragOptions = params.dragOptions || {},
- defaultOpts = jsPlumb.extend( {}, jpcl.defaultDragOptions),
- startEvent = jpcl.dragEvents["start"],
- stopEvent = jpcl.dragEvents["stop"],
- dragEvent = jpcl.dragEvents["drag"];
-
- dragOptions = jsPlumb.extend(defaultOpts, dragOptions);
- dragOptions.scope = dragOptions.scope || self.scope;
- dragOptions[startEvent] = _wrap(dragOptions[startEvent], start);
-
- dragOptions[dragEvent] = _wrap(dragOptions[dragEvent], _dragHandler.drag);
- dragOptions[stopEvent] = _wrap(dragOptions[stopEvent],
- function() {
- _currentInstance.currentlyDragging = false;
- _removeWithFunction(endpointsByElement[placeholderInfo.id], function(e) {
- return e.id == floatingEndpoint.id;
- });
- _removeElements( [ placeholderInfo.element[0], floatingEndpoint.canvas ], _element);
- _removeElement(inPlaceCopy.canvas, _element);
- _currentInstance.anchorManager.clearFor(placeholderInfo.id);
- var idx = jpc.floatingAnchorIndex == null ? 1 : jpc.floatingAnchorIndex;
- jpc.endpoints[idx == 0 ? 1 : 0].anchor.locked = false;
- if (jpc.endpoints[idx] == floatingEndpoint) {
-
- if (existingJpc && jpc.suspendedEndpoint) {
-
-
- if (idx == 0) {
- jpc.source = existingJpcParams[0];
- jpc.sourceId = existingJpcParams[1];
- } else {
- jpc.target = existingJpcParams[0];
- jpc.targetId = existingJpcParams[1];
- }
-
-
- jsPlumb.CurrentLibrary.setDragScope(existingJpcParams[2], existingJpcParams[3]);
- jpc.endpoints[idx] = jpc.suspendedEndpoint;
- if (self.isReattach || jpc._forceDetach || !jpc.endpoints[idx == 0 ? 1 : 0].detach(jpc)) {
- jpc.setHover(false);
- jpc.floatingAnchorIndex = null;
- jpc.suspendedEndpoint.addConnection(jpc);
- _currentInstance.repaint(existingJpcParams[1]);
- }
- jpc._forceDetach = null;
- } else {
-
-
- _removeElements(jpc.connector.getDisplayElements(), self.parent);
- self.detachFromConnection(jpc);
- }
- }
- self.anchor.locked = false;
- self.paint({recalc:false});
- jpc.setHover(false, false);
- fireConnectionDragStopEvent(jpc);
- jpc = null;
- inPlaceCopy = null;
- delete endpointsByElement[floatingEndpoint.elementId];
- floatingEndpoint.anchor = null;
- floatingEndpoint = null;
- _currentInstance.currentlyDragging = false;
- });
-
- var i = _getElementObject(self.canvas);
- jsPlumb.CurrentLibrary.initDraggable(i, dragOptions, true);
- }
-
-
- var _initDropTarget = function(canvas, forceInit, isTransient, endpoint) {
- if ((params.isTarget || forceInit) && jsPlumb.CurrentLibrary.isDropSupported(_element)) {
- var dropOptions = params.dropOptions || _currentInstance.Defaults.DropOptions || jsPlumb.Defaults.DropOptions;
- dropOptions = jsPlumb.extend( {}, dropOptions);
- dropOptions.scope = dropOptions.scope || self.scope;
- var dropEvent = jsPlumb.CurrentLibrary.dragEvents['drop'],
- overEvent = jsPlumb.CurrentLibrary.dragEvents['over'],
- outEvent = jsPlumb.CurrentLibrary.dragEvents['out'],
- drop = function() {
- var originalEvent = jsPlumb.CurrentLibrary.getDropEvent(arguments);
- var draggable = _getElementObject(jsPlumb.CurrentLibrary.getDragObject(arguments)),
- id = _getAttribute(draggable, "dragId"),
- elId = _getAttribute(draggable, "elId"),
- scope = _getAttribute(draggable, "originalScope"),
- jpc = floatingConnections[id];
- if (jpc != null) {
- var idx = jpc.floatingAnchorIndex == null ? 1 : jpc.floatingAnchorIndex, oidx = idx == 0 ? 1 : 0;
-
-
- if (scope) jsPlumb.CurrentLibrary.setDragScope(draggable, scope);
-
- var endpointEnabled = endpoint != null ? endpoint.isEnabled() : true;
- if (!self.isFull() && !(idx == 0 && !self.isSource) && !(idx == 1 && !self.isTarget) && endpointEnabled) {
-
- var _doContinue = true;
-
-
- if (jpc.suspendedEndpoint && jpc.suspendedEndpoint.id != self.id) {
- if (idx == 0) {
- jpc.source = jpc.suspendedEndpoint.element;
- jpc.sourceId = jpc.suspendedEndpoint.elementId;
- } else {
- jpc.target = jpc.suspendedEndpoint.element;
- jpc.targetId = jpc.suspendedEndpoint.elementId;
- }
- if (!jpc.isDetachAllowed(jpc) || !jpc.endpoints[idx].isDetachAllowed(jpc) || !jpc.suspendedEndpoint.isDetachAllowed(jpc) || !_currentInstance.checkCondition("beforeDetach", jpc))
- _doContinue = false;
- }
-
-
- if (idx == 0) {
- jpc.source = self.element;
- jpc.sourceId = self.elementId;
- } else {
- jpc.target = self.element;
- jpc.targetId = self.elementId;
- }
-
-
-
-
-
-
- _doContinue = _doContinue && self.isDropAllowed(jpc.sourceId, jpc.targetId, jpc.scope);
-
- if (_doContinue) {
-
- jpc.endpoints[idx].detachFromConnection(jpc);
- if (jpc.suspendedEndpoint) jpc.suspendedEndpoint.detachFromConnection(jpc);
- jpc.endpoints[idx] = self;
- self.addConnection(jpc);
- if (!jpc.suspendedEndpoint) {
-
- _initDraggableIfNecessary(self.element, params.draggable, {});
- }
- else {
- var suspendedElement = jpc.suspendedEndpoint.getElement(), suspendedElementId = jpc.suspendedEndpoint.elementId;
-
- fireDetachEvent({
- source : idx == 0 ? suspendedElement : jpc.source,
- target : idx == 1 ? suspendedElement : jpc.target,
- sourceId : idx == 0 ? suspendedElementId : jpc.sourceId,
- targetId : idx == 1 ? suspendedElementId : jpc.targetId,
- sourceEndpoint : idx == 0 ? jpc.suspendedEndpoint : jpc.endpoints[0],
- targetEndpoint : idx == 1 ? jpc.suspendedEndpoint : jpc.endpoints[1],
- connection : jpc
- }, true, originalEvent);
- }
-
-
- _finaliseConnection(jpc, null, originalEvent);
- }
- else {
-
- if (jpc.suspendedEndpoint) {
-
- jpc.endpoints[idx] = jpc.suspendedEndpoint;
- jpc.setHover(false);
- jpc._forceDetach = true;
- if (idx == 0) {
- jpc.source = jpc.suspendedEndpoint.element;
- jpc.sourceId = jpc.suspendedEndpoint.elementId;
- } else {
- jpc.target = jpc.suspendedEndpoint.element;
- jpc.targetId = jpc.suspendedEndpoint.elementId;;
- }
- jpc.suspendedEndpoint.addConnection(jpc);
- jpc.endpoints[0].repaint();
- jpc.repaint();
- _currentInstance.repaint(jpc.source.elementId);
- jpc._forceDetach = false;
- }
- }
- jpc.floatingAnchorIndex = null;
- }
- _currentInstance.currentlyDragging = false;
- delete floatingConnections[id];
- }
- };
-
- dropOptions[dropEvent] = _wrap(dropOptions[dropEvent], drop);
- dropOptions[overEvent] = _wrap(dropOptions[overEvent], function() {
- if (self.isTarget) {
- var draggable = jsPlumb.CurrentLibrary.getDragObject(arguments),
- id = _getAttribute( _getElementObject(draggable), "dragId"),
- jpc = floatingConnections[id];
- if (jpc != null) {
- var idx = jpc.floatingAnchorIndex == null ? 1 : jpc.floatingAnchorIndex;
- jpc.endpoints[idx].anchor.over(self.anchor);
- }
- }
- });
- dropOptions[outEvent] = _wrap(dropOptions[outEvent], function() {
- if (self.isTarget) {
- var draggable = jsPlumb.CurrentLibrary.getDragObject(arguments),
- id = _getAttribute( _getElementObject(draggable), "dragId"),
- jpc = floatingConnections[id];
- if (jpc != null) {
- var idx = jpc.floatingAnchorIndex == null ? 1 : jpc.floatingAnchorIndex;
- jpc.endpoints[idx].anchor.out();
- }
- }
- });
- jsPlumb.CurrentLibrary.initDroppable(canvas, dropOptions, true, isTransient);
- }
- };
-
-
- _initDropTarget(_getElementObject(self.canvas), true, !(params._transient || self.anchor.isFloating), self);
- return self;
- };
- };
- var jsPlumb = window.jsPlumb = new jsPlumbInstance();
- jsPlumb.getInstance = function(_defaults) {
- var j = new jsPlumbInstance(_defaults);
- j.init();
- return j;
- };
- jsPlumb.util = {
- convertStyle : function(s, ignoreAlpha) {
-
- if ("transparent" === s) return s;
- var o = s,
- pad = function(n) { return n.length == 1 ? "0" + n : n; },
- hex = function(k) { return pad(Number(k).toString(16)); },
- pattern = /(rgb[a]?\()(.*)(\))/;
- if (s.match(pattern)) {
- var parts = s.match(pattern)[2].split(",");
- o = "#" + hex(parts[0]) + hex(parts[1]) + hex(parts[2]);
- if (!ignoreAlpha && parts.length == 4)
- o = o + hex(parts[3]);
- }
- return o;
- },
- gradient : function(p1, p2) {
- p1 = p1.constructor == Array ? p1 : [p1.x, p1.y];
- p2 = p2.constructor == Array ? p2 : [p2.x, p2.y];
- return (p2[1] - p1[1]) / (p2[0] - p1[0]);
- },
- normal : function(p1, p2) {
- return -1 / jsPlumb.util.gradient(p1,p2);
- },
- segment : function(p1, p2) {
- p1 = p1.constructor == Array ? p1 : [p1.x, p1.y];
- p2 = p2.constructor == Array ? p2 : [p2.x, p2.y];
- if (p2[0] > p1[0]) {
- return (p2[1] > p1[1]) ? 2 : 1;
- }
- else {
- return (p2[1] > p1[1]) ? 3 : 4;
- }
- },
- intersects : function(r1, r2) {
- var x1 = r1.x, x2 = r1.x + r1.w, y1 = r1.y, y2 = r1.y + r1.h,
- a1 = r2.x, a2 = r2.x + r2.w, b1 = r2.y, b2 = r2.y + r2.h;
-
- return ( (x1 < a1 && a1 < x2) && (y1 < b1 && b1 < y2) ) ||
- ( (x1 < a2 && a2 < x2) && (y1 < b1 && b1 < y2) ) ||
- ( (x1 < a1 && a1 < x2) && (y1 < b2 && b2 < y2) ) ||
- ( (x1 < a2 && a1 < x2) && (y1 < b2 && b2 < y2) ) ||
-
- ( (a1 < x1 && x1 < a2) && (b1 < y1 && y1 < b2) ) ||
- ( (a1 < x2 && x2 < a2) && (b1 < y1 && y1 < b2) ) ||
- ( (a1 < x1 && x1 < a2) && (b1 < y2 && y2 < b2) ) ||
- ( (a1 < x2 && x1 < a2) && (b1 < y2 && y2 < b2) );
- },
- segmentMultipliers : [null, [1, -1], [1, 1], [-1, 1], [-1, -1] ],
- inverseSegmentMultipliers : [null, [-1, -1], [-1, 1], [1, 1], [1, -1] ],
- pointOnLine : function(fromPoint, toPoint, distance) {
- var m = jsPlumb.util.gradient(fromPoint, toPoint),
- s = jsPlumb.util.segment(fromPoint, toPoint),
- segmentMultiplier = distance > 0 ? jsPlumb.util.segmentMultipliers[s] : jsPlumb.util.inverseSegmentMultipliers[s],
- theta = Math.atan(m),
- y = Math.abs(distance * Math.sin(theta)) * segmentMultiplier[1],
- x = Math.abs(distance * Math.cos(theta)) * segmentMultiplier[0];
- return { x:fromPoint.x + x, y:fromPoint.y + y };
- },
-
- perpendicularLineTo : function(fromPoint, toPoint, length) {
- var m = jsPlumb.util.gradient(fromPoint, toPoint),
- theta2 = Math.atan(-1 / m),
- y = length / 2 * Math.sin(theta2),
- x = length / 2 * Math.cos(theta2);
- return [{x:toPoint.x + x, y:toPoint.y + y}, {x:toPoint.x - x, y:toPoint.y - y}];
- }
- };
-
- var _curryAnchor = function(x, y, ox, oy, type, fnInit) {
- return function(params) {
- params = params || {};
-
- var a = params.jsPlumbInstance.makeAnchor([ x, y, ox, oy, 0, 0 ], params.elementId, params.jsPlumbInstance);
- a.type = type;
- if (fnInit) fnInit(a, params);
- return a;
- };
- };
- jsPlumb.Anchors["TopCenter"] = _curryAnchor(0.5, 0, 0,-1, "TopCenter");
- jsPlumb.Anchors["BottomCenter"] = _curryAnchor(0.5, 1, 0, 1, "BottomCenter");
- jsPlumb.Anchors["LeftMiddle"] = _curryAnchor(0, 0.5, -1, 0, "LeftMiddle");
- jsPlumb.Anchors["RightMiddle"] = _curryAnchor(1, 0.5, 1, 0, "RightMiddle");
- jsPlumb.Anchors["Center"] = _curryAnchor(0.5, 0.5, 0, 0, "Center");
- jsPlumb.Anchors["TopRight"] = _curryAnchor(1, 0, 0,-1, "TopRight");
- jsPlumb.Anchors["BottomRight"] = _curryAnchor(1, 1, 0, 1, "BottomRight");
- jsPlumb.Anchors["TopLeft"] = _curryAnchor(0, 0, 0, -1, "TopLeft");
- jsPlumb.Anchors["BottomLeft"] = _curryAnchor(0, 1, 0, 1, "BottomLeft");
-
-
- jsPlumb.Defaults.DynamicAnchors = function(params) {
- return params.jsPlumbInstance.makeAnchors(["TopCenter", "RightMiddle", "BottomCenter", "LeftMiddle"], params.elementId, params.jsPlumbInstance);
- };
- jsPlumb.Anchors["AutoDefault"] = function(params) {
- var a = params.jsPlumbInstance.makeDynamicAnchor(jsPlumb.Defaults.DynamicAnchors(params));
- a.type = "AutoDefault";
- return a;
- };
-
- jsPlumb.Anchors["Assign"] = _curryAnchor(0,0,0,0,"Assign", function(anchor, params) {
-
-
-
- var pf = params.position || "Fixed";
- anchor.positionFinder = pf.constructor == String ? params.jsPlumbInstance.AnchorPositionFinders[pf] : pf;
-
-
- anchor.constructorParams = params;
- });
-
-
- jsPlumb.Anchors["Continuous"] = function(params) {
- return params.jsPlumbInstance.continuousAnchorFactory.get(params);
- };
-
-
-
- jsPlumb.AnchorPositionFinders = {
- "Fixed": function(dp, ep, es, params) {
- return [ (dp.left - ep.left) / es[0], (dp.top - ep.top) / es[1] ];
- },
- "Grid":function(dp, ep, es, params) {
- var dx = dp.left - ep.left, dy = dp.top - ep.top,
- gx = es[0] / (params.grid[0]), gy = es[1] / (params.grid[1]),
- mx = Math.floor(dx / gx), my = Math.floor(dy / gy);
- return [ ((mx * gx) + (gx / 2)) / es[0], ((my * gy) + (gy / 2)) / es[1] ];
- }
- };
- })();
- (function() {
-
-
- jsPlumb.DOMElementComponent = function(params) {
- jsPlumb.jsPlumbUIComponent.apply(this, arguments);
-
-
- this.mousemove =
- this.dblclick =
- this.click =
- this.mousedown =
- this.mouseup = function(e) { };
- };
-
-
- jsPlumb.Connectors.Straight = function() {
- this.type = "Straight";
- var self = this,
- currentPoints = null,
- _m, _m2, _b, _dx, _dy, _theta, _theta2, _sx, _sy, _tx, _ty, _segment, _length;
-
- this.compute = function(sourcePos, targetPos, sourceEndpoint, targetEndpoint, sourceAnchor, targetAnchor, lineWidth, minWidth) {
- var w = Math.abs(sourcePos[0] - targetPos[0]),
- h = Math.abs(sourcePos[1] - targetPos[1]),
-
- xo = 0.45 * w, yo = 0.45 * h;
-
- w *= 1.9; h *=1.9;
-
- var x = Math.min(sourcePos[0], targetPos[0]) - xo;
- var y = Math.min(sourcePos[1], targetPos[1]) - yo;
-
-
- var calculatedMinWidth = Math.max(2 * lineWidth, minWidth);
-
- if (w < calculatedMinWidth) {
- w = calculatedMinWidth;
- x = sourcePos[0] + ((targetPos[0] - sourcePos[0]) / 2) - (calculatedMinWidth / 2);
- xo = (w - Math.abs(sourcePos[0]-targetPos[0])) / 2;
- }
- if (h < calculatedMinWidth) {
- h = calculatedMinWidth;
- y = sourcePos[1] + ((targetPos[1] - sourcePos[1]) / 2) - (calculatedMinWidth / 2);
- yo = (h - Math.abs(sourcePos[1]-targetPos[1])) / 2;
- }
-
- _sx = sourcePos[0] < targetPos[0] ? xo : w-xo;
- _sy = sourcePos[1] < targetPos[1] ? yo:h-yo;
- _tx = sourcePos[0] < targetPos[0] ? w-xo : xo;
- _ty = sourcePos[1] < targetPos[1] ? h-yo : yo;
- currentPoints = [ x, y, w, h, _sx, _sy, _tx, _ty ];
- _dx = _tx - _sx, _dy = _ty - _sy;
-
- _m = jsPlumb.util.gradient({x:_sx, y:_sy}, {x:_tx, y:_ty}), _m2 = -1 / _m;
- _b = -1 * ((_m * _sx) - _sy);
- _theta = Math.atan(_m); _theta2 = Math.atan(_m2);
-
- _length = Math.sqrt((_dx * _dx) + (_dy * _dy));
-
- return currentPoints;
- };
-
-
-
- this.pointOnPath = function(location) {
- if (location == 0)
- return { x:_sx, y:_sy };
- else if (location == 1)
- return { x:_tx, y:_ty };
- else
- return jsPlumb.util.pointOnLine({x:_sx, y:_sy}, {x:_tx, y:_ty}, location * _length);
- };
-
-
- this.gradientAtPoint = function(location) {
- return _m;
- };
-
-
- this.pointAlongPathFrom = function(location, distance) {
- var p = self.pointOnPath(location),
- farAwayPoint = location == 1 ? {
- x:_sx + ((_tx - _sx) * 10),
- y:_sy + ((_sy - _ty) * 10)
- } : {x:_tx, y:_ty };
- return jsPlumb.util.pointOnLine(p, farAwayPoint, distance);
- };
- };
-
-
-
-
- jsPlumb.Connectors.Bezier = function(params) {
- var self = this;
- params = params || {};
- this.majorAnchor = params.curviness || 150;
- this.minorAnchor = 10;
- var currentPoints = null;
- this.type = "Bezier";
-
- this._findControlPoint = function(point, sourceAnchorPosition, targetAnchorPosition, sourceEndpoint, targetEndpoint, sourceAnchor, targetAnchor) {
-
-
- var soo = sourceAnchor.getOrientation(sourceEndpoint),
- too = targetAnchor.getOrientation(targetEndpoint),
- perpendicular = soo[0] != too[0] || soo[1] == too[1],
- p = [],
- ma = self.majorAnchor, mi = self.minorAnchor;
-
- if (!perpendicular) {
- if (soo[0] == 0)
- p.push(sourceAnchorPosition[0] < targetAnchorPosition[0] ? point[0] + mi : point[0] - mi);
- else p.push(point[0] - (ma * soo[0]));
-
- if (soo[1] == 0)
- p.push(sourceAnchorPosition[1] < targetAnchorPosition[1] ? point[1] + mi : point[1] - mi);
- else p.push(point[1] + (ma * too[1]));
- }
- else {
- if (too[0] == 0)
- p.push(targetAnchorPosition[0] < sourceAnchorPosition[0] ? point[0] + mi : point[0] - mi);
- else p.push(point[0] + (ma * too[0]));
-
- if (too[1] == 0)
- p.push(targetAnchorPosition[1] < sourceAnchorPosition[1] ? point[1] + mi : point[1] - mi);
- else p.push(point[1] + (ma * soo[1]));
- }
- return p;
- };
- var _CP, _CP2, _sx, _tx, _ty, _sx, _sy, _canvasX, _canvasY, _w, _h, _sStubX, _sStubY, _tStubX, _tStubY;
- this.compute = function(sourcePos, targetPos, sourceEndpoint, targetEndpoint, sourceAnchor, targetAnchor, lineWidth, minWidth) {
- lineWidth = lineWidth || 0;
- _w = Math.abs(sourcePos[0] - targetPos[0]) + lineWidth;
- _h = Math.abs(sourcePos[1] - targetPos[1]) + lineWidth;
- _canvasX = Math.min(sourcePos[0], targetPos[0])-(lineWidth/2);
- _canvasY = Math.min(sourcePos[1], targetPos[1])-(lineWidth/2);
- _sx = sourcePos[0] < targetPos[0] ? _w - (lineWidth/2): (lineWidth/2);
- _sy = sourcePos[1] < targetPos[1] ? _h - (lineWidth/2) : (lineWidth/2);
- _tx = sourcePos[0] < targetPos[0] ? (lineWidth/2) : _w - (lineWidth/2);
- _ty = sourcePos[1] < targetPos[1] ? (lineWidth/2) : _h - (lineWidth/2);
-
- _CP = self._findControlPoint([_sx,_sy], sourcePos, targetPos, sourceEndpoint, targetEndpoint, sourceAnchor, targetAnchor);
- _CP2 = self._findControlPoint([_tx,_ty], targetPos, sourcePos, sourceEndpoint, targetEndpoint, targetAnchor, sourceAnchor);
- var minx1 = Math.min(_sx,_tx), minx2 = Math.min(_CP[0], _CP2[0]), minx = Math.min(minx1,minx2),
- maxx1 = Math.max(_sx,_tx), maxx2 = Math.max(_CP[0], _CP2[0]), maxx = Math.max(maxx1,maxx2);
-
- if (maxx > _w) _w = maxx;
- if (minx < 0) {
- _canvasX += minx; var ox = Math.abs(minx);
- _w += ox; _CP[0] += ox; _sx += ox; _tx +=ox; _CP2[0] += ox;
- }
- var miny1 = Math.min(_sy,_ty), miny2 = Math.min(_CP[1], _CP2[1]), miny = Math.min(miny1,miny2),
- maxy1 = Math.max(_sy,_ty), maxy2 = Math.max(_CP[1], _CP2[1]), maxy = Math.max(maxy1,maxy2);
-
- if (maxy > _h) _h = maxy;
- if (miny < 0) {
- _canvasY += miny; var oy = Math.abs(miny);
- _h += oy; _CP[1] += oy; _sy += oy; _ty +=oy; _CP2[1] += oy;
- }
-
- if (minWidth && _w < minWidth) {
- var posAdjust = (minWidth - _w) / 2;
- _w = minWidth;
- _canvasX -= posAdjust; _sx = _sx + posAdjust ; _tx = _tx + posAdjust; _CP[0] = _CP[0] + posAdjust; _CP2[0] = _CP2[0] + posAdjust;
- }
-
- if (minWidth && _h < minWidth) {
- var posAdjust = (minWidth - _h) / 2;
- _h = minWidth;
- _canvasY -= posAdjust; _sy = _sy + posAdjust ; _ty = _ty + posAdjust; _CP[1] = _CP[1] + posAdjust; _CP2[1] = _CP2[1] + posAdjust;
- }
- currentPoints = [_canvasX, _canvasY, _w, _h,
- _sx, _sy, _tx, _ty,
- _CP[0], _CP[1], _CP2[0], _CP2[1] ];
-
- return currentPoints;
- };
-
- var _makeCurve = function() {
- return [
- { x:_sx, y:_sy },
- { x:_CP[0], y:_CP[1] },
- { x:_CP2[0], y:_CP2[1] },
- { x:_tx, y:_ty }
- ];
- };
-
-
- this.pointOnPath = function(location) {
- return jsBezier.pointOnCurve(_makeCurve(), location);
- };
-
-
- this.gradientAtPoint = function(location) {
- return jsBezier.gradientAtPoint(_makeCurve(), location);
- };
-
-
- this.pointAlongPathFrom = function(location, distance) {
- return jsBezier.pointAlongCurveFrom(_makeCurve(), location, distance);
- };
- };
-
-
-
-
- jsPlumb.Connectors.Flowchart = function(params) {
- this.type = "Flowchart";
- params = params || {};
- var self = this,
- minStubLength = params.stub || params.minStubLength || 30,
- segments = [],
- totalLength = 0,
- segmentProportions = [],
- segmentProportionalLengths = [],
- points = [],
- swapX, swapY,
- maxX = 0, maxY = 0,
-
- updateSegmentProportions = function(startX, startY, endX, endY) {
- var curLoc = 0;
- for (var i = 0; i < segments.length; i++) {
- segmentProportionalLengths[i] = segments[i][5] / totalLength;
- segmentProportions[i] = [curLoc, (curLoc += (segments[i][5] / totalLength)) ];
- }
- },
- appendSegmentsToPoints = function() {
- points.push(segments.length);
- for (var i = 0; i < segments.length; i++) {
- points.push(segments[i][0]);
- points.push(segments[i][1]);
- }
- },
-
- addSegment = function(x, y, sx, sy, tx, ty) {
- var lx = segments.length == 0 ? sx : segments[segments.length - 1][0],
- ly = segments.length == 0 ? sy : segments[segments.length - 1][1],
- m = x == lx ? Infinity : 0,
- l = Math.abs(x == lx ? y - ly : x - lx);
- segments.push([x, y, lx, ly, m, l]);
- totalLength += l;
-
- maxX = Math.max(maxX, x);
- maxY = Math.max(maxY, y);
- },
-
- findSegmentForLocation = function(location) {
- var idx = segmentProportions.length - 1, inSegmentProportion = 1;
- for (var i = 0; i < segmentProportions.length; i++) {
- if (segmentProportions[i][1] >= location) {
- idx = i;
- inSegmentProportion = (location - segmentProportions[i][0]) / segmentProportionalLengths[i];
- break;
- }
- }
- return { segment:segments[idx], proportion:inSegmentProportion, index:idx };
- };
-
- this.compute = function(sourcePos, targetPos, sourceEndpoint, targetEndpoint,
- sourceAnchor, targetAnchor, lineWidth, minWidth, sourceInfo, targetInfo) {
-
- segments = [];
- totalLength = 0;
- segmentProportionalLengths = [];
- maxX = maxY = 0;
-
- swapX = targetPos[0] < sourcePos[0];
- swapY = targetPos[1] < sourcePos[1];
-
- var lw = lineWidth || 1,
- offx = (lw / 2) + (minStubLength * 2),
- offy = (lw / 2) + (minStubLength * 2),
- so = sourceAnchor.orientation || sourceAnchor.getOrientation(sourceEndpoint),
- to = targetAnchor.orientation || targetAnchor.getOrientation(targetEndpoint),
- x = swapX ? targetPos[0] : sourcePos[0],
- y = swapY ? targetPos[1] : sourcePos[1],
- w = Math.abs(targetPos[0] - sourcePos[0]) + 2*offx,
- h = Math.abs(targetPos[1] - sourcePos[1]) + 2*offy;
-
-
-
- if (so[0] == 0 && so[1] == 0 || to[0] == 0 && to[1] == 0) {
- var index = w > h ? 0 : 1, oIndex = [1,0][index];
- so = []; to = [];
- so[index] = sourcePos[index] > targetPos[index] ? -1 : 1;
- to[index] = sourcePos[index] > targetPos[index] ? 1 : -1;
- so[oIndex] = 0;
- to[oIndex] = 0;
- }
- if (w < minWidth) {
- offx += (minWidth - w) / 2;
- w = minWidth;
- }
- if (h < minWidth) {
- offy += (minWidth - h) / 2;
- h = minWidth;
- }
- var sx = swapX ? w-offx : offx,
- sy = swapY ? h-offy : offy,
- tx = swapX ? offx : w-offx ,
- ty = swapY ? offy : h-offy,
- startStubX = sx + (so[0] * minStubLength),
- startStubY = sy + (so[1] * minStubLength),
- endStubX = tx + (to[0] * minStubLength),
- endStubY = ty + (to[1] * minStubLength),
- isXGreaterThanStubTimes2 = Math.abs(sx - tx) > 2 * minStubLength,
- isYGreaterThanStubTimes2 = Math.abs(sy - ty) > 2 * minStubLength,
- midx = startStubX + ((endStubX - startStubX) / 2),
- midy = startStubY + ((endStubY - startStubY) / 2),
- oProduct = ((so[0] * to[0]) + (so[1] * to[1])),
- opposite = oProduct == -1,
- perpendicular = oProduct == 0,
- orthogonal = oProduct == 1;
-
- x -= offx; y -= offy;
- points = [x, y, w, h, sx, sy, tx, ty];
- var extraPoints = [];
-
- addSegment(startStubX, startStubY, sx, sy, tx, ty);
-
- var sourceAxis = so[0] == 0 ? "y" : "x",
- anchorOrientation = opposite ? "opposite" : orthogonal ? "orthogonal" : "perpendicular",
- segment = jsPlumb.util.segment([sx, sy], [tx, ty]),
- flipSourceSegments = so[sourceAxis == "x" ? 0 : 1] == -1,
- flipSegments = {
- "x":[null, 4, 3, 2, 1],
- "y":[null, 2, 1, 4, 3]
- }
-
- if (flipSourceSegments)
- segment = flipSegments[sourceAxis][segment];
- var findClearedLine = function(start, mult, anchorPos, dimension) {
- return start + (mult * (( 1 - anchorPos) * dimension) + minStubLength);
-
- },
- lineCalculators = {
- oppositex : function() {
- if (sourceEndpoint.elementId == targetEndpoint.elementId) {
- var _y = startStubY + ((1 - sourceAnchor.y) * sourceInfo.height) + minStubLength;
- return [ [ startStubX, _y ], [ endStubX, _y ]];
- }
- else if (isXGreaterThanStubTimes2 && (segment == 1 || segment == 2)) {
- return [[ midx, sy ], [ midx, ty ]];
- }
- else {
- return [[ startStubX, midy ], [endStubX, midy ]];
- }
- },
- orthogonalx : function() {
- if (segment == 1 || segment == 2) {
- return [ [ endStubX, startStubY ]];
- }
- else {
- return [ [ startStubX, endStubY ]];
- }
- },
- perpendicularx : function() {
- var my = (ty + sy) / 2;
- if ((segment == 1 && to[1] == 1) || (segment == 2 && to[1] == -1)) {
- if (Math.abs(tx - sx) > minStubLength)
- return [ [endStubX, startStubY ]];
- else
- return [ [startStubX, startStubY ], [ startStubX, my ], [ endStubX, my ]];
- }
- else if ((segment == 3 && to[1] == -1) || (segment == 4 && to[1] == 1)) {
- return [ [ startStubX, my ], [ endStubX, my ]];
- }
- else if ((segment == 3 && to[1] == 1) || (segment == 4 && to[1] == -1)) {
- return [ [ startStubX, endStubY ]];
- }
- else if ((segment == 1 && to[1] == -1) || (segment == 2 && to[1] == 1)) {
- if (Math.abs(tx - sx) > minStubLength)
- return [ [ midx, startStubY ], [ midx, endStubY ]];
- else
- return [ [ startStubX, endStubY ]];
- }
- },
- oppositey : function() {
- if (sourceEndpoint.elementId == targetEndpoint.elementId) {
- var _x = startStubX + ((1 - sourceAnchor.x) * sourceInfo.width) + minStubLength;
- return [ [ _x, startStubY ], [ _x, endStubY ]];
- }
- else if (isYGreaterThanStubTimes2 && (segment == 2 || segment == 3)) {
- return [[ sx, midy ], [ tx, midy ]];
- }
- else {
- return [[ midx, startStubY ], [midx, endStubY ]];
- }
- },
- orthogonaly : function() {
- if (segment == 2 || segment == 3) {
- return [ [ startStubX, endStubY ]];
- }
- else {
- return [ [ endStubX, startStubY ]];
- }
- },
- perpendiculary : function() {
- var mx = (tx + sx) / 2;
- if ((segment == 2 && to[0] == -1) || (segment == 3 && to[0] == 1)) {
- if (Math.abs(tx - sx) > minStubLength)
- return [ [startStubX, endStubY ]];
- else
- return [ [startStubX, midy ], [ endStubX, midy ]];
- }
- else if ((segment == 1 && to[0] == -1) || (segment == 4 && to[0] == 1)) {
- var mx = (tx + sx) / 2;
- return [ [ mx, startStubY ], [ mx, endStubY ]];
- }
- else if ((segment == 1 && to[0] == 1) || (segment == 4 && to[0] == -1)) {
- return [ [ endStubX, startStubY ]];
- }
- else if ((segment == 2 && to[0] == 1) || (segment == 3 && to[0] == -1)) {
- if (Math.abs(ty - sy) > minStubLength)
- return [ [ startStubX, midy ], [ endStubX, midy ]];
- else
- return [ [ endStubX, startStubY ]];
- }
- }
- };
- var p = lineCalculators[anchorOrientation + sourceAxis]();
- if (p) {
- for (var i = 0; i < p.length; i++) {
- addSegment(p[i][0], p[i][1], sx, sy, tx, ty);
- }
- }
-
- addSegment(endStubX, endStubY, sx, sy, tx, ty);
- addSegment(tx, ty, sx, sy, tx, ty);
-
- appendSegmentsToPoints();
- updateSegmentProportions(sx, sy, tx, ty);
-
-
-
- if (maxY > points[3]) points[3] = maxY + (lineWidth * 2);
- if (maxX > points[2]) points[2] = maxX + (lineWidth * 2);
-
- return points;
- };
-
-
- this.pointOnPath = function(location) {
- return self.pointAlongPathFrom(location, 0);
- };
-
-
- this.gradientAtPoint = function(location) {
- return segments[findSegmentForLocation(location)["index"]][4];
- };
-
-
- this.pointAlongPathFrom = function(location, distance) {
- var s = findSegmentForLocation(location), seg = s.segment, p = s.proportion, sl = segments[s.index][5], m = segments[s.index][4];
- var e = {
- x : m == Infinity ? seg[2] : seg[2] > seg[0] ? seg[0] + ((1 - p) * sl) - distance : seg[2] + (p * sl) + distance,
- y : m == 0 ? seg[3] : seg[3] > seg[1] ? seg[1] + ((1 - p) * sl) - distance : seg[3] + (p * sl) + distance,
- segmentInfo : s
- };
-
- return e;
- };
- };
-
-
-
-
-
-
-
-
- jsPlumb.Endpoints.Dot = function(params) {
- this.type = "Dot";
- var self = this;
- params = params || {};
- this.radius = params.radius || 10;
- this.defaultOffset = 0.5 * this.radius;
- this.defaultInnerRadius = this.radius / 3;
-
- this.compute = function(anchorPoint, orientation, endpointStyle, connectorPaintStyle) {
- var r = endpointStyle.radius || self.radius,
- x = anchorPoint[0] - r,
- y = anchorPoint[1] - r;
- return [ x, y, r * 2, r * 2, r ];
- };
- };
-
-
-
- jsPlumb.Endpoints.Rectangle = function(params) {
- this.type = "Rectangle";
- var self = this;
- params = params || {};
- this.width = params.width || 20;
- this.height = params.height || 20;
-
- this.compute = function(anchorPoint, orientation, endpointStyle, connectorPaintStyle) {
- var width = endpointStyle.width || self.width,
- height = endpointStyle.height || self.height,
- x = anchorPoint[0] - (width/2),
- y = anchorPoint[1] - (height/2);
- return [ x, y, width, height];
- };
- };
-
- var DOMElementEndpoint = function(params) {
- jsPlumb.DOMElementComponent.apply(this, arguments);
- var self = this;
- var displayElements = [ ];
- this.getDisplayElements = function() {
- return displayElements;
- };
-
- this.appendDisplayElement = function(el) {
- displayElements.push(el);
- };
- };
-
-
- jsPlumb.Endpoints.Image = function(params) {
-
- this.type = "Image";
- DOMElementEndpoint.apply(this, arguments);
-
- var self = this,
- initialized = false,
- widthToUse = params.width,
- heightToUse = params.height,
- _onload = null,
- _endpoint = params.endpoint;
-
- this.img = new Image();
- self.ready = false;
- this.img.onload = function() {
- self.ready = true;
- widthToUse = widthToUse || self.img.width;
- heightToUse = heightToUse || self.img.height;
- if (_onload) {
- _onload(self);
- }
- };
- _endpoint.setImage = function(img, onload) {
- var s = img.constructor == String ? img : img.src;
- _onload = onload;
- self.img.src = img;
- };
- _endpoint.setImage(params.src || params.url, params.onload);
- this.compute = function(anchorPoint, orientation, endpointStyle, connectorPaintStyle) {
- self.anchorPoint = anchorPoint;
- if (self.ready) return [anchorPoint[0] - widthToUse / 2, anchorPoint[1] - heightToUse / 2,
- widthToUse, heightToUse];
- else return [0,0,0,0];
- };
-
- self.canvas = document.createElement("img"), initialized = false;
- self.canvas.style["margin"] = 0;
- self.canvas.style["padding"] = 0;
- self.canvas.style["outline"] = 0;
- self.canvas.style["position"] = "absolute";
- var clazz = params.cssClass ? " " + params.cssClass : "";
- self.canvas.className = jsPlumb.endpointClass + clazz;
- if (widthToUse) self.canvas.setAttribute("width", widthToUse);
- if (heightToUse) self.canvas.setAttribute("height", heightToUse);
- jsPlumb.appendElement(self.canvas, params.parent);
- self.attachListeners(self.canvas, self);
-
- var actuallyPaint = function(d, style, anchor) {
- if (!initialized) {
- self.canvas.setAttribute("src", self.img.src);
- initialized = true;
- }
- var x = self.anchorPoint[0] - (widthToUse / 2),
- y = self.anchorPoint[1] - (heightToUse / 2);
- jsPlumb.sizeCanvas(self.canvas, x, y, widthToUse, heightToUse);
- };
-
- this.paint = function(d, style, anchor) {
- if (self.ready) {
- actuallyPaint(d, style, anchor);
- }
- else {
- window.setTimeout(function() {
- self.paint(d, style, anchor);
- }, 200);
- }
- };
- };
-
-
- jsPlumb.Endpoints.Blank = function(params) {
- var self = this;
- this.type = "Blank";
- DOMElementEndpoint.apply(this, arguments);
- this.compute = function(anchorPoint, orientation, endpointStyle, connectorPaintStyle) {
- return [anchorPoint[0], anchorPoint[1],10,0];
- };
-
- self.canvas = document.createElement("div");
- self.canvas.style.display = "block";
- self.canvas.style.width = "1px";
- self.canvas.style.height = "1px";
- self.canvas.style.background = "transparent";
- self.canvas.style.position = "absolute";
- self.canvas.className = self._jsPlumb.endpointClass;
- jsPlumb.appendElement(self.canvas, params.parent);
-
- this.paint = function(d, style, anchor) {
- jsPlumb.sizeCanvas(self.canvas, d[0], d[1], d[2], d[3]);
- };
- };
-
-
-
- jsPlumb.Endpoints.Triangle = function(params) {
- this.type = "Triangle";
- params = params || { };
- params.width = params.width || 55;
- params.height = params.height || 55;
- this.width = params.width;
- this.height = params.height;
- this.compute = function(anchorPoint, orientation, endpointStyle, connectorPaintStyle) {
- var width = endpointStyle.width || self.width,
- height = endpointStyle.height || self.height,
- x = anchorPoint[0] - (width/2),
- y = anchorPoint[1] - (height/2);
- return [ x, y, width, height ];
- };
- };
-
- var AbstractOverlay = function(params) {
- var visible = true, self = this;
- this.isAppendedAtTopLevel = true;
- this.component = params.component;
- this.loc = params.location == null ? 0.5 : params.location;
- this.endpointLoc = params.endpointLocation == null ? [ 0.5, 0.5] : params.endpointLocation;
- this.setVisible = function(val) {
- visible = val;
- self.component.repaint();
- };
- this.isVisible = function() { return visible; };
- this.hide = function() { self.setVisible(false); };
- this.show = function() { self.setVisible(true); };
-
- this.incrementLocation = function(amount) {
- self.loc += amount;
- self.component.repaint();
- };
- this.setLocation = function(l) {
- self.loc = l;
- self.component.repaint();
- };
- this.getLocation = function() {
- return self.loc;
- };
- };
-
-
-
-
- jsPlumb.Overlays.Arrow = function(params) {
- this.type = "Arrow";
- AbstractOverlay.apply(this, arguments);
- this.isAppendedAtTopLevel = false;
- params = params || {};
- var self = this;
-
- this.length = params.length || 20;
- this.width = params.width || 20;
- this.id = params.id;
- var direction = (params.direction || 1) < 0 ? -1 : 1,
- paintStyle = params.paintStyle || { lineWidth:1 },
-
- foldback = params.foldback || 0.623;
-
- this.computeMaxSize = function() { return self.width * 1.5; };
-
- this.cleanup = function() { };
-
- this.draw = function(connector, currentConnectionPaintStyle, connectorDimensions) {
- var hxy, mid, txy, tail, cxy;
- if (connector.pointAlongPathFrom) {
- if (self.loc == 1) {
- hxy = connector.pointOnPath(self.loc);
- mid = connector.pointAlongPathFrom(self.loc, -1);
- txy = jsPlumb.util.pointOnLine(hxy, mid, self.length);
- }
- else if (self.loc == 0) {
- txy = connector.pointOnPath(self.loc);
- mid = connector.pointAlongPathFrom(self.loc, 1);
- hxy = jsPlumb.util.pointOnLine(txy, mid, self.length);
- }
- else {
- hxy = connector.pointAlongPathFrom(self.loc, direction * self.length / 2),
- mid = connector.pointOnPath(self.loc),
- txy = jsPlumb.util.pointOnLine(hxy, mid, self.length);
- }
- tail = jsPlumb.util.perpendicularLineTo(hxy, txy, self.width);
- cxy = jsPlumb.util.pointOnLine(hxy, txy, foldback * self.length);
- var minx = Math.min(hxy.x, tail[0].x, tail[1].x),
- maxx = Math.max(hxy.x, tail[0].x, tail[1].x),
- miny = Math.min(hxy.y, tail[0].y, tail[1].y),
- maxy = Math.max(hxy.y, tail[0].y, tail[1].y);
-
- var d = { hxy:hxy, tail:tail, cxy:cxy },
- strokeStyle = paintStyle.strokeStyle || currentConnectionPaintStyle.strokeStyle,
- fillStyle = paintStyle.fillStyle || currentConnectionPaintStyle.strokeStyle,
- lineWidth = paintStyle.lineWidth || currentConnectionPaintStyle.lineWidth;
-
- self.paint(connector, d, lineWidth, strokeStyle, fillStyle, connectorDimensions);
-
- return [ minx, maxx, miny, maxy];
- }
- else return [0,0,0,0];
- };
- };
-
-
-
- jsPlumb.Overlays.PlainArrow = function(params) {
- params = params || {};
- var p = jsPlumb.extend(params, {foldback:1});
- jsPlumb.Overlays.Arrow.call(this, p);
- this.type = "PlainArrow";
- };
-
-
-
- jsPlumb.Overlays.Diamond = function(params) {
- params = params || {};
- var l = params.length || 40,
- p = jsPlumb.extend(params, {length:l/2, foldback:2});
- jsPlumb.Overlays.Arrow.call(this, p);
- this.type = "Diamond";
- };
-
-
-
-
-
- jsPlumb.Overlays.Label = function(params) {
- this.type = "Label";
- jsPlumb.DOMElementComponent.apply(this, arguments);
- AbstractOverlay.apply(this, arguments);
- this.labelStyle = params.labelStyle || jsPlumb.Defaults.LabelStyle;
- this.id = params.id;
- this.cachedDimensions = null;
- var label = params.label || "",
- self = this,
- initialised = false,
- div = document.createElement("div"),
- labelText = null;
- div.style["position"] = "absolute";
-
- var clazz = params["_jsPlumb"].overlayClass + " " +
- (self.labelStyle.cssClass ? self.labelStyle.cssClass :
- params.cssClass ? params.cssClass : "");
-
- div.className = clazz;
-
- jsPlumb.appendElement(div, params.component.parent);
- jsPlumb.getId(div);
- self.attachListeners(div, self);
- self.canvas = div;
-
-
- var osv = self.setVisible;
- self.setVisible = function(state) {
- osv(state);
- div.style.display = state ? "block" : "none";
- };
-
- this.getElement = function() {
- return div;
- };
-
- this.cleanup = function() {
- if (div != null) jsPlumb.CurrentLibrary.removeElement(div);
- };
-
-
- this.setLabel = function(l) {
- label = l;
- labelText = null;
- self.component.repaint();
- };
-
- this.getLabel = function() {
- return label;
- };
-
- this.paint = function(component, d, componentDimensions) {
- if (!initialised) {
- component.appendDisplayElement(div);
- self.attachListeners(div, component);
- initialised = true;
- }
- div.style.left = (componentDimensions[0] + d.minx) + "px";
- div.style.top = (componentDimensions[1] + d.miny) + "px";
- };
-
- this.getTextDimensions = function() {
- if (typeof label == "function") {
- var lt = label(self);
- div.innerHTML = lt.replace(/\r\n/g, "<br/>");
- }
- else {
- if (labelText == null) {
- labelText = label;
- div.innerHTML = labelText.replace(/\r\n/g, "<br/>");
- }
- }
- var de = jsPlumb.CurrentLibrary.getElementObject(div),
- s = jsPlumb.CurrentLibrary.getSize(de);
- return {width:s[0], height:s[1]};
- };
-
- this.computeMaxSize = function(connector) {
- var td = self.getTextDimensions(connector);
- return td.width ? Math.max(td.width, td.height) * 1.5 : 0;
- };
-
- this.draw = function(component, currentConnectionPaintStyle, componentDimensions) {
- var td = self.getTextDimensions(component);
- if (td.width != null) {
- var cxy = {x:0,y:0};
- if (component.pointOnPath)
- cxy = component.pointOnPath(self.loc);
- else {
- var locToUse = self.loc.constructor == Array ? self.loc : self.endpointLoc;
- cxy = { x:locToUse[0] * componentDimensions[2],
- y:locToUse[1] * componentDimensions[3] };
- }
-
- minx = cxy.x - (td.width / 2),
- miny = cxy.y - (td.height / 2);
-
- self.paint(component, {
- minx:minx,
- miny:miny,
- td:td,
- cxy:cxy
- }, componentDimensions);
-
- return [minx, minx+td.width, miny, miny+td.height];
- }
- else return [0,0,0,0];
- };
-
- this.reattachListeners = function(connector) {
- if (div) {
- self.reattachListenersForElement(div, self, connector);
- }
- };
- };
-
- jsPlumb.Overlays.GuideLines = function() {
- var self = this;
- self.length = 50;
- self.lineWidth = 5;
- this.type = "GuideLines";
- AbstractOverlay.apply(this, arguments);
- jsPlumb.jsPlumbUIComponent.apply(this, arguments);
- this.draw = function(connector, currentConnectionPaintStyle, connectorDimensions) {
- var head = connector.pointAlongPathFrom(self.loc, self.length / 2),
- mid = connector.pointOnPath(self.loc),
- tail = jsPlumb.util.pointOnLine(head, mid, self.length),
- tailLine = jsPlumb.util.perpendicularLineTo(head, tail, 40),
- headLine = jsPlumb.util.perpendicularLineTo(tail, head, 20);
- self.paint(connector, [head, tail, tailLine, headLine], self.lineWidth, "red", null, connectorDimensions);
- return [Math.min(head.x, tail.x), Math.min(head.y, tail.y), Math.max(head.x, tail.x), Math.max(head.y,tail.y)];
- };
- this.computeMaxSize = function() { return 50; };
- this.cleanup = function() { };
- };
-
-
-
-
-
- })();
- ;(function() {
- var Line = function(x1, y1, x2, y2) {
- this.m = (y2 - y1) / (x2 - x1);
- this.b = -1 * ((this.m * x1) - y1);
-
- this.rectIntersect = function(x,y,w,h) {
- var results = [];
-
-
-
- var xInt = (y - this.b) / this.m;
-
- if (xInt >= x && xInt <= (x + w)) results.push([ xInt, (this.m * xInt) + this.b ]);
-
-
- var yInt = (this.m * (x + w)) + this.b;
- if (yInt >= y && yInt <= (y + h)) results.push([ (yInt - this.b) / this.m, yInt ]);
-
-
- var xInt = ((y + h) - this.b) / this.m;
-
- if (xInt >= x && xInt <= (x + w)) results.push([ xInt, (this.m * xInt) + this.b ]);
-
-
- var yInt = (this.m * x) + this.b;
- if (yInt >= y && yInt <= (y + h)) results.push([ (yInt - this.b) / this.m, yInt ]);
- if (results.length == 2) {
- var midx = (results[0][0] + results[1][0]) / 2, midy = (results[0][1] + results[1][1]) / 2;
- results.push([ midx,midy ]);
-
- var xseg = midx <= x + (w / 2) ? -1 : 1,
- yseg = midy <= y + (h / 2) ? -1 : 1;
- results.push([xseg, yseg]);
- return results;
- }
-
- return null;
- };
- },
- _segment = function(x1, y1, x2, y2) {
- if (x1 <= x2 && y2 <= y1) return 1;
- else if (x1 <= x2 && y1 <= y2) return 2;
- else if (x2 <= x1 && y2 >= y1) return 3;
- return 4;
- },
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- _findControlPoint = function(midx, midy, segment, sourceEdge, targetEdge, dx, dy, distance, proximityLimit) {
-
-
- if (distance <= proximityLimit) return [midx, midy];
- if (segment == 1) {
- if (sourceEdge[3] <= 0 && targetEdge[3] >= 1) return [ midx + (sourceEdge[2] < 0.5 ? -1 * dx : dx), midy ];
- else if (sourceEdge[2] >= 1 && targetEdge[2] <= 0) return [ midx, midy + (sourceEdge[3] < 0.5 ? -1 * dy : dy) ];
- else return [ midx + (-1 * dx) , midy + (-1 * dy) ];
- }
- else if (segment == 2) {
- if (sourceEdge[3] >= 1 && targetEdge[3] <= 0) return [ midx + (sourceEdge[2] < 0.5 ? -1 * dx : dx), midy ];
- else if (sourceEdge[2] >= 1 && targetEdge[2] <= 0) return [ midx, midy + (sourceEdge[3] < 0.5 ? -1 * dy : dy) ];
- else return [ midx + (1 * dx) , midy + (-1 * dy) ];
- }
- else if (segment == 3) {
- if (sourceEdge[3] >= 1 && targetEdge[3] <= 0) return [ midx + (sourceEdge[2] < 0.5 ? -1 * dx : dx), midy ];
- else if (sourceEdge[2] <= 0 && targetEdge[2] >= 1) return [ midx, midy + (sourceEdge[3] < 0.5 ? -1 * dy : dy) ];
- else return [ midx + (-1 * dx) , midy + (-1 * dy) ];
- }
- else if (segment == 4) {
- if (sourceEdge[3] <= 0 && targetEdge[3] >= 1) return [ midx + (sourceEdge[2] < 0.5 ? -1 * dx : dx), midy ];
- else if (sourceEdge[2] <= 0 && targetEdge[2] >= 1) return [ midx, midy + (sourceEdge[3] < 0.5 ? -1 * dy : dy) ];
- else return [ midx + (1 * dx) , midy + (-1 * dy) ];
- }
- };
-
- jsPlumb.Connectors.StateMachine = function(params) {
- var self = this,
- currentPoints = null,
- _sx, _sy, _tx, _ty, _controlPoint = [],
- curviness = params.curviness || 10,
- margin = params.margin || 5,
- proximityLimit = params.proximityLimit || 80,
- clockwise = params.orientation && params.orientation == "clockwise",
- loopbackRadius = params.loopbackRadius || 25,
- isLoopback = false;
- this.type = "StateMachine";
- params = params || {};
-
- this.compute = function(sourcePos, targetPos, sourceEndpoint, targetEndpoint, sourceAnchor, targetAnchor, lineWidth, minWidth) {
- var w = Math.abs(sourcePos[0] - targetPos[0]),
- h = Math.abs(sourcePos[1] - targetPos[1]),
-
- xo = 0.45 * w, yo = 0.45 * h;
-
- w *= 1.9; h *= 1.9;
-
- lineWidth = lineWidth || 1;
- var x = Math.min(sourcePos[0], targetPos[0]) - xo,
- y = Math.min(sourcePos[1], targetPos[1]) - yo;
-
- if (sourceEndpoint.elementId != targetEndpoint.elementId) {
-
- isLoopback = false;
-
- _sx = sourcePos[0] < targetPos[0] ? xo : w-xo;
- _sy = sourcePos[1] < targetPos[1] ? yo:h-yo;
- _tx = sourcePos[0] < targetPos[0] ? w-xo : xo;
- _ty = sourcePos[1] < targetPos[1] ? h-yo : yo;
-
-
- if (sourcePos[2] == 0) _sx -= margin;
- if (sourcePos[2] == 1) _sx += margin;
- if (sourcePos[3] == 0) _sy -= margin;
- if (sourcePos[3] == 1) _sy += margin;
- if (targetPos[2] == 0) _tx -= margin;
- if (targetPos[2] == 1) _tx += margin;
- if (targetPos[3] == 0) _ty -= margin;
- if (targetPos[3] == 1) _ty += margin;
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- var _midx = (_sx + _tx) / 2, _midy = (_sy + _ty) / 2,
- m2 = (-1 * _midx) / _midy, theta2 = Math.atan(m2),
- dy = (m2 == Infinity || m2 == -Infinity) ? 0 : Math.abs(curviness / 2 * Math.sin(theta2)),
- dx = (m2 == Infinity || m2 == -Infinity) ? 0 : Math.abs(curviness / 2 * Math.cos(theta2)),
- segment = _segment(_sx, _sy, _tx, _ty),
- distance = Math.sqrt(Math.pow(_tx - _sx, 2) + Math.pow(_ty - _sy, 2));
-
-
-
- _controlPoint = _findControlPoint(_midx,
- _midy,
- segment,
- sourcePos,
- targetPos,
- curviness, curviness,
- distance,
- proximityLimit);
-
- var requiredWidth = Math.max(Math.abs(_controlPoint[0] - _sx) * 3, Math.abs(_controlPoint[0] - _tx) * 3, Math.abs(_tx-_sx), 2 * lineWidth, minWidth),
- requiredHeight = Math.max(Math.abs(_controlPoint[1] - _sy) * 3, Math.abs(_controlPoint[1] - _ty) * 3, Math.abs(_ty-_sy), 2 * lineWidth, minWidth);
- if (w < requiredWidth) {
- var dw = requiredWidth - w;
- x -= (dw / 2);
- _sx += (dw / 2);
- _tx += (dw / 2);
- w = requiredWidth;
- _controlPoint[0] += (dw / 2);
- }
-
- if (h < requiredHeight) {
- var dh = requiredHeight - h;
- y -= (dh / 2);
- _sy += (dh / 2);
- _ty += (dh / 2);
- h = requiredHeight;
- _controlPoint[1] += (dh / 2);
- }
- currentPoints = [ x, y, w, h, _sx, _sy, _tx, _ty, _controlPoint[0], _controlPoint[1] ];
- }
- else {
- isLoopback = true;
-
-
- var x1 = sourcePos[0], x2 = sourcePos[0], y1 = sourcePos[1] - margin, y2 = sourcePos[1] - margin,
- cx = x1, cy = y1 - loopbackRadius;
-
-
- w = ((2 * lineWidth) + (4 * loopbackRadius)), h = ((2 * lineWidth) + (4 * loopbackRadius));
- x = cx - loopbackRadius - lineWidth - loopbackRadius, y = cy - loopbackRadius - lineWidth - loopbackRadius;
- currentPoints = [ x, y, w, h, cx-x, cy-y, loopbackRadius, clockwise, x1-x, y1-y, x2-x, y2-y];
- }
-
- return currentPoints;
- };
-
- var _makeCurve = function() {
- return [
- { x:_tx, y:_ty },
- { x:_controlPoint[0], y:_controlPoint[1] },
- { x:_controlPoint[0] + 1, y:_controlPoint[1] + 1},
- { x:_sx, y:_sy }
- ];
- };
-
-
- this.pointOnPath = function(location) {
- if (isLoopback) {
- if (location > 0 && location < 1) location = 1- location;
-
-
-
-
-
-
- var startAngle = (location * 2 * Math.PI) + (Math.PI / 2),
- startX = currentPoints[4] + (currentPoints[6] * Math.cos(startAngle)),
- startY = currentPoints[5] + (currentPoints[6] * Math.sin(startAngle));
- return {x:startX, y:startY};
-
- }
- else return jsBezier.pointOnCurve(_makeCurve(), location);
- };
-
-
- this.gradientAtPoint = function(location) {
- if (isLoopback)
- return Math.atan(location * 2 * Math.PI);
- else
- return jsBezier.gradientAtPoint(_makeCurve(), location);
- };
-
-
- this.pointAlongPathFrom = function(location, distance) {
- if (isLoopback) {
- if (location > 0 && location < 1) location = 1- location;
- var circumference = 2 * Math.PI * currentPoints[6],
- arcSpan = distance / circumference * 2 * Math.PI,
- startAngle = (location * 2 * Math.PI) - arcSpan + (Math.PI / 2),
-
- startX = currentPoints[4] + (currentPoints[6] * Math.cos(startAngle)),
- startY = currentPoints[5] + (currentPoints[6] * Math.sin(startAngle));
- return {x:startX, y:startY};
- }
- return jsBezier.pointAlongCurveFrom(_makeCurve(), location, distance);
- };
-
- };
-
-
- jsPlumb.Connectors.canvas.StateMachine = function(params) {
- params = params || {};
- var self = this, drawGuideline = params.drawGuideline || true, avoidSelector = params.avoidSelector;
- jsPlumb.Connectors.StateMachine.apply(this, arguments);
- jsPlumb.CanvasConnector.apply(this, arguments);
-
-
- this._paint = function(dimensions) {
-
- if (dimensions.length == 10) {
- self.ctx.beginPath();
- self.ctx.moveTo(dimensions[4], dimensions[5]);
- self.ctx.quadraticCurveTo(dimensions[8], dimensions[9], dimensions[6], dimensions[7]);
- self.ctx.stroke();
-
-
- }
- else {
-
- self.ctx.save();
- self.ctx.beginPath();
- var startAngle = 0,
- endAngle = 2 * Math.PI,
- clockwise = dimensions[7];
- self.ctx.arc(dimensions[4],dimensions[5],dimensions[6],0, endAngle, clockwise);
- self.ctx.stroke();
- self.ctx.closePath();
- self.ctx.restore();
- }
- };
-
- this.createGradient = function(dim, ctx) {
- return ctx.createLinearGradient(dim[4], dim[5], dim[6], dim[7]);
- };
- };
-
-
- jsPlumb.Connectors.svg.StateMachine = function() {
- var self = this;
- jsPlumb.Connectors.StateMachine.apply(this, arguments);
- jsPlumb.SvgConnector.apply(this, arguments);
- this.getPath = function(d) {
-
- if (d.length == 10)
- return "M " + d[4] + " " + d[5] + " C " + d[8] + " " + d[9] + " " + d[8] + " " + d[9] + " " + d[6] + " " + d[7];
- else {
-
- return "M" + (d[8] + 4) + " " + d[9] + " A " + d[6] + " " + d[6] + " 0 1,0 " + (d[8]-4) + " " + d[9];
- }
- };
- };
-
-
- jsPlumb.Connectors.vml.StateMachine = function() {
- jsPlumb.Connectors.StateMachine.apply(this, arguments);
- jsPlumb.VmlConnector.apply(this, arguments);
- var _conv = jsPlumb.vml.convertValue;
- this.getPath = function(d) {
- if (d.length == 10) {
- return "m" + _conv(d[4]) + "," + _conv(d[5]) +
- " c" + _conv(d[8]) + "," + _conv(d[9]) + "," + _conv(d[8]) + "," + _conv(d[9]) + "," + _conv(d[6]) + "," + _conv(d[7]) + " e";
- }
- else {
-
- var left = _conv(d[8] - d[6]),
- top = _conv(d[9] - (2 * d[6])),
- right = left + _conv(2 * d[6]),
- bottom = top + _conv(2 * d[6]),
- posString = left + "," + top + "," + right + "," + bottom;
-
- var o = "ar " + posString + "," + _conv(d[8]) + ","
- + _conv(d[9]) + "," + _conv(d[8]) + "," + _conv(d[9]) + " e";
-
- return o;
- }
- };
- };
- })();
- ;(function() {
-
-
-
-
-
- var vmlAttributeMap = {
- "stroke-linejoin":"joinstyle",
- "joinstyle":"joinstyle",
- "endcap":"endcap",
- "miterlimit":"miterlimit"
- };
-
- if (document.createStyleSheet) {
-
-
- document.createStyleSheet().addRule(".jsplumb_vml", "behavior:url(#default#VML);position:absolute;");
-
-
-
-
- document.createStyleSheet().addRule("jsplumb\\:textbox", "behavior:url(#default#VML);position:absolute;");
- document.createStyleSheet().addRule("jsplumb\\:oval", "behavior:url(#default#VML);position:absolute;");
- document.createStyleSheet().addRule("jsplumb\\:rect", "behavior:url(#default#VML);position:absolute;");
- document.createStyleSheet().addRule("jsplumb\\:stroke", "behavior:url(#default#VML);position:absolute;");
- document.createStyleSheet().addRule("jsplumb\\:shape", "behavior:url(#default#VML);position:absolute;");
- document.createStyleSheet().addRule("jsplumb\\:group", "behavior:url(#default#VML);position:absolute;");
-
-
-
-
-
-
- document.namespaces.add("jsplumb", "urn:schemas-microsoft-com:vml");
-
-
- }
-
- jsPlumb.vml = {};
-
- var scale = 1000,
- _groupMap = {},
- _getGroup = function(container, connectorClass) {
- var id = jsPlumb.getId(container),
- g = _groupMap[id];
- if(!g) {
- g = _node("group", [0,0,scale, scale], {"class":connectorClass});
-
-
- g.style.backgroundColor="red";
- _groupMap[id] = g;
- jsPlumb.appendElement(g, container);
-
- }
- return g;
- },
- _atts = function(o, atts) {
- for (var i in atts) {
-
-
-
-
- o[i] = atts[i];
- }
- },
- _node = function(name, d, atts) {
- atts = atts || {};
- var o = document.createElement("jsplumb:" + name);
- o.className = (atts["class"] ? atts["class"] + " " : "") + "jsplumb_vml";
- _pos(o, d);
- _atts(o, atts);
- return o;
- },
- _pos = function(o,d) {
- o.style.left = d[0] + "px";
- o.style.top = d[1] + "px";
- o.style.width= d[2] + "px";
- o.style.height= d[3] + "px";
- o.style.position = "absolute";
- },
- _conv = jsPlumb.vml.convertValue = function(v) {
- return Math.floor(v * scale);
- },
-
-
- _maybeSetOpacity = function(styleToWrite, styleToCheck, type, component) {
- if ("transparent" === styleToCheck)
- component.setOpacity(type, "0.0");
- else
- component.setOpacity(type, "1.0");
- },
- _applyStyles = function(node, style, component) {
- var styleToWrite = {};
- if (style.strokeStyle) {
- styleToWrite["stroked"] = "true";
- var strokeColor = jsPlumb.util.convertStyle(style.strokeStyle, true);
- styleToWrite["strokecolor"] = strokeColor;
- _maybeSetOpacity(styleToWrite, strokeColor, "stroke", component);
- styleToWrite["strokeweight"] = style.lineWidth + "px";
- }
- else styleToWrite["stroked"] = "false";
-
- if (style.fillStyle) {
- styleToWrite["filled"] = "true";
- var fillColor = jsPlumb.util.convertStyle(style.fillStyle, true);
- styleToWrite["fillcolor"] = fillColor;
- _maybeSetOpacity(styleToWrite, fillColor, "fill", component);
- }
- else styleToWrite["filled"] = "false";
-
- if(style["dashstyle"]) {
- if (component.strokeNode == null) {
- component.strokeNode = _node("stroke", [0,0,0,0], { dashstyle:style["dashstyle"] });
- node.appendChild(component.strokeNode);
- }
- else
- component.strokeNode.dashstyle = style["dashstyle"];
- }
- else if (style["stroke-dasharray"] && style["lineWidth"]) {
- var sep = style["stroke-dasharray"].indexOf(",") == -1 ? " " : ",",
- parts = style["stroke-dasharray"].split(sep),
- styleToUse = "";
- for(var i = 0; i < parts.length; i++) {
- styleToUse += (Math.floor(parts[i] / style.lineWidth) + sep);
- }
- if (component.strokeNode == null) {
- component.strokeNode = _node("stroke", [0,0,0,0], { dashstyle:styleToUse });
- node.appendChild(component.strokeNode);
- }
- else
- component.strokeNode.dashstyle = styleToUse;
- }
-
- _atts(node, styleToWrite);
- },
-
- VmlComponent = function() {
- var self = this;
- jsPlumb.jsPlumbUIComponent.apply(this, arguments);
- this.opacityNodes = {
- "stroke":null,
- "fill":null
- };
- this.initOpacityNodes = function(vml) {
- self.opacityNodes["stroke"] = _node("stroke", [0,0,1,1], {opacity:"0.0"});
- self.opacityNodes["fill"] = _node("fill", [0,0,1,1], {opacity:"0.0"});
- vml.appendChild(self.opacityNodes["stroke"]);
- vml.appendChild(self.opacityNodes["fill"]);
- };
- this.setOpacity = function(type, value) {
- var node = self.opacityNodes[type];
- if (node) node["opacity"] = "" + value;
- };
- var displayElements = [ ];
- this.getDisplayElements = function() {
- return displayElements;
- };
-
- this.appendDisplayElement = function(el, doNotAppendToCanvas) {
- if (!doNotAppendToCanvas) self.canvas.parentNode.appendChild(el);
- displayElements.push(el);
- };
- },
-
- VmlConnector = jsPlumb.VmlConnector = function(params) {
- var self = this;
- self.strokeNode = null;
- self.canvas = null;
- VmlComponent.apply(this, arguments);
- var clazz = self._jsPlumb.connectorClass + (params.cssClass ? (" " + params.cssClass) : "");
- this.paint = function(d, style, anchor) {
- if (style != null) {
- var path = self.getPath(d), p = { "path":path };
-
- if (style.outlineColor) {
- var outlineWidth = style.outlineWidth || 1,
- outlineStrokeWidth = style.lineWidth + (2 * outlineWidth),
- outlineStyle = {
- strokeStyle : jsPlumb.util.convertStyle(style.outlineColor),
- lineWidth : outlineStrokeWidth
- };
- for (var aa in vmlAttributeMap) outlineStyle[aa] = style[aa];
-
- if (self.bgCanvas == null) {
- p["class"] = clazz;
- p["coordsize"] = (d[2] * scale) + "," + (d[3] * scale);
- self.bgCanvas = _node("shape", d, p);
- params["_jsPlumb"].appendElement(self.bgCanvas, params.parent);
- _pos(self.bgCanvas, d);
- self.appendDisplayElement(self.bgCanvas, true);
- }
- else {
- p["coordsize"] = (d[2] * scale) + "," + (d[3] * scale);
- _pos(self.bgCanvas, d);
- _atts(self.bgCanvas, p);
- }
-
- _applyStyles(self.bgCanvas, outlineStyle, self);
- }
-
-
- if (self.canvas == null) {
- p["class"] = clazz;
- p["coordsize"] = (d[2] * scale) + "," + (d[3] * scale);
- if (self.tooltip) p["label"] = self.tooltip;
- self.canvas = _node("shape", d, p);
-
-
-
- params["_jsPlumb"].appendElement(self.canvas, params.parent);
- self.appendDisplayElement(self.canvas, true);
-
- self.attachListeners(self.canvas, self);
-
- self.initOpacityNodes(self.canvas, ["stroke"]);
- }
- else {
- p["coordsize"] = (d[2] * scale) + "," + (d[3] * scale);
- _pos(self.canvas, d);
- _atts(self.canvas, p);
- }
-
- _applyStyles(self.canvas, style, self);
- }
- };
-
-
-
- this.reattachListeners = function() {
- if (self.canvas) self.reattachListenersForElement(self.canvas, self);
- };
- },
-
- VmlEndpoint = function(params) {
- VmlComponent.apply(this, arguments);
- var vml = null, self = this, opacityStrokeNode = null, opacityFillNode = null;
- self.canvas = document.createElement("div");
- self.canvas.style["position"] = "absolute";
-
-
- params["_jsPlumb"].appendElement(self.canvas, params.parent);
- if (self.tooltip) self.canvas.setAttribute("label", self.tooltip);
-
- this.paint = function(d, style, anchor) {
- var p = { };
-
- jsPlumb.sizeCanvas(self.canvas, d[0], d[1], d[2], d[3]);
- if (vml == null) {
- p["class"] = jsPlumb.endpointClass;
- vml = self.getVml([0,0, d[2], d[3]], p, anchor);
- self.canvas.appendChild(vml);
- self.attachListeners(vml, self);
- self.appendDisplayElement(vml, true);
- self.appendDisplayElement(self.canvas, true);
-
- self.initOpacityNodes(vml, ["fill"]);
- }
- else {
-
- _pos(vml, [0,0, d[2], d[3]]);
- _atts(vml, p);
- }
-
- _applyStyles(vml, style, self);
- };
-
- this.reattachListeners = function() {
- if (vml) self.reattachListenersForElement(vml, self);
- };
- };
-
- jsPlumb.Connectors.vml.Bezier = function() {
- jsPlumb.Connectors.Bezier.apply(this, arguments);
- VmlConnector.apply(this, arguments);
- this.getPath = function(d) {
- return "m" + _conv(d[4]) + "," + _conv(d[5]) +
- " c" + _conv(d[8]) + "," + _conv(d[9]) + "," + _conv(d[10]) + "," + _conv(d[11]) + "," + _conv(d[6]) + "," + _conv(d[7]) + " e";
- };
- };
-
- jsPlumb.Connectors.vml.Straight = function() {
- jsPlumb.Connectors.Straight.apply(this, arguments);
- VmlConnector.apply(this, arguments);
- this.getPath = function(d) {
- return "m" + _conv(d[4]) + "," + _conv(d[5]) + " l" + _conv(d[6]) + "," + _conv(d[7]) + " e";
- };
- };
-
- jsPlumb.Connectors.vml.Flowchart = function() {
- jsPlumb.Connectors.Flowchart.apply(this, arguments);
- VmlConnector.apply(this, arguments);
- this.getPath = function(dimensions) {
- var p = "m " + _conv(dimensions[4]) + "," + _conv(dimensions[5]) + " l";
-
- for (var i = 0; i < dimensions[8]; i++) {
- p = p + " " + _conv(dimensions[9 + (i*2)]) + "," + _conv(dimensions[10 + (i*2)]);
- }
-
- p = p + " " + _conv(dimensions[6]) + "," + _conv(dimensions[7]) + " e";
- return p;
- };
- };
-
- jsPlumb.Endpoints.vml.Dot = function() {
- jsPlumb.Endpoints.Dot.apply(this, arguments);
- VmlEndpoint.apply(this, arguments);
- this.getVml = function(d, atts, anchor) { return _node("oval", d, atts); };
- };
-
- jsPlumb.Endpoints.vml.Rectangle = function() {
- jsPlumb.Endpoints.Rectangle.apply(this, arguments);
- VmlEndpoint.apply(this, arguments);
- this.getVml = function(d, atts, anchor) { return _node("rect", d, atts); };
- };
-
-
- jsPlumb.Endpoints.vml.Image = jsPlumb.Endpoints.Image;
-
-
- jsPlumb.Endpoints.vml.Blank = jsPlumb.Endpoints.Blank;
-
-
- jsPlumb.Overlays.vml.Label = jsPlumb.Overlays.Label;
-
- var AbstractVmlArrowOverlay = function(superclass, originalArgs) {
- superclass.apply(this, originalArgs);
- VmlComponent.apply(this, arguments);
- var self = this, path = null;
- self.canvas = null;
- var getPath = function(d, connectorDimensions) {
- return "m " + _conv(d.hxy.x) + "," + _conv(d.hxy.y) +
- " l " + _conv(d.tail[0].x) + "," + _conv(d.tail[0].y) +
- " " + _conv(d.cxy.x) + "," + _conv(d.cxy.y) +
- " " + _conv(d.tail[1].x) + "," + _conv(d.tail[1].y) +
- " x e";
- };
- this.paint = function(connector, d, lineWidth, strokeStyle, fillStyle, connectorDimensions) {
- var p = {};
- if (strokeStyle) {
- p["stroked"] = "true";
- p["strokecolor"] = jsPlumb.util.convertStyle(strokeStyle, true);
- }
- if (lineWidth) p["strokeweight"] = lineWidth + "px";
- if (fillStyle) {
- p["filled"] = "true";
- p["fillcolor"] = fillStyle;
- }
- var xmin = Math.min(d.hxy.x, d.tail[0].x, d.tail[1].x, d.cxy.x),
- ymin = Math.min(d.hxy.y, d.tail[0].y, d.tail[1].y, d.cxy.y),
- xmax = Math.max(d.hxy.x, d.tail[0].x, d.tail[1].x, d.cxy.x),
- ymax = Math.max(d.hxy.y, d.tail[0].y, d.tail[1].y, d.cxy.y),
- w = Math.abs(xmax - xmin),
- h = Math.abs(ymax - ymin),
- dim = [xmin, ymin, w, h];
-
-
-
-
-
- p["path"] = getPath(d, connectorDimensions);
- p["coordsize"] = (connectorDimensions[2] * scale) + "," + (connectorDimensions[3] * scale);
-
- dim[0] = connectorDimensions[0];
- dim[1] = connectorDimensions[1];
- dim[2] = connectorDimensions[2];
- dim[3] = connectorDimensions[3];
-
- if (self.canvas == null) {
-
- self.canvas = _node("shape", dim, p);
- connector.appendDisplayElement(self.canvas);
- self.attachListeners(self.canvas, connector);
- }
- else {
- _pos(self.canvas, dim);
- _atts(self.canvas, p);
- }
- };
-
- this.reattachListeners = function() {
- if (self.canvas) self.reattachListenersForElement(self.canvas, self);
- };
- };
-
- jsPlumb.Overlays.vml.Arrow = function() {
- AbstractVmlArrowOverlay.apply(this, [jsPlumb.Overlays.Arrow, arguments]);
- };
-
- jsPlumb.Overlays.vml.PlainArrow = function() {
- AbstractVmlArrowOverlay.apply(this, [jsPlumb.Overlays.PlainArrow, arguments]);
- };
-
- jsPlumb.Overlays.vml.Diamond = function() {
- AbstractVmlArrowOverlay.apply(this, [jsPlumb.Overlays.Diamond, arguments]);
- };
- })();
- ;(function() {
-
- var svgAttributeMap = {
- "joinstyle":"stroke-linejoin",
- "stroke-linejoin":"stroke-linejoin",
- "stroke-dashoffset":"stroke-dashoffset",
- "stroke-linecap":"stroke-linecap"
- },
- STROKE_DASHARRAY = "stroke-dasharray",
- DASHSTYLE = "dashstyle",
- LINEAR_GRADIENT = "linearGradient",
- RADIAL_GRADIENT = "radialGradient",
- FILL = "fill",
- STOP = "stop",
- STROKE = "stroke",
- STROKE_WIDTH = "stroke-width",
- STYLE = "style",
- NONE = "none",
- JSPLUMB_GRADIENT = "jsplumb_gradient_",
- LINE_WIDTH = "lineWidth",
- ns = {
- svg:"http://www.w3.org/2000/svg",
- xhtml:"http://www.w3.org/1999/xhtml"
- },
- _attr = function(node, attributes) {
- for (var i in attributes)
- node.setAttribute(i, "" + attributes[i]);
- },
- _node = function(name, attributes) {
- var n = document.createElementNS(ns.svg, name);
- attributes = attributes || {};
- attributes["version"] = "1.1";
- attributes["xmlns"] = ns.xhtml;
- _attr(n, attributes);
- return n;
- },
- _pos = function(d) { return "position:absolute;left:" + d[0] + "px;top:" + d[1] + "px"; },
- _clearGradient = function(parent) {
- for (var i = 0; i < parent.childNodes.length; i++) {
- if (parent.childNodes[i].tagName == LINEAR_GRADIENT || parent.childNodes[i].tagName == RADIAL_GRADIENT)
- parent.removeChild(parent.childNodes[i]);
- }
- },
- _updateGradient = function(parent, node, style, dimensions, uiComponent) {
- var id = JSPLUMB_GRADIENT + uiComponent._jsPlumb.idstamp();
-
- _clearGradient(parent);
-
-
-
-
-
- if (!style.gradient.offset) {
- var g = _node(LINEAR_GRADIENT, {id:id});
- parent.appendChild(g);
- }
- else {
- var g = _node(RADIAL_GRADIENT, {
- id:id
- });
- parent.appendChild(g);
- }
-
-
-
-
- for (var i = 0; i < style.gradient.stops.length; i++) {
-
-
-
- var styleToUse = i;
- if (dimensions.length == 8)
- styleToUse = dimensions[4] < dimensions[6] ? i: style.gradient.stops.length - 1 - i;
- else
- styleToUse = dimensions[4] < dimensions[6] ? style.gradient.stops.length - 1 - i : i;
- var stopColor = jsPlumb.util.convertStyle(style.gradient.stops[styleToUse][1], true);
- var s = _node(STOP, {"offset":Math.floor(style.gradient.stops[i][0] * 100) + "%", "stop-color":stopColor});
- g.appendChild(s);
- }
- var applyGradientTo = style.strokeStyle ? STROKE : FILL;
- node.setAttribute(STYLE, applyGradientTo + ":url(#" + id + ")");
- },
- _applyStyles = function(parent, node, style, dimensions, uiComponent) {
-
- if (style.gradient) {
- _updateGradient(parent, node, style, dimensions, uiComponent);
- }
- else {
-
- _clearGradient(parent);
- node.setAttribute(STYLE, "");
- }
-
- node.setAttribute(FILL, style.fillStyle ? jsPlumb.util.convertStyle(style.fillStyle, true) : NONE);
- node.setAttribute(STROKE, style.strokeStyle ? jsPlumb.util.convertStyle(style.strokeStyle, true) : NONE);
- if (style.lineWidth) {
- node.setAttribute(STROKE_WIDTH, style.lineWidth);
- }
-
-
-
-
-
-
-
-
-
- if (style[DASHSTYLE] && style[LINE_WIDTH] && !style[STROKE_DASHARRAY]) {
- var sep = style[DASHSTYLE].indexOf(",") == -1 ? " " : ",",
- parts = style[DASHSTYLE].split(sep),
- styleToUse = "";
- parts.forEach(function(p) {
- styleToUse += (Math.floor(p * style.lineWidth) + sep);
- });
- node.setAttribute(STROKE_DASHARRAY, styleToUse);
- }
- else if(style[STROKE_DASHARRAY]) {
- node.setAttribute(STROKE_DASHARRAY, style[STROKE_DASHARRAY]);
- }
-
-
- for (var i in svgAttributeMap) {
- if (style[i]) {
- node.setAttribute(svgAttributeMap[i], style[i]);
- }
- }
- },
- _decodeFont = function(f) {
- var r = /([0-9].)(p[xt])\s(.*)/;
- var bits = f.match(r);
- return {size:bits[1] + bits[2], font:bits[3]};
- },
- _classManip = function(el, add, clazz) {
- var classesToAddOrRemove = clazz.split(" "),
- className = el.className,
- curClasses = className.baseVal.split(" ");
-
- for (var i = 0; i < classesToAddOrRemove.length; i++) {
- if (add) {
- if (curClasses.indexOf(classesToAddOrRemove[i]) == -1)
- curClasses.push(classesToAddOrRemove[i]);
- }
- else {
- var idx = curClasses.indexOf(classesToAddOrRemove[i]);
- if (idx != -1)
- curClasses.splice(idx, 1);
- }
- }
-
- el.className.baseVal = curClasses.join(" ");
- },
- _addClass = function(el, clazz) {
- _classManip(el, true, clazz);
- },
- _removeClass = function(el, clazz) {
- _classManip(el, false, clazz);
- };
-
-
- jsPlumb.util.svg = {
- addClass:_addClass,
- removeClass:_removeClass
- };
-
-
-
- var SvgComponent = function(params) {
- var self = this,
- pointerEventsSpec = params.pointerEventsSpec || "all";
- jsPlumb.jsPlumbUIComponent.apply(this, params.originalArgs);
- self.canvas = null, self.path = null, self.svg = null;
-
- var clazz = params.cssClass + " " + (params.originalArgs[0].cssClass || ""),
- svgParams = {
- "style":"",
- "width":0,
- "height":0,
- "pointer-events":pointerEventsSpec,
- "position":"absolute"
- };
- if (self.tooltip) svgParams["title"] = self.tooltip;
- self.svg = _node("svg", svgParams);
- if (params.useDivWrapper) {
- self.canvas = document.createElement("div");
- self.canvas.style["position"] = "absolute";
- jsPlumb.sizeCanvas(self.canvas,0,0,1,1);
- self.canvas.className = clazz;
- if (self.tooltip) self.canvas.setAttribute("title", self.tooltip);
- }
- else {
- _attr(self.svg, { "class":clazz });
- self.canvas = self.svg;
- }
-
- params._jsPlumb.appendElement(self.canvas, params.originalArgs[0]["parent"]);
- if (params.useDivWrapper) self.canvas.appendChild(self.svg);
-
-
-
- var displayElements = [ self.canvas ];
- this.getDisplayElements = function() {
- return displayElements;
- };
-
- this.appendDisplayElement = function(el) {
- displayElements.push(el);
- };
-
- this.paint = function(d, style, anchor) {
- if (style != null) {
- var x = d[0], y = d[1];
- if (params.useDivWrapper) {
- jsPlumb.sizeCanvas(self.canvas, d[0], d[1], d[2], d[3]);
- x = 0, y = 0;
- }
- _attr(self.svg, {
- "style":_pos([x, y, d[2], d[3]]),
- "width": d[2],
- "height": d[3]
- });
- self._paint.apply(this, arguments);
- }
- };
- };
-
-
- var SvgConnector = jsPlumb.SvgConnector = function(params) {
- var self = this;
- SvgComponent.apply(this, [ {
- cssClass:params["_jsPlumb"].connectorClass,
- originalArgs:arguments,
- pointerEventsSpec:"none",
- tooltip:params.tooltip,
- _jsPlumb:params["_jsPlumb"]
- } ]);
- this._paint = function(d, style) {
- var p = self.getPath(d), a = { "d":p }, outlineStyle = null;
- a["pointer-events"] = "all";
-
-
- if (style.outlineColor) {
- var outlineWidth = style.outlineWidth || 1,
- outlineStrokeWidth = style.lineWidth + (2 * outlineWidth),
- outlineStyle = jsPlumb.CurrentLibrary.extend({}, style);
- outlineStyle.strokeStyle = jsPlumb.util.convertStyle(style.outlineColor);
- outlineStyle.lineWidth = outlineStrokeWidth;
-
- if (self.bgPath == null) {
- self.bgPath = _node("path", a);
- self.svg.appendChild(self.bgPath);
- self.attachListeners(self.bgPath, self);
- }
- else {
- _attr(self.bgPath, a);
- }
-
- _applyStyles(self.svg, self.bgPath, outlineStyle, d, self);
- }
-
-
-
-
-
- if (self.path == null) {
- self.path = _node("path", a);
- self.svg.appendChild(self.path);
- self.attachListeners(self.path, self);
-
-
- }
- else {
- _attr(self.path, a);
- }
-
- _applyStyles(self.svg, self.path, style, d, self);
- };
-
- this.reattachListeners = function() {
- if (self.bgPath) self.reattachListenersForElement(self.bgPath, self);
- if (self.path) self.reattachListenersForElement(self.path, self);
- };
-
- };
-
- jsPlumb.Connectors.svg.Bezier = function(params) {
- jsPlumb.Connectors.Bezier.apply(this, arguments);
- SvgConnector.apply(this, arguments);
- this.getPath = function(d) {
- var _p = "M " + d[4] + " " + d[5];
- _p += (" C " + d[8] + " " + d[9] + " " + d[10] + " " + d[11] + " " + d[6] + " " + d[7]);
- return _p;
- };
- };
-
-
- jsPlumb.Connectors.svg.Straight = function(params) {
- jsPlumb.Connectors.Straight.apply(this, arguments);
- SvgConnector.apply(this, arguments);
- this.getPath = function(d) { return "M " + d[4] + " " + d[5] + " L " + d[6] + " " + d[7]; };
- };
-
- jsPlumb.Connectors.svg.Flowchart = function() {
- var self = this;
- jsPlumb.Connectors.Flowchart.apply(this, arguments);
- SvgConnector.apply(this, arguments);
- this.getPath = function(dimensions) {
- var p = "M " + dimensions[4] + "," + dimensions[5];
-
- for (var i = 0; i < dimensions[8]; i++) {
- p = p + " L " + dimensions[9 + (i*2)] + " " + dimensions[10 + (i*2)];
- }
-
- p = p + " " + dimensions[6] + "," + dimensions[7];
- return p;
- };
- };
-
-
- var SvgEndpoint = function(params) {
- var self = this;
- SvgComponent.apply(this, [ {
- cssClass:params["_jsPlumb"].endpointClass,
- originalArgs:arguments,
- pointerEventsSpec:"all",
- useDivWrapper:true,
- _jsPlumb:params["_jsPlumb"]
- } ]);
- this._paint = function(d, style) {
- var s = jsPlumb.extend({}, style);
- if (s.outlineColor) {
- s.strokeWidth = s.outlineWidth;
- s.strokeStyle = jsPlumb.util.convertStyle(s.outlineColor, true);
- }
-
- if (self.node == null) {
- self.node = self.makeNode(d, s);
- self.svg.appendChild(self.node);
- self.attachListeners(self.node, self);
- }
- _applyStyles(self.svg, self.node, s, d, self);
- _pos(self.node, d);
- };
-
- this.reattachListeners = function() {
- if (self.node) self.reattachListenersForElement(self.node, self);
- };
- };
-
-
- jsPlumb.Endpoints.svg.Dot = function() {
- jsPlumb.Endpoints.Dot.apply(this, arguments);
- SvgEndpoint.apply(this, arguments);
- this.makeNode = function(d, style) {
- return _node("circle", {
- "cx" : d[2] / 2,
- "cy" : d[3] / 2,
- "r" : d[2] / 3
- });
- };
- };
-
-
- jsPlumb.Endpoints.svg.Rectangle = function() {
- jsPlumb.Endpoints.Rectangle.apply(this, arguments);
- SvgEndpoint.apply(this, arguments);
- this.makeNode = function(d, style) {
- return _node("rect", {
- "width":d[2],
- "height":d[3]
- });
- };
- };
-
-
- jsPlumb.Endpoints.svg.Image = jsPlumb.Endpoints.Image;
-
- jsPlumb.Endpoints.svg.Blank = jsPlumb.Endpoints.Blank;
-
- jsPlumb.Overlays.svg.Label = jsPlumb.Overlays.Label;
-
- var AbstractSvgArrowOverlay = function(superclass, originalArgs) {
- superclass.apply(this, originalArgs);
- jsPlumb.jsPlumbUIComponent.apply(this, originalArgs);
- this.isAppendedAtTopLevel = false;
- var self = this, path =null;
- this.paint = function(connector, d, lineWidth, strokeStyle, fillStyle) {
- if (path == null) {
- path = _node("path");
- connector.svg.appendChild(path);
- self.attachListeners(path, connector);
- self.attachListeners(path, self);
- }
- var clazz = originalArgs && (originalArgs.length == 1) ? (originalArgs[0].cssClass || "") : "";
-
- _attr(path, {
- "d" : makePath(d),
- "class" : clazz,
- stroke : strokeStyle ? strokeStyle : null,
- fill : fillStyle ? fillStyle : null
- });
- };
- var makePath = function(d) {
- return "M" + d.hxy.x + "," + d.hxy.y +
- " L" + d.tail[0].x + "," + d.tail[0].y +
- " L" + d.cxy.x + "," + d.cxy.y +
- " L" + d.tail[1].x + "," + d.tail[1].y +
- " L" + d.hxy.x + "," + d.hxy.y;
- };
- this.reattachListeners = function() {
- if (path) self.reattachListenersForElement(path, self);
- };
- };
-
- jsPlumb.Overlays.svg.Arrow = function() {
- AbstractSvgArrowOverlay.apply(this, [jsPlumb.Overlays.Arrow, arguments]);
- };
-
- jsPlumb.Overlays.svg.PlainArrow = function() {
- AbstractSvgArrowOverlay.apply(this, [jsPlumb.Overlays.PlainArrow, arguments]);
- };
-
- jsPlumb.Overlays.svg.Diamond = function() {
- AbstractSvgArrowOverlay.apply(this, [jsPlumb.Overlays.Diamond, arguments]);
- };
-
- jsPlumb.Overlays.svg.GuideLines = function() {
- var path = null, self = this, path2 = null, p1_1, p1_2;
- jsPlumb.Overlays.GuideLines.apply(this, arguments);
- this.paint = function(connector, d, lineWidth, strokeStyle, fillStyle) {
- if (path == null) {
- path = _node("path");
- connector.svg.appendChild(path);
- self.attachListeners(path, connector);
- self.attachListeners(path, self);
- p1_1 = _node("path");
- connector.svg.appendChild(p1_1);
- self.attachListeners(p1_1, connector);
- self.attachListeners(p1_1, self);
- p1_2 = _node("path");
- connector.svg.appendChild(p1_2);
- self.attachListeners(p1_2, connector);
- self.attachListeners(p1_2, self);
- }
- _attr(path, {
- "d" : makePath(d[0], d[1]),
- stroke : "red",
- fill : null
- });
- _attr(p1_1, {
- "d" : makePath(d[2][0], d[2][1]),
- stroke : "blue",
- fill : null
- });
- _attr(p1_2, {
- "d" : makePath(d[3][0], d[3][1]),
- stroke : "green",
- fill : null
- });
- };
- var makePath = function(d1, d2) {
- return "M " + d1.x + "," + d1.y +
- " L" + d2.x + "," + d2.y;
- };
- };
- })();
- ;(function() {
-
-
-
- var _connectionBeingDragged = null,
- _hasClass = function(el, clazz) { return jsPlumb.CurrentLibrary.hasClass(_getElementObject(el), clazz); },
- _getElementObject = function(el) { return jsPlumb.CurrentLibrary.getElementObject(el); },
- _getOffset = function(el) { return jsPlumb.CurrentLibrary.getOffset(_getElementObject(el)); },
- _pageXY = function(el) { return jsPlumb.CurrentLibrary.getPageXY(el); },
- _clientXY = function(el) { return jsPlumb.CurrentLibrary.getClientXY(el); };
-
-
- var CanvasMouseAdapter = function() {
- var self = this;
- self.overlayPlacements = [];
- jsPlumb.jsPlumbUIComponent.apply(this, arguments);
- jsPlumb.EventGenerator.apply(this, arguments);
-
- this._over = function(e) {
- var o = _getOffset(_getElementObject(self.canvas)),
- pageXY = _pageXY(e),
- x = pageXY[0] - o.left, y = pageXY[1] - o.top;
- if (x > 0 && y > 0 && x < self.canvas.width && y < self.canvas.height) {
-
- for ( var i = 0; i < self.overlayPlacements.length; i++) {
- var p = self.overlayPlacements[i];
- if (p && (p[0] <= x && p[1] >= x && p[2] <= y && p[3] >= y))
- return true;
- }
-
-
- var d = self.canvas.getContext("2d").getImageData(parseInt(x), parseInt(y), 1, 1);
- return d.data[0] != 0 || d.data[1] != 0 || d.data[2] != 0 || d.data[3] != 0;
- }
- return false;
- };
-
- var _mouseover = false, _mouseDown = false, _posWhenMouseDown = null, _mouseWasDown = false,
- _nullSafeHasClass = function(el, clazz) {
- return el != null && _hasClass(el, clazz);
- };
- this.mousemove = function(e) {
- var pageXY = _pageXY(e), clientXY = _clientXY(e),
- ee = document.elementFromPoint(clientXY[0], clientXY[1]),
- eventSourceWasOverlay = _nullSafeHasClass(ee, "_jsPlumb_overlay");
- var _continue = _connectionBeingDragged == null && (_nullSafeHasClass(ee, "_jsPlumb_endpoint") || _nullSafeHasClass(ee, "_jsPlumb_connector"));
- if (!_mouseover && _continue && self._over(e)) {
- _mouseover = true;
- self.fire("mouseenter", self, e);
- return true;
- }
-
-
-
- else if (_mouseover && (!self._over(e) || !_continue) && !eventSourceWasOverlay) {
- _mouseover = false;
- self.fire("mouseexit", self, e);
- }
- self.fire("mousemove", self, e);
- };
-
- this.click = function(e) {
- if (_mouseover && self._over(e) && !_mouseWasDown)
- self.fire("click", self, e);
- _mouseWasDown = false;
- };
-
- this.dblclick = function(e) {
- if (_mouseover && self._over(e) && !_mouseWasDown)
- self.fire("dblclick", self, e);
- _mouseWasDown = false;
- };
-
- this.mousedown = function(e) {
- if(self._over(e) && !_mouseDown) {
- _mouseDown = true;
- _posWhenMouseDown = _getOffset(_getElementObject(self.canvas));
- self.fire("mousedown", self, e);
- }
- };
-
- this.mouseup = function(e) {
- _mouseDown = false;
- self.fire("mouseup", self, e);
- };
- this.contextmenu = function(e) {
- if (_mouseover && self._over(e) && !_mouseWasDown)
- self.fire("contextmenu", self, e);
- _mouseWasDown = false;
- };
- };
-
- var _newCanvas = function(params) {
- var canvas = document.createElement("canvas");
- params["_jsPlumb"].appendElement(canvas, params.parent);
- canvas.style.position = "absolute";
- if (params["class"]) canvas.className = params["class"];
-
-
- params["_jsPlumb"].getId(canvas, params.uuid);
- if (params.tooltip) canvas.setAttribute("title", params.tooltip);
- return canvas;
- };
- var CanvasComponent = function(params) {
- CanvasMouseAdapter.apply(this, arguments);
- var displayElements = [ ];
- this.getDisplayElements = function() { return displayElements; };
- this.appendDisplayElement = function(el) { displayElements.push(el); };
- }
-
-
- var CanvasConnector = jsPlumb.CanvasConnector = function(params) {
-
- CanvasComponent.apply(this, arguments);
-
- var _paintOneStyle = function(dim, aStyle) {
- self.ctx.save();
- jsPlumb.extend(self.ctx, aStyle);
- if (aStyle.gradient) {
- var g = self.createGradient(dim, self.ctx);
- for ( var i = 0; i < aStyle.gradient.stops.length; i++)
- g.addColorStop(aStyle.gradient.stops[i][0], aStyle.gradient.stops[i][1]);
- self.ctx.strokeStyle = g;
- }
- self._paint(dim);
- self.ctx.restore();
- };
- var self = this,
- clazz = self._jsPlumb.connectorClass + " " + (params.cssClass || "");
- self.canvas = _newCanvas({
- "class":clazz,
- _jsPlumb:self._jsPlumb,
- parent:params.parent,
- tooltip:params.tooltip
- });
- self.ctx = self.canvas.getContext("2d");
-
- self.appendDisplayElement(self.canvas);
-
- self.paint = function(dim, style) {
- if (style != null) {
- jsPlumb.sizeCanvas(self.canvas, dim[0], dim[1], dim[2], dim[3]);
- if (style.outlineColor != null) {
- var outlineWidth = style.outlineWidth || 1,
- outlineStrokeWidth = style.lineWidth + (2 * outlineWidth),
- outlineStyle = {
- strokeStyle:style.outlineColor,
- lineWidth:outlineStrokeWidth
- };
- _paintOneStyle(dim, outlineStyle);
- }
- _paintOneStyle(dim, style);
- }
- };
- };
-
-
- var CanvasEndpoint = function(params) {
- var self = this;
- CanvasComponent.apply(this, arguments);
- var clazz = self._jsPlumb.endpointClass + " " + (params.cssClass || ""),
- canvasParams = {
- "class":clazz,
- _jsPlumb:self._jsPlumb,
- parent:params.parent,
- tooltip:self.tooltip
- };
- self.canvas = _newCanvas(canvasParams);
- self.ctx = self.canvas.getContext("2d");
- self.appendDisplayElement(self.canvas);
-
- this.paint = function(d, style, anchor) {
- jsPlumb.sizeCanvas(self.canvas, d[0], d[1], d[2], d[3]);
- if (style.outlineColor != null) {
- var outlineWidth = style.outlineWidth || 1,
- outlineStrokeWidth = style.lineWidth + (2 * outlineWidth);
- var outlineStyle = {
- strokeStyle:style.outlineColor,
- lineWidth:outlineStrokeWidth
- };
- }
-
- self._paint.apply(this, arguments);
- };
- };
-
- jsPlumb.Endpoints.canvas.Dot = function(params) {
- jsPlumb.Endpoints.Dot.apply(this, arguments);
- CanvasEndpoint.apply(this, arguments);
- var self = this,
- parseValue = function(value) {
- try { return parseInt(value); }
- catch(e) {
- if (value.substring(value.length - 1) == '%')
- return parseInt(value.substring(0, value - 1));
- }
- },
- calculateAdjustments = function(gradient) {
- var offsetAdjustment = self.defaultOffset, innerRadius = self.defaultInnerRadius;
- gradient.offset && (offsetAdjustment = parseValue(gradient.offset));
- gradient.innerRadius && (innerRadius = parseValue(gradient.innerRadius));
- return [offsetAdjustment, innerRadius];
- };
- this._paint = function(d, style, anchor) {
- if (style != null) {
- var ctx = self.canvas.getContext('2d'), orientation = anchor.getOrientation(self);
- jsPlumb.extend(ctx, style);
- if (style.gradient) {
- var adjustments = calculateAdjustments(style.gradient),
- yAdjust = orientation[1] == 1 ? adjustments[0] * -1 : adjustments[0],
- xAdjust = orientation[0] == 1 ? adjustments[0] * -1: adjustments[0],
- g = ctx.createRadialGradient(d[4], d[4], d[4], d[4] + xAdjust, d[4] + yAdjust, adjustments[1]);
- for (var i = 0; i < style.gradient.stops.length; i++)
- g.addColorStop(style.gradient.stops[i][0], style.gradient.stops[i][1]);
- ctx.fillStyle = g;
- }
- ctx.beginPath();
- ctx.arc(d[4], d[4], d[4], 0, Math.PI*2, true);
- ctx.closePath();
- if (style.fillStyle || style.gradient) ctx.fill();
- if (style.strokeStyle) ctx.stroke();
- }
- };
- };
-
- jsPlumb.Endpoints.canvas.Rectangle = function(params) {
-
- var self = this;
- jsPlumb.Endpoints.Rectangle.apply(this, arguments);
- CanvasEndpoint.apply(this, arguments);
-
- this._paint = function(d, style, anchor) {
-
- var ctx = self.canvas.getContext("2d"), orientation = anchor.getOrientation(self);
- jsPlumb.extend(ctx, style);
-
-
- if (style.gradient) {
-
- var y1 = orientation[1] == 1 ? d[3] : orientation[1] == 0 ? d[3] / 2 : 0;
- var y2 = orientation[1] == -1 ? d[3] : orientation[1] == 0 ? d[3] / 2 : 0;
- var x1 = orientation[0] == 1 ? d[2] : orientation[0] == 0 ? d[2] / 2 : 0;
- var x2 = orientation[0] == -1 ? d[2] : orientation[0] == 0 ? d[2] / 2 : 0;
- var g = ctx.createLinearGradient(x1,y1,x2,y2);
- for (var i = 0; i < style.gradient.stops.length; i++)
- g.addColorStop(style.gradient.stops[i][0], style.gradient.stops[i][1]);
- ctx.fillStyle = g;
- }
-
- ctx.beginPath();
- ctx.rect(0, 0, d[2], d[3]);
- ctx.closePath();
- if (style.fillStyle || style.gradient) ctx.fill();
- if (style.strokeStyle) ctx.stroke();
- };
- };
-
- jsPlumb.Endpoints.canvas.Triangle = function(params) {
-
- var self = this;
- jsPlumb.Endpoints.Triangle.apply(this, arguments);
- CanvasEndpoint.apply(this, arguments);
-
- this._paint = function(d, style, anchor)
- {
- var width = d[2], height = d[3], x = d[0], y = d[1],
- ctx = self.canvas.getContext('2d'),
- offsetX = 0, offsetY = 0, angle = 0,
- orientation = anchor.getOrientation(self);
-
- if( orientation[0] == 1 ) {
- offsetX = width;
- offsetY = height;
- angle = 180;
- }
- if( orientation[1] == -1 ) {
- offsetX = width;
- angle = 90;
- }
- if( orientation[1] == 1 ) {
- offsetY = height;
- angle = -90;
- }
-
- ctx.fillStyle = style.fillStyle;
-
- ctx.translate(offsetX, offsetY);
- ctx.rotate(angle * Math.PI/180);
- ctx.beginPath();
- ctx.moveTo(0, 0);
- ctx.lineTo(width/2, height/2);
- ctx.lineTo(0, height);
- ctx.closePath();
- if (style.fillStyle || style.gradient) ctx.fill();
- if (style.strokeStyle) ctx.stroke();
- };
- };
-
-
- jsPlumb.Endpoints.canvas.Image = jsPlumb.Endpoints.Image;
-
-
- jsPlumb.Endpoints.canvas.Blank = jsPlumb.Endpoints.Blank;
-
-
- jsPlumb.Connectors.canvas.Bezier = function() {
- var self = this;
- jsPlumb.Connectors.Bezier.apply(this, arguments);
- CanvasConnector.apply(this, arguments);
- this._paint = function(dimensions) {
- self.ctx.beginPath();
- self.ctx.moveTo(dimensions[4], dimensions[5]);
- self.ctx.bezierCurveTo(dimensions[8], dimensions[9], dimensions[10], dimensions[11], dimensions[6], dimensions[7]);
- self.ctx.stroke();
- };
-
-
- this.createGradient = function(dim, ctx, swap) {
- return self.ctx.createLinearGradient(dim[6], dim[7], dim[4], dim[5]);
- };
- };
-
-
- jsPlumb.Connectors.canvas.Straight = function() {
- var self = this;
- jsPlumb.Connectors.Straight.apply(this, arguments);
- CanvasConnector.apply(this, arguments);
- this._paint = function(dimensions) {
- self.ctx.beginPath();
- self.ctx.moveTo(dimensions[4], dimensions[5]);
- self.ctx.lineTo(dimensions[6], dimensions[7]);
- self.ctx.stroke();
- };
-
-
- this.createGradient = function(dim, ctx) {
- return ctx.createLinearGradient(dim[4], dim[5], dim[6], dim[7]);
- };
- };
-
- jsPlumb.Connectors.canvas.Flowchart = function() {
- var self = this;
- jsPlumb.Connectors.Flowchart.apply(this, arguments);
- CanvasConnector.apply(this, arguments);
- this._paint = function(dimensions) {
- self.ctx.beginPath();
- self.ctx.moveTo(dimensions[4], dimensions[5]);
-
- for (var i = 0; i < dimensions[8]; i++) {
- self.ctx.lineTo(dimensions[9 + (i*2)], dimensions[10 + (i*2)]);
- }
-
- self.ctx.lineTo(dimensions[6], dimensions[7]);
- self.ctx.stroke();
- };
-
- this.createGradient = function(dim, ctx) {
- return ctx.createLinearGradient(dim[4], dim[5], dim[6], dim[7]);
- };
- };
-
-
- jsPlumb.Overlays.canvas.Label = jsPlumb.Overlays.Label;
-
-
- var CanvasOverlay = function() {
- jsPlumb.jsPlumbUIComponent.apply(this, arguments);
- };
-
- var AbstractCanvasArrowOverlay = function(superclass, originalArgs) {
- superclass.apply(this, originalArgs);
- CanvasOverlay.apply(this, arguments);
- this.paint = function(connector, d, lineWidth, strokeStyle, fillStyle) {
- var ctx = connector.ctx;
-
- ctx.lineWidth = lineWidth;
- ctx.beginPath();
- ctx.moveTo(d.hxy.x, d.hxy.y);
- ctx.lineTo(d.tail[0].x, d.tail[0].y);
- ctx.lineTo(d.cxy.x, d.cxy.y);
- ctx.lineTo(d.tail[1].x, d.tail[1].y);
- ctx.lineTo(d.hxy.x, d.hxy.y);
- ctx.closePath();
-
- if (strokeStyle) {
- ctx.strokeStyle = strokeStyle;
- ctx.stroke();
- }
- if (fillStyle) {
- ctx.fillStyle = fillStyle;
- ctx.fill();
- }
- };
- };
-
- jsPlumb.Overlays.canvas.Arrow = function() {
- AbstractCanvasArrowOverlay.apply(this, [jsPlumb.Overlays.Arrow, arguments]);
- };
-
- jsPlumb.Overlays.canvas.PlainArrow = function() {
- AbstractCanvasArrowOverlay.apply(this, [jsPlumb.Overlays.PlainArrow, arguments]);
- };
-
- jsPlumb.Overlays.canvas.Diamond = function() {
- AbstractCanvasArrowOverlay.apply(this, [jsPlumb.Overlays.Diamond, arguments]);
- };
- })();
-
- (function($) {
-
-
- jsPlumb.CurrentLibrary = {
-
-
- addClass : function(el, clazz) {
- el = jsPlumb.CurrentLibrary.getElementObject(el);
- try {
- if (el[0].className.constructor == SVGAnimatedString) {
- jsPlumb.util.svg.addClass(el[0], clazz);
- }
- }
- catch (e) {
-
- }
- el.addClass(clazz);
- },
-
-
- animate : function(el, properties, options) {
- el.animate(properties, options);
- },
-
-
- appendElement : function(child, parent) {
- jsPlumb.CurrentLibrary.getElementObject(parent).append(child);
- },
-
-
- bind : function(el, event, callback) {
- el = jsPlumb.CurrentLibrary.getElementObject(el);
- el.bind(event, callback);
- },
-
-
- dragEvents : {
- 'start':'start', 'stop':'stop', 'drag':'drag', 'step':'step',
- 'over':'over', 'out':'out', 'drop':'drop', 'complete':'complete'
- },
-
-
- extend : function(o1, o2) {
- return $.extend(o1, o2);
- },
-
-
- getAttribute : function(el, attName) {
- return el.attr(attName);
- },
-
- getClientXY : function(eventObject) {
- return [eventObject.clientX, eventObject.clientY];
- },
-
- getDocumentElement : function() { return document; },
-
-
- getDragObject : function(eventArgs) {
- return eventArgs[1].draggable;
- },
-
- getDragScope : function(el) {
- return el.draggable("option", "scope");
- },
- getDropEvent : function(args) {
- return args[0];
- },
-
- getDropScope : function(el) {
- return el.droppable("option", "scope");
- },
-
- getDOMElement : function(el) {
- if (typeof(el) == "string") return document.getElementById(el);
- else if (el.context) return el[0];
- else return el;
- },
-
-
-
- getElementObject : function(el) {
- return typeof(el) == "string" ? $("#" + el) : $(el);
- },
-
-
- getOffset : function(el) {
- return el.offset();
- },
-
- getPageXY : function(eventObject) {
- return [eventObject.pageX, eventObject.pageY];
- },
-
- getParent : function(el) {
- return jsPlumb.CurrentLibrary.getElementObject(el).parent();
- },
-
- getScrollLeft : function(el) {
- return el.scrollLeft();
- },
-
- getScrollTop : function(el) {
- return el.scrollTop();
- },
-
- getSelector : function(spec) {
- return $(spec);
- },
-
-
- getSize : function(el) {
- return [el.outerWidth(), el.outerHeight()];
- },
- getTagName : function(el) {
- var e = jsPlumb.CurrentLibrary.getElementObject(el);
- return e.length > 0 ? e[0].tagName : null;
- },
-
-
- getUIPosition : function(eventArgs) {
-
-
-
-
-
-
-
- if (eventArgs.length == 1) {
- ret = { left: eventArgs[0].pageX, top:eventArgs[0].pageY };
- }
- else {
- var ui = eventArgs[1], _offset = ui.offset;
- ret = _offset || ui.absolutePosition;
- }
- return ret;
- },
-
- hasClass : function(el, clazz) {
- return el.hasClass(clazz);
- },
-
-
- initDraggable : function(el, options) {
- options = options || {};
-
- options.helper = null;
- options['scope'] = options['scope'] || jsPlumb.Defaults.Scope;
- el.draggable(options);
- },
-
-
- initDroppable : function(el, options) {
- options['scope'] = options['scope'] || jsPlumb.Defaults.Scope;
- el.droppable(options);
- },
-
- isAlreadyDraggable : function(el) {
- el = jsPlumb.CurrentLibrary.getElementObject(el);
- return el.hasClass("ui-draggable");
- },
-
-
- isDragSupported : function(el, options) {
- return el.draggable;
- },
-
-
- isDropSupported : function(el, options) {
- return el.droppable;
- },
-
-
- removeClass : function(el, clazz) {
- el = jsPlumb.CurrentLibrary.getElementObject(el);
- try {
- if (el[0].className.constructor == SVGAnimatedString) {
- jsPlumb.util.svg.removeClass(el[0], clazz);
- }
- }
- catch (e) {
-
- }
- el.removeClass(clazz);
- },
-
- removeElement : function(element, parent) {
- jsPlumb.CurrentLibrary.getElementObject(element).remove();
- },
-
-
- setAttribute : function(el, attName, attValue) {
- el.attr(attName, attValue);
- },
-
-
- setDraggable : function(el, draggable) {
- el.draggable("option", "disabled", !draggable);
- },
-
-
- setDragScope : function(el, scope) {
- el.draggable("option", "scope", scope);
- },
-
- setOffset : function(el, o) {
- jsPlumb.CurrentLibrary.getElementObject(el).offset(o);
- },
-
-
- trigger : function(el, event, originalEvent) {
-
-
- var h = jQuery._data(jsPlumb.CurrentLibrary.getElementObject(el)[0], "handle");
- h(originalEvent);
-
- },
-
-
- unbind : function(el, event, callback) {
- el = jsPlumb.CurrentLibrary.getElementObject(el);
- el.unbind(event, callback);
- }
- };
-
- $(document).ready(jsPlumb.init);
-
- })(jQuery);
- (function(){if("undefined"==typeof Math.sgn)Math.sgn=function(a){return 0==a?0:0<a?1:-1};var l={subtract:function(a,b){return{x:a.x-b.x,y:a.y-b.y}},dotProduct:function(a,b){return a.x*b.x+a.y*b.y},square:function(a){return Math.sqrt(a.x*a.x+a.y*a.y)},scale:function(a,b){return{x:a.x*b,y:a.y*b}}},w=Math.pow(2,-65),u=function(a,b){for(var f=[],d=b.length-1,h=2*d-1,g=[],c=[],k=[],i=[],m=[[1,0.6,0.3,0.1],[0.4,0.6,0.6,0.4],[0.1,0.3,0.6,1]],e=0;e<=d;e++)g[e]=l.subtract(b[e],a);for(e=0;e<=d-1;e++)c[e]=l.subtract(b[e+
- 1],b[e]),c[e]=l.scale(c[e],3);for(e=0;e<=d-1;e++)for(var n=0;n<=d;n++)k[e]||(k[e]=[]),k[e][n]=l.dotProduct(c[e],g[n]);for(e=0;e<=h;e++)i[e]||(i[e]=[]),i[e].y=0,i[e].x=parseFloat(e)/h;h=d-1;for(g=0;g<=d+h;g++){e=Math.max(0,g-h);for(c=Math.min(g,d);e<=c;e++)j=g-e,i[e+j].y+=k[j][e]*m[j][e]}d=b.length-1;i=q(i,2*d-1,f,0);h=l.subtract(a,b[0]);k=l.square(h);for(e=m=0;e<i;e++)h=l.subtract(a,r(b,d,f[e],null,null)),h=l.square(h),h<k&&(k=h,m=f[e]);h=l.subtract(a,b[d]);h=l.square(h);h<k&&(k=h,m=1);return{location:m,
- distance:k}},q=function(a,b,f,d){var h=[],g=[],c=[],k=[],i=0,m,e;e=Math.sgn(a[0].y);for(var n=1;n<=b;n++)m=Math.sgn(a[n].y),m!=e&&i++,e=m;switch(i){case 0:return 0;case 1:if(64<=d)return f[0]=(a[0].x+a[b].x)/2,1;var o,i=a[0].y-a[b].y;m=a[b].x-a[0].x;e=a[0].x*a[b].y-a[b].x*a[0].y;n=max_distance_below=0;for(o=1;o<b;o++){var l=i*a[o].x+m*a[o].y+e;l>n?n=l:l<max_distance_below&&(max_distance_below=l)}o=m;n=(1*(e-n)-0*o)*(1/(0*o-1*i));o=m;i=(1*(e-max_distance_below)-0*o)*(1/(0*o-1*i));m=Math.min(n,i);if(Math.max(n,
- i)-m<w)return c=a[b].x-a[0].x,k=a[b].y-a[0].y,f[0]=0+1*(c*(a[0].y-0)-k*(a[0].x-0))*(1/(0*c-1*k)),1}r(a,b,0.5,h,g);a=q(h,b,c,d+1);b=q(g,b,k,d+1);for(d=0;d<a;d++)f[d]=c[d];for(d=0;d<b;d++)f[d+a]=k[d];return a+b},r=function(a,b,f,d,h){for(var g=[[]],c=0;c<=b;c++)g[0][c]=a[c];for(a=1;a<=b;a++)for(c=0;c<=b-a;c++)g[a]||(g[a]=[]),g[a][c]||(g[a][c]={}),g[a][c].x=(1-f)*g[a-1][c].x+f*g[a-1][c+1].x,g[a][c].y=(1-f)*g[a-1][c].y+f*g[a-1][c+1].y;if(null!=d)for(c=0;c<=b;c++)d[c]=g[c][0];if(null!=h)for(c=0;c<=b;c++)h[c]=
- g[b-c][c];return g[b][0]},v={},x=function(a){var b=v[a];if(!b){var b=[],f=function(a){return function(){return a}},d=function(){return function(a){return a}},h=function(){return function(a){return 1-a}},g=function(a){return function(b){for(var c=1,d=0;d<a.length;d++)c*=a[d](b);return c}};b.push(new function(){return function(b){return Math.pow(b,a)}});for(var c=1;c<a;c++){for(var k=[new f(a)],i=0;i<a-c;i++)k.push(new d);for(i=0;i<c;i++)k.push(new h);b.push(new g(k))}b.push(new function(){return function(b){return Math.pow(1-
- b,a)}});v[a]=b}return b},p=function(a,b){for(var f=x(a.length-1),d=0,h=0,g=0;g<a.length;g++)d+=a[g].x*f[g](b),h+=a[g].y*f[g](b);return{x:d,y:h}},s=function(a,b,f){for(var d=p(a,b),h=0,g=0<f?1:-1,c=null;h<Math.abs(f);)b+=0.005*g,c=p(a,b),h+=Math.sqrt(Math.pow(c.x-d.x,2)+Math.pow(c.y-d.y,2)),d=c;return{point:c,location:b}},t=function(a,b){var f=p(a,b),d=p(a.slice(0,a.length-1),b),h=d.y-f.y,f=d.x-f.x;return 0==h?Infinity:Math.atan(h/f)};window.jsBezier={distanceFromCurve:u,gradientAtPoint:t,gradientAtPointAlongCurveFrom:function(a,
- b,f){b=s(a,b,f);if(1<b.location)b.location=1;if(0>b.location)b.location=0;return t(a,b.location)},nearestPointOnCurve:function(a,b){var f=u(a,b);return{point:r(b,b.length-1,f.location,null,null),location:f.location}},pointOnCurve:p,pointAlongCurveFrom:function(a,b,f){return s(a,b,f).point},perpendicularToCurveAt:function(a,b,f,d){b=s(a,b,null==d?0:d);a=t(a,b.location);d=Math.atan(-1/a);a=f/2*Math.sin(d);f=f/2*Math.cos(d);return[{x:b.point.x+f,y:b.point.y+a},{x:b.point.x-f,y:b.point.y-a}]}}})();
|