bpmn-navigated-viewer.development.js 567 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390839183928393839483958396839783988399840084018402840384048405840684078408840984108411841284138414841584168417841884198420842184228423842484258426842784288429843084318432843384348435843684378438843984408441844284438444844584468447844884498450845184528453845484558456845784588459846084618462846384648465846684678468846984708471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540854185428543854485458546854785488549855085518552855385548555855685578558855985608561856285638564856585668567856885698570857185728573857485758576857785788579858085818582858385848585858685878588858985908591859285938594859585968597859885998600860186028603860486058606860786088609861086118612861386148615861686178618861986208621862286238624862586268627862886298630863186328633863486358636863786388639864086418642864386448645864686478648864986508651865286538654865586568657865886598660866186628663866486658666866786688669867086718672867386748675867686778678867986808681868286838684868586868687868886898690869186928693869486958696869786988699870087018702870387048705870687078708870987108711871287138714871587168717871887198720872187228723872487258726872787288729873087318732873387348735873687378738873987408741874287438744874587468747874887498750875187528753875487558756875787588759876087618762876387648765876687678768876987708771877287738774877587768777877887798780878187828783878487858786878787888789879087918792879387948795879687978798879988008801880288038804880588068807880888098810881188128813881488158816881788188819882088218822882388248825882688278828882988308831883288338834883588368837883888398840884188428843884488458846884788488849885088518852885388548855885688578858885988608861886288638864886588668867886888698870887188728873887488758876887788788879888088818882888388848885888688878888888988908891889288938894889588968897889888998900890189028903890489058906890789088909891089118912891389148915891689178918891989208921892289238924892589268927892889298930893189328933893489358936893789388939894089418942894389448945894689478948894989508951895289538954895589568957895889598960896189628963896489658966896789688969897089718972897389748975897689778978897989808981898289838984898589868987898889898990899189928993899489958996899789988999900090019002900390049005900690079008900990109011901290139014901590169017901890199020902190229023902490259026902790289029903090319032903390349035903690379038903990409041904290439044904590469047904890499050905190529053905490559056905790589059906090619062906390649065906690679068906990709071907290739074907590769077907890799080908190829083908490859086908790889089909090919092909390949095909690979098909991009101910291039104910591069107910891099110911191129113911491159116911791189119912091219122912391249125912691279128912991309131913291339134913591369137913891399140914191429143914491459146914791489149915091519152915391549155915691579158915991609161916291639164916591669167916891699170917191729173917491759176917791789179918091819182918391849185918691879188918991909191919291939194919591969197919891999200920192029203920492059206920792089209921092119212921392149215921692179218921992209221922292239224922592269227922892299230923192329233923492359236923792389239924092419242924392449245924692479248924992509251925292539254925592569257925892599260926192629263926492659266926792689269927092719272927392749275927692779278927992809281928292839284928592869287928892899290929192929293929492959296929792989299930093019302930393049305930693079308930993109311931293139314931593169317931893199320932193229323932493259326932793289329933093319332933393349335933693379338933993409341934293439344934593469347934893499350935193529353935493559356935793589359936093619362936393649365936693679368936993709371937293739374937593769377937893799380938193829383938493859386938793889389939093919392939393949395939693979398939994009401940294039404940594069407940894099410941194129413941494159416941794189419942094219422942394249425942694279428942994309431943294339434943594369437943894399440944194429443944494459446944794489449945094519452945394549455945694579458945994609461946294639464946594669467946894699470947194729473947494759476947794789479948094819482948394849485948694879488948994909491949294939494949594969497949894999500950195029503950495059506950795089509951095119512951395149515951695179518951995209521952295239524952595269527952895299530953195329533953495359536953795389539954095419542954395449545954695479548954995509551955295539554955595569557955895599560956195629563956495659566956795689569957095719572957395749575957695779578957995809581958295839584958595869587958895899590959195929593959495959596959795989599960096019602960396049605960696079608960996109611961296139614961596169617961896199620962196229623962496259626962796289629963096319632963396349635963696379638963996409641964296439644964596469647964896499650965196529653965496559656965796589659966096619662966396649665966696679668966996709671967296739674967596769677967896799680968196829683968496859686968796889689969096919692969396949695969696979698969997009701970297039704970597069707970897099710971197129713971497159716971797189719972097219722972397249725972697279728972997309731973297339734973597369737973897399740974197429743974497459746974797489749975097519752975397549755975697579758975997609761976297639764976597669767976897699770977197729773977497759776977797789779978097819782978397849785978697879788978997909791979297939794979597969797979897999800980198029803980498059806980798089809981098119812981398149815981698179818981998209821982298239824982598269827982898299830983198329833983498359836983798389839984098419842984398449845984698479848984998509851985298539854985598569857985898599860986198629863986498659866986798689869987098719872987398749875987698779878987998809881988298839884988598869887988898899890989198929893989498959896989798989899990099019902990399049905990699079908990999109911991299139914991599169917991899199920992199229923992499259926992799289929993099319932993399349935993699379938993999409941994299439944994599469947994899499950995199529953995499559956995799589959996099619962996399649965996699679968996999709971997299739974997599769977997899799980998199829983998499859986998799889989999099919992999399949995999699979998999910000100011000210003100041000510006100071000810009100101001110012100131001410015100161001710018100191002010021100221002310024100251002610027100281002910030100311003210033100341003510036100371003810039100401004110042100431004410045100461004710048100491005010051100521005310054100551005610057100581005910060100611006210063100641006510066100671006810069100701007110072100731007410075100761007710078100791008010081100821008310084100851008610087100881008910090100911009210093100941009510096100971009810099101001010110102101031010410105101061010710108101091011010111101121011310114101151011610117101181011910120101211012210123101241012510126101271012810129101301013110132101331013410135101361013710138101391014010141101421014310144101451014610147101481014910150101511015210153101541015510156101571015810159101601016110162101631016410165101661016710168101691017010171101721017310174101751017610177101781017910180101811018210183101841018510186101871018810189101901019110192101931019410195101961019710198101991020010201102021020310204102051020610207102081020910210102111021210213102141021510216102171021810219102201022110222102231022410225102261022710228102291023010231102321023310234102351023610237102381023910240102411024210243102441024510246102471024810249102501025110252102531025410255102561025710258102591026010261102621026310264102651026610267102681026910270102711027210273102741027510276102771027810279102801028110282102831028410285102861028710288102891029010291102921029310294102951029610297102981029910300103011030210303103041030510306103071030810309103101031110312103131031410315103161031710318103191032010321103221032310324103251032610327103281032910330103311033210333103341033510336103371033810339103401034110342103431034410345103461034710348103491035010351103521035310354103551035610357103581035910360103611036210363103641036510366103671036810369103701037110372103731037410375103761037710378103791038010381103821038310384103851038610387103881038910390103911039210393103941039510396103971039810399104001040110402104031040410405104061040710408104091041010411104121041310414104151041610417104181041910420104211042210423104241042510426104271042810429104301043110432104331043410435104361043710438104391044010441104421044310444104451044610447104481044910450104511045210453104541045510456104571045810459104601046110462104631046410465104661046710468104691047010471104721047310474104751047610477104781047910480104811048210483104841048510486104871048810489104901049110492104931049410495104961049710498104991050010501105021050310504105051050610507105081050910510105111051210513105141051510516105171051810519105201052110522105231052410525105261052710528105291053010531105321053310534105351053610537105381053910540105411054210543105441054510546105471054810549105501055110552105531055410555105561055710558105591056010561105621056310564105651056610567105681056910570105711057210573105741057510576105771057810579105801058110582105831058410585105861058710588105891059010591105921059310594105951059610597105981059910600106011060210603106041060510606106071060810609106101061110612106131061410615106161061710618106191062010621106221062310624106251062610627106281062910630106311063210633106341063510636106371063810639106401064110642106431064410645106461064710648106491065010651106521065310654106551065610657106581065910660106611066210663106641066510666106671066810669106701067110672106731067410675106761067710678106791068010681106821068310684106851068610687106881068910690106911069210693106941069510696106971069810699107001070110702107031070410705107061070710708107091071010711107121071310714107151071610717107181071910720107211072210723107241072510726107271072810729107301073110732107331073410735107361073710738107391074010741107421074310744107451074610747107481074910750107511075210753107541075510756107571075810759107601076110762107631076410765107661076710768107691077010771107721077310774107751077610777107781077910780107811078210783107841078510786107871078810789107901079110792107931079410795107961079710798107991080010801108021080310804108051080610807108081080910810108111081210813108141081510816108171081810819108201082110822108231082410825108261082710828108291083010831108321083310834108351083610837108381083910840108411084210843108441084510846108471084810849108501085110852108531085410855108561085710858108591086010861108621086310864108651086610867108681086910870108711087210873108741087510876108771087810879108801088110882108831088410885108861088710888108891089010891108921089310894108951089610897108981089910900109011090210903109041090510906109071090810909109101091110912109131091410915109161091710918109191092010921109221092310924109251092610927109281092910930109311093210933109341093510936109371093810939109401094110942109431094410945109461094710948109491095010951109521095310954109551095610957109581095910960109611096210963109641096510966109671096810969109701097110972109731097410975109761097710978109791098010981109821098310984109851098610987109881098910990109911099210993109941099510996109971099810999110001100111002110031100411005110061100711008110091101011011110121101311014110151101611017110181101911020110211102211023110241102511026110271102811029110301103111032110331103411035110361103711038110391104011041110421104311044110451104611047110481104911050110511105211053110541105511056110571105811059110601106111062110631106411065110661106711068110691107011071110721107311074110751107611077110781107911080110811108211083110841108511086110871108811089110901109111092110931109411095110961109711098110991110011101111021110311104111051110611107111081110911110111111111211113111141111511116111171111811119111201112111122111231112411125111261112711128111291113011131111321113311134111351113611137111381113911140111411114211143111441114511146111471114811149111501115111152111531115411155111561115711158111591116011161111621116311164111651116611167111681116911170111711117211173111741117511176111771117811179111801118111182111831118411185111861118711188111891119011191111921119311194111951119611197111981119911200112011120211203112041120511206112071120811209112101121111212112131121411215112161121711218112191122011221112221122311224112251122611227112281122911230112311123211233112341123511236112371123811239112401124111242112431124411245112461124711248112491125011251112521125311254112551125611257112581125911260112611126211263112641126511266112671126811269112701127111272112731127411275112761127711278112791128011281112821128311284112851128611287112881128911290112911129211293112941129511296112971129811299113001130111302113031130411305113061130711308113091131011311113121131311314113151131611317113181131911320113211132211323113241132511326113271132811329113301133111332113331133411335113361133711338113391134011341113421134311344113451134611347113481134911350113511135211353113541135511356113571135811359113601136111362113631136411365113661136711368113691137011371113721137311374113751137611377113781137911380113811138211383113841138511386113871138811389113901139111392113931139411395113961139711398113991140011401114021140311404114051140611407114081140911410114111141211413114141141511416114171141811419114201142111422114231142411425114261142711428114291143011431114321143311434114351143611437114381143911440114411144211443114441144511446114471144811449114501145111452114531145411455114561145711458114591146011461114621146311464114651146611467114681146911470114711147211473114741147511476114771147811479114801148111482114831148411485114861148711488114891149011491114921149311494114951149611497114981149911500115011150211503115041150511506115071150811509115101151111512115131151411515115161151711518115191152011521115221152311524115251152611527115281152911530115311153211533115341153511536115371153811539115401154111542115431154411545115461154711548115491155011551115521155311554115551155611557115581155911560115611156211563115641156511566115671156811569115701157111572115731157411575115761157711578115791158011581115821158311584115851158611587115881158911590115911159211593115941159511596115971159811599116001160111602116031160411605116061160711608116091161011611116121161311614116151161611617116181161911620116211162211623116241162511626116271162811629116301163111632116331163411635116361163711638116391164011641116421164311644116451164611647116481164911650116511165211653116541165511656116571165811659116601166111662116631166411665116661166711668116691167011671116721167311674116751167611677116781167911680116811168211683116841168511686116871168811689116901169111692116931169411695116961169711698116991170011701117021170311704117051170611707117081170911710117111171211713117141171511716117171171811719117201172111722117231172411725117261172711728117291173011731117321173311734117351173611737117381173911740117411174211743117441174511746117471174811749117501175111752117531175411755117561175711758117591176011761117621176311764117651176611767117681176911770117711177211773117741177511776117771177811779117801178111782117831178411785117861178711788117891179011791117921179311794117951179611797117981179911800118011180211803118041180511806118071180811809118101181111812118131181411815118161181711818118191182011821118221182311824118251182611827118281182911830118311183211833118341183511836118371183811839118401184111842118431184411845118461184711848118491185011851118521185311854118551185611857118581185911860118611186211863118641186511866118671186811869118701187111872118731187411875118761187711878118791188011881118821188311884118851188611887118881188911890118911189211893118941189511896118971189811899119001190111902119031190411905119061190711908119091191011911119121191311914119151191611917119181191911920119211192211923119241192511926119271192811929119301193111932119331193411935119361193711938119391194011941119421194311944119451194611947119481194911950119511195211953119541195511956119571195811959119601196111962119631196411965119661196711968119691197011971119721197311974119751197611977119781197911980119811198211983119841198511986119871198811989119901199111992119931199411995119961199711998119991200012001120021200312004120051200612007120081200912010120111201212013120141201512016120171201812019120201202112022120231202412025120261202712028120291203012031120321203312034120351203612037120381203912040120411204212043120441204512046120471204812049120501205112052120531205412055120561205712058120591206012061120621206312064120651206612067120681206912070120711207212073120741207512076120771207812079120801208112082120831208412085120861208712088120891209012091120921209312094120951209612097120981209912100121011210212103121041210512106121071210812109121101211112112121131211412115121161211712118121191212012121121221212312124121251212612127121281212912130121311213212133121341213512136121371213812139121401214112142121431214412145121461214712148121491215012151121521215312154121551215612157121581215912160121611216212163121641216512166121671216812169121701217112172121731217412175121761217712178121791218012181121821218312184121851218612187121881218912190121911219212193121941219512196121971219812199122001220112202122031220412205122061220712208122091221012211122121221312214122151221612217122181221912220122211222212223122241222512226122271222812229122301223112232122331223412235122361223712238122391224012241122421224312244122451224612247122481224912250122511225212253122541225512256122571225812259122601226112262122631226412265122661226712268122691227012271122721227312274122751227612277122781227912280122811228212283122841228512286122871228812289122901229112292122931229412295122961229712298122991230012301123021230312304123051230612307123081230912310123111231212313123141231512316123171231812319123201232112322123231232412325123261232712328123291233012331123321233312334123351233612337123381233912340123411234212343123441234512346123471234812349123501235112352123531235412355123561235712358123591236012361123621236312364123651236612367123681236912370123711237212373123741237512376123771237812379123801238112382123831238412385123861238712388123891239012391123921239312394123951239612397123981239912400124011240212403124041240512406124071240812409124101241112412124131241412415124161241712418124191242012421124221242312424124251242612427124281242912430124311243212433124341243512436124371243812439124401244112442124431244412445124461244712448124491245012451124521245312454124551245612457124581245912460124611246212463124641246512466124671246812469124701247112472124731247412475124761247712478124791248012481124821248312484124851248612487124881248912490124911249212493124941249512496124971249812499125001250112502125031250412505125061250712508125091251012511125121251312514125151251612517125181251912520125211252212523125241252512526125271252812529125301253112532125331253412535125361253712538125391254012541125421254312544125451254612547125481254912550125511255212553125541255512556125571255812559125601256112562125631256412565125661256712568125691257012571125721257312574125751257612577125781257912580125811258212583125841258512586125871258812589125901259112592125931259412595125961259712598125991260012601126021260312604126051260612607126081260912610126111261212613126141261512616126171261812619126201262112622126231262412625126261262712628126291263012631126321263312634126351263612637126381263912640126411264212643126441264512646126471264812649126501265112652126531265412655126561265712658126591266012661126621266312664126651266612667126681266912670126711267212673126741267512676126771267812679126801268112682126831268412685126861268712688126891269012691126921269312694126951269612697126981269912700127011270212703127041270512706127071270812709127101271112712127131271412715127161271712718127191272012721127221272312724127251272612727127281272912730127311273212733127341273512736127371273812739127401274112742127431274412745127461274712748127491275012751127521275312754127551275612757127581275912760127611276212763127641276512766127671276812769127701277112772127731277412775127761277712778127791278012781127821278312784127851278612787127881278912790127911279212793127941279512796127971279812799128001280112802128031280412805128061280712808128091281012811128121281312814128151281612817128181281912820128211282212823128241282512826128271282812829128301283112832128331283412835128361283712838128391284012841128421284312844128451284612847128481284912850128511285212853128541285512856128571285812859128601286112862128631286412865128661286712868128691287012871128721287312874128751287612877128781287912880128811288212883128841288512886128871288812889128901289112892128931289412895128961289712898128991290012901129021290312904129051290612907129081290912910129111291212913129141291512916129171291812919129201292112922129231292412925129261292712928129291293012931129321293312934129351293612937129381293912940129411294212943129441294512946129471294812949129501295112952129531295412955129561295712958129591296012961129621296312964129651296612967129681296912970129711297212973129741297512976129771297812979129801298112982129831298412985129861298712988129891299012991129921299312994129951299612997129981299913000130011300213003130041300513006130071300813009130101301113012130131301413015130161301713018130191302013021130221302313024130251302613027130281302913030130311303213033130341303513036130371303813039130401304113042130431304413045130461304713048130491305013051130521305313054130551305613057130581305913060130611306213063130641306513066130671306813069130701307113072130731307413075130761307713078130791308013081130821308313084130851308613087130881308913090130911309213093130941309513096130971309813099131001310113102131031310413105131061310713108131091311013111131121311313114131151311613117131181311913120131211312213123131241312513126131271312813129131301313113132131331313413135131361313713138131391314013141131421314313144131451314613147131481314913150131511315213153131541315513156131571315813159131601316113162131631316413165131661316713168131691317013171131721317313174131751317613177131781317913180131811318213183131841318513186131871318813189131901319113192131931319413195131961319713198131991320013201132021320313204132051320613207132081320913210132111321213213132141321513216132171321813219132201322113222132231322413225132261322713228132291323013231132321323313234132351323613237132381323913240132411324213243132441324513246132471324813249132501325113252132531325413255132561325713258132591326013261132621326313264132651326613267132681326913270132711327213273132741327513276132771327813279132801328113282132831328413285132861328713288132891329013291132921329313294132951329613297132981329913300133011330213303133041330513306133071330813309133101331113312133131331413315133161331713318133191332013321133221332313324133251332613327133281332913330133311333213333133341333513336133371333813339133401334113342133431334413345133461334713348133491335013351133521335313354133551335613357133581335913360133611336213363133641336513366133671336813369133701337113372133731337413375133761337713378133791338013381133821338313384133851338613387133881338913390133911339213393133941339513396133971339813399134001340113402134031340413405134061340713408134091341013411134121341313414134151341613417134181341913420134211342213423134241342513426134271342813429134301343113432134331343413435134361343713438134391344013441134421344313444134451344613447134481344913450134511345213453134541345513456134571345813459134601346113462134631346413465134661346713468134691347013471134721347313474134751347613477134781347913480134811348213483134841348513486134871348813489134901349113492134931349413495134961349713498134991350013501135021350313504135051350613507135081350913510135111351213513135141351513516135171351813519135201352113522135231352413525135261352713528135291353013531135321353313534135351353613537135381353913540135411354213543135441354513546135471354813549135501355113552135531355413555135561355713558135591356013561135621356313564135651356613567135681356913570135711357213573135741357513576135771357813579135801358113582135831358413585135861358713588135891359013591135921359313594135951359613597135981359913600136011360213603136041360513606136071360813609136101361113612136131361413615136161361713618136191362013621136221362313624136251362613627136281362913630136311363213633136341363513636136371363813639136401364113642136431364413645136461364713648136491365013651136521365313654136551365613657136581365913660136611366213663136641366513666136671366813669136701367113672136731367413675136761367713678136791368013681136821368313684136851368613687136881368913690136911369213693136941369513696136971369813699137001370113702137031370413705137061370713708137091371013711137121371313714137151371613717137181371913720137211372213723137241372513726137271372813729137301373113732137331373413735137361373713738137391374013741137421374313744137451374613747137481374913750137511375213753137541375513756137571375813759137601376113762137631376413765137661376713768137691377013771137721377313774137751377613777137781377913780137811378213783137841378513786137871378813789137901379113792137931379413795137961379713798137991380013801138021380313804138051380613807138081380913810138111381213813138141381513816138171381813819138201382113822138231382413825138261382713828138291383013831138321383313834138351383613837138381383913840138411384213843138441384513846138471384813849138501385113852138531385413855138561385713858138591386013861138621386313864138651386613867138681386913870138711387213873138741387513876138771387813879138801388113882138831388413885138861388713888138891389013891138921389313894138951389613897138981389913900139011390213903139041390513906139071390813909139101391113912139131391413915139161391713918139191392013921139221392313924139251392613927139281392913930139311393213933139341393513936139371393813939139401394113942139431394413945139461394713948139491395013951139521395313954139551395613957139581395913960139611396213963139641396513966139671396813969139701397113972139731397413975139761397713978139791398013981139821398313984139851398613987139881398913990139911399213993139941399513996139971399813999140001400114002140031400414005140061400714008140091401014011140121401314014140151401614017140181401914020140211402214023140241402514026140271402814029140301403114032140331403414035140361403714038140391404014041140421404314044140451404614047140481404914050140511405214053140541405514056140571405814059140601406114062140631406414065140661406714068140691407014071140721407314074140751407614077140781407914080140811408214083140841408514086140871408814089140901409114092140931409414095140961409714098140991410014101141021410314104141051410614107141081410914110141111411214113141141411514116141171411814119141201412114122141231412414125141261412714128141291413014131141321413314134141351413614137141381413914140141411414214143141441414514146141471414814149141501415114152141531415414155141561415714158141591416014161141621416314164141651416614167141681416914170141711417214173141741417514176141771417814179141801418114182141831418414185141861418714188141891419014191141921419314194141951419614197141981419914200142011420214203142041420514206142071420814209142101421114212142131421414215142161421714218142191422014221142221422314224142251422614227142281422914230142311423214233142341423514236142371423814239142401424114242142431424414245142461424714248142491425014251142521425314254142551425614257142581425914260142611426214263142641426514266142671426814269142701427114272142731427414275142761427714278142791428014281142821428314284142851428614287142881428914290142911429214293142941429514296142971429814299143001430114302143031430414305143061430714308143091431014311143121431314314143151431614317143181431914320143211432214323143241432514326143271432814329143301433114332143331433414335143361433714338143391434014341143421434314344143451434614347143481434914350143511435214353143541435514356143571435814359143601436114362143631436414365143661436714368143691437014371143721437314374143751437614377143781437914380143811438214383143841438514386143871438814389143901439114392143931439414395143961439714398143991440014401144021440314404144051440614407144081440914410144111441214413144141441514416144171441814419144201442114422144231442414425144261442714428144291443014431144321443314434144351443614437144381443914440144411444214443144441444514446144471444814449144501445114452144531445414455144561445714458144591446014461144621446314464144651446614467144681446914470144711447214473144741447514476144771447814479144801448114482144831448414485144861448714488144891449014491144921449314494144951449614497144981449914500145011450214503145041450514506145071450814509145101451114512145131451414515145161451714518145191452014521145221452314524145251452614527145281452914530145311453214533145341453514536145371453814539145401454114542145431454414545145461454714548145491455014551145521455314554145551455614557145581455914560145611456214563145641456514566145671456814569145701457114572145731457414575145761457714578145791458014581145821458314584145851458614587145881458914590145911459214593145941459514596145971459814599146001460114602146031460414605146061460714608146091461014611146121461314614146151461614617146181461914620146211462214623146241462514626146271462814629146301463114632146331463414635146361463714638146391464014641146421464314644146451464614647146481464914650146511465214653146541465514656146571465814659146601466114662146631466414665146661466714668146691467014671146721467314674146751467614677146781467914680146811468214683146841468514686146871468814689146901469114692146931469414695146961469714698146991470014701147021470314704147051470614707147081470914710147111471214713147141471514716147171471814719147201472114722147231472414725147261472714728147291473014731147321473314734147351473614737147381473914740147411474214743147441474514746147471474814749147501475114752147531475414755147561475714758147591476014761147621476314764147651476614767147681476914770147711477214773147741477514776147771477814779147801478114782147831478414785147861478714788147891479014791147921479314794147951479614797147981479914800148011480214803148041480514806148071480814809148101481114812148131481414815148161481714818148191482014821148221482314824148251482614827148281482914830148311483214833148341483514836148371483814839148401484114842148431484414845148461484714848148491485014851148521485314854148551485614857148581485914860148611486214863148641486514866148671486814869148701487114872148731487414875148761487714878148791488014881148821488314884148851488614887148881488914890148911489214893148941489514896148971489814899149001490114902149031490414905149061490714908149091491014911149121491314914149151491614917149181491914920149211492214923149241492514926149271492814929149301493114932149331493414935149361493714938149391494014941149421494314944149451494614947149481494914950149511495214953149541495514956149571495814959149601496114962149631496414965149661496714968149691497014971149721497314974149751497614977149781497914980149811498214983149841498514986149871498814989149901499114992149931499414995149961499714998149991500015001150021500315004150051500615007150081500915010150111501215013150141501515016150171501815019150201502115022150231502415025150261502715028150291503015031150321503315034150351503615037150381503915040150411504215043150441504515046150471504815049150501505115052150531505415055150561505715058150591506015061150621506315064150651506615067150681506915070150711507215073150741507515076150771507815079150801508115082150831508415085150861508715088150891509015091150921509315094150951509615097150981509915100151011510215103151041510515106151071510815109151101511115112151131511415115151161511715118151191512015121151221512315124151251512615127151281512915130151311513215133151341513515136151371513815139151401514115142151431514415145151461514715148151491515015151151521515315154151551515615157151581515915160151611516215163151641516515166151671516815169151701517115172151731517415175151761517715178151791518015181151821518315184151851518615187151881518915190151911519215193151941519515196151971519815199152001520115202152031520415205152061520715208152091521015211152121521315214152151521615217152181521915220152211522215223152241522515226152271522815229152301523115232152331523415235152361523715238152391524015241152421524315244152451524615247152481524915250152511525215253152541525515256152571525815259152601526115262152631526415265152661526715268152691527015271152721527315274152751527615277152781527915280152811528215283152841528515286152871528815289152901529115292152931529415295152961529715298152991530015301153021530315304153051530615307153081530915310153111531215313153141531515316153171531815319153201532115322153231532415325153261532715328153291533015331153321533315334153351533615337153381533915340153411534215343153441534515346153471534815349153501535115352153531535415355153561535715358153591536015361153621536315364153651536615367153681536915370153711537215373153741537515376153771537815379153801538115382153831538415385153861538715388153891539015391153921539315394153951539615397153981539915400154011540215403154041540515406154071540815409154101541115412154131541415415154161541715418154191542015421154221542315424154251542615427154281542915430154311543215433154341543515436154371543815439154401544115442154431544415445154461544715448154491545015451154521545315454154551545615457154581545915460154611546215463154641546515466154671546815469154701547115472154731547415475154761547715478154791548015481154821548315484154851548615487154881548915490154911549215493154941549515496154971549815499155001550115502155031550415505155061550715508155091551015511155121551315514155151551615517155181551915520155211552215523155241552515526155271552815529155301553115532155331553415535155361553715538155391554015541155421554315544155451554615547155481554915550155511555215553155541555515556155571555815559155601556115562155631556415565155661556715568155691557015571155721557315574155751557615577155781557915580155811558215583155841558515586155871558815589155901559115592155931559415595155961559715598155991560015601156021560315604156051560615607156081560915610156111561215613156141561515616156171561815619156201562115622156231562415625156261562715628156291563015631156321563315634156351563615637156381563915640156411564215643156441564515646156471564815649156501565115652156531565415655156561565715658156591566015661156621566315664156651566615667156681566915670156711567215673156741567515676156771567815679156801568115682156831568415685156861568715688156891569015691156921569315694156951569615697156981569915700157011570215703157041570515706157071570815709157101571115712157131571415715157161571715718157191572015721157221572315724157251572615727157281572915730157311573215733157341573515736157371573815739157401574115742157431574415745157461574715748157491575015751157521575315754157551575615757157581575915760157611576215763157641576515766157671576815769157701577115772157731577415775157761577715778157791578015781157821578315784157851578615787157881578915790157911579215793157941579515796157971579815799158001580115802158031580415805158061580715808158091581015811158121581315814158151581615817158181581915820158211582215823158241582515826158271582815829158301583115832158331583415835158361583715838158391584015841158421584315844158451584615847158481584915850158511585215853158541585515856158571585815859158601586115862158631586415865158661586715868158691587015871158721587315874158751587615877158781587915880158811588215883158841588515886158871588815889158901589115892158931589415895158961589715898158991590015901159021590315904159051590615907159081590915910159111591215913159141591515916159171591815919159201592115922159231592415925159261592715928159291593015931159321593315934159351593615937159381593915940159411594215943159441594515946159471594815949159501595115952159531595415955159561595715958159591596015961159621596315964159651596615967159681596915970159711597215973159741597515976159771597815979159801598115982159831598415985159861598715988159891599015991159921599315994159951599615997159981599916000160011600216003160041600516006160071600816009160101601116012160131601416015160161601716018160191602016021160221602316024160251602616027160281602916030160311603216033160341603516036160371603816039160401604116042160431604416045160461604716048160491605016051160521605316054160551605616057160581605916060160611606216063160641606516066160671606816069160701607116072160731607416075160761607716078160791608016081160821608316084160851608616087160881608916090160911609216093160941609516096160971609816099161001610116102161031610416105161061610716108161091611016111161121611316114161151611616117161181611916120161211612216123161241612516126161271612816129161301613116132161331613416135161361613716138161391614016141161421614316144161451614616147161481614916150161511615216153161541615516156161571615816159161601616116162161631616416165161661616716168161691617016171161721617316174161751617616177161781617916180161811618216183161841618516186161871618816189161901619116192161931619416195161961619716198161991620016201162021620316204162051620616207162081620916210162111621216213162141621516216162171621816219162201622116222162231622416225162261622716228162291623016231162321623316234162351623616237162381623916240162411624216243162441624516246162471624816249162501625116252162531625416255162561625716258162591626016261162621626316264162651626616267162681626916270162711627216273162741627516276162771627816279162801628116282162831628416285162861628716288162891629016291162921629316294162951629616297162981629916300163011630216303163041630516306163071630816309163101631116312163131631416315163161631716318163191632016321163221632316324163251632616327163281632916330163311633216333163341633516336163371633816339163401634116342163431634416345163461634716348163491635016351163521635316354163551635616357163581635916360163611636216363163641636516366163671636816369163701637116372163731637416375163761637716378163791638016381163821638316384163851638616387163881638916390163911639216393163941639516396163971639816399164001640116402164031640416405164061640716408164091641016411164121641316414164151641616417164181641916420164211642216423164241642516426164271642816429164301643116432164331643416435164361643716438164391644016441164421644316444164451644616447164481644916450164511645216453164541645516456164571645816459164601646116462164631646416465164661646716468164691647016471164721647316474164751647616477164781647916480164811648216483164841648516486164871648816489164901649116492164931649416495164961649716498164991650016501165021650316504165051650616507165081650916510165111651216513165141651516516165171651816519165201652116522165231652416525165261652716528165291653016531165321653316534165351653616537165381653916540165411654216543165441654516546165471654816549165501655116552165531655416555165561655716558165591656016561165621656316564165651656616567165681656916570165711657216573165741657516576165771657816579165801658116582165831658416585165861658716588165891659016591165921659316594165951659616597165981659916600166011660216603166041660516606166071660816609166101661116612166131661416615166161661716618166191662016621166221662316624166251662616627166281662916630166311663216633166341663516636166371663816639166401664116642166431664416645166461664716648166491665016651166521665316654166551665616657166581665916660166611666216663166641666516666166671666816669166701667116672166731667416675166761667716678166791668016681166821668316684166851668616687166881668916690166911669216693166941669516696166971669816699167001670116702167031670416705167061670716708167091671016711167121671316714167151671616717167181671916720167211672216723167241672516726167271672816729167301673116732167331673416735167361673716738167391674016741167421674316744167451674616747167481674916750167511675216753167541675516756167571675816759167601676116762167631676416765167661676716768167691677016771167721677316774167751677616777167781677916780167811678216783167841678516786167871678816789167901679116792167931679416795167961679716798167991680016801168021680316804168051680616807168081680916810168111681216813168141681516816168171681816819168201682116822168231682416825168261682716828168291683016831168321683316834168351683616837168381683916840168411684216843168441684516846168471684816849168501685116852168531685416855168561685716858168591686016861168621686316864168651686616867168681686916870168711687216873168741687516876168771687816879168801688116882168831688416885168861688716888168891689016891168921689316894168951689616897168981689916900169011690216903169041690516906169071690816909169101691116912169131691416915169161691716918169191692016921169221692316924169251692616927169281692916930169311693216933169341693516936169371693816939169401694116942169431694416945169461694716948169491695016951169521695316954169551695616957169581695916960169611696216963169641696516966169671696816969169701697116972169731697416975169761697716978169791698016981169821698316984169851698616987169881698916990169911699216993169941699516996169971699816999170001700117002170031700417005170061700717008170091701017011170121701317014170151701617017170181701917020170211702217023170241702517026170271702817029170301703117032170331703417035170361703717038170391704017041170421704317044170451704617047170481704917050170511705217053170541705517056170571705817059170601706117062170631706417065170661706717068170691707017071170721707317074170751707617077170781707917080170811708217083170841708517086170871708817089170901709117092170931709417095170961709717098170991710017101171021710317104171051710617107171081710917110171111711217113171141711517116171171711817119171201712117122171231712417125171261712717128171291713017131171321713317134171351713617137171381713917140171411714217143171441714517146171471714817149171501715117152171531715417155171561715717158171591716017161171621716317164171651716617167171681716917170171711717217173171741717517176171771717817179171801718117182171831718417185171861718717188171891719017191171921719317194171951719617197171981719917200172011720217203172041720517206172071720817209172101721117212172131721417215172161721717218172191722017221172221722317224172251722617227172281722917230172311723217233172341723517236172371723817239172401724117242172431724417245172461724717248172491725017251172521725317254172551725617257172581725917260172611726217263172641726517266172671726817269172701727117272172731727417275172761727717278172791728017281172821728317284172851728617287172881728917290172911729217293172941729517296172971729817299173001730117302173031730417305173061730717308173091731017311173121731317314173151731617317173181731917320173211732217323173241732517326173271732817329173301733117332173331733417335173361733717338173391734017341173421734317344173451734617347173481734917350173511735217353173541735517356173571735817359173601736117362173631736417365173661736717368173691737017371173721737317374173751737617377173781737917380173811738217383173841738517386173871738817389173901739117392173931739417395173961739717398173991740017401174021740317404174051740617407174081740917410174111741217413174141741517416174171741817419174201742117422174231742417425174261742717428174291743017431174321743317434174351743617437174381743917440174411744217443174441744517446174471744817449174501745117452174531745417455174561745717458174591746017461174621746317464174651746617467174681746917470174711747217473174741747517476174771747817479174801748117482174831748417485174861748717488174891749017491174921749317494174951749617497174981749917500175011750217503175041750517506175071750817509175101751117512175131751417515175161751717518175191752017521175221752317524175251752617527175281752917530175311753217533175341753517536175371753817539175401754117542175431754417545175461754717548175491755017551175521755317554175551755617557175581755917560175611756217563175641756517566175671756817569175701757117572175731757417575175761757717578175791758017581175821758317584175851758617587175881758917590175911759217593175941759517596175971759817599176001760117602176031760417605176061760717608176091761017611176121761317614176151761617617176181761917620176211762217623176241762517626176271762817629176301763117632176331763417635176361763717638176391764017641176421764317644176451764617647176481764917650176511765217653176541765517656176571765817659176601766117662176631766417665176661766717668176691767017671176721767317674176751767617677176781767917680176811768217683176841768517686176871768817689176901769117692176931769417695176961769717698176991770017701177021770317704177051770617707177081770917710177111771217713177141771517716177171771817719177201772117722177231772417725177261772717728177291773017731177321773317734177351773617737177381773917740177411774217743177441774517746177471774817749177501775117752177531775417755177561775717758177591776017761177621776317764177651776617767177681776917770177711777217773177741777517776177771777817779177801778117782177831778417785177861778717788177891779017791177921779317794177951779617797177981779917800178011780217803178041780517806178071780817809178101781117812178131781417815178161781717818178191782017821178221782317824178251782617827178281782917830178311783217833178341783517836178371783817839178401784117842178431784417845178461784717848178491785017851178521785317854178551785617857178581785917860178611786217863178641786517866178671786817869178701787117872178731787417875178761787717878178791788017881178821788317884178851788617887178881788917890178911789217893178941789517896178971789817899179001790117902179031790417905179061790717908179091791017911179121791317914179151791617917179181791917920179211792217923179241792517926179271792817929179301793117932179331793417935179361793717938179391794017941179421794317944179451794617947179481794917950179511795217953179541795517956179571795817959179601796117962179631796417965179661796717968179691797017971179721797317974179751797617977179781797917980179811798217983179841798517986179871798817989179901799117992179931799417995179961799717998179991800018001180021800318004180051800618007180081800918010180111801218013180141801518016180171801818019180201802118022180231802418025180261802718028180291803018031180321803318034180351803618037180381803918040180411804218043180441804518046180471804818049180501805118052180531805418055180561805718058180591806018061180621806318064180651806618067180681806918070180711807218073180741807518076180771807818079180801808118082180831808418085180861808718088180891809018091180921809318094180951809618097180981809918100181011810218103181041810518106181071810818109181101811118112181131811418115181161811718118181191812018121181221812318124181251812618127181281812918130181311813218133181341813518136181371813818139181401814118142181431814418145181461814718148181491815018151181521815318154181551815618157181581815918160181611816218163181641816518166181671816818169181701817118172181731817418175181761817718178181791818018181181821818318184181851818618187181881818918190181911819218193181941819518196181971819818199182001820118202182031820418205182061820718208182091821018211182121821318214182151821618217182181821918220182211822218223182241822518226182271822818229182301823118232182331823418235182361823718238182391824018241182421824318244182451824618247182481824918250182511825218253182541825518256182571825818259182601826118262182631826418265182661826718268182691827018271182721827318274182751827618277182781827918280182811828218283182841828518286182871828818289182901829118292182931829418295182961829718298182991830018301183021830318304183051830618307183081830918310183111831218313183141831518316183171831818319183201832118322183231832418325183261832718328183291833018331183321833318334183351833618337183381833918340183411834218343183441834518346183471834818349183501835118352183531835418355183561835718358183591836018361183621836318364183651836618367183681836918370183711837218373183741837518376183771837818379183801838118382183831838418385183861838718388183891839018391183921839318394183951839618397183981839918400184011840218403184041840518406184071840818409184101841118412184131841418415184161841718418184191842018421184221842318424184251842618427184281842918430184311843218433184341843518436184371843818439184401844118442184431844418445184461844718448184491845018451184521845318454184551845618457184581845918460184611846218463184641846518466184671846818469184701847118472184731847418475184761847718478184791848018481184821848318484184851848618487184881848918490184911849218493184941849518496184971849818499185001850118502185031850418505185061850718508185091851018511185121851318514185151851618517185181851918520185211852218523185241852518526185271852818529185301853118532185331853418535185361853718538185391854018541185421854318544185451854618547185481854918550185511855218553185541855518556185571855818559185601856118562185631856418565185661856718568185691857018571185721857318574185751857618577185781857918580185811858218583185841858518586185871858818589185901859118592185931859418595185961859718598185991860018601186021860318604186051860618607186081860918610186111861218613186141861518616186171861818619186201862118622186231862418625186261862718628186291863018631186321863318634186351863618637186381863918640186411864218643186441864518646186471864818649186501865118652186531865418655186561865718658186591866018661186621866318664186651866618667186681866918670186711867218673186741867518676186771867818679186801868118682186831868418685186861868718688186891869018691186921869318694186951869618697186981869918700187011870218703187041870518706187071870818709187101871118712187131871418715187161871718718187191872018721187221872318724187251872618727187281872918730187311873218733187341873518736187371873818739187401874118742187431874418745187461874718748187491875018751187521875318754187551875618757187581875918760187611876218763187641876518766187671876818769187701877118772187731877418775187761877718778187791878018781187821878318784187851878618787187881878918790187911879218793187941879518796187971879818799188001880118802188031880418805188061880718808188091881018811188121881318814188151881618817188181881918820188211882218823188241882518826188271882818829188301883118832188331883418835188361883718838188391884018841188421884318844188451884618847188481884918850188511885218853188541885518856188571885818859188601886118862188631886418865188661886718868188691887018871188721887318874188751887618877188781887918880188811888218883188841888518886188871888818889188901889118892188931889418895188961889718898188991890018901189021890318904189051890618907189081890918910189111891218913189141891518916189171891818919189201892118922189231892418925189261892718928189291893018931189321893318934189351893618937189381893918940189411894218943189441894518946189471894818949189501895118952189531895418955189561895718958189591896018961189621896318964189651896618967189681896918970189711897218973189741897518976189771897818979189801898118982189831898418985189861898718988189891899018991189921899318994189951899618997189981899919000190011900219003190041900519006190071900819009190101901119012190131901419015190161901719018190191902019021190221902319024190251902619027190281902919030190311903219033190341903519036190371903819039190401904119042190431904419045190461904719048190491905019051190521905319054190551905619057190581905919060190611906219063190641906519066190671906819069190701907119072190731907419075190761907719078190791908019081190821908319084190851908619087190881908919090190911909219093190941909519096190971909819099191001910119102191031910419105191061910719108191091911019111191121911319114191151911619117191181911919120191211912219123191241912519126191271912819129191301913119132191331913419135191361913719138191391914019141191421914319144191451914619147191481914919150191511915219153191541915519156191571915819159191601916119162191631916419165191661916719168191691917019171191721917319174191751917619177191781917919180191811918219183191841918519186191871918819189191901919119192191931919419195191961919719198191991920019201192021920319204192051920619207192081920919210192111921219213192141921519216192171921819219192201922119222192231922419225192261922719228192291923019231192321923319234192351923619237192381923919240192411924219243192441924519246192471924819249192501925119252192531925419255192561925719258192591926019261192621926319264192651926619267192681926919270192711927219273192741927519276192771927819279192801928119282192831928419285192861928719288192891929019291192921929319294192951929619297192981929919300193011930219303193041930519306193071930819309193101931119312193131931419315193161931719318193191932019321193221932319324193251932619327193281932919330193311933219333193341933519336193371933819339193401934119342193431934419345193461934719348193491935019351193521935319354193551935619357193581935919360193611936219363193641936519366193671936819369193701937119372193731937419375193761937719378193791938019381193821938319384193851938619387193881938919390193911939219393193941939519396193971939819399194001940119402194031940419405194061940719408194091941019411194121941319414194151941619417194181941919420194211942219423194241942519426194271942819429194301943119432194331943419435194361943719438194391944019441194421944319444194451944619447194481944919450194511945219453194541945519456194571945819459194601946119462194631946419465194661946719468194691947019471194721947319474194751947619477194781947919480194811948219483194841948519486194871948819489194901949119492194931949419495194961949719498194991950019501195021950319504195051950619507195081950919510195111951219513195141951519516195171951819519195201952119522195231952419525195261952719528195291953019531195321953319534195351953619537195381953919540195411954219543195441954519546195471954819549195501955119552195531955419555195561955719558195591956019561195621956319564195651956619567195681956919570195711957219573195741957519576195771957819579195801958119582195831958419585195861958719588195891959019591195921959319594195951959619597195981959919600196011960219603196041960519606196071960819609196101961119612196131961419615196161961719618196191962019621196221962319624196251962619627196281962919630196311963219633196341963519636196371963819639196401964119642196431964419645196461964719648196491965019651196521965319654196551965619657196581965919660196611966219663196641966519666196671966819669196701967119672196731967419675196761967719678196791968019681196821968319684196851968619687196881968919690196911969219693196941969519696196971969819699197001970119702197031970419705197061970719708197091971019711197121971319714197151971619717197181971919720197211972219723197241972519726197271972819729197301973119732197331973419735197361973719738197391974019741197421974319744197451974619747197481974919750197511975219753197541975519756197571975819759197601976119762197631976419765197661976719768197691977019771197721977319774197751977619777197781977919780197811978219783197841978519786197871978819789197901979119792197931979419795197961979719798197991980019801198021980319804198051980619807198081980919810198111981219813198141981519816198171981819819198201982119822198231982419825198261982719828198291983019831198321983319834198351983619837198381983919840198411984219843198441984519846198471984819849198501985119852198531985419855198561985719858198591986019861198621986319864198651986619867198681986919870198711987219873198741987519876198771987819879198801988119882198831988419885198861988719888198891989019891198921989319894198951989619897198981989919900199011990219903199041990519906199071990819909199101991119912199131991419915199161991719918199191992019921199221992319924199251992619927199281992919930199311993219933199341993519936199371993819939199401994119942199431994419945199461994719948199491995019951199521995319954199551995619957199581995919960199611996219963199641996519966199671996819969199701997119972199731997419975199761997719978199791998019981199821998319984199851998619987199881998919990199911999219993199941999519996199971999819999200002000120002200032000420005200062000720008200092001020011200122001320014200152001620017200182001920020200212002220023200242002520026200272002820029200302003120032200332003420035200362003720038200392004020041200422004320044200452004620047200482004920050200512005220053200542005520056200572005820059200602006120062200632006420065200662006720068200692007020071200722007320074200752007620077200782007920080200812008220083200842008520086200872008820089200902009120092200932009420095200962009720098200992010020101201022010320104201052010620107201082010920110201112011220113201142011520116201172011820119201202012120122201232012420125201262012720128201292013020131201322013320134201352013620137201382013920140201412014220143201442014520146201472014820149201502015120152201532015420155201562015720158201592016020161201622016320164201652016620167201682016920170201712017220173201742017520176201772017820179201802018120182201832018420185201862018720188201892019020191201922019320194201952019620197201982019920200202012020220203202042020520206202072020820209202102021120212202132021420215202162021720218202192022020221202222022320224202252022620227202282022920230202312023220233202342023520236202372023820239202402024120242202432024420245202462024720248
  1. /*!
  2. * bpmn-js - bpmn-navigated-viewer v6.5.1
  3. *
  4. * Copyright (c) 2014-present, camunda Services GmbH
  5. *
  6. * Released under the bpmn.io license
  7. * http://bpmn.io/license
  8. *
  9. * Source Code: https://github.com/bpmn-io/bpmn-js
  10. *
  11. * Date: 2020-04-28
  12. */
  13. (function (global, factory) {
  14. typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
  15. typeof define === 'function' && define.amd ? define(factory) :
  16. (global = global || self, global.BpmnJS = factory());
  17. }(this, function () {
  18. 'use strict';
  19. function createCommonjsModule(fn, module) {
  20. return module = {exports: {}}, fn(module, module.exports), module.exports;
  21. }
  22. var inherits_browser = createCommonjsModule(function (module) {
  23. if (typeof Object.create === 'function') {
  24. // implementation from standard node.js 'util' module
  25. module.exports = function inherits(ctor, superCtor) {
  26. ctor.super_ = superCtor;
  27. ctor.prototype = Object.create(superCtor.prototype, {
  28. constructor: {
  29. value: ctor,
  30. enumerable: false,
  31. writable: true,
  32. configurable: true
  33. }
  34. });
  35. };
  36. } else {
  37. // old school shim for old browsers
  38. module.exports = function inherits(ctor, superCtor) {
  39. ctor.super_ = superCtor;
  40. var TempCtor = function () {
  41. };
  42. TempCtor.prototype = superCtor.prototype;
  43. ctor.prototype = new TempCtor();
  44. ctor.prototype.constructor = ctor;
  45. };
  46. }
  47. });
  48. /**
  49. * Flatten array, one level deep.
  50. *
  51. * @param {Array<?>} arr
  52. *
  53. * @return {Array<?>}
  54. */
  55. var nativeToString = Object.prototype.toString;
  56. var nativeHasOwnProperty = Object.prototype.hasOwnProperty;
  57. function isUndefined(obj) {
  58. return obj === undefined;
  59. }
  60. function isDefined(obj) {
  61. return obj !== undefined;
  62. }
  63. function isArray(obj) {
  64. return nativeToString.call(obj) === '[object Array]';
  65. }
  66. function isObject(obj) {
  67. return nativeToString.call(obj) === '[object Object]';
  68. }
  69. function isNumber(obj) {
  70. return nativeToString.call(obj) === '[object Number]';
  71. }
  72. function isFunction(obj) {
  73. var tag = nativeToString.call(obj);
  74. return tag === '[object Function]' || tag === '[object AsyncFunction]' || tag === '[object GeneratorFunction]' || tag === '[object AsyncGeneratorFunction]' || tag === '[object Proxy]';
  75. }
  76. function isString(obj) {
  77. return nativeToString.call(obj) === '[object String]';
  78. }
  79. /**
  80. * Return true, if target owns a property with the given key.
  81. *
  82. * @param {Object} target
  83. * @param {String} key
  84. *
  85. * @return {Boolean}
  86. */
  87. function has(target, key) {
  88. return nativeHasOwnProperty.call(target, key);
  89. }
  90. /**
  91. * Find element in collection.
  92. *
  93. * @param {Array|Object} collection
  94. * @param {Function|Object} matcher
  95. *
  96. * @return {Object}
  97. */
  98. function find(collection, matcher) {
  99. matcher = toMatcher(matcher);
  100. var match;
  101. forEach(collection, function (val, key) {
  102. if (matcher(val, key)) {
  103. match = val;
  104. return false;
  105. }
  106. });
  107. return match;
  108. }
  109. /**
  110. * Find element in collection.
  111. *
  112. * @param {Array|Object} collection
  113. * @param {Function} matcher
  114. *
  115. * @return {Array} result
  116. */
  117. function filter(collection, matcher) {
  118. var result = [];
  119. forEach(collection, function (val, key) {
  120. if (matcher(val, key)) {
  121. result.push(val);
  122. }
  123. });
  124. return result;
  125. }
  126. /**
  127. * Iterate over collection; returning something
  128. * (non-undefined) will stop iteration.
  129. *
  130. * @param {Array|Object} collection
  131. * @param {Function} iterator
  132. *
  133. * @return {Object} return result that stopped the iteration
  134. */
  135. function forEach(collection, iterator) {
  136. var val, result;
  137. if (isUndefined(collection)) {
  138. return;
  139. }
  140. var convertKey = isArray(collection) ? toNum : identity;
  141. for (var key in collection) {
  142. if (has(collection, key)) {
  143. val = collection[key];
  144. result = iterator(val, convertKey(key));
  145. if (result === false) {
  146. return val;
  147. }
  148. }
  149. }
  150. }
  151. /**
  152. * Reduce collection, returning a single result.
  153. *
  154. * @param {Object|Array} collection
  155. * @param {Function} iterator
  156. * @param {Any} result
  157. *
  158. * @return {Any} result returned from last iterator
  159. */
  160. function reduce(collection, iterator, result) {
  161. forEach(collection, function (value, idx) {
  162. result = iterator(result, value, idx);
  163. });
  164. return result;
  165. }
  166. /**
  167. * Return true if every element in the collection
  168. * matches the criteria.
  169. *
  170. * @param {Object|Array} collection
  171. * @param {Function} matcher
  172. *
  173. * @return {Boolean}
  174. */
  175. function every(collection, matcher) {
  176. return !!reduce(collection, function (matches, val, key) {
  177. return matches && matcher(val, key);
  178. }, true);
  179. }
  180. /**
  181. * Return true if some elements in the collection
  182. * match the criteria.
  183. *
  184. * @param {Object|Array} collection
  185. * @param {Function} matcher
  186. *
  187. * @return {Boolean}
  188. */
  189. function some(collection, matcher) {
  190. return !!find(collection, matcher);
  191. }
  192. /**
  193. * Transform a collection into another collection
  194. * by piping each member through the given fn.
  195. *
  196. * @param {Object|Array} collection
  197. * @param {Function} fn
  198. *
  199. * @return {Array} transformed collection
  200. */
  201. function map(collection, fn) {
  202. var result = [];
  203. forEach(collection, function (val, key) {
  204. result.push(fn(val, key));
  205. });
  206. return result;
  207. }
  208. /**
  209. * Create an object pattern matcher.
  210. *
  211. * @example
  212. *
  213. * const matcher = matchPattern({ id: 1 });
  214. *
  215. * var element = find(elements, matcher);
  216. *
  217. * @param {Object} pattern
  218. *
  219. * @return {Function} matcherFn
  220. */
  221. function matchPattern(pattern) {
  222. return function (el) {
  223. return every(pattern, function (val, key) {
  224. return el[key] === val;
  225. });
  226. };
  227. }
  228. function toMatcher(matcher) {
  229. return isFunction(matcher) ? matcher : function (e) {
  230. return e === matcher;
  231. };
  232. }
  233. function identity(arg) {
  234. return arg;
  235. }
  236. function toNum(arg) {
  237. return Number(arg);
  238. }
  239. /**
  240. * Debounce fn, calling it only once if
  241. * the given time elapsed between calls.
  242. *
  243. * @param {Function} fn
  244. * @param {Number} timeout
  245. *
  246. * @return {Function} debounced function
  247. */
  248. function debounce(fn, timeout) {
  249. var timer;
  250. var lastArgs;
  251. var lastThis;
  252. var lastNow;
  253. function fire() {
  254. var now = Date.now();
  255. var scheduledDiff = lastNow + timeout - now;
  256. if (scheduledDiff > 0) {
  257. return schedule(scheduledDiff);
  258. }
  259. fn.apply(lastThis, lastArgs);
  260. timer = lastNow = lastArgs = lastThis = undefined;
  261. }
  262. function schedule(timeout) {
  263. timer = setTimeout(fire, timeout);
  264. }
  265. return function () {
  266. lastNow = Date.now();
  267. for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
  268. args[_key] = arguments[_key];
  269. }
  270. lastArgs = args;
  271. lastThis = this; // ensure an execution is scheduled
  272. if (!timer) {
  273. schedule(timeout);
  274. }
  275. };
  276. }
  277. /**
  278. * Bind function against target <this>.
  279. *
  280. * @param {Function} fn
  281. * @param {Object} target
  282. *
  283. * @return {Function} bound function
  284. */
  285. function bind(fn, target) {
  286. return fn.bind(target);
  287. }
  288. function _extends() {
  289. _extends = Object.assign || function (target) {
  290. for (var i = 1; i < arguments.length; i++) {
  291. var source = arguments[i];
  292. for (var key in source) {
  293. if (Object.prototype.hasOwnProperty.call(source, key)) {
  294. target[key] = source[key];
  295. }
  296. }
  297. }
  298. return target;
  299. };
  300. return _extends.apply(this, arguments);
  301. }
  302. /**
  303. * Convenience wrapper for `Object.assign`.
  304. *
  305. * @param {Object} target
  306. * @param {...Object} others
  307. *
  308. * @return {Object} the target
  309. */
  310. function assign(target) {
  311. for (var _len = arguments.length, others = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
  312. others[_key - 1] = arguments[_key];
  313. }
  314. return _extends.apply(void 0, [target].concat(others));
  315. }
  316. /**
  317. * Pick given properties from the target object.
  318. *
  319. * @param {Object} target
  320. * @param {Array} properties
  321. *
  322. * @return {Object} target
  323. */
  324. function pick(target, properties) {
  325. var result = {};
  326. var obj = Object(target);
  327. forEach(properties, function (prop) {
  328. if (prop in obj) {
  329. result[prop] = target[prop];
  330. }
  331. });
  332. return result;
  333. }
  334. /**
  335. * Pick all target properties, excluding the given ones.
  336. *
  337. * @param {Object} target
  338. * @param {Array} properties
  339. *
  340. * @return {Object} target
  341. */
  342. function omit(target, properties) {
  343. var result = {};
  344. var obj = Object(target);
  345. forEach(obj, function (prop, key) {
  346. if (properties.indexOf(key) === -1) {
  347. result[key] = prop;
  348. }
  349. });
  350. return result;
  351. }
  352. var DEFAULT_RENDER_PRIORITY = 1000;
  353. /**
  354. * The base implementation of shape and connection renderers.
  355. *
  356. * @param {EventBus} eventBus
  357. * @param {number} [renderPriority=1000]
  358. */
  359. function BaseRenderer(eventBus, renderPriority) {
  360. var self = this;
  361. renderPriority = renderPriority || DEFAULT_RENDER_PRIORITY;
  362. eventBus.on(['render.shape', 'render.connection'], renderPriority, function (evt, context) {
  363. var type = evt.type,
  364. element = context.element,
  365. visuals = context.gfx;
  366. if (self.canRender(element)) {
  367. if (type === 'render.shape') {
  368. return self.drawShape(visuals, element);
  369. } else {
  370. return self.drawConnection(visuals, element);
  371. }
  372. }
  373. });
  374. eventBus.on(['render.getShapePath', 'render.getConnectionPath'], renderPriority, function (evt, element) {
  375. if (self.canRender(element)) {
  376. if (evt.type === 'render.getShapePath') {
  377. return self.getShapePath(element);
  378. } else {
  379. return self.getConnectionPath(element);
  380. }
  381. }
  382. });
  383. }
  384. /**
  385. * Should check whether *this* renderer can render
  386. * the element/connection.
  387. *
  388. * @param {element} element
  389. *
  390. * @returns {boolean}
  391. */
  392. BaseRenderer.prototype.canRender = function () {
  393. };
  394. /**
  395. * Provides the shape's snap svg element to be drawn on the `canvas`.
  396. *
  397. * @param {djs.Graphics} visuals
  398. * @param {Shape} shape
  399. *
  400. * @returns {Snap.svg} [returns a Snap.svg paper element ]
  401. */
  402. BaseRenderer.prototype.drawShape = function () {
  403. };
  404. /**
  405. * Provides the shape's snap svg element to be drawn on the `canvas`.
  406. *
  407. * @param {djs.Graphics} visuals
  408. * @param {Connection} connection
  409. *
  410. * @returns {Snap.svg} [returns a Snap.svg paper element ]
  411. */
  412. BaseRenderer.prototype.drawConnection = function () {
  413. };
  414. /**
  415. * Gets the SVG path of a shape that represents it's visual bounds.
  416. *
  417. * @param {Shape} shape
  418. *
  419. * @return {string} svg path
  420. */
  421. BaseRenderer.prototype.getShapePath = function () {
  422. };
  423. /**
  424. * Gets the SVG path of a connection that represents it's visual bounds.
  425. *
  426. * @param {Connection} connection
  427. *
  428. * @return {string} svg path
  429. */
  430. BaseRenderer.prototype.getConnectionPath = function () {
  431. };
  432. /**
  433. * Is an element of the given BPMN type?
  434. *
  435. * @param {djs.model.Base|ModdleElement} element
  436. * @param {string} type
  437. *
  438. * @return {boolean}
  439. */
  440. function is(element, type) {
  441. var bo = getBusinessObject(element);
  442. return bo && (typeof bo.$instanceOf === 'function') && bo.$instanceOf(type);
  443. }
  444. /**
  445. * Return the business object for a given element.
  446. *
  447. * @param {djs.model.Base|ModdleElement} element
  448. *
  449. * @return {ModdleElement}
  450. */
  451. function getBusinessObject(element) {
  452. return (element && element.businessObject) || element;
  453. }
  454. function isExpanded(element) {
  455. if (is(element, 'bpmn:CallActivity')) {
  456. return false;
  457. }
  458. if (is(element, 'bpmn:SubProcess')) {
  459. return !!getBusinessObject(element).di.isExpanded;
  460. }
  461. if (is(element, 'bpmn:Participant')) {
  462. return !!getBusinessObject(element).processRef;
  463. }
  464. return true;
  465. }
  466. function isEventSubProcess(element) {
  467. return element && !!getBusinessObject(element).triggeredByEvent;
  468. }
  469. function getLabelAttr(semantic) {
  470. if (
  471. is(semantic, 'bpmn:FlowElement') ||
  472. is(semantic, 'bpmn:Participant') ||
  473. is(semantic, 'bpmn:Lane') ||
  474. is(semantic, 'bpmn:SequenceFlow') ||
  475. is(semantic, 'bpmn:MessageFlow') ||
  476. is(semantic, 'bpmn:DataInput') ||
  477. is(semantic, 'bpmn:DataOutput')
  478. ) {
  479. return 'name';
  480. }
  481. if (is(semantic, 'bpmn:TextAnnotation')) {
  482. return 'text';
  483. }
  484. if (is(semantic, 'bpmn:Group')) {
  485. return 'categoryValueRef';
  486. }
  487. }
  488. function getCategoryValue(semantic) {
  489. var categoryValueRef = semantic['categoryValueRef'];
  490. if (!categoryValueRef) {
  491. return '';
  492. }
  493. return categoryValueRef.value || '';
  494. }
  495. function getLabel(element) {
  496. var semantic = element.businessObject,
  497. attr = getLabelAttr(semantic);
  498. if (attr) {
  499. if (attr === 'categoryValueRef') {
  500. return getCategoryValue(semantic);
  501. }
  502. return semantic[attr] || '';
  503. }
  504. }
  505. function ensureImported(element, target) {
  506. if (element.ownerDocument !== target.ownerDocument) {
  507. try {
  508. // may fail on webkit
  509. return target.ownerDocument.importNode(element, true);
  510. } catch (e) {
  511. // ignore
  512. }
  513. }
  514. return element;
  515. }
  516. /**
  517. * appendTo utility
  518. */
  519. /**
  520. * Append a node to a target element and return the appended node.
  521. *
  522. * @param {SVGElement} element
  523. * @param {SVGElement} target
  524. *
  525. * @return {SVGElement} the appended node
  526. */
  527. function appendTo(element, target) {
  528. return target.appendChild(ensureImported(element, target));
  529. }
  530. /**
  531. * append utility
  532. */
  533. /**
  534. * Append a node to an element
  535. *
  536. * @param {SVGElement} element
  537. * @param {SVGElement} node
  538. *
  539. * @return {SVGElement} the element
  540. */
  541. function append(target, node) {
  542. appendTo(node, target);
  543. return target;
  544. }
  545. /**
  546. * attribute accessor utility
  547. */
  548. var LENGTH_ATTR = 2;
  549. var CSS_PROPERTIES = {
  550. 'alignment-baseline': 1,
  551. 'baseline-shift': 1,
  552. 'clip': 1,
  553. 'clip-path': 1,
  554. 'clip-rule': 1,
  555. 'color': 1,
  556. 'color-interpolation': 1,
  557. 'color-interpolation-filters': 1,
  558. 'color-profile': 1,
  559. 'color-rendering': 1,
  560. 'cursor': 1,
  561. 'direction': 1,
  562. 'display': 1,
  563. 'dominant-baseline': 1,
  564. 'enable-background': 1,
  565. 'fill': 1,
  566. 'fill-opacity': 1,
  567. 'fill-rule': 1,
  568. 'filter': 1,
  569. 'flood-color': 1,
  570. 'flood-opacity': 1,
  571. 'font': 1,
  572. 'font-family': 1,
  573. 'font-size': LENGTH_ATTR,
  574. 'font-size-adjust': 1,
  575. 'font-stretch': 1,
  576. 'font-style': 1,
  577. 'font-variant': 1,
  578. 'font-weight': 1,
  579. 'glyph-orientation-horizontal': 1,
  580. 'glyph-orientation-vertical': 1,
  581. 'image-rendering': 1,
  582. 'kerning': 1,
  583. 'letter-spacing': 1,
  584. 'lighting-color': 1,
  585. 'marker': 1,
  586. 'marker-end': 1,
  587. 'marker-mid': 1,
  588. 'marker-start': 1,
  589. 'mask': 1,
  590. 'opacity': 1,
  591. 'overflow': 1,
  592. 'pointer-events': 1,
  593. 'shape-rendering': 1,
  594. 'stop-color': 1,
  595. 'stop-opacity': 1,
  596. 'stroke': 1,
  597. 'stroke-dasharray': 1,
  598. 'stroke-dashoffset': 1,
  599. 'stroke-linecap': 1,
  600. 'stroke-linejoin': 1,
  601. 'stroke-miterlimit': 1,
  602. 'stroke-opacity': 1,
  603. 'stroke-width': LENGTH_ATTR,
  604. 'text-anchor': 1,
  605. 'text-decoration': 1,
  606. 'text-rendering': 1,
  607. 'unicode-bidi': 1,
  608. 'visibility': 1,
  609. 'word-spacing': 1,
  610. 'writing-mode': 1
  611. };
  612. function getAttribute(node, name) {
  613. if (CSS_PROPERTIES[name]) {
  614. return node.style[name];
  615. } else {
  616. return node.getAttributeNS(null, name);
  617. }
  618. }
  619. function setAttribute(node, name, value) {
  620. var hyphenated = name.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
  621. var type = CSS_PROPERTIES[hyphenated];
  622. if (type) {
  623. // append pixel unit, unless present
  624. if (type === LENGTH_ATTR && typeof value === 'number') {
  625. value = String(value) + 'px';
  626. }
  627. node.style[hyphenated] = value;
  628. } else {
  629. node.setAttributeNS(null, name, value);
  630. }
  631. }
  632. function setAttributes(node, attrs) {
  633. var names = Object.keys(attrs), i, name;
  634. for (i = 0, name; (name = names[i]); i++) {
  635. setAttribute(node, name, attrs[name]);
  636. }
  637. }
  638. /**
  639. * Gets or sets raw attributes on a node.
  640. *
  641. * @param {SVGElement} node
  642. * @param {Object} [attrs]
  643. * @param {String} [name]
  644. * @param {String} [value]
  645. *
  646. * @return {String}
  647. */
  648. function attr(node, name, value) {
  649. if (typeof name === 'string') {
  650. if (value !== undefined) {
  651. setAttribute(node, name, value);
  652. } else {
  653. return getAttribute(node, name);
  654. }
  655. } else {
  656. setAttributes(node, name);
  657. }
  658. return node;
  659. }
  660. /**
  661. * Clear utility
  662. */
  663. function index(arr, obj) {
  664. if (arr.indexOf) {
  665. return arr.indexOf(obj);
  666. }
  667. for (var i = 0; i < arr.length; ++i) {
  668. if (arr[i] === obj) {
  669. return i;
  670. }
  671. }
  672. return -1;
  673. }
  674. var re = /\s+/;
  675. var toString = Object.prototype.toString;
  676. function defined(o) {
  677. return typeof o !== 'undefined';
  678. }
  679. /**
  680. * Wrap `el` in a `ClassList`.
  681. *
  682. * @param {Element} el
  683. * @return {ClassList}
  684. * @api public
  685. */
  686. function classes(el) {
  687. return new ClassList(el);
  688. }
  689. function ClassList(el) {
  690. if (!el || !el.nodeType) {
  691. throw new Error('A DOM element reference is required');
  692. }
  693. this.el = el;
  694. this.list = el.classList;
  695. }
  696. /**
  697. * Add class `name` if not already present.
  698. *
  699. * @param {String} name
  700. * @return {ClassList}
  701. * @api public
  702. */
  703. ClassList.prototype.add = function (name) {
  704. // classList
  705. if (this.list) {
  706. this.list.add(name);
  707. return this;
  708. }
  709. // fallback
  710. var arr = this.array();
  711. var i = index(arr, name);
  712. if (!~i) {
  713. arr.push(name);
  714. }
  715. if (defined(this.el.className.baseVal)) {
  716. this.el.className.baseVal = arr.join(' ');
  717. } else {
  718. this.el.className = arr.join(' ');
  719. }
  720. return this;
  721. };
  722. /**
  723. * Remove class `name` when present, or
  724. * pass a regular expression to remove
  725. * any which match.
  726. *
  727. * @param {String|RegExp} name
  728. * @return {ClassList}
  729. * @api public
  730. */
  731. ClassList.prototype.remove = function (name) {
  732. if ('[object RegExp]' === toString.call(name)) {
  733. return this.removeMatching(name);
  734. }
  735. // classList
  736. if (this.list) {
  737. this.list.remove(name);
  738. return this;
  739. }
  740. // fallback
  741. var arr = this.array();
  742. var i = index(arr, name);
  743. if (~i) {
  744. arr.splice(i, 1);
  745. }
  746. this.el.className.baseVal = arr.join(' ');
  747. return this;
  748. };
  749. /**
  750. * Remove all classes matching `re`.
  751. *
  752. * @param {RegExp} re
  753. * @return {ClassList}
  754. * @api private
  755. */
  756. ClassList.prototype.removeMatching = function (re) {
  757. var arr = this.array();
  758. for (var i = 0; i < arr.length; i++) {
  759. if (re.test(arr[i])) {
  760. this.remove(arr[i]);
  761. }
  762. }
  763. return this;
  764. };
  765. /**
  766. * Toggle class `name`, can force state via `force`.
  767. *
  768. * For browsers that support classList, but do not support `force` yet,
  769. * the mistake will be detected and corrected.
  770. *
  771. * @param {String} name
  772. * @param {Boolean} force
  773. * @return {ClassList}
  774. * @api public
  775. */
  776. ClassList.prototype.toggle = function (name, force) {
  777. // classList
  778. if (this.list) {
  779. if (defined(force)) {
  780. if (force !== this.list.toggle(name, force)) {
  781. this.list.toggle(name); // toggle again to correct
  782. }
  783. } else {
  784. this.list.toggle(name);
  785. }
  786. return this;
  787. }
  788. // fallback
  789. if (defined(force)) {
  790. if (!force) {
  791. this.remove(name);
  792. } else {
  793. this.add(name);
  794. }
  795. } else {
  796. if (this.has(name)) {
  797. this.remove(name);
  798. } else {
  799. this.add(name);
  800. }
  801. }
  802. return this;
  803. };
  804. /**
  805. * Return an array of classes.
  806. *
  807. * @return {Array}
  808. * @api public
  809. */
  810. ClassList.prototype.array = function () {
  811. var className = this.el.getAttribute('class') || '';
  812. var str = className.replace(/^\s+|\s+$/g, '');
  813. var arr = str.split(re);
  814. if ('' === arr[0]) {
  815. arr.shift();
  816. }
  817. return arr;
  818. };
  819. /**
  820. * Check if class `name` is present.
  821. *
  822. * @param {String} name
  823. * @return {ClassList}
  824. * @api public
  825. */
  826. ClassList.prototype.has =
  827. ClassList.prototype.contains = function (name) {
  828. return (
  829. this.list ?
  830. this.list.contains(name) :
  831. !!~index(this.array(), name)
  832. );
  833. };
  834. function remove(element) {
  835. var parent = element.parentNode;
  836. if (parent) {
  837. parent.removeChild(element);
  838. }
  839. return element;
  840. }
  841. /**
  842. * Clear utility
  843. */
  844. /**
  845. * Removes all children from the given element
  846. *
  847. * @param {DOMElement} element
  848. * @return {DOMElement} the element (for chaining)
  849. */
  850. function clear(element) {
  851. var child;
  852. while ((child = element.firstChild)) {
  853. remove(child);
  854. }
  855. return element;
  856. }
  857. var ns = {
  858. svg: 'http://www.w3.org/2000/svg'
  859. };
  860. /**
  861. * DOM parsing utility
  862. */
  863. var SVG_START = '<svg xmlns="' + ns.svg + '"';
  864. function parse(svg) {
  865. var unwrap = false;
  866. // ensure we import a valid svg document
  867. if (svg.substring(0, 4) === '<svg') {
  868. if (svg.indexOf(ns.svg) === -1) {
  869. svg = SVG_START + svg.substring(4);
  870. }
  871. } else {
  872. // namespace svg
  873. svg = SVG_START + '>' + svg + '</svg>';
  874. unwrap = true;
  875. }
  876. var parsed = parseDocument(svg);
  877. if (!unwrap) {
  878. return parsed;
  879. }
  880. var fragment = document.createDocumentFragment();
  881. var parent = parsed.firstChild;
  882. while (parent.firstChild) {
  883. fragment.appendChild(parent.firstChild);
  884. }
  885. return fragment;
  886. }
  887. function parseDocument(svg) {
  888. var parser;
  889. // parse
  890. parser = new DOMParser();
  891. parser.async = false;
  892. return parser.parseFromString(svg, 'text/xml');
  893. }
  894. /**
  895. * Create utility for SVG elements
  896. */
  897. /**
  898. * Create a specific type from name or SVG markup.
  899. *
  900. * @param {String} name the name or markup of the element
  901. * @param {Object} [attrs] attributes to set on the element
  902. *
  903. * @returns {SVGElement}
  904. */
  905. function create(name, attrs) {
  906. var element;
  907. if (name.charAt(0) === '<') {
  908. element = parse(name).firstChild;
  909. element = document.importNode(element, true);
  910. } else {
  911. element = document.createElementNS(ns.svg, name);
  912. }
  913. if (attrs) {
  914. attr(element, attrs);
  915. }
  916. return element;
  917. }
  918. /**
  919. * Geometry helpers
  920. */
  921. // fake node used to instantiate svg geometry elements
  922. var node = create('svg');
  923. function extend(object, props) {
  924. var i, k, keys = Object.keys(props);
  925. for (i = 0; (k = keys[i]); i++) {
  926. object[k] = props[k];
  927. }
  928. return object;
  929. }
  930. /**
  931. * Create matrix via args.
  932. *
  933. * @example
  934. *
  935. * createMatrix({ a: 1, b: 1 });
  936. * createMatrix();
  937. * createMatrix(1, 2, 0, 0, 30, 20);
  938. *
  939. * @return {SVGMatrix}
  940. */
  941. function createMatrix(a, b, c, d, e, f) {
  942. var matrix = node.createSVGMatrix();
  943. switch (arguments.length) {
  944. case 0:
  945. return matrix;
  946. case 1:
  947. return extend(matrix, a);
  948. case 6:
  949. return extend(matrix, {
  950. a: a,
  951. b: b,
  952. c: c,
  953. d: d,
  954. e: e,
  955. f: f
  956. });
  957. }
  958. }
  959. function createTransform(matrix) {
  960. if (matrix) {
  961. return node.createSVGTransformFromMatrix(matrix);
  962. } else {
  963. return node.createSVGTransform();
  964. }
  965. }
  966. /**
  967. * Serialization util
  968. */
  969. var TEXT_ENTITIES = /([&<>]{1})/g;
  970. var ATTR_ENTITIES = /([\n\r"]{1})/g;
  971. var ENTITY_REPLACEMENT = {
  972. '&': '&amp;',
  973. '<': '&lt;',
  974. '>': '&gt;',
  975. '"': '\''
  976. };
  977. function escape(str, pattern) {
  978. function replaceFn(match, entity) {
  979. return ENTITY_REPLACEMENT[entity] || entity;
  980. }
  981. return str.replace(pattern, replaceFn);
  982. }
  983. function serialize(node, output) {
  984. var i, len, attrMap, attrNode, childNodes;
  985. switch (node.nodeType) {
  986. // TEXT
  987. case 3:
  988. // replace special XML characters
  989. output.push(escape(node.textContent, TEXT_ENTITIES));
  990. break;
  991. // ELEMENT
  992. case 1:
  993. output.push('<', node.tagName);
  994. if (node.hasAttributes()) {
  995. attrMap = node.attributes;
  996. for (i = 0, len = attrMap.length; i < len; ++i) {
  997. attrNode = attrMap.item(i);
  998. output.push(' ', attrNode.name, '="', escape(attrNode.value, ATTR_ENTITIES), '"');
  999. }
  1000. }
  1001. if (node.hasChildNodes()) {
  1002. output.push('>');
  1003. childNodes = node.childNodes;
  1004. for (i = 0, len = childNodes.length; i < len; ++i) {
  1005. serialize(childNodes.item(i), output);
  1006. }
  1007. output.push('</', node.tagName, '>');
  1008. } else {
  1009. output.push('/>');
  1010. }
  1011. break;
  1012. // COMMENT
  1013. case 8:
  1014. output.push('<!--', escape(node.nodeValue, TEXT_ENTITIES), '-->');
  1015. break;
  1016. // CDATA
  1017. case 4:
  1018. output.push('<![CDATA[', node.nodeValue, ']]>');
  1019. break;
  1020. default:
  1021. throw new Error('unable to handle node ' + node.nodeType);
  1022. }
  1023. return output;
  1024. }
  1025. /**
  1026. * innerHTML like functionality for SVG elements.
  1027. * based on innerSVG (https://code.google.com/p/innersvg)
  1028. */
  1029. function set(element, svg) {
  1030. var parsed = parse(svg);
  1031. // clear element contents
  1032. clear(element);
  1033. if (!svg) {
  1034. return;
  1035. }
  1036. if (!isFragment(parsed)) {
  1037. // extract <svg> from parsed document
  1038. parsed = parsed.documentElement;
  1039. }
  1040. var nodes = slice(parsed.childNodes);
  1041. // import + append each node
  1042. for (var i = 0; i < nodes.length; i++) {
  1043. appendTo(nodes[i], element);
  1044. }
  1045. }
  1046. function get(element) {
  1047. var child = element.firstChild,
  1048. output = [];
  1049. while (child) {
  1050. serialize(child, output);
  1051. child = child.nextSibling;
  1052. }
  1053. return output.join('');
  1054. }
  1055. function isFragment(node) {
  1056. return node.nodeName === '#document-fragment';
  1057. }
  1058. function innerSVG(element, svg) {
  1059. if (svg !== undefined) {
  1060. try {
  1061. set(element, svg);
  1062. } catch (e) {
  1063. throw new Error('error parsing SVG: ' + e.message);
  1064. }
  1065. return element;
  1066. } else {
  1067. return get(element);
  1068. }
  1069. }
  1070. function slice(arr) {
  1071. return Array.prototype.slice.call(arr);
  1072. }
  1073. /**
  1074. * transform accessor utility
  1075. */
  1076. function wrapMatrix(transformList, transform) {
  1077. if (transform instanceof SVGMatrix) {
  1078. return transformList.createSVGTransformFromMatrix(transform);
  1079. }
  1080. return transform;
  1081. }
  1082. function setTransforms(transformList, transforms) {
  1083. var i, t;
  1084. transformList.clear();
  1085. for (i = 0; (t = transforms[i]); i++) {
  1086. transformList.appendItem(wrapMatrix(transformList, t));
  1087. }
  1088. }
  1089. /**
  1090. * Get or set the transforms on the given node.
  1091. *
  1092. * @param {SVGElement} node
  1093. * @param {SVGTransform|SVGMatrix|Array<SVGTransform|SVGMatrix>} [transforms]
  1094. *
  1095. * @return {SVGTransform} the consolidated transform
  1096. */
  1097. function transform(node, transforms) {
  1098. var transformList = node.transform.baseVal;
  1099. if (transforms) {
  1100. if (!Array.isArray(transforms)) {
  1101. transforms = [transforms];
  1102. }
  1103. setTransforms(transformList, transforms);
  1104. }
  1105. return transformList.consolidate();
  1106. }
  1107. function componentsToPath(elements) {
  1108. return elements.join(',').replace(/,?([A-z]),?/g, '$1');
  1109. }
  1110. function toSVGPoints(points) {
  1111. var result = '';
  1112. for (var i = 0, p; (p = points[i]); i++) {
  1113. result += p.x + ',' + p.y + ' ';
  1114. }
  1115. return result;
  1116. }
  1117. function createLine(points, attrs) {
  1118. var line = create('polyline');
  1119. attr(line, {points: toSVGPoints(points)});
  1120. if (attrs) {
  1121. attr(line, attrs);
  1122. }
  1123. return line;
  1124. }
  1125. function updateLine(gfx, points) {
  1126. attr(gfx, {points: toSVGPoints(points)});
  1127. return gfx;
  1128. }
  1129. // element utils //////////////////////
  1130. /**
  1131. * Checks if eventDefinition of the given element matches with semantic type.
  1132. *
  1133. * @return {boolean} true if element is of the given semantic type
  1134. */
  1135. function isTypedEvent(event, eventDefinitionType, filter) {
  1136. function matches(definition, filter) {
  1137. return every(filter, function (val, key) {
  1138. // we want a == conversion here, to be able to catch
  1139. // undefined == false and friends
  1140. /* jshint -W116 */
  1141. return definition[key] == val;
  1142. });
  1143. }
  1144. return some(event.eventDefinitions, function (definition) {
  1145. return definition.$type === eventDefinitionType && matches(event, filter);
  1146. });
  1147. }
  1148. function isThrowEvent(event) {
  1149. return (event.$type === 'bpmn:IntermediateThrowEvent') || (event.$type === 'bpmn:EndEvent');
  1150. }
  1151. function isCollection(element) {
  1152. var dataObject = element.dataObjectRef;
  1153. return element.isCollection || (dataObject && dataObject.isCollection);
  1154. }
  1155. function getDi(element) {
  1156. return element.businessObject.di;
  1157. }
  1158. function getSemantic(element) {
  1159. return element.businessObject;
  1160. }
  1161. // color access //////////////////////
  1162. function getFillColor(element, defaultColor) {
  1163. return getDi(element).get('bioc:fill') || defaultColor || 'white';
  1164. }
  1165. function getStrokeColor(element, defaultColor) {
  1166. return getDi(element).get('bioc:stroke') || defaultColor || 'black';
  1167. }
  1168. // cropping path customizations //////////////////////
  1169. function getCirclePath(shape) {
  1170. var cx = shape.x + shape.width / 2,
  1171. cy = shape.y + shape.height / 2,
  1172. radius = shape.width / 2;
  1173. var circlePath = [
  1174. ['M', cx, cy],
  1175. ['m', 0, -radius],
  1176. ['a', radius, radius, 0, 1, 1, 0, 2 * radius],
  1177. ['a', radius, radius, 0, 1, 1, 0, -2 * radius],
  1178. ['z']
  1179. ];
  1180. return componentsToPath(circlePath);
  1181. }
  1182. function getRoundRectPath(shape, borderRadius) {
  1183. var x = shape.x,
  1184. y = shape.y,
  1185. width = shape.width,
  1186. height = shape.height;
  1187. var roundRectPath = [
  1188. ['M', x + borderRadius, y],
  1189. ['l', width - borderRadius * 2, 0],
  1190. ['a', borderRadius, borderRadius, 0, 0, 1, borderRadius, borderRadius],
  1191. ['l', 0, height - borderRadius * 2],
  1192. ['a', borderRadius, borderRadius, 0, 0, 1, -borderRadius, borderRadius],
  1193. ['l', borderRadius * 2 - width, 0],
  1194. ['a', borderRadius, borderRadius, 0, 0, 1, -borderRadius, -borderRadius],
  1195. ['l', 0, borderRadius * 2 - height],
  1196. ['a', borderRadius, borderRadius, 0, 0, 1, borderRadius, -borderRadius],
  1197. ['z']
  1198. ];
  1199. return componentsToPath(roundRectPath);
  1200. }
  1201. function getDiamondPath(shape) {
  1202. var width = shape.width,
  1203. height = shape.height,
  1204. x = shape.x,
  1205. y = shape.y,
  1206. halfWidth = width / 2,
  1207. halfHeight = height / 2;
  1208. var diamondPath = [
  1209. ['M', x + halfWidth, y],
  1210. ['l', halfWidth, halfHeight],
  1211. ['l', -halfWidth, halfHeight],
  1212. ['l', -halfWidth, -halfHeight],
  1213. ['z']
  1214. ];
  1215. return componentsToPath(diamondPath);
  1216. }
  1217. function getRectPath(shape) {
  1218. var x = shape.x,
  1219. y = shape.y,
  1220. width = shape.width,
  1221. height = shape.height;
  1222. var rectPath = [
  1223. ['M', x, y],
  1224. ['l', width, 0],
  1225. ['l', 0, height],
  1226. ['l', -width, 0],
  1227. ['z']
  1228. ];
  1229. return componentsToPath(rectPath);
  1230. }
  1231. /**
  1232. * Set attribute `name` to `val`, or get attr `name`.
  1233. *
  1234. * @param {Element} el
  1235. * @param {String} name
  1236. * @param {String} [val]
  1237. * @api public
  1238. */
  1239. function attr$1(el, name, val) {
  1240. // get
  1241. if (arguments.length == 2) {
  1242. return el.getAttribute(name);
  1243. }
  1244. // remove
  1245. if (val === null) {
  1246. return el.removeAttribute(name);
  1247. }
  1248. // set
  1249. el.setAttribute(name, val);
  1250. return el;
  1251. }
  1252. var indexOf = [].indexOf;
  1253. var indexof = function (arr, obj) {
  1254. if (indexOf) return arr.indexOf(obj);
  1255. for (var i = 0; i < arr.length; ++i) {
  1256. if (arr[i] === obj) return i;
  1257. }
  1258. return -1;
  1259. };
  1260. /**
  1261. * Taken from https://github.com/component/classes
  1262. *
  1263. * Without the component bits.
  1264. */
  1265. /**
  1266. * Whitespace regexp.
  1267. */
  1268. var re$1 = /\s+/;
  1269. /**
  1270. * toString reference.
  1271. */
  1272. var toString$1 = Object.prototype.toString;
  1273. /**
  1274. * Wrap `el` in a `ClassList`.
  1275. *
  1276. * @param {Element} el
  1277. * @return {ClassList}
  1278. * @api public
  1279. */
  1280. function classes$1(el) {
  1281. return new ClassList$1(el);
  1282. }
  1283. /**
  1284. * Initialize a new ClassList for `el`.
  1285. *
  1286. * @param {Element} el
  1287. * @api private
  1288. */
  1289. function ClassList$1(el) {
  1290. if (!el || !el.nodeType) {
  1291. throw new Error('A DOM element reference is required');
  1292. }
  1293. this.el = el;
  1294. this.list = el.classList;
  1295. }
  1296. /**
  1297. * Add class `name` if not already present.
  1298. *
  1299. * @param {String} name
  1300. * @return {ClassList}
  1301. * @api public
  1302. */
  1303. ClassList$1.prototype.add = function (name) {
  1304. // classList
  1305. if (this.list) {
  1306. this.list.add(name);
  1307. return this;
  1308. }
  1309. // fallback
  1310. var arr = this.array();
  1311. var i = indexof(arr, name);
  1312. if (!~i) arr.push(name);
  1313. this.el.className = arr.join(' ');
  1314. return this;
  1315. };
  1316. /**
  1317. * Remove class `name` when present, or
  1318. * pass a regular expression to remove
  1319. * any which match.
  1320. *
  1321. * @param {String|RegExp} name
  1322. * @return {ClassList}
  1323. * @api public
  1324. */
  1325. ClassList$1.prototype.remove = function (name) {
  1326. if ('[object RegExp]' == toString$1.call(name)) {
  1327. return this.removeMatching(name);
  1328. }
  1329. // classList
  1330. if (this.list) {
  1331. this.list.remove(name);
  1332. return this;
  1333. }
  1334. // fallback
  1335. var arr = this.array();
  1336. var i = indexof(arr, name);
  1337. if (~i) arr.splice(i, 1);
  1338. this.el.className = arr.join(' ');
  1339. return this;
  1340. };
  1341. /**
  1342. * Remove all classes matching `re`.
  1343. *
  1344. * @param {RegExp} re
  1345. * @return {ClassList}
  1346. * @api private
  1347. */
  1348. ClassList$1.prototype.removeMatching = function (re) {
  1349. var arr = this.array();
  1350. for (var i = 0; i < arr.length; i++) {
  1351. if (re.test(arr[i])) {
  1352. this.remove(arr[i]);
  1353. }
  1354. }
  1355. return this;
  1356. };
  1357. /**
  1358. * Toggle class `name`, can force state via `force`.
  1359. *
  1360. * For browsers that support classList, but do not support `force` yet,
  1361. * the mistake will be detected and corrected.
  1362. *
  1363. * @param {String} name
  1364. * @param {Boolean} force
  1365. * @return {ClassList}
  1366. * @api public
  1367. */
  1368. ClassList$1.prototype.toggle = function (name, force) {
  1369. // classList
  1370. if (this.list) {
  1371. if ('undefined' !== typeof force) {
  1372. if (force !== this.list.toggle(name, force)) {
  1373. this.list.toggle(name); // toggle again to correct
  1374. }
  1375. } else {
  1376. this.list.toggle(name);
  1377. }
  1378. return this;
  1379. }
  1380. // fallback
  1381. if ('undefined' !== typeof force) {
  1382. if (!force) {
  1383. this.remove(name);
  1384. } else {
  1385. this.add(name);
  1386. }
  1387. } else {
  1388. if (this.has(name)) {
  1389. this.remove(name);
  1390. } else {
  1391. this.add(name);
  1392. }
  1393. }
  1394. return this;
  1395. };
  1396. /**
  1397. * Return an array of classes.
  1398. *
  1399. * @return {Array}
  1400. * @api public
  1401. */
  1402. ClassList$1.prototype.array = function () {
  1403. var className = this.el.getAttribute('class') || '';
  1404. var str = className.replace(/^\s+|\s+$/g, '');
  1405. var arr = str.split(re$1);
  1406. if ('' === arr[0]) arr.shift();
  1407. return arr;
  1408. };
  1409. /**
  1410. * Check if class `name` is present.
  1411. *
  1412. * @param {String} name
  1413. * @return {ClassList}
  1414. * @api public
  1415. */
  1416. ClassList$1.prototype.has = ClassList$1.prototype.contains = function (name) {
  1417. return this.list ? this.list.contains(name) : !!~indexof(this.array(), name);
  1418. };
  1419. /**
  1420. * Remove all children from the given element.
  1421. */
  1422. function clear$1(el) {
  1423. var c;
  1424. while (el.childNodes.length) {
  1425. c = el.childNodes[0];
  1426. el.removeChild(c);
  1427. }
  1428. return el;
  1429. }
  1430. var proto = typeof Element !== 'undefined' ? Element.prototype : {};
  1431. var vendor = proto.matches
  1432. || proto.matchesSelector
  1433. || proto.webkitMatchesSelector
  1434. || proto.mozMatchesSelector
  1435. || proto.msMatchesSelector
  1436. || proto.oMatchesSelector;
  1437. var matchesSelector = match;
  1438. /**
  1439. * Match `el` to `selector`.
  1440. *
  1441. * @param {Element} el
  1442. * @param {String} selector
  1443. * @return {Boolean}
  1444. * @api public
  1445. */
  1446. function match(el, selector) {
  1447. if (!el || el.nodeType !== 1) return false;
  1448. if (vendor) return vendor.call(el, selector);
  1449. var nodes = el.parentNode.querySelectorAll(selector);
  1450. for (var i = 0; i < nodes.length; i++) {
  1451. if (nodes[i] == el) return true;
  1452. }
  1453. return false;
  1454. }
  1455. /**
  1456. * Closest
  1457. *
  1458. * @param {Element} el
  1459. * @param {String} selector
  1460. * @param {Boolean} checkYourSelf (optional)
  1461. */
  1462. function closest(element, selector, checkYourSelf) {
  1463. var currentElem = checkYourSelf ? element : element.parentNode;
  1464. while (currentElem && currentElem.nodeType !== document.DOCUMENT_NODE && currentElem.nodeType !== document.DOCUMENT_FRAGMENT_NODE) {
  1465. if (matchesSelector(currentElem, selector)) {
  1466. return currentElem;
  1467. }
  1468. currentElem = currentElem.parentNode;
  1469. }
  1470. return matchesSelector(currentElem, selector) ? currentElem : null;
  1471. }
  1472. /**
  1473. * Element prototype.
  1474. */
  1475. var proto$1 = Element.prototype;
  1476. /**
  1477. * Vendor function.
  1478. */
  1479. var vendor$1 = proto$1.matchesSelector
  1480. || proto$1.webkitMatchesSelector
  1481. || proto$1.mozMatchesSelector
  1482. || proto$1.msMatchesSelector
  1483. || proto$1.oMatchesSelector;
  1484. /**
  1485. * Expose `match()`.
  1486. */
  1487. var matchesSelector$1 = match$1;
  1488. /**
  1489. * Match `el` to `selector`.
  1490. *
  1491. * @param {Element} el
  1492. * @param {String} selector
  1493. * @return {Boolean}
  1494. * @api public
  1495. */
  1496. function match$1(el, selector) {
  1497. if (vendor$1) return vendor$1.call(el, selector);
  1498. var nodes = el.parentNode.querySelectorAll(selector);
  1499. for (var i = 0; i < nodes.length; ++i) {
  1500. if (nodes[i] == el) return true;
  1501. }
  1502. return false;
  1503. }
  1504. var closest$1 = function (element, selector, checkYoSelf) {
  1505. var parent = checkYoSelf ? element : element.parentNode;
  1506. while (parent && parent !== document) {
  1507. if (matchesSelector$1(parent, selector)) return parent;
  1508. parent = parent.parentNode;
  1509. }
  1510. };
  1511. var bind$1 = window.addEventListener ? 'addEventListener' : 'attachEvent',
  1512. unbind = window.removeEventListener ? 'removeEventListener' : 'detachEvent',
  1513. prefix = bind$1 !== 'addEventListener' ? 'on' : '';
  1514. /**
  1515. * Bind `el` event `type` to `fn`.
  1516. *
  1517. * @param {Element} el
  1518. * @param {String} type
  1519. * @param {Function} fn
  1520. * @param {Boolean} capture
  1521. * @return {Function}
  1522. * @api public
  1523. */
  1524. var bind_1 = function (el, type, fn, capture) {
  1525. el[bind$1](prefix + type, fn, capture || false);
  1526. return fn;
  1527. };
  1528. /**
  1529. * Unbind `el` event `type`'s callback `fn`.
  1530. *
  1531. * @param {Element} el
  1532. * @param {String} type
  1533. * @param {Function} fn
  1534. * @param {Boolean} capture
  1535. * @return {Function}
  1536. * @api public
  1537. */
  1538. var unbind_1 = function (el, type, fn, capture) {
  1539. el[unbind](prefix + type, fn, capture || false);
  1540. return fn;
  1541. };
  1542. var componentEvent = {
  1543. bind: bind_1,
  1544. unbind: unbind_1
  1545. };
  1546. /**
  1547. * Module dependencies.
  1548. */
  1549. /**
  1550. * Delegate event `type` to `selector`
  1551. * and invoke `fn(e)`. A callback function
  1552. * is returned which may be passed to `.unbind()`.
  1553. *
  1554. * @param {Element} el
  1555. * @param {String} selector
  1556. * @param {String} type
  1557. * @param {Function} fn
  1558. * @param {Boolean} capture
  1559. * @return {Function}
  1560. * @api public
  1561. */
  1562. // Some events don't bubble, so we want to bind to the capture phase instead
  1563. // when delegating.
  1564. var forceCaptureEvents = ['focus', 'blur'];
  1565. var bind$1$1 = function (el, selector, type, fn, capture) {
  1566. if (forceCaptureEvents.indexOf(type) !== -1) capture = true;
  1567. return componentEvent.bind(el, type, function (e) {
  1568. var target = e.target || e.srcElement;
  1569. e.delegateTarget = closest$1(target, selector, true);
  1570. if (e.delegateTarget) fn.call(el, e);
  1571. }, capture);
  1572. };
  1573. /**
  1574. * Unbind event `type`'s callback `fn`.
  1575. *
  1576. * @param {Element} el
  1577. * @param {String} type
  1578. * @param {Function} fn
  1579. * @param {Boolean} capture
  1580. * @api public
  1581. */
  1582. var unbind$1 = function (el, type, fn, capture) {
  1583. if (forceCaptureEvents.indexOf(type) !== -1) capture = true;
  1584. componentEvent.unbind(el, type, fn, capture);
  1585. };
  1586. var delegateEvents = {
  1587. bind: bind$1$1,
  1588. unbind: unbind$1
  1589. };
  1590. /**
  1591. * Expose `parse`.
  1592. */
  1593. var domify = parse$1;
  1594. /**
  1595. * Tests for browser support.
  1596. */
  1597. var innerHTMLBug = false;
  1598. var bugTestDiv;
  1599. if (typeof document !== 'undefined') {
  1600. bugTestDiv = document.createElement('div');
  1601. // Setup
  1602. bugTestDiv.innerHTML = ' <link/><table></table><a href="/a">a</a><input type="checkbox"/>';
  1603. // Make sure that link elements get serialized correctly by innerHTML
  1604. // This requires a wrapper element in IE
  1605. innerHTMLBug = !bugTestDiv.getElementsByTagName('link').length;
  1606. bugTestDiv = undefined;
  1607. }
  1608. /**
  1609. * Wrap map from jquery.
  1610. */
  1611. var map$1 = {
  1612. legend: [1, '<fieldset>', '</fieldset>'],
  1613. tr: [2, '<table><tbody>', '</tbody></table>'],
  1614. col: [2, '<table><tbody></tbody><colgroup>', '</colgroup></table>'],
  1615. // for script/link/style tags to work in IE6-8, you have to wrap
  1616. // in a div with a non-whitespace character in front, ha!
  1617. _default: innerHTMLBug ? [1, 'X<div>', '</div>'] : [0, '', '']
  1618. };
  1619. map$1.td =
  1620. map$1.th = [3, '<table><tbody><tr>', '</tr></tbody></table>'];
  1621. map$1.option =
  1622. map$1.optgroup = [1, '<select multiple="multiple">', '</select>'];
  1623. map$1.thead =
  1624. map$1.tbody =
  1625. map$1.colgroup =
  1626. map$1.caption =
  1627. map$1.tfoot = [1, '<table>', '</table>'];
  1628. map$1.polyline =
  1629. map$1.ellipse =
  1630. map$1.polygon =
  1631. map$1.circle =
  1632. map$1.text =
  1633. map$1.line =
  1634. map$1.path =
  1635. map$1.rect =
  1636. map$1.g = [1, '<svg xmlns="http://www.w3.org/2000/svg" version="1.1">', '</svg>'];
  1637. /**
  1638. * Parse `html` and return a DOM Node instance, which could be a TextNode,
  1639. * HTML DOM Node of some kind (<div> for example), or a DocumentFragment
  1640. * instance, depending on the contents of the `html` string.
  1641. *
  1642. * @param {String} html - HTML string to "domify"
  1643. * @param {Document} doc - The `document` instance to create the Node for
  1644. * @return {DOMNode} the TextNode, DOM Node, or DocumentFragment instance
  1645. * @api private
  1646. */
  1647. function parse$1(html, doc) {
  1648. if ('string' != typeof html) throw new TypeError('String expected');
  1649. // default to the global `document` object
  1650. if (!doc) doc = document;
  1651. // tag name
  1652. var m = /<([\w:]+)/.exec(html);
  1653. if (!m) return doc.createTextNode(html);
  1654. html = html.replace(/^\s+|\s+$/g, ''); // Remove leading/trailing whitespace
  1655. var tag = m[1];
  1656. // body support
  1657. if (tag == 'body') {
  1658. var el = doc.createElement('html');
  1659. el.innerHTML = html;
  1660. return el.removeChild(el.lastChild);
  1661. }
  1662. // wrap map
  1663. var wrap = map$1[tag] || map$1._default;
  1664. var depth = wrap[0];
  1665. var prefix = wrap[1];
  1666. var suffix = wrap[2];
  1667. var el = doc.createElement('div');
  1668. el.innerHTML = prefix + html + suffix;
  1669. while (depth--) el = el.lastChild;
  1670. // one element
  1671. if (el.firstChild == el.lastChild) {
  1672. return el.removeChild(el.firstChild);
  1673. }
  1674. // several elements
  1675. var fragment = doc.createDocumentFragment();
  1676. while (el.firstChild) {
  1677. fragment.appendChild(el.removeChild(el.firstChild));
  1678. }
  1679. return fragment;
  1680. }
  1681. function query(selector, el) {
  1682. el = el || document;
  1683. return el.querySelector(selector);
  1684. }
  1685. function all(selector, el) {
  1686. el = el || document;
  1687. return el.querySelectorAll(selector);
  1688. }
  1689. function remove$1(el) {
  1690. el.parentNode && el.parentNode.removeChild(el);
  1691. }
  1692. /**
  1693. * @param {<SVGElement>} element
  1694. * @param {number} x
  1695. * @param {number} y
  1696. * @param {number} angle
  1697. * @param {number} amount
  1698. */
  1699. function transform$1(gfx, x, y, angle, amount) {
  1700. var translate = createTransform();
  1701. translate.setTranslate(x, y);
  1702. var rotate = createTransform();
  1703. rotate.setRotate(angle || 0, 0, 0);
  1704. var scale = createTransform();
  1705. scale.setScale(amount || 1, amount || 1);
  1706. transform(gfx, [translate, rotate, scale]);
  1707. }
  1708. /**
  1709. * @param {SVGElement} element
  1710. * @param {number} x
  1711. * @param {number} y
  1712. */
  1713. function translate(gfx, x, y) {
  1714. var translate = createTransform();
  1715. translate.setTranslate(x, y);
  1716. transform(gfx, translate);
  1717. }
  1718. /**
  1719. * @param {SVGElement} element
  1720. * @param {number} angle
  1721. */
  1722. function rotate(gfx, angle) {
  1723. var rotate = createTransform();
  1724. rotate.setRotate(angle, 0, 0);
  1725. transform(gfx, rotate);
  1726. }
  1727. function createCommonjsModule$1(fn, module) {
  1728. return module = {exports: {}}, fn(module, module.exports), module.exports;
  1729. }
  1730. var hat_1 = createCommonjsModule$1(function (module) {
  1731. var hat = module.exports = function (bits, base) {
  1732. if (!base) base = 16;
  1733. if (bits === undefined) bits = 128;
  1734. if (bits <= 0) return '0';
  1735. var digits = Math.log(Math.pow(2, bits)) / Math.log(base);
  1736. for (var i = 2; digits === Infinity; i *= 2) {
  1737. digits = Math.log(Math.pow(2, bits / i)) / Math.log(base) * i;
  1738. }
  1739. var rem = digits - Math.floor(digits);
  1740. var res = '';
  1741. for (var i = 0; i < Math.floor(digits); i++) {
  1742. var x = Math.floor(Math.random() * base).toString(base);
  1743. res = x + res;
  1744. }
  1745. if (rem) {
  1746. var b = Math.pow(base, rem);
  1747. var x = Math.floor(Math.random() * b).toString(base);
  1748. res = x + res;
  1749. }
  1750. var parsed = parseInt(res, base);
  1751. if (parsed !== Infinity && parsed >= Math.pow(2, bits)) {
  1752. return hat(bits, base)
  1753. } else return res;
  1754. };
  1755. hat.rack = function (bits, base, expandBy) {
  1756. var fn = function (data) {
  1757. var iters = 0;
  1758. do {
  1759. if (iters++ > 10) {
  1760. if (expandBy) bits += expandBy;
  1761. else throw new Error('too many ID collisions, use more bits')
  1762. }
  1763. var id = hat(bits, base);
  1764. } while (Object.hasOwnProperty.call(hats, id));
  1765. hats[id] = data;
  1766. return id;
  1767. };
  1768. var hats = fn.hats = {};
  1769. fn.get = function (id) {
  1770. return fn.hats[id];
  1771. };
  1772. fn.set = function (id, value) {
  1773. fn.hats[id] = value;
  1774. return fn;
  1775. };
  1776. fn.bits = bits || 128;
  1777. fn.base = base || 16;
  1778. return fn;
  1779. };
  1780. });
  1781. /**
  1782. * Create a new id generator / cache instance.
  1783. *
  1784. * You may optionally provide a seed that is used internally.
  1785. *
  1786. * @param {Seed} seed
  1787. */
  1788. function Ids(seed) {
  1789. if (!(this instanceof Ids)) {
  1790. return new Ids(seed);
  1791. }
  1792. seed = seed || [128, 36, 1];
  1793. this._seed = seed.length ? hat_1.rack(seed[0], seed[1], seed[2]) : seed;
  1794. }
  1795. /**
  1796. * Generate a next id.
  1797. *
  1798. * @param {Object} [element] element to bind the id to
  1799. *
  1800. * @return {String} id
  1801. */
  1802. Ids.prototype.next = function (element) {
  1803. return this._seed(element || true);
  1804. };
  1805. /**
  1806. * Generate a next id with a given prefix.
  1807. *
  1808. * @param {Object} [element] element to bind the id to
  1809. *
  1810. * @return {String} id
  1811. */
  1812. Ids.prototype.nextPrefixed = function (prefix, element) {
  1813. var id;
  1814. do {
  1815. id = prefix + this.next(true);
  1816. } while (this.assigned(id)); // claim {prefix}{random}
  1817. this.claim(id, element); // return
  1818. return id;
  1819. };
  1820. /**
  1821. * Manually claim an existing id.
  1822. *
  1823. * @param {String} id
  1824. * @param {String} [element] element the id is claimed by
  1825. */
  1826. Ids.prototype.claim = function (id, element) {
  1827. this._seed.set(id, element || true);
  1828. };
  1829. /**
  1830. * Returns true if the given id has already been assigned.
  1831. *
  1832. * @param {String} id
  1833. * @return {Boolean}
  1834. */
  1835. Ids.prototype.assigned = function (id) {
  1836. return this._seed.get(id) || false;
  1837. };
  1838. /**
  1839. * Unclaim an id.
  1840. *
  1841. * @param {String} id the id to unclaim
  1842. */
  1843. Ids.prototype.unclaim = function (id) {
  1844. delete this._seed.hats[id];
  1845. };
  1846. /**
  1847. * Clear all claimed ids.
  1848. */
  1849. Ids.prototype.clear = function () {
  1850. var hats = this._seed.hats,
  1851. id;
  1852. for (id in hats) {
  1853. this.unclaim(id);
  1854. }
  1855. };
  1856. var RENDERER_IDS = new Ids();
  1857. var TASK_BORDER_RADIUS = 10;
  1858. var INNER_OUTER_DIST = 3;
  1859. var DEFAULT_FILL_OPACITY = .95,
  1860. HIGH_FILL_OPACITY = .35;
  1861. function BpmnRenderer(
  1862. config, eventBus, styles, pathMap,
  1863. canvas, textRenderer, priority) {
  1864. BaseRenderer.call(this, eventBus, priority);
  1865. var defaultFillColor = config && config.defaultFillColor,
  1866. defaultStrokeColor = config && config.defaultStrokeColor;
  1867. var rendererId = RENDERER_IDS.next();
  1868. var markers = {};
  1869. var computeStyle = styles.computeStyle;
  1870. function addMarker(id, options) {
  1871. var attrs = assign({
  1872. fill: 'black',
  1873. strokeWidth: 1,
  1874. strokeLinecap: 'round',
  1875. strokeDasharray: 'none'
  1876. }, options.attrs);
  1877. var ref = options.ref || {x: 0, y: 0};
  1878. var scale = options.scale || 1;
  1879. // fix for safari / chrome / firefox bug not correctly
  1880. // resetting stroke dash array
  1881. if (attrs.strokeDasharray === 'none') {
  1882. attrs.strokeDasharray = [10000, 1];
  1883. }
  1884. var marker = create('marker');
  1885. attr(options.element, attrs);
  1886. append(marker, options.element);
  1887. attr(marker, {
  1888. id: id,
  1889. viewBox: '0 0 20 20',
  1890. refX: ref.x,
  1891. refY: ref.y,
  1892. markerWidth: 20 * scale,
  1893. markerHeight: 20 * scale,
  1894. orient: 'auto'
  1895. });
  1896. var defs = query('defs', canvas._svg);
  1897. if (!defs) {
  1898. defs = create('defs');
  1899. append(canvas._svg, defs);
  1900. }
  1901. append(defs, marker);
  1902. markers[id] = marker;
  1903. }
  1904. function colorEscape(str) {
  1905. // only allow characters and numbers
  1906. return str.replace(/[^0-9a-zA-z]+/g, '_');
  1907. }
  1908. function marker(type, fill, stroke) {
  1909. var id = type + '-' + colorEscape(fill) + '-' + colorEscape(stroke) + '-' + rendererId;
  1910. if (!markers[id]) {
  1911. createMarker(id, type, fill, stroke);
  1912. }
  1913. return 'url(#' + id + ')';
  1914. }
  1915. function createMarker(id, type, fill, stroke) {
  1916. if (type === 'sequenceflow-end') {
  1917. var sequenceflowEnd = create('path');
  1918. attr(sequenceflowEnd, {d: 'M 1 5 L 11 10 L 1 15 Z'});
  1919. addMarker(id, {
  1920. element: sequenceflowEnd,
  1921. ref: {x: 11, y: 10},
  1922. scale: 0.5,
  1923. attrs: {
  1924. fill: stroke,
  1925. stroke: stroke
  1926. }
  1927. });
  1928. }
  1929. if (type === 'messageflow-start') {
  1930. var messageflowStart = create('circle');
  1931. attr(messageflowStart, {cx: 6, cy: 6, r: 3.5});
  1932. addMarker(id, {
  1933. element: messageflowStart,
  1934. attrs: {
  1935. fill: fill,
  1936. stroke: stroke
  1937. },
  1938. ref: {x: 6, y: 6}
  1939. });
  1940. }
  1941. if (type === 'messageflow-end') {
  1942. var messageflowEnd = create('path');
  1943. attr(messageflowEnd, {d: 'm 1 5 l 0 -3 l 7 3 l -7 3 z'});
  1944. addMarker(id, {
  1945. element: messageflowEnd,
  1946. attrs: {
  1947. fill: fill,
  1948. stroke: stroke,
  1949. strokeLinecap: 'butt'
  1950. },
  1951. ref: {x: 8.5, y: 5}
  1952. });
  1953. }
  1954. if (type === 'association-start') {
  1955. var associationStart = create('path');
  1956. attr(associationStart, {d: 'M 11 5 L 1 10 L 11 15'});
  1957. addMarker(id, {
  1958. element: associationStart,
  1959. attrs: {
  1960. fill: 'none',
  1961. stroke: stroke,
  1962. strokeWidth: 1.5
  1963. },
  1964. ref: {x: 1, y: 10},
  1965. scale: 0.5
  1966. });
  1967. }
  1968. if (type === 'association-end') {
  1969. var associationEnd = create('path');
  1970. attr(associationEnd, {d: 'M 1 5 L 11 10 L 1 15'});
  1971. addMarker(id, {
  1972. element: associationEnd,
  1973. attrs: {
  1974. fill: 'none',
  1975. stroke: stroke,
  1976. strokeWidth: 1.5
  1977. },
  1978. ref: {x: 12, y: 10},
  1979. scale: 0.5
  1980. });
  1981. }
  1982. if (type === 'conditional-flow-marker') {
  1983. var conditionalflowMarker = create('path');
  1984. attr(conditionalflowMarker, {d: 'M 0 10 L 8 6 L 16 10 L 8 14 Z'});
  1985. addMarker(id, {
  1986. element: conditionalflowMarker,
  1987. attrs: {
  1988. fill: fill,
  1989. stroke: stroke
  1990. },
  1991. ref: {x: -1, y: 10},
  1992. scale: 0.5
  1993. });
  1994. }
  1995. if (type === 'conditional-default-flow-marker') {
  1996. var conditionaldefaultflowMarker = create('path');
  1997. attr(conditionaldefaultflowMarker, {d: 'M 6 4 L 10 16'});
  1998. addMarker(id, {
  1999. element: conditionaldefaultflowMarker,
  2000. attrs: {
  2001. stroke: stroke
  2002. },
  2003. ref: {x: 0, y: 10},
  2004. scale: 0.5
  2005. });
  2006. }
  2007. }
  2008. function drawCircle(parentGfx, width, height, offset, attrs) {
  2009. if (isObject(offset)) {
  2010. attrs = offset;
  2011. offset = 0;
  2012. }
  2013. offset = offset || 0;
  2014. attrs = computeStyle(attrs, {
  2015. stroke: 'black',
  2016. strokeWidth: 2,
  2017. fill: 'white'
  2018. });
  2019. if (attrs.fill === 'none') {
  2020. delete attrs.fillOpacity;
  2021. }
  2022. var cx = width / 2,
  2023. cy = height / 2;
  2024. var circle = create('circle');
  2025. attr(circle, {
  2026. cx: cx,
  2027. cy: cy,
  2028. r: Math.round((width + height) / 4 - offset)
  2029. });
  2030. attr(circle, attrs);
  2031. append(parentGfx, circle);
  2032. return circle;
  2033. }
  2034. function drawRect(parentGfx, width, height, r, offset, attrs) {
  2035. if (isObject(offset)) {
  2036. attrs = offset;
  2037. offset = 0;
  2038. }
  2039. offset = offset || 0;
  2040. attrs = computeStyle(attrs, {
  2041. stroke: 'black',
  2042. strokeWidth: 2,
  2043. fill: 'white'
  2044. });
  2045. var rect = create('rect');
  2046. attr(rect, {
  2047. x: offset,
  2048. y: offset,
  2049. width: width - offset * 2,
  2050. height: height - offset * 2,
  2051. rx: r,
  2052. ry: r
  2053. });
  2054. attr(rect, attrs);
  2055. append(parentGfx, rect);
  2056. return rect;
  2057. }
  2058. function drawDiamond(parentGfx, width, height, attrs) {
  2059. var x_2 = width / 2;
  2060. var y_2 = height / 2;
  2061. var points = [{x: x_2, y: 0}, {x: width, y: y_2}, {x: x_2, y: height}, {x: 0, y: y_2}];
  2062. var pointsString = points.map(function (point) {
  2063. return point.x + ',' + point.y;
  2064. }).join(' ');
  2065. attrs = computeStyle(attrs, {
  2066. stroke: 'black',
  2067. strokeWidth: 2,
  2068. fill: 'white'
  2069. });
  2070. var polygon = create('polygon');
  2071. attr(polygon, {
  2072. points: pointsString
  2073. });
  2074. attr(polygon, attrs);
  2075. append(parentGfx, polygon);
  2076. return polygon;
  2077. }
  2078. function drawLine(parentGfx, waypoints, attrs) {
  2079. attrs = computeStyle(attrs, ['no-fill'], {
  2080. stroke: 'black',
  2081. strokeWidth: 2,
  2082. fill: 'none'
  2083. });
  2084. var line = createLine(waypoints, attrs);
  2085. append(parentGfx, line);
  2086. return line;
  2087. }
  2088. function drawPath(parentGfx, d, attrs) {
  2089. attrs = computeStyle(attrs, ['no-fill'], {
  2090. strokeWidth: 2,
  2091. stroke: 'black'
  2092. });
  2093. var path = create('path');
  2094. attr(path, {d: d});
  2095. attr(path, attrs);
  2096. append(parentGfx, path);
  2097. return path;
  2098. }
  2099. function drawMarker(type, parentGfx, path, attrs) {
  2100. return drawPath(parentGfx, path, assign({'data-marker': type}, attrs));
  2101. }
  2102. function as(type) {
  2103. return function (parentGfx, element) {
  2104. return handlers[type](parentGfx, element);
  2105. };
  2106. }
  2107. function renderer(type) {
  2108. return handlers[type];
  2109. }
  2110. function renderEventContent(element, parentGfx) {
  2111. var event = getSemantic(element);
  2112. var isThrowing = isThrowEvent(event);
  2113. if (event.eventDefinitions && event.eventDefinitions.length > 1) {
  2114. if (event.parallelMultiple) {
  2115. return renderer('bpmn:ParallelMultipleEventDefinition')(parentGfx, element, isThrowing);
  2116. } else {
  2117. return renderer('bpmn:MultipleEventDefinition')(parentGfx, element, isThrowing);
  2118. }
  2119. }
  2120. if (isTypedEvent(event, 'bpmn:MessageEventDefinition')) {
  2121. return renderer('bpmn:MessageEventDefinition')(parentGfx, element, isThrowing);
  2122. }
  2123. if (isTypedEvent(event, 'bpmn:TimerEventDefinition')) {
  2124. return renderer('bpmn:TimerEventDefinition')(parentGfx, element, isThrowing);
  2125. }
  2126. if (isTypedEvent(event, 'bpmn:ConditionalEventDefinition')) {
  2127. return renderer('bpmn:ConditionalEventDefinition')(parentGfx, element);
  2128. }
  2129. if (isTypedEvent(event, 'bpmn:SignalEventDefinition')) {
  2130. return renderer('bpmn:SignalEventDefinition')(parentGfx, element, isThrowing);
  2131. }
  2132. if (isTypedEvent(event, 'bpmn:EscalationEventDefinition')) {
  2133. return renderer('bpmn:EscalationEventDefinition')(parentGfx, element, isThrowing);
  2134. }
  2135. if (isTypedEvent(event, 'bpmn:LinkEventDefinition')) {
  2136. return renderer('bpmn:LinkEventDefinition')(parentGfx, element, isThrowing);
  2137. }
  2138. if (isTypedEvent(event, 'bpmn:ErrorEventDefinition')) {
  2139. return renderer('bpmn:ErrorEventDefinition')(parentGfx, element, isThrowing);
  2140. }
  2141. if (isTypedEvent(event, 'bpmn:CancelEventDefinition')) {
  2142. return renderer('bpmn:CancelEventDefinition')(parentGfx, element, isThrowing);
  2143. }
  2144. if (isTypedEvent(event, 'bpmn:CompensateEventDefinition')) {
  2145. return renderer('bpmn:CompensateEventDefinition')(parentGfx, element, isThrowing);
  2146. }
  2147. if (isTypedEvent(event, 'bpmn:TerminateEventDefinition')) {
  2148. return renderer('bpmn:TerminateEventDefinition')(parentGfx, element, isThrowing);
  2149. }
  2150. return null;
  2151. }
  2152. function renderLabel(parentGfx, label, options) {
  2153. options = assign({
  2154. size: {
  2155. width: 100
  2156. }
  2157. }, options);
  2158. var text = textRenderer.createText(label || '', options);
  2159. classes(text).add('djs-label');
  2160. append(parentGfx, text);
  2161. return text;
  2162. }
  2163. function renderEmbeddedLabel(parentGfx, element, align) {
  2164. var semantic = getSemantic(element);
  2165. return renderLabel(parentGfx, semantic.name, {
  2166. box: element,
  2167. align: align,
  2168. padding: 5,
  2169. style: {
  2170. fill: getStrokeColor(element, defaultStrokeColor)
  2171. }
  2172. });
  2173. }
  2174. function renderExternalLabel(parentGfx, element) {
  2175. var box = {
  2176. width: 90,
  2177. height: 30,
  2178. x: element.width / 2 + element.x,
  2179. y: element.height / 2 + element.y
  2180. };
  2181. return renderLabel(parentGfx, getLabel(element), {
  2182. box: box,
  2183. fitBox: true,
  2184. style: assign(
  2185. {},
  2186. textRenderer.getExternalStyle(),
  2187. {
  2188. fill: getStrokeColor(element, defaultStrokeColor)
  2189. }
  2190. )
  2191. });
  2192. }
  2193. function renderLaneLabel(parentGfx, text, element) {
  2194. var textBox = renderLabel(parentGfx, text, {
  2195. box: {
  2196. height: 30,
  2197. width: element.height
  2198. },
  2199. align: 'center-middle',
  2200. style: {
  2201. fill: getStrokeColor(element, defaultStrokeColor)
  2202. }
  2203. });
  2204. var top = -1 * element.height;
  2205. transform$1(textBox, 0, -top, 270);
  2206. }
  2207. function createPathFromConnection(connection) {
  2208. var waypoints = connection.waypoints;
  2209. var pathData = 'm ' + waypoints[0].x + ',' + waypoints[0].y;
  2210. for (var i = 1; i < waypoints.length; i++) {
  2211. pathData += 'L' + waypoints[i].x + ',' + waypoints[i].y + ' ';
  2212. }
  2213. return pathData;
  2214. }
  2215. var handlers = this.handlers = {
  2216. 'bpmn:Event': function (parentGfx, element, attrs) {
  2217. if (!('fillOpacity' in attrs)) {
  2218. attrs.fillOpacity = DEFAULT_FILL_OPACITY;
  2219. }
  2220. return drawCircle(parentGfx, element.width, element.height, attrs);
  2221. },
  2222. 'bpmn:StartEvent': function (parentGfx, element) {
  2223. var attrs = {
  2224. fill: getFillColor(element, defaultFillColor),
  2225. stroke: getStrokeColor(element, defaultStrokeColor)
  2226. };
  2227. var semantic = getSemantic(element);
  2228. if (!semantic.isInterrupting) {
  2229. attrs = {
  2230. strokeDasharray: '6',
  2231. strokeLinecap: 'round',
  2232. fill: getFillColor(element, defaultFillColor),
  2233. stroke: getStrokeColor(element, defaultStrokeColor)
  2234. };
  2235. }
  2236. var circle = renderer('bpmn:Event')(parentGfx, element, attrs);
  2237. renderEventContent(element, parentGfx);
  2238. return circle;
  2239. },
  2240. 'bpmn:MessageEventDefinition': function (parentGfx, element, isThrowing) {
  2241. var pathData = pathMap.getScaledPath('EVENT_MESSAGE', {
  2242. xScaleFactor: 0.9,
  2243. yScaleFactor: 0.9,
  2244. containerWidth: element.width,
  2245. containerHeight: element.height,
  2246. position: {
  2247. mx: 0.235,
  2248. my: 0.315
  2249. }
  2250. });
  2251. var fill = isThrowing ? getStrokeColor(element, defaultStrokeColor) : getFillColor(element, defaultFillColor);
  2252. var stroke = isThrowing ? getFillColor(element, defaultFillColor) : getStrokeColor(element, defaultStrokeColor);
  2253. var messagePath = drawPath(parentGfx, pathData, {
  2254. strokeWidth: 1,
  2255. fill: fill,
  2256. stroke: stroke
  2257. });
  2258. return messagePath;
  2259. },
  2260. 'bpmn:TimerEventDefinition': function (parentGfx, element) {
  2261. var circle = drawCircle(parentGfx, element.width, element.height, 0.2 * element.height, {
  2262. strokeWidth: 2,
  2263. fill: getFillColor(element, defaultFillColor),
  2264. stroke: getStrokeColor(element, defaultStrokeColor)
  2265. });
  2266. var pathData = pathMap.getScaledPath('EVENT_TIMER_WH', {
  2267. xScaleFactor: 0.75,
  2268. yScaleFactor: 0.75,
  2269. containerWidth: element.width,
  2270. containerHeight: element.height,
  2271. position: {
  2272. mx: 0.5,
  2273. my: 0.5
  2274. }
  2275. });
  2276. drawPath(parentGfx, pathData, {
  2277. strokeWidth: 2,
  2278. strokeLinecap: 'square',
  2279. stroke: getStrokeColor(element, defaultStrokeColor)
  2280. });
  2281. for (var i = 0; i < 12; i++) {
  2282. var linePathData = pathMap.getScaledPath('EVENT_TIMER_LINE', {
  2283. xScaleFactor: 0.75,
  2284. yScaleFactor: 0.75,
  2285. containerWidth: element.width,
  2286. containerHeight: element.height,
  2287. position: {
  2288. mx: 0.5,
  2289. my: 0.5
  2290. }
  2291. });
  2292. var width = element.width / 2;
  2293. var height = element.height / 2;
  2294. drawPath(parentGfx, linePathData, {
  2295. strokeWidth: 1,
  2296. strokeLinecap: 'square',
  2297. transform: 'rotate(' + (i * 30) + ',' + height + ',' + width + ')',
  2298. stroke: getStrokeColor(element, defaultStrokeColor)
  2299. });
  2300. }
  2301. return circle;
  2302. },
  2303. 'bpmn:EscalationEventDefinition': function (parentGfx, event, isThrowing) {
  2304. var pathData = pathMap.getScaledPath('EVENT_ESCALATION', {
  2305. xScaleFactor: 1,
  2306. yScaleFactor: 1,
  2307. containerWidth: event.width,
  2308. containerHeight: event.height,
  2309. position: {
  2310. mx: 0.5,
  2311. my: 0.2
  2312. }
  2313. });
  2314. var fill = isThrowing ? getStrokeColor(event, defaultStrokeColor) : 'none';
  2315. return drawPath(parentGfx, pathData, {
  2316. strokeWidth: 1,
  2317. fill: fill,
  2318. stroke: getStrokeColor(event, defaultStrokeColor)
  2319. });
  2320. },
  2321. 'bpmn:ConditionalEventDefinition': function (parentGfx, event) {
  2322. var pathData = pathMap.getScaledPath('EVENT_CONDITIONAL', {
  2323. xScaleFactor: 1,
  2324. yScaleFactor: 1,
  2325. containerWidth: event.width,
  2326. containerHeight: event.height,
  2327. position: {
  2328. mx: 0.5,
  2329. my: 0.222
  2330. }
  2331. });
  2332. return drawPath(parentGfx, pathData, {
  2333. strokeWidth: 1,
  2334. stroke: getStrokeColor(event, defaultStrokeColor)
  2335. });
  2336. },
  2337. 'bpmn:LinkEventDefinition': function (parentGfx, event, isThrowing) {
  2338. var pathData = pathMap.getScaledPath('EVENT_LINK', {
  2339. xScaleFactor: 1,
  2340. yScaleFactor: 1,
  2341. containerWidth: event.width,
  2342. containerHeight: event.height,
  2343. position: {
  2344. mx: 0.57,
  2345. my: 0.263
  2346. }
  2347. });
  2348. var fill = isThrowing ? getStrokeColor(event, defaultStrokeColor) : 'none';
  2349. return drawPath(parentGfx, pathData, {
  2350. strokeWidth: 1,
  2351. fill: fill,
  2352. stroke: getStrokeColor(event, defaultStrokeColor)
  2353. });
  2354. },
  2355. 'bpmn:ErrorEventDefinition': function (parentGfx, event, isThrowing) {
  2356. var pathData = pathMap.getScaledPath('EVENT_ERROR', {
  2357. xScaleFactor: 1.1,
  2358. yScaleFactor: 1.1,
  2359. containerWidth: event.width,
  2360. containerHeight: event.height,
  2361. position: {
  2362. mx: 0.2,
  2363. my: 0.722
  2364. }
  2365. });
  2366. var fill = isThrowing ? getStrokeColor(event, defaultStrokeColor) : 'none';
  2367. return drawPath(parentGfx, pathData, {
  2368. strokeWidth: 1,
  2369. fill: fill,
  2370. stroke: getStrokeColor(event, defaultStrokeColor)
  2371. });
  2372. },
  2373. 'bpmn:CancelEventDefinition': function (parentGfx, event, isThrowing) {
  2374. var pathData = pathMap.getScaledPath('EVENT_CANCEL_45', {
  2375. xScaleFactor: 1.0,
  2376. yScaleFactor: 1.0,
  2377. containerWidth: event.width,
  2378. containerHeight: event.height,
  2379. position: {
  2380. mx: 0.638,
  2381. my: -0.055
  2382. }
  2383. });
  2384. var fill = isThrowing ? getStrokeColor(event, defaultStrokeColor) : 'none';
  2385. var path = drawPath(parentGfx, pathData, {
  2386. strokeWidth: 1,
  2387. fill: fill,
  2388. stroke: getStrokeColor(event, defaultStrokeColor)
  2389. });
  2390. rotate(path, 45);
  2391. return path;
  2392. },
  2393. 'bpmn:CompensateEventDefinition': function (parentGfx, event, isThrowing) {
  2394. var pathData = pathMap.getScaledPath('EVENT_COMPENSATION', {
  2395. xScaleFactor: 1,
  2396. yScaleFactor: 1,
  2397. containerWidth: event.width,
  2398. containerHeight: event.height,
  2399. position: {
  2400. mx: 0.22,
  2401. my: 0.5
  2402. }
  2403. });
  2404. var fill = isThrowing ? getStrokeColor(event, defaultStrokeColor) : 'none';
  2405. return drawPath(parentGfx, pathData, {
  2406. strokeWidth: 1,
  2407. fill: fill,
  2408. stroke: getStrokeColor(event, defaultStrokeColor)
  2409. });
  2410. },
  2411. 'bpmn:SignalEventDefinition': function (parentGfx, event, isThrowing) {
  2412. var pathData = pathMap.getScaledPath('EVENT_SIGNAL', {
  2413. xScaleFactor: 0.9,
  2414. yScaleFactor: 0.9,
  2415. containerWidth: event.width,
  2416. containerHeight: event.height,
  2417. position: {
  2418. mx: 0.5,
  2419. my: 0.2
  2420. }
  2421. });
  2422. var fill = isThrowing ? getStrokeColor(event, defaultStrokeColor) : 'none';
  2423. return drawPath(parentGfx, pathData, {
  2424. strokeWidth: 1,
  2425. fill: fill,
  2426. stroke: getStrokeColor(event, defaultStrokeColor)
  2427. });
  2428. },
  2429. 'bpmn:MultipleEventDefinition': function (parentGfx, event, isThrowing) {
  2430. var pathData = pathMap.getScaledPath('EVENT_MULTIPLE', {
  2431. xScaleFactor: 1.1,
  2432. yScaleFactor: 1.1,
  2433. containerWidth: event.width,
  2434. containerHeight: event.height,
  2435. position: {
  2436. mx: 0.222,
  2437. my: 0.36
  2438. }
  2439. });
  2440. var fill = isThrowing ? getStrokeColor(event, defaultStrokeColor) : 'none';
  2441. return drawPath(parentGfx, pathData, {
  2442. strokeWidth: 1,
  2443. fill: fill
  2444. });
  2445. },
  2446. 'bpmn:ParallelMultipleEventDefinition': function (parentGfx, event) {
  2447. var pathData = pathMap.getScaledPath('EVENT_PARALLEL_MULTIPLE', {
  2448. xScaleFactor: 1.2,
  2449. yScaleFactor: 1.2,
  2450. containerWidth: event.width,
  2451. containerHeight: event.height,
  2452. position: {
  2453. mx: 0.458,
  2454. my: 0.194
  2455. }
  2456. });
  2457. return drawPath(parentGfx, pathData, {
  2458. strokeWidth: 1,
  2459. fill: getStrokeColor(event, defaultStrokeColor),
  2460. stroke: getStrokeColor(event, defaultStrokeColor)
  2461. });
  2462. },
  2463. 'bpmn:EndEvent': function (parentGfx, element) {
  2464. var circle = renderer('bpmn:Event')(parentGfx, element, {
  2465. strokeWidth: 4,
  2466. fill: getFillColor(element, defaultFillColor),
  2467. stroke: getStrokeColor(element, defaultStrokeColor)
  2468. });
  2469. renderEventContent(element, parentGfx);
  2470. return circle;
  2471. },
  2472. 'bpmn:TerminateEventDefinition': function (parentGfx, element) {
  2473. var circle = drawCircle(parentGfx, element.width, element.height, 8, {
  2474. strokeWidth: 4,
  2475. fill: getStrokeColor(element, defaultStrokeColor),
  2476. stroke: getStrokeColor(element, defaultStrokeColor)
  2477. });
  2478. return circle;
  2479. },
  2480. 'bpmn:IntermediateEvent': function (parentGfx, element) {
  2481. var outer = renderer('bpmn:Event')(parentGfx, element, {
  2482. strokeWidth: 1,
  2483. fill: getFillColor(element, defaultFillColor),
  2484. stroke: getStrokeColor(element, defaultStrokeColor)
  2485. });
  2486. /* inner */
  2487. drawCircle(parentGfx, element.width, element.height, INNER_OUTER_DIST, {
  2488. strokeWidth: 1,
  2489. fill: getFillColor(element, 'none'),
  2490. stroke: getStrokeColor(element, defaultStrokeColor)
  2491. });
  2492. renderEventContent(element, parentGfx);
  2493. return outer;
  2494. },
  2495. 'bpmn:IntermediateCatchEvent': as('bpmn:IntermediateEvent'),
  2496. 'bpmn:IntermediateThrowEvent': as('bpmn:IntermediateEvent'),
  2497. 'bpmn:Activity': function (parentGfx, element, attrs) {
  2498. attrs = attrs || {};
  2499. if (!('fillOpacity' in attrs)) {
  2500. attrs.fillOpacity = DEFAULT_FILL_OPACITY;
  2501. }
  2502. return drawRect(parentGfx, element.width, element.height, TASK_BORDER_RADIUS, attrs);
  2503. },
  2504. 'bpmn:Task': function (parentGfx, element) {
  2505. var attrs = {
  2506. fill: getFillColor(element, defaultFillColor),
  2507. stroke: getStrokeColor(element, defaultStrokeColor)
  2508. };
  2509. var rect = renderer('bpmn:Activity')(parentGfx, element, attrs);
  2510. renderEmbeddedLabel(parentGfx, element, 'center-middle');
  2511. attachTaskMarkers(parentGfx, element);
  2512. return rect;
  2513. },
  2514. 'bpmn:ServiceTask': function (parentGfx, element) {
  2515. var task = renderer('bpmn:Task')(parentGfx, element);
  2516. var pathDataBG = pathMap.getScaledPath('TASK_TYPE_SERVICE', {
  2517. abspos: {
  2518. x: 12,
  2519. y: 18
  2520. }
  2521. });
  2522. /* service bg */
  2523. drawPath(parentGfx, pathDataBG, {
  2524. strokeWidth: 1,
  2525. fill: getFillColor(element, defaultFillColor),
  2526. stroke: getStrokeColor(element, defaultStrokeColor)
  2527. });
  2528. var fillPathData = pathMap.getScaledPath('TASK_TYPE_SERVICE_FILL', {
  2529. abspos: {
  2530. x: 17.2,
  2531. y: 18
  2532. }
  2533. });
  2534. /* service fill */
  2535. drawPath(parentGfx, fillPathData, {
  2536. strokeWidth: 0,
  2537. fill: getFillColor(element, defaultFillColor)
  2538. });
  2539. var pathData = pathMap.getScaledPath('TASK_TYPE_SERVICE', {
  2540. abspos: {
  2541. x: 17,
  2542. y: 22
  2543. }
  2544. });
  2545. /* service */
  2546. drawPath(parentGfx, pathData, {
  2547. strokeWidth: 1,
  2548. fill: getFillColor(element, defaultFillColor),
  2549. stroke: getStrokeColor(element, defaultStrokeColor)
  2550. });
  2551. return task;
  2552. },
  2553. 'bpmn:UserTask': function (parentGfx, element) {
  2554. var task = renderer('bpmn:Task')(parentGfx, element);
  2555. var x = 15;
  2556. var y = 12;
  2557. var pathData = pathMap.getScaledPath('TASK_TYPE_USER_1', {
  2558. abspos: {
  2559. x: x,
  2560. y: y
  2561. }
  2562. });
  2563. /* user path */
  2564. drawPath(parentGfx, pathData, {
  2565. strokeWidth: 0.5,
  2566. fill: getFillColor(element, defaultFillColor),
  2567. stroke: getStrokeColor(element, defaultStrokeColor)
  2568. });
  2569. var pathData2 = pathMap.getScaledPath('TASK_TYPE_USER_2', {
  2570. abspos: {
  2571. x: x,
  2572. y: y
  2573. }
  2574. });
  2575. /* user2 path */
  2576. drawPath(parentGfx, pathData2, {
  2577. strokeWidth: 0.5,
  2578. fill: getFillColor(element, defaultFillColor),
  2579. stroke: getStrokeColor(element, defaultStrokeColor)
  2580. });
  2581. var pathData3 = pathMap.getScaledPath('TASK_TYPE_USER_3', {
  2582. abspos: {
  2583. x: x,
  2584. y: y
  2585. }
  2586. });
  2587. /* user3 path */
  2588. drawPath(parentGfx, pathData3, {
  2589. strokeWidth: 0.5,
  2590. fill: getStrokeColor(element, defaultStrokeColor),
  2591. stroke: getStrokeColor(element, defaultStrokeColor)
  2592. });
  2593. return task;
  2594. },
  2595. 'bpmn:ManualTask': function (parentGfx, element) {
  2596. var task = renderer('bpmn:Task')(parentGfx, element);
  2597. var pathData = pathMap.getScaledPath('TASK_TYPE_MANUAL', {
  2598. abspos: {
  2599. x: 17,
  2600. y: 15
  2601. }
  2602. });
  2603. /* manual path */
  2604. drawPath(parentGfx, pathData, {
  2605. strokeWidth: 0.5, // 0.25,
  2606. fill: getFillColor(element, defaultFillColor),
  2607. stroke: getStrokeColor(element, defaultStrokeColor)
  2608. });
  2609. return task;
  2610. },
  2611. 'bpmn:SendTask': function (parentGfx, element) {
  2612. var task = renderer('bpmn:Task')(parentGfx, element);
  2613. var pathData = pathMap.getScaledPath('TASK_TYPE_SEND', {
  2614. xScaleFactor: 1,
  2615. yScaleFactor: 1,
  2616. containerWidth: 21,
  2617. containerHeight: 14,
  2618. position: {
  2619. mx: 0.285,
  2620. my: 0.357
  2621. }
  2622. });
  2623. /* send path */
  2624. drawPath(parentGfx, pathData, {
  2625. strokeWidth: 1,
  2626. fill: getStrokeColor(element, defaultStrokeColor),
  2627. stroke: getFillColor(element, defaultFillColor)
  2628. });
  2629. return task;
  2630. },
  2631. 'bpmn:ReceiveTask': function (parentGfx, element) {
  2632. var semantic = getSemantic(element);
  2633. var task = renderer('bpmn:Task')(parentGfx, element);
  2634. var pathData;
  2635. if (semantic.instantiate) {
  2636. drawCircle(parentGfx, 28, 28, 20 * 0.22, {strokeWidth: 1});
  2637. pathData = pathMap.getScaledPath('TASK_TYPE_INSTANTIATING_SEND', {
  2638. abspos: {
  2639. x: 7.77,
  2640. y: 9.52
  2641. }
  2642. });
  2643. } else {
  2644. pathData = pathMap.getScaledPath('TASK_TYPE_SEND', {
  2645. xScaleFactor: 0.9,
  2646. yScaleFactor: 0.9,
  2647. containerWidth: 21,
  2648. containerHeight: 14,
  2649. position: {
  2650. mx: 0.3,
  2651. my: 0.4
  2652. }
  2653. });
  2654. }
  2655. /* receive path */
  2656. drawPath(parentGfx, pathData, {
  2657. strokeWidth: 1,
  2658. fill: getFillColor(element, defaultFillColor),
  2659. stroke: getStrokeColor(element, defaultStrokeColor)
  2660. });
  2661. return task;
  2662. },
  2663. 'bpmn:ScriptTask': function (parentGfx, element) {
  2664. var task = renderer('bpmn:Task')(parentGfx, element);
  2665. var pathData = pathMap.getScaledPath('TASK_TYPE_SCRIPT', {
  2666. abspos: {
  2667. x: 15,
  2668. y: 20
  2669. }
  2670. });
  2671. /* script path */
  2672. drawPath(parentGfx, pathData, {
  2673. strokeWidth: 1,
  2674. stroke: getStrokeColor(element, defaultStrokeColor)
  2675. });
  2676. return task;
  2677. },
  2678. 'bpmn:BusinessRuleTask': function (parentGfx, element) {
  2679. var task = renderer('bpmn:Task')(parentGfx, element);
  2680. var headerPathData = pathMap.getScaledPath('TASK_TYPE_BUSINESS_RULE_HEADER', {
  2681. abspos: {
  2682. x: 8,
  2683. y: 8
  2684. }
  2685. });
  2686. var businessHeaderPath = drawPath(parentGfx, headerPathData);
  2687. attr(businessHeaderPath, {
  2688. strokeWidth: 1,
  2689. fill: getFillColor(element, '#aaaaaa'),
  2690. stroke: getStrokeColor(element, defaultStrokeColor)
  2691. });
  2692. var headerData = pathMap.getScaledPath('TASK_TYPE_BUSINESS_RULE_MAIN', {
  2693. abspos: {
  2694. x: 8,
  2695. y: 8
  2696. }
  2697. });
  2698. var businessPath = drawPath(parentGfx, headerData);
  2699. attr(businessPath, {
  2700. strokeWidth: 1,
  2701. stroke: getStrokeColor(element, defaultStrokeColor)
  2702. });
  2703. return task;
  2704. },
  2705. 'bpmn:SubProcess': function (parentGfx, element, attrs) {
  2706. attrs = assign({
  2707. fill: getFillColor(element, defaultFillColor),
  2708. stroke: getStrokeColor(element, defaultStrokeColor)
  2709. }, attrs);
  2710. var rect = renderer('bpmn:Activity')(parentGfx, element, attrs);
  2711. var expanded = isExpanded(element);
  2712. if (isEventSubProcess(element)) {
  2713. attr(rect, {
  2714. strokeDasharray: '1,2'
  2715. });
  2716. }
  2717. renderEmbeddedLabel(parentGfx, element, expanded ? 'center-top' : 'center-middle');
  2718. if (expanded) {
  2719. attachTaskMarkers(parentGfx, element);
  2720. } else {
  2721. attachTaskMarkers(parentGfx, element, ['SubProcessMarker']);
  2722. }
  2723. return rect;
  2724. },
  2725. 'bpmn:AdHocSubProcess': function (parentGfx, element) {
  2726. return renderer('bpmn:SubProcess')(parentGfx, element);
  2727. },
  2728. 'bpmn:Transaction': function (parentGfx, element) {
  2729. var outer = renderer('bpmn:SubProcess')(parentGfx, element);
  2730. var innerAttrs = styles.style(['no-fill', 'no-events'], {
  2731. stroke: getStrokeColor(element, defaultStrokeColor)
  2732. });
  2733. /* inner path */
  2734. drawRect(parentGfx, element.width, element.height, TASK_BORDER_RADIUS - 2, INNER_OUTER_DIST, innerAttrs);
  2735. return outer;
  2736. },
  2737. 'bpmn:CallActivity': function (parentGfx, element) {
  2738. return renderer('bpmn:SubProcess')(parentGfx, element, {
  2739. strokeWidth: 5
  2740. });
  2741. },
  2742. 'bpmn:Participant': function (parentGfx, element) {
  2743. var attrs = {
  2744. fillOpacity: DEFAULT_FILL_OPACITY,
  2745. fill: getFillColor(element, defaultFillColor),
  2746. stroke: getStrokeColor(element, defaultStrokeColor)
  2747. };
  2748. var lane = renderer('bpmn:Lane')(parentGfx, element, attrs);
  2749. var expandedPool = isExpanded(element);
  2750. if (expandedPool) {
  2751. drawLine(parentGfx, [
  2752. {x: 30, y: 0},
  2753. {x: 30, y: element.height}
  2754. ], {
  2755. stroke: getStrokeColor(element, defaultStrokeColor)
  2756. });
  2757. var text = getSemantic(element).name;
  2758. renderLaneLabel(parentGfx, text, element);
  2759. } else {
  2760. // Collapsed pool draw text inline
  2761. var text2 = getSemantic(element).name;
  2762. renderLabel(parentGfx, text2, {
  2763. box: element, align: 'center-middle',
  2764. style: {
  2765. fill: getStrokeColor(element, defaultStrokeColor)
  2766. }
  2767. });
  2768. }
  2769. var participantMultiplicity = !!(getSemantic(element).participantMultiplicity);
  2770. if (participantMultiplicity) {
  2771. renderer('ParticipantMultiplicityMarker')(parentGfx, element);
  2772. }
  2773. return lane;
  2774. },
  2775. 'bpmn:Lane': function (parentGfx, element, attrs) {
  2776. var rect = drawRect(parentGfx, element.width, element.height, 0, assign({
  2777. fill: getFillColor(element, defaultFillColor),
  2778. fillOpacity: HIGH_FILL_OPACITY,
  2779. stroke: getStrokeColor(element, defaultStrokeColor)
  2780. }, attrs));
  2781. var semantic = getSemantic(element);
  2782. if (semantic.$type === 'bpmn:Lane') {
  2783. var text = semantic.name;
  2784. renderLaneLabel(parentGfx, text, element);
  2785. }
  2786. return rect;
  2787. },
  2788. 'bpmn:InclusiveGateway': function (parentGfx, element) {
  2789. var diamond = renderer('bpmn:Gateway')(parentGfx, element);
  2790. /* circle path */
  2791. drawCircle(parentGfx, element.width, element.height, element.height * 0.24, {
  2792. strokeWidth: 2.5,
  2793. fill: getFillColor(element, defaultFillColor),
  2794. stroke: getStrokeColor(element, defaultStrokeColor)
  2795. });
  2796. return diamond;
  2797. },
  2798. 'bpmn:ExclusiveGateway': function (parentGfx, element) {
  2799. var diamond = renderer('bpmn:Gateway')(parentGfx, element);
  2800. var pathData = pathMap.getScaledPath('GATEWAY_EXCLUSIVE', {
  2801. xScaleFactor: 0.4,
  2802. yScaleFactor: 0.4,
  2803. containerWidth: element.width,
  2804. containerHeight: element.height,
  2805. position: {
  2806. mx: 0.32,
  2807. my: 0.3
  2808. }
  2809. });
  2810. if ((getDi(element).isMarkerVisible)) {
  2811. drawPath(parentGfx, pathData, {
  2812. strokeWidth: 1,
  2813. fill: getStrokeColor(element, defaultStrokeColor),
  2814. stroke: getStrokeColor(element, defaultStrokeColor)
  2815. });
  2816. }
  2817. return diamond;
  2818. },
  2819. 'bpmn:ComplexGateway': function (parentGfx, element) {
  2820. var diamond = renderer('bpmn:Gateway')(parentGfx, element);
  2821. var pathData = pathMap.getScaledPath('GATEWAY_COMPLEX', {
  2822. xScaleFactor: 0.5,
  2823. yScaleFactor: 0.5,
  2824. containerWidth: element.width,
  2825. containerHeight: element.height,
  2826. position: {
  2827. mx: 0.46,
  2828. my: 0.26
  2829. }
  2830. });
  2831. /* complex path */
  2832. drawPath(parentGfx, pathData, {
  2833. strokeWidth: 1,
  2834. fill: getStrokeColor(element, defaultStrokeColor),
  2835. stroke: getStrokeColor(element, defaultStrokeColor)
  2836. });
  2837. return diamond;
  2838. },
  2839. 'bpmn:ParallelGateway': function (parentGfx, element) {
  2840. var diamond = renderer('bpmn:Gateway')(parentGfx, element);
  2841. var pathData = pathMap.getScaledPath('GATEWAY_PARALLEL', {
  2842. xScaleFactor: 0.6,
  2843. yScaleFactor: 0.6,
  2844. containerWidth: element.width,
  2845. containerHeight: element.height,
  2846. position: {
  2847. mx: 0.46,
  2848. my: 0.2
  2849. }
  2850. });
  2851. /* parallel path */
  2852. drawPath(parentGfx, pathData, {
  2853. strokeWidth: 1,
  2854. fill: getStrokeColor(element, defaultStrokeColor),
  2855. stroke: getStrokeColor(element, defaultStrokeColor)
  2856. });
  2857. return diamond;
  2858. },
  2859. 'bpmn:EventBasedGateway': function (parentGfx, element) {
  2860. var semantic = getSemantic(element);
  2861. var diamond = renderer('bpmn:Gateway')(parentGfx, element);
  2862. /* outer circle path */
  2863. drawCircle(parentGfx, element.width, element.height, element.height * 0.20, {
  2864. strokeWidth: 1,
  2865. fill: 'none',
  2866. stroke: getStrokeColor(element, defaultStrokeColor)
  2867. });
  2868. var type = semantic.eventGatewayType;
  2869. var instantiate = !!semantic.instantiate;
  2870. function drawEvent() {
  2871. var pathData = pathMap.getScaledPath('GATEWAY_EVENT_BASED', {
  2872. xScaleFactor: 0.18,
  2873. yScaleFactor: 0.18,
  2874. containerWidth: element.width,
  2875. containerHeight: element.height,
  2876. position: {
  2877. mx: 0.36,
  2878. my: 0.44
  2879. }
  2880. });
  2881. var attrs = {
  2882. strokeWidth: 2,
  2883. fill: getFillColor(element, 'none'),
  2884. stroke: getStrokeColor(element, defaultStrokeColor)
  2885. };
  2886. /* event path */
  2887. drawPath(parentGfx, pathData, attrs);
  2888. }
  2889. if (type === 'Parallel') {
  2890. var pathData = pathMap.getScaledPath('GATEWAY_PARALLEL', {
  2891. xScaleFactor: 0.4,
  2892. yScaleFactor: 0.4,
  2893. containerWidth: element.width,
  2894. containerHeight: element.height,
  2895. position: {
  2896. mx: 0.474,
  2897. my: 0.296
  2898. }
  2899. });
  2900. var parallelPath = drawPath(parentGfx, pathData);
  2901. attr(parallelPath, {
  2902. strokeWidth: 1,
  2903. fill: 'none'
  2904. });
  2905. } else if (type === 'Exclusive') {
  2906. if (!instantiate) {
  2907. var innerCircle = drawCircle(parentGfx, element.width, element.height, element.height * 0.26);
  2908. attr(innerCircle, {
  2909. strokeWidth: 1,
  2910. fill: 'none',
  2911. stroke: getStrokeColor(element, defaultStrokeColor)
  2912. });
  2913. }
  2914. drawEvent();
  2915. }
  2916. return diamond;
  2917. },
  2918. 'bpmn:Gateway': function (parentGfx, element) {
  2919. var attrs = {
  2920. fill: getFillColor(element, defaultFillColor),
  2921. fillOpacity: DEFAULT_FILL_OPACITY,
  2922. stroke: getStrokeColor(element, defaultStrokeColor)
  2923. };
  2924. return drawDiamond(parentGfx, element.width, element.height, attrs);
  2925. },
  2926. 'bpmn:SequenceFlow': function (parentGfx, element) {
  2927. var pathData = createPathFromConnection(element);
  2928. var fill = getFillColor(element, defaultFillColor),
  2929. stroke = getStrokeColor(element, defaultStrokeColor);
  2930. var attrs = {
  2931. strokeLinejoin: 'round',
  2932. markerEnd: marker('sequenceflow-end', fill, stroke),
  2933. stroke: getStrokeColor(element, defaultStrokeColor)
  2934. };
  2935. var path = drawPath(parentGfx, pathData, attrs);
  2936. var sequenceFlow = getSemantic(element);
  2937. var source;
  2938. if (element.source) {
  2939. source = element.source.businessObject;
  2940. // conditional flow marker
  2941. if (sequenceFlow.conditionExpression && source.$instanceOf('bpmn:Activity')) {
  2942. attr(path, {
  2943. markerStart: marker('conditional-flow-marker', fill, stroke)
  2944. });
  2945. }
  2946. // default marker
  2947. if (source.default && (source.$instanceOf('bpmn:Gateway') || source.$instanceOf('bpmn:Activity')) &&
  2948. source.default === sequenceFlow) {
  2949. attr(path, {
  2950. markerStart: marker('conditional-default-flow-marker', fill, stroke)
  2951. });
  2952. }
  2953. }
  2954. return path;
  2955. },
  2956. 'bpmn:Association': function (parentGfx, element, attrs) {
  2957. var semantic = getSemantic(element);
  2958. var fill = getFillColor(element, defaultFillColor),
  2959. stroke = getStrokeColor(element, defaultStrokeColor);
  2960. attrs = assign({
  2961. strokeDasharray: '0.5, 5',
  2962. strokeLinecap: 'round',
  2963. strokeLinejoin: 'round',
  2964. stroke: getStrokeColor(element, defaultStrokeColor)
  2965. }, attrs || {});
  2966. if (semantic.associationDirection === 'One' ||
  2967. semantic.associationDirection === 'Both') {
  2968. attrs.markerEnd = marker('association-end', fill, stroke);
  2969. }
  2970. if (semantic.associationDirection === 'Both') {
  2971. attrs.markerStart = marker('association-start', fill, stroke);
  2972. }
  2973. return drawLine(parentGfx, element.waypoints, attrs);
  2974. },
  2975. 'bpmn:DataInputAssociation': function (parentGfx, element) {
  2976. var fill = getFillColor(element, defaultFillColor),
  2977. stroke = getStrokeColor(element, defaultStrokeColor);
  2978. return renderer('bpmn:Association')(parentGfx, element, {
  2979. markerEnd: marker('association-end', fill, stroke)
  2980. });
  2981. },
  2982. 'bpmn:DataOutputAssociation': function (parentGfx, element) {
  2983. var fill = getFillColor(element, defaultFillColor),
  2984. stroke = getStrokeColor(element, defaultStrokeColor);
  2985. return renderer('bpmn:Association')(parentGfx, element, {
  2986. markerEnd: marker('association-end', fill, stroke)
  2987. });
  2988. },
  2989. 'bpmn:MessageFlow': function (parentGfx, element) {
  2990. var semantic = getSemantic(element),
  2991. di = getDi(element);
  2992. var fill = getFillColor(element, defaultFillColor),
  2993. stroke = getStrokeColor(element, defaultStrokeColor);
  2994. var pathData = createPathFromConnection(element);
  2995. var attrs = {
  2996. markerEnd: marker('messageflow-end', fill, stroke),
  2997. markerStart: marker('messageflow-start', fill, stroke),
  2998. strokeDasharray: '10, 12',
  2999. strokeLinecap: 'round',
  3000. strokeLinejoin: 'round',
  3001. strokeWidth: '1.5px',
  3002. stroke: getStrokeColor(element, defaultStrokeColor)
  3003. };
  3004. var path = drawPath(parentGfx, pathData, attrs);
  3005. if (semantic.messageRef) {
  3006. var midPoint = path.getPointAtLength(path.getTotalLength() / 2);
  3007. var markerPathData = pathMap.getScaledPath('MESSAGE_FLOW_MARKER', {
  3008. abspos: {
  3009. x: midPoint.x,
  3010. y: midPoint.y
  3011. }
  3012. });
  3013. var messageAttrs = {strokeWidth: 1};
  3014. if (di.messageVisibleKind === 'initiating') {
  3015. messageAttrs.fill = 'white';
  3016. messageAttrs.stroke = 'black';
  3017. } else {
  3018. messageAttrs.fill = '#888';
  3019. messageAttrs.stroke = 'white';
  3020. }
  3021. drawPath(parentGfx, markerPathData, messageAttrs);
  3022. }
  3023. return path;
  3024. },
  3025. 'bpmn:DataObject': function (parentGfx, element) {
  3026. var pathData = pathMap.getScaledPath('DATA_OBJECT_PATH', {
  3027. xScaleFactor: 1,
  3028. yScaleFactor: 1,
  3029. containerWidth: element.width,
  3030. containerHeight: element.height,
  3031. position: {
  3032. mx: 0.474,
  3033. my: 0.296
  3034. }
  3035. });
  3036. var elementObject = drawPath(parentGfx, pathData, {
  3037. fill: getFillColor(element, defaultFillColor),
  3038. fillOpacity: DEFAULT_FILL_OPACITY,
  3039. stroke: getStrokeColor(element, defaultStrokeColor)
  3040. });
  3041. var semantic = getSemantic(element);
  3042. if (isCollection(semantic)) {
  3043. renderDataItemCollection(parentGfx, element);
  3044. }
  3045. return elementObject;
  3046. },
  3047. 'bpmn:DataObjectReference': as('bpmn:DataObject'),
  3048. 'bpmn:DataInput': function (parentGfx, element) {
  3049. var arrowPathData = pathMap.getRawPath('DATA_ARROW');
  3050. // page
  3051. var elementObject = renderer('bpmn:DataObject')(parentGfx, element);
  3052. /* input arrow path */
  3053. drawPath(parentGfx, arrowPathData, {strokeWidth: 1});
  3054. return elementObject;
  3055. },
  3056. 'bpmn:DataOutput': function (parentGfx, element) {
  3057. var arrowPathData = pathMap.getRawPath('DATA_ARROW');
  3058. // page
  3059. var elementObject = renderer('bpmn:DataObject')(parentGfx, element);
  3060. /* output arrow path */
  3061. drawPath(parentGfx, arrowPathData, {
  3062. strokeWidth: 1,
  3063. fill: 'black'
  3064. });
  3065. return elementObject;
  3066. },
  3067. 'bpmn:DataStoreReference': function (parentGfx, element) {
  3068. var DATA_STORE_PATH = pathMap.getScaledPath('DATA_STORE', {
  3069. xScaleFactor: 1,
  3070. yScaleFactor: 1,
  3071. containerWidth: element.width,
  3072. containerHeight: element.height,
  3073. position: {
  3074. mx: 0,
  3075. my: 0.133
  3076. }
  3077. });
  3078. var elementStore = drawPath(parentGfx, DATA_STORE_PATH, {
  3079. strokeWidth: 2,
  3080. fill: getFillColor(element, defaultFillColor),
  3081. fillOpacity: DEFAULT_FILL_OPACITY,
  3082. stroke: getStrokeColor(element, defaultStrokeColor)
  3083. });
  3084. return elementStore;
  3085. },
  3086. 'bpmn:BoundaryEvent': function (parentGfx, element) {
  3087. var semantic = getSemantic(element),
  3088. cancel = semantic.cancelActivity;
  3089. var attrs = {
  3090. strokeWidth: 1,
  3091. fill: getFillColor(element, defaultFillColor),
  3092. stroke: getStrokeColor(element, defaultStrokeColor)
  3093. };
  3094. if (!cancel) {
  3095. attrs.strokeDasharray = '6';
  3096. attrs.strokeLinecap = 'round';
  3097. }
  3098. // apply fillOpacity
  3099. var outerAttrs = assign({}, attrs, {
  3100. fillOpacity: 1
  3101. });
  3102. // apply no-fill
  3103. var innerAttrs = assign({}, attrs, {
  3104. fill: 'none'
  3105. });
  3106. var outer = renderer('bpmn:Event')(parentGfx, element, outerAttrs);
  3107. /* inner path */
  3108. drawCircle(parentGfx, element.width, element.height, INNER_OUTER_DIST, innerAttrs);
  3109. renderEventContent(element, parentGfx);
  3110. return outer;
  3111. },
  3112. 'bpmn:Group': function (parentGfx, element) {
  3113. var group = drawRect(parentGfx, element.width, element.height, TASK_BORDER_RADIUS, {
  3114. stroke: getStrokeColor(element, defaultStrokeColor),
  3115. strokeWidth: 1,
  3116. strokeDasharray: '8,3,1,3',
  3117. fill: 'none',
  3118. pointerEvents: 'none'
  3119. });
  3120. return group;
  3121. },
  3122. 'label': function (parentGfx, element) {
  3123. return renderExternalLabel(parentGfx, element);
  3124. },
  3125. 'bpmn:TextAnnotation': function (parentGfx, element) {
  3126. var style = {
  3127. 'fill': 'none',
  3128. 'stroke': 'none'
  3129. };
  3130. var textElement = drawRect(parentGfx, element.width, element.height, 0, 0, style);
  3131. var textPathData = pathMap.getScaledPath('TEXT_ANNOTATION', {
  3132. xScaleFactor: 1,
  3133. yScaleFactor: 1,
  3134. containerWidth: element.width,
  3135. containerHeight: element.height,
  3136. position: {
  3137. mx: 0.0,
  3138. my: 0.0
  3139. }
  3140. });
  3141. drawPath(parentGfx, textPathData, {
  3142. stroke: getStrokeColor(element, defaultStrokeColor)
  3143. });
  3144. var text = getSemantic(element).text || '';
  3145. renderLabel(parentGfx, text, {
  3146. box: element,
  3147. align: 'left-top',
  3148. padding: 5,
  3149. style: {
  3150. fill: getStrokeColor(element, defaultStrokeColor)
  3151. }
  3152. });
  3153. return textElement;
  3154. },
  3155. 'ParticipantMultiplicityMarker': function (parentGfx, element) {
  3156. var markerPath = pathMap.getScaledPath('MARKER_PARALLEL', {
  3157. xScaleFactor: 1,
  3158. yScaleFactor: 1,
  3159. containerWidth: element.width,
  3160. containerHeight: element.height,
  3161. position: {
  3162. mx: ((element.width / 2) / element.width),
  3163. my: (element.height - 15) / element.height
  3164. }
  3165. });
  3166. drawMarker('participant-multiplicity', parentGfx, markerPath, {
  3167. strokeWidth: 1,
  3168. fill: getFillColor(element, defaultFillColor),
  3169. stroke: getStrokeColor(element, defaultStrokeColor)
  3170. });
  3171. },
  3172. 'SubProcessMarker': function (parentGfx, element) {
  3173. var markerRect = drawRect(parentGfx, 14, 14, 0, {
  3174. strokeWidth: 1,
  3175. fill: getFillColor(element, defaultFillColor),
  3176. stroke: getStrokeColor(element, defaultStrokeColor)
  3177. });
  3178. // Process marker is placed in the middle of the box
  3179. // therefore fixed values can be used here
  3180. translate(markerRect, element.width / 2 - 7.5, element.height - 20);
  3181. var markerPath = pathMap.getScaledPath('MARKER_SUB_PROCESS', {
  3182. xScaleFactor: 1.5,
  3183. yScaleFactor: 1.5,
  3184. containerWidth: element.width,
  3185. containerHeight: element.height,
  3186. position: {
  3187. mx: (element.width / 2 - 7.5) / element.width,
  3188. my: (element.height - 20) / element.height
  3189. }
  3190. });
  3191. drawMarker('sub-process', parentGfx, markerPath, {
  3192. fill: getFillColor(element, defaultFillColor),
  3193. stroke: getStrokeColor(element, defaultStrokeColor)
  3194. });
  3195. },
  3196. 'ParallelMarker': function (parentGfx, element, position) {
  3197. var markerPath = pathMap.getScaledPath('MARKER_PARALLEL', {
  3198. xScaleFactor: 1,
  3199. yScaleFactor: 1,
  3200. containerWidth: element.width,
  3201. containerHeight: element.height,
  3202. position: {
  3203. mx: ((element.width / 2 + position.parallel) / element.width),
  3204. my: (element.height - 20) / element.height
  3205. }
  3206. });
  3207. drawMarker('parallel', parentGfx, markerPath, {
  3208. fill: getFillColor(element, defaultFillColor),
  3209. stroke: getStrokeColor(element, defaultStrokeColor)
  3210. });
  3211. },
  3212. 'SequentialMarker': function (parentGfx, element, position) {
  3213. var markerPath = pathMap.getScaledPath('MARKER_SEQUENTIAL', {
  3214. xScaleFactor: 1,
  3215. yScaleFactor: 1,
  3216. containerWidth: element.width,
  3217. containerHeight: element.height,
  3218. position: {
  3219. mx: ((element.width / 2 + position.seq) / element.width),
  3220. my: (element.height - 19) / element.height
  3221. }
  3222. });
  3223. drawMarker('sequential', parentGfx, markerPath, {
  3224. fill: getFillColor(element, defaultFillColor),
  3225. stroke: getStrokeColor(element, defaultStrokeColor)
  3226. });
  3227. },
  3228. 'CompensationMarker': function (parentGfx, element, position) {
  3229. var markerMath = pathMap.getScaledPath('MARKER_COMPENSATION', {
  3230. xScaleFactor: 1,
  3231. yScaleFactor: 1,
  3232. containerWidth: element.width,
  3233. containerHeight: element.height,
  3234. position: {
  3235. mx: ((element.width / 2 + position.compensation) / element.width),
  3236. my: (element.height - 13) / element.height
  3237. }
  3238. });
  3239. drawMarker('compensation', parentGfx, markerMath, {
  3240. strokeWidth: 1,
  3241. fill: getFillColor(element, defaultFillColor),
  3242. stroke: getStrokeColor(element, defaultStrokeColor)
  3243. });
  3244. },
  3245. 'LoopMarker': function (parentGfx, element, position) {
  3246. var markerPath = pathMap.getScaledPath('MARKER_LOOP', {
  3247. xScaleFactor: 1,
  3248. yScaleFactor: 1,
  3249. containerWidth: element.width,
  3250. containerHeight: element.height,
  3251. position: {
  3252. mx: ((element.width / 2 + position.loop) / element.width),
  3253. my: (element.height - 7) / element.height
  3254. }
  3255. });
  3256. drawMarker('loop', parentGfx, markerPath, {
  3257. strokeWidth: 1,
  3258. fill: getFillColor(element, defaultFillColor),
  3259. stroke: getStrokeColor(element, defaultStrokeColor),
  3260. strokeLinecap: 'round',
  3261. strokeMiterlimit: 0.5
  3262. });
  3263. },
  3264. 'AdhocMarker': function (parentGfx, element, position) {
  3265. var markerPath = pathMap.getScaledPath('MARKER_ADHOC', {
  3266. xScaleFactor: 1,
  3267. yScaleFactor: 1,
  3268. containerWidth: element.width,
  3269. containerHeight: element.height,
  3270. position: {
  3271. mx: ((element.width / 2 + position.adhoc) / element.width),
  3272. my: (element.height - 15) / element.height
  3273. }
  3274. });
  3275. drawMarker('adhoc', parentGfx, markerPath, {
  3276. strokeWidth: 1,
  3277. fill: getStrokeColor(element, defaultStrokeColor),
  3278. stroke: getStrokeColor(element, defaultStrokeColor)
  3279. });
  3280. }
  3281. };
  3282. function attachTaskMarkers(parentGfx, element, taskMarkers) {
  3283. var obj = getSemantic(element);
  3284. var subprocess = taskMarkers && taskMarkers.indexOf('SubProcessMarker') !== -1;
  3285. var position;
  3286. if (subprocess) {
  3287. position = {
  3288. seq: -21,
  3289. parallel: -22,
  3290. compensation: -42,
  3291. loop: -18,
  3292. adhoc: 10
  3293. };
  3294. } else {
  3295. position = {
  3296. seq: -3,
  3297. parallel: -6,
  3298. compensation: -27,
  3299. loop: 0,
  3300. adhoc: 10
  3301. };
  3302. }
  3303. forEach(taskMarkers, function (marker) {
  3304. renderer(marker)(parentGfx, element, position);
  3305. });
  3306. if (obj.isForCompensation) {
  3307. renderer('CompensationMarker')(parentGfx, element, position);
  3308. }
  3309. if (obj.$type === 'bpmn:AdHocSubProcess') {
  3310. renderer('AdhocMarker')(parentGfx, element, position);
  3311. }
  3312. var loopCharacteristics = obj.loopCharacteristics,
  3313. isSequential = loopCharacteristics && loopCharacteristics.isSequential;
  3314. if (loopCharacteristics) {
  3315. if (isSequential === undefined) {
  3316. renderer('LoopMarker')(parentGfx, element, position);
  3317. }
  3318. if (isSequential === false) {
  3319. renderer('ParallelMarker')(parentGfx, element, position);
  3320. }
  3321. if (isSequential === true) {
  3322. renderer('SequentialMarker')(parentGfx, element, position);
  3323. }
  3324. }
  3325. }
  3326. function renderDataItemCollection(parentGfx, element) {
  3327. var yPosition = (element.height - 16) / element.height;
  3328. var pathData = pathMap.getScaledPath('DATA_OBJECT_COLLECTION_PATH', {
  3329. xScaleFactor: 1,
  3330. yScaleFactor: 1,
  3331. containerWidth: element.width,
  3332. containerHeight: element.height,
  3333. position: {
  3334. mx: 0.451,
  3335. my: yPosition
  3336. }
  3337. });
  3338. /* collection path */
  3339. drawPath(parentGfx, pathData, {
  3340. strokeWidth: 2
  3341. });
  3342. }
  3343. // extension API, use at your own risk
  3344. this._drawPath = drawPath;
  3345. }
  3346. inherits_browser(BpmnRenderer, BaseRenderer);
  3347. BpmnRenderer.$inject = [
  3348. 'config.bpmnRenderer',
  3349. 'eventBus',
  3350. 'styles',
  3351. 'pathMap',
  3352. 'canvas',
  3353. 'textRenderer'
  3354. ];
  3355. BpmnRenderer.prototype.canRender = function (element) {
  3356. return is(element, 'bpmn:BaseElement');
  3357. };
  3358. BpmnRenderer.prototype.drawShape = function (parentGfx, element) {
  3359. var type = element.type;
  3360. var h = this.handlers[type];
  3361. /* jshint -W040 */
  3362. return h(parentGfx, element);
  3363. };
  3364. BpmnRenderer.prototype.drawConnection = function (parentGfx, element) {
  3365. var type = element.type;
  3366. var h = this.handlers[type];
  3367. /* jshint -W040 */
  3368. return h(parentGfx, element);
  3369. };
  3370. BpmnRenderer.prototype.getShapePath = function (element) {
  3371. if (is(element, 'bpmn:Event')) {
  3372. return getCirclePath(element);
  3373. }
  3374. if (is(element, 'bpmn:Activity')) {
  3375. return getRoundRectPath(element, TASK_BORDER_RADIUS);
  3376. }
  3377. if (is(element, 'bpmn:Gateway')) {
  3378. return getDiamondPath(element);
  3379. }
  3380. return getRectPath(element);
  3381. };
  3382. var DEFAULT_BOX_PADDING = 0;
  3383. var DEFAULT_LABEL_SIZE = {
  3384. width: 150,
  3385. height: 50
  3386. };
  3387. function parseAlign(align) {
  3388. var parts = align.split('-');
  3389. return {
  3390. horizontal: parts[0] || 'center',
  3391. vertical: parts[1] || 'top'
  3392. };
  3393. }
  3394. function parsePadding(padding) {
  3395. if (isObject(padding)) {
  3396. return assign({top: 0, left: 0, right: 0, bottom: 0}, padding);
  3397. } else {
  3398. return {
  3399. top: padding,
  3400. left: padding,
  3401. right: padding,
  3402. bottom: padding
  3403. };
  3404. }
  3405. }
  3406. function getTextBBox(text, fakeText) {
  3407. fakeText.textContent = text;
  3408. var textBBox;
  3409. try {
  3410. var bbox,
  3411. emptyLine = text === '';
  3412. // add dummy text, when line is empty to
  3413. // determine correct height
  3414. fakeText.textContent = emptyLine ? 'dummy' : text;
  3415. textBBox = fakeText.getBBox();
  3416. // take text rendering related horizontal
  3417. // padding into account
  3418. bbox = {
  3419. width: textBBox.width + textBBox.x * 2,
  3420. height: textBBox.height
  3421. };
  3422. if (emptyLine) {
  3423. // correct width
  3424. bbox.width = 0;
  3425. }
  3426. return bbox;
  3427. } catch (e) {
  3428. return {width: 0, height: 0};
  3429. }
  3430. }
  3431. /**
  3432. * Layout the next line and return the layouted element.
  3433. *
  3434. * Alters the lines passed.
  3435. *
  3436. * @param {Array<string>} lines
  3437. * @return {Object} the line descriptor, an object { width, height, text }
  3438. */
  3439. function layoutNext(lines, maxWidth, fakeText) {
  3440. var originalLine = lines.shift(),
  3441. fitLine = originalLine;
  3442. var textBBox;
  3443. for (; ;) {
  3444. textBBox = getTextBBox(fitLine, fakeText);
  3445. textBBox.width = fitLine ? textBBox.width : 0;
  3446. // try to fit
  3447. if (fitLine === ' ' || fitLine === '' || textBBox.width < Math.round(maxWidth) || fitLine.length < 2) {
  3448. return fit(lines, fitLine, originalLine, textBBox);
  3449. }
  3450. fitLine = shortenLine(fitLine, textBBox.width, maxWidth);
  3451. }
  3452. }
  3453. function fit(lines, fitLine, originalLine, textBBox) {
  3454. if (fitLine.length < originalLine.length) {
  3455. var remainder = originalLine.slice(fitLine.length).trim();
  3456. lines.unshift(remainder);
  3457. }
  3458. return {
  3459. width: textBBox.width,
  3460. height: textBBox.height,
  3461. text: fitLine
  3462. };
  3463. }
  3464. /**
  3465. * Shortens a line based on spacing and hyphens.
  3466. * Returns the shortened result on success.
  3467. *
  3468. * @param {string} line
  3469. * @param {number} maxLength the maximum characters of the string
  3470. * @return {string} the shortened string
  3471. */
  3472. function semanticShorten(line, maxLength) {
  3473. var parts = line.split(/(\s|-)/g),
  3474. part,
  3475. shortenedParts = [],
  3476. length = 0;
  3477. // try to shorten via spaces + hyphens
  3478. if (parts.length > 1) {
  3479. while ((part = parts.shift())) {
  3480. if (part.length + length < maxLength) {
  3481. shortenedParts.push(part);
  3482. length += part.length;
  3483. } else {
  3484. // remove previous part, too if hyphen does not fit anymore
  3485. if (part === '-') {
  3486. shortenedParts.pop();
  3487. }
  3488. break;
  3489. }
  3490. }
  3491. }
  3492. return shortenedParts.join('');
  3493. }
  3494. function shortenLine(line, width, maxWidth) {
  3495. var length = Math.max(line.length * (maxWidth / width), 1);
  3496. // try to shorten semantically (i.e. based on spaces and hyphens)
  3497. var shortenedLine = semanticShorten(line, length);
  3498. if (!shortenedLine) {
  3499. // force shorten by cutting the long word
  3500. shortenedLine = line.slice(0, Math.max(Math.round(length - 1), 1));
  3501. }
  3502. return shortenedLine;
  3503. }
  3504. function getHelperSvg() {
  3505. var helperSvg = document.getElementById('helper-svg');
  3506. if (!helperSvg) {
  3507. helperSvg = create('svg');
  3508. attr(helperSvg, {
  3509. id: 'helper-svg',
  3510. width: 0,
  3511. height: 0,
  3512. style: 'visibility: hidden; position: fixed'
  3513. });
  3514. document.body.appendChild(helperSvg);
  3515. }
  3516. return helperSvg;
  3517. }
  3518. /**
  3519. * Creates a new label utility
  3520. *
  3521. * @param {Object} config
  3522. * @param {Dimensions} config.size
  3523. * @param {number} config.padding
  3524. * @param {Object} config.style
  3525. * @param {string} config.align
  3526. */
  3527. function Text(config) {
  3528. this._config = assign({}, {
  3529. size: DEFAULT_LABEL_SIZE,
  3530. padding: DEFAULT_BOX_PADDING,
  3531. style: {},
  3532. align: 'center-top'
  3533. }, config || {});
  3534. }
  3535. /**
  3536. * Returns the layouted text as an SVG element.
  3537. *
  3538. * @param {string} text
  3539. * @param {Object} options
  3540. *
  3541. * @return {SVGElement}
  3542. */
  3543. Text.prototype.createText = function (text, options) {
  3544. return this.layoutText(text, options).element;
  3545. };
  3546. /**
  3547. * Returns a labels layouted dimensions.
  3548. *
  3549. * @param {string} text to layout
  3550. * @param {Object} options
  3551. *
  3552. * @return {Dimensions}
  3553. */
  3554. Text.prototype.getDimensions = function (text, options) {
  3555. return this.layoutText(text, options).dimensions;
  3556. };
  3557. /**
  3558. * Creates and returns a label and its bounding box.
  3559. *
  3560. * @method Text#createText
  3561. *
  3562. * @param {string} text the text to render on the label
  3563. * @param {Object} options
  3564. * @param {string} options.align how to align in the bounding box.
  3565. * Any of { 'center-middle', 'center-top' },
  3566. * defaults to 'center-top'.
  3567. * @param {string} options.style style to be applied to the text
  3568. * @param {boolean} options.fitBox indicates if box will be recalculated to
  3569. * fit text
  3570. *
  3571. * @return {Object} { element, dimensions }
  3572. */
  3573. Text.prototype.layoutText = function (text, options) {
  3574. var box = assign({}, this._config.size, options.box),
  3575. style = assign({}, this._config.style, options.style),
  3576. align = parseAlign(options.align || this._config.align),
  3577. padding = parsePadding(options.padding !== undefined ? options.padding : this._config.padding),
  3578. fitBox = options.fitBox || false;
  3579. var lineHeight = getLineHeight(style);
  3580. var lines = text.split(/\r?\n/g),
  3581. layouted = [];
  3582. var maxWidth = box.width - padding.left - padding.right;
  3583. // ensure correct rendering by attaching helper text node to invisible SVG
  3584. var helperText = create('text');
  3585. attr(helperText, {x: 0, y: 0});
  3586. attr(helperText, style);
  3587. var helperSvg = getHelperSvg();
  3588. append(helperSvg, helperText);
  3589. while (lines.length) {
  3590. layouted.push(layoutNext(lines, maxWidth, helperText));
  3591. }
  3592. if (align.vertical === 'middle') {
  3593. padding.top = padding.bottom = 0;
  3594. }
  3595. var totalHeight = reduce(layouted, function (sum, line, idx) {
  3596. return sum + (lineHeight || line.height);
  3597. }, 0) + padding.top + padding.bottom;
  3598. var maxLineWidth = reduce(layouted, function (sum, line, idx) {
  3599. return line.width > sum ? line.width : sum;
  3600. }, 0);
  3601. // the y position of the next line
  3602. var y = padding.top;
  3603. if (align.vertical === 'middle') {
  3604. y += (box.height - totalHeight) / 2;
  3605. }
  3606. // magic number initial offset
  3607. y -= (lineHeight || layouted[0].height) / 4;
  3608. var textElement = create('text');
  3609. attr(textElement, style);
  3610. // layout each line taking into account that parent
  3611. // shape might resize to fit text size
  3612. forEach(layouted, function (line) {
  3613. var x;
  3614. y += (lineHeight || line.height);
  3615. switch (align.horizontal) {
  3616. case 'left':
  3617. x = padding.left;
  3618. break;
  3619. case 'right':
  3620. x = ((fitBox ? maxLineWidth : maxWidth)
  3621. - padding.right - line.width);
  3622. break;
  3623. default:
  3624. // aka center
  3625. x = Math.max((((fitBox ? maxLineWidth : maxWidth)
  3626. - line.width) / 2 + padding.left), 0);
  3627. }
  3628. var tspan = create('tspan');
  3629. attr(tspan, {x: x, y: y});
  3630. tspan.textContent = line.text;
  3631. append(textElement, tspan);
  3632. });
  3633. remove(helperText);
  3634. var dimensions = {
  3635. width: maxLineWidth,
  3636. height: totalHeight
  3637. };
  3638. return {
  3639. dimensions: dimensions,
  3640. element: textElement
  3641. };
  3642. };
  3643. function getLineHeight(style) {
  3644. if ('fontSize' in style && 'lineHeight' in style) {
  3645. return style.lineHeight * parseInt(style.fontSize, 10);
  3646. }
  3647. }
  3648. var DEFAULT_FONT_SIZE = 12;
  3649. var LINE_HEIGHT_RATIO = 1.2;
  3650. var MIN_TEXT_ANNOTATION_HEIGHT = 30;
  3651. function TextRenderer(config) {
  3652. var defaultStyle = assign({
  3653. fontFamily: 'Arial, sans-serif',
  3654. fontSize: DEFAULT_FONT_SIZE,
  3655. fontWeight: 'normal',
  3656. lineHeight: LINE_HEIGHT_RATIO
  3657. }, config && config.defaultStyle || {});
  3658. var fontSize = parseInt(defaultStyle.fontSize, 10) - 1;
  3659. var externalStyle = assign({}, defaultStyle, {
  3660. fontSize: fontSize
  3661. }, config && config.externalStyle || {});
  3662. var textUtil = new Text({
  3663. style: defaultStyle
  3664. });
  3665. /**
  3666. * Get the new bounds of an externally rendered,
  3667. * layouted label.
  3668. *
  3669. * @param {Bounds} bounds
  3670. * @param {string} text
  3671. *
  3672. * @return {Bounds}
  3673. */
  3674. this.getExternalLabelBounds = function (bounds, text) {
  3675. var layoutedDimensions = textUtil.getDimensions(text, {
  3676. box: {
  3677. width: 90,
  3678. height: 30,
  3679. x: bounds.width / 2 + bounds.x,
  3680. y: bounds.height / 2 + bounds.y
  3681. },
  3682. style: externalStyle
  3683. });
  3684. // resize label shape to fit label text
  3685. return {
  3686. x: Math.round(bounds.x + bounds.width / 2 - layoutedDimensions.width / 2),
  3687. y: Math.round(bounds.y),
  3688. width: Math.ceil(layoutedDimensions.width),
  3689. height: Math.ceil(layoutedDimensions.height)
  3690. };
  3691. };
  3692. /**
  3693. * Get the new bounds of text annotation.
  3694. *
  3695. * @param {Bounds} bounds
  3696. * @param {string} text
  3697. *
  3698. * @return {Bounds}
  3699. */
  3700. this.getTextAnnotationBounds = function (bounds, text) {
  3701. var layoutedDimensions = textUtil.getDimensions(text, {
  3702. box: bounds,
  3703. style: defaultStyle,
  3704. align: 'left-top',
  3705. padding: 5
  3706. });
  3707. return {
  3708. x: bounds.x,
  3709. y: bounds.y,
  3710. width: bounds.width,
  3711. height: Math.max(MIN_TEXT_ANNOTATION_HEIGHT, Math.round(layoutedDimensions.height))
  3712. };
  3713. };
  3714. /**
  3715. * Create a layouted text element.
  3716. *
  3717. * @param {string} text
  3718. * @param {Object} [options]
  3719. *
  3720. * @return {SVGElement} rendered text
  3721. */
  3722. this.createText = function (text, options) {
  3723. return textUtil.createText(text, options || {});
  3724. };
  3725. /**
  3726. * Get default text style.
  3727. */
  3728. this.getDefaultStyle = function () {
  3729. return defaultStyle;
  3730. };
  3731. /**
  3732. * Get the external text style.
  3733. */
  3734. this.getExternalStyle = function () {
  3735. return externalStyle;
  3736. };
  3737. }
  3738. TextRenderer.$inject = [
  3739. 'config.textRenderer'
  3740. ];
  3741. /**
  3742. * Map containing SVG paths needed by BpmnRenderer.
  3743. */
  3744. function PathMap() {
  3745. /**
  3746. * Contains a map of path elements
  3747. *
  3748. * <h1>Path definition</h1>
  3749. * A parameterized path is defined like this:
  3750. * <pre>
  3751. * 'GATEWAY_PARALLEL': {
  3752. * d: 'm {mx},{my} {e.x0},0 0,{e.x1} {e.x1},0 0,{e.y0} -{e.x1},0 0,{e.y1} ' +
  3753. '-{e.x0},0 0,-{e.y1} -{e.x1},0 0,-{e.y0} {e.x1},0 z',
  3754. * height: 17.5,
  3755. * width: 17.5,
  3756. * heightElements: [2.5, 7.5],
  3757. * widthElements: [2.5, 7.5]
  3758. * }
  3759. * </pre>
  3760. * <p>It's important to specify a correct <b>height and width</b> for the path as the scaling
  3761. * is based on the ratio between the specified height and width in this object and the
  3762. * height and width that is set as scale target (Note x,y coordinates will be scaled with
  3763. * individual ratios).</p>
  3764. * <p>The '<b>heightElements</b>' and '<b>widthElements</b>' array must contain the values that will be scaled.
  3765. * The scaling is based on the computed ratios.
  3766. * Coordinates on the y axis should be in the <b>heightElement</b>'s array, they will be scaled using
  3767. * the computed ratio coefficient.
  3768. * In the parameterized path the scaled values can be accessed through the 'e' object in {} brackets.
  3769. * <ul>
  3770. * <li>The values for the y axis can be accessed in the path string using {e.y0}, {e.y1}, ....</li>
  3771. * <li>The values for the x axis can be accessed in the path string using {e.x0}, {e.x1}, ....</li>
  3772. * </ul>
  3773. * The numbers x0, x1 respectively y0, y1, ... map to the corresponding array index.
  3774. * </p>
  3775. */
  3776. this.pathMap = {
  3777. 'EVENT_MESSAGE': {
  3778. d: 'm {mx},{my} l 0,{e.y1} l {e.x1},0 l 0,-{e.y1} z l {e.x0},{e.y0} l {e.x0},-{e.y0}',
  3779. height: 36,
  3780. width: 36,
  3781. heightElements: [6, 14],
  3782. widthElements: [10.5, 21]
  3783. },
  3784. 'EVENT_SIGNAL': {
  3785. d: 'M {mx},{my} l {e.x0},{e.y0} l -{e.x1},0 Z',
  3786. height: 36,
  3787. width: 36,
  3788. heightElements: [18],
  3789. widthElements: [10, 20]
  3790. },
  3791. 'EVENT_ESCALATION': {
  3792. d: 'M {mx},{my} l {e.x0},{e.y0} l -{e.x0},-{e.y1} l -{e.x0},{e.y1} Z',
  3793. height: 36,
  3794. width: 36,
  3795. heightElements: [20, 7],
  3796. widthElements: [8]
  3797. },
  3798. 'EVENT_CONDITIONAL': {
  3799. d: 'M {e.x0},{e.y0} l {e.x1},0 l 0,{e.y2} l -{e.x1},0 Z ' +
  3800. 'M {e.x2},{e.y3} l {e.x0},0 ' +
  3801. 'M {e.x2},{e.y4} l {e.x0},0 ' +
  3802. 'M {e.x2},{e.y5} l {e.x0},0 ' +
  3803. 'M {e.x2},{e.y6} l {e.x0},0 ' +
  3804. 'M {e.x2},{e.y7} l {e.x0},0 ' +
  3805. 'M {e.x2},{e.y8} l {e.x0},0 ',
  3806. height: 36,
  3807. width: 36,
  3808. heightElements: [8.5, 14.5, 18, 11.5, 14.5, 17.5, 20.5, 23.5, 26.5],
  3809. widthElements: [10.5, 14.5, 12.5]
  3810. },
  3811. 'EVENT_LINK': {
  3812. d: 'm {mx},{my} 0,{e.y0} -{e.x1},0 0,{e.y1} {e.x1},0 0,{e.y0} {e.x0},-{e.y2} -{e.x0},-{e.y2} z',
  3813. height: 36,
  3814. width: 36,
  3815. heightElements: [4.4375, 6.75, 7.8125],
  3816. widthElements: [9.84375, 13.5]
  3817. },
  3818. 'EVENT_ERROR': {
  3819. d: 'm {mx},{my} {e.x0},-{e.y0} {e.x1},-{e.y1} {e.x2},{e.y2} {e.x3},-{e.y3} -{e.x4},{e.y4} -{e.x5},-{e.y5} z',
  3820. height: 36,
  3821. width: 36,
  3822. heightElements: [0.023, 8.737, 8.151, 16.564, 10.591, 8.714],
  3823. widthElements: [0.085, 6.672, 6.97, 4.273, 5.337, 6.636]
  3824. },
  3825. 'EVENT_CANCEL_45': {
  3826. d: 'm {mx},{my} -{e.x1},0 0,{e.x0} {e.x1},0 0,{e.y1} {e.x0},0 ' +
  3827. '0,-{e.y1} {e.x1},0 0,-{e.y0} -{e.x1},0 0,-{e.y1} -{e.x0},0 z',
  3828. height: 36,
  3829. width: 36,
  3830. heightElements: [4.75, 8.5],
  3831. widthElements: [4.75, 8.5]
  3832. },
  3833. 'EVENT_COMPENSATION': {
  3834. d: 'm {mx},{my} {e.x0},-{e.y0} 0,{e.y1} z m {e.x1},-{e.y2} {e.x2},-{e.y3} 0,{e.y1} -{e.x2},-{e.y3} z',
  3835. height: 36,
  3836. width: 36,
  3837. heightElements: [6.5, 13, 0.4, 6.1],
  3838. widthElements: [9, 9.3, 8.7]
  3839. },
  3840. 'EVENT_TIMER_WH': {
  3841. d: 'M {mx},{my} l {e.x0},-{e.y0} m -{e.x0},{e.y0} l {e.x1},{e.y1} ',
  3842. height: 36,
  3843. width: 36,
  3844. heightElements: [10, 2],
  3845. widthElements: [3, 7]
  3846. },
  3847. 'EVENT_TIMER_LINE': {
  3848. d: 'M {mx},{my} ' +
  3849. 'm {e.x0},{e.y0} l -{e.x1},{e.y1} ',
  3850. height: 36,
  3851. width: 36,
  3852. heightElements: [10, 3],
  3853. widthElements: [0, 0]
  3854. },
  3855. 'EVENT_MULTIPLE': {
  3856. d: 'm {mx},{my} {e.x1},-{e.y0} {e.x1},{e.y0} -{e.x0},{e.y1} -{e.x2},0 z',
  3857. height: 36,
  3858. width: 36,
  3859. heightElements: [6.28099, 12.56199],
  3860. widthElements: [3.1405, 9.42149, 12.56198]
  3861. },
  3862. 'EVENT_PARALLEL_MULTIPLE': {
  3863. d: 'm {mx},{my} {e.x0},0 0,{e.y1} {e.x1},0 0,{e.y0} -{e.x1},0 0,{e.y1} ' +
  3864. '-{e.x0},0 0,-{e.y1} -{e.x1},0 0,-{e.y0} {e.x1},0 z',
  3865. height: 36,
  3866. width: 36,
  3867. heightElements: [2.56228, 7.68683],
  3868. widthElements: [2.56228, 7.68683]
  3869. },
  3870. 'GATEWAY_EXCLUSIVE': {
  3871. d: 'm {mx},{my} {e.x0},{e.y0} {e.x1},{e.y0} {e.x2},0 {e.x4},{e.y2} ' +
  3872. '{e.x4},{e.y1} {e.x2},0 {e.x1},{e.y3} {e.x0},{e.y3} ' +
  3873. '{e.x3},0 {e.x5},{e.y1} {e.x5},{e.y2} {e.x3},0 z',
  3874. height: 17.5,
  3875. width: 17.5,
  3876. heightElements: [8.5, 6.5312, -6.5312, -8.5],
  3877. widthElements: [6.5, -6.5, 3, -3, 5, -5]
  3878. },
  3879. 'GATEWAY_PARALLEL': {
  3880. d: 'm {mx},{my} 0,{e.y1} -{e.x1},0 0,{e.y0} {e.x1},0 0,{e.y1} {e.x0},0 ' +
  3881. '0,-{e.y1} {e.x1},0 0,-{e.y0} -{e.x1},0 0,-{e.y1} -{e.x0},0 z',
  3882. height: 30,
  3883. width: 30,
  3884. heightElements: [5, 12.5],
  3885. widthElements: [5, 12.5]
  3886. },
  3887. 'GATEWAY_EVENT_BASED': {
  3888. d: 'm {mx},{my} {e.x0},{e.y0} {e.x0},{e.y1} {e.x1},{e.y2} {e.x2},0 z',
  3889. height: 11,
  3890. width: 11,
  3891. heightElements: [-6, 6, 12, -12],
  3892. widthElements: [9, -3, -12]
  3893. },
  3894. 'GATEWAY_COMPLEX': {
  3895. d: 'm {mx},{my} 0,{e.y0} -{e.x0},-{e.y1} -{e.x1},{e.y2} {e.x0},{e.y1} -{e.x2},0 0,{e.y3} ' +
  3896. '{e.x2},0 -{e.x0},{e.y1} l {e.x1},{e.y2} {e.x0},-{e.y1} 0,{e.y0} {e.x3},0 0,-{e.y0} {e.x0},{e.y1} ' +
  3897. '{e.x1},-{e.y2} -{e.x0},-{e.y1} {e.x2},0 0,-{e.y3} -{e.x2},0 {e.x0},-{e.y1} -{e.x1},-{e.y2} ' +
  3898. '-{e.x0},{e.y1} 0,-{e.y0} -{e.x3},0 z',
  3899. height: 17.125,
  3900. width: 17.125,
  3901. heightElements: [4.875, 3.4375, 2.125, 3],
  3902. widthElements: [3.4375, 2.125, 4.875, 3]
  3903. },
  3904. 'DATA_OBJECT_PATH': {
  3905. d: 'm 0,0 {e.x1},0 {e.x0},{e.y0} 0,{e.y1} -{e.x2},0 0,-{e.y2} {e.x1},0 0,{e.y0} {e.x0},0',
  3906. height: 61,
  3907. width: 51,
  3908. heightElements: [10, 50, 60],
  3909. widthElements: [10, 40, 50, 60]
  3910. },
  3911. 'DATA_OBJECT_COLLECTION_PATH': {
  3912. d: 'm {mx}, {my} ' +
  3913. 'm 0 15 l 0 -15 ' +
  3914. 'm 4 15 l 0 -15 ' +
  3915. 'm 4 15 l 0 -15 ',
  3916. height: 61,
  3917. width: 51,
  3918. heightElements: [12],
  3919. widthElements: [1, 6, 12, 15]
  3920. },
  3921. 'DATA_ARROW': {
  3922. d: 'm 5,9 9,0 0,-3 5,5 -5,5 0,-3 -9,0 z',
  3923. height: 61,
  3924. width: 51,
  3925. heightElements: [],
  3926. widthElements: []
  3927. },
  3928. 'DATA_STORE': {
  3929. d: 'm {mx},{my} ' +
  3930. 'l 0,{e.y2} ' +
  3931. 'c {e.x0},{e.y1} {e.x1},{e.y1} {e.x2},0 ' +
  3932. 'l 0,-{e.y2} ' +
  3933. 'c -{e.x0},-{e.y1} -{e.x1},-{e.y1} -{e.x2},0' +
  3934. 'c {e.x0},{e.y1} {e.x1},{e.y1} {e.x2},0 ' +
  3935. 'm -{e.x2},{e.y0}' +
  3936. 'c {e.x0},{e.y1} {e.x1},{e.y1} {e.x2},0' +
  3937. 'm -{e.x2},{e.y0}' +
  3938. 'c {e.x0},{e.y1} {e.x1},{e.y1} {e.x2},0',
  3939. height: 61,
  3940. width: 61,
  3941. heightElements: [7, 10, 45],
  3942. widthElements: [2, 58, 60]
  3943. },
  3944. 'TEXT_ANNOTATION': {
  3945. d: 'm {mx}, {my} m 10,0 l -10,0 l 0,{e.y0} l 10,0',
  3946. height: 30,
  3947. width: 10,
  3948. heightElements: [30],
  3949. widthElements: [10]
  3950. },
  3951. 'MARKER_SUB_PROCESS': {
  3952. d: 'm{mx},{my} m 7,2 l 0,10 m -5,-5 l 10,0',
  3953. height: 10,
  3954. width: 10,
  3955. heightElements: [],
  3956. widthElements: []
  3957. },
  3958. 'MARKER_PARALLEL': {
  3959. d: 'm{mx},{my} m 3,2 l 0,10 m 3,-10 l 0,10 m 3,-10 l 0,10',
  3960. height: 10,
  3961. width: 10,
  3962. heightElements: [],
  3963. widthElements: []
  3964. },
  3965. 'MARKER_SEQUENTIAL': {
  3966. d: 'm{mx},{my} m 0,3 l 10,0 m -10,3 l 10,0 m -10,3 l 10,0',
  3967. height: 10,
  3968. width: 10,
  3969. heightElements: [],
  3970. widthElements: []
  3971. },
  3972. 'MARKER_COMPENSATION': {
  3973. d: 'm {mx},{my} 7,-5 0,10 z m 7.1,-0.3 6.9,-4.7 0,10 -6.9,-4.7 z',
  3974. height: 10,
  3975. width: 21,
  3976. heightElements: [],
  3977. widthElements: []
  3978. },
  3979. 'MARKER_LOOP': {
  3980. d: 'm {mx},{my} c 3.526979,0 6.386161,-2.829858 6.386161,-6.320661 0,-3.490806 -2.859182,-6.320661 ' +
  3981. '-6.386161,-6.320661 -3.526978,0 -6.38616,2.829855 -6.38616,6.320661 0,1.745402 ' +
  3982. '0.714797,3.325567 1.870463,4.469381 0.577834,0.571908 1.265885,1.034728 2.029916,1.35457 ' +
  3983. 'l -0.718163,-3.909793 m 0.718163,3.909793 -3.885211,0.802902',
  3984. height: 13.9,
  3985. width: 13.7,
  3986. heightElements: [],
  3987. widthElements: []
  3988. },
  3989. 'MARKER_ADHOC': {
  3990. d: 'm {mx},{my} m 0.84461,2.64411 c 1.05533,-1.23780996 2.64337,-2.07882 4.29653,-1.97997996 2.05163,0.0805 ' +
  3991. '3.85579,1.15803 5.76082,1.79107 1.06385,0.34139996 2.24454,0.1438 3.18759,-0.43767 0.61743,-0.33642 ' +
  3992. '1.2775,-0.64078 1.7542,-1.17511 0,0.56023 0,1.12046 0,1.6807 -0.98706,0.96237996 -2.29792,1.62393996 ' +
  3993. '-3.6918,1.66181996 -1.24459,0.0927 -2.46671,-0.2491 -3.59505,-0.74812 -1.35789,-0.55965 ' +
  3994. '-2.75133,-1.33436996 -4.27027,-1.18121996 -1.37741,0.14601 -2.41842,1.13685996 -3.44288,1.96782996 z',
  3995. height: 4,
  3996. width: 15,
  3997. heightElements: [],
  3998. widthElements: []
  3999. },
  4000. 'TASK_TYPE_SEND': {
  4001. d: 'm {mx},{my} l 0,{e.y1} l {e.x1},0 l 0,-{e.y1} z l {e.x0},{e.y0} l {e.x0},-{e.y0}',
  4002. height: 14,
  4003. width: 21,
  4004. heightElements: [6, 14],
  4005. widthElements: [10.5, 21]
  4006. },
  4007. 'TASK_TYPE_SCRIPT': {
  4008. d: 'm {mx},{my} c 9.966553,-6.27276 -8.000926,-7.91932 2.968968,-14.938 l -8.802728,0 ' +
  4009. 'c -10.969894,7.01868 6.997585,8.66524 -2.968967,14.938 z ' +
  4010. 'm -7,-12 l 5,0 ' +
  4011. 'm -4.5,3 l 4.5,0 ' +
  4012. 'm -3,3 l 5,0' +
  4013. 'm -4,3 l 5,0',
  4014. height: 15,
  4015. width: 12.6,
  4016. heightElements: [6, 14],
  4017. widthElements: [10.5, 21]
  4018. },
  4019. 'TASK_TYPE_USER_1': {
  4020. d: 'm {mx},{my} c 0.909,-0.845 1.594,-2.049 1.594,-3.385 0,-2.554 -1.805,-4.62199999 ' +
  4021. '-4.357,-4.62199999 -2.55199998,0 -4.28799998,2.06799999 -4.28799998,4.62199999 0,1.348 ' +
  4022. '0.974,2.562 1.89599998,3.405 -0.52899998,0.187 -5.669,2.097 -5.794,4.7560005 v 6.718 ' +
  4023. 'h 17 v -6.718 c 0,-2.2980005 -5.5279996,-4.5950005 -6.0509996,-4.7760005 z' +
  4024. 'm -8,6 l 0,5.5 m 11,0 l 0,-5'
  4025. },
  4026. 'TASK_TYPE_USER_2': {
  4027. d: 'm {mx},{my} m 2.162,1.009 c 0,2.4470005 -2.158,4.4310005 -4.821,4.4310005 ' +
  4028. '-2.66499998,0 -4.822,-1.981 -4.822,-4.4310005 '
  4029. },
  4030. 'TASK_TYPE_USER_3': {
  4031. d: 'm {mx},{my} m -6.9,-3.80 c 0,0 2.25099998,-2.358 4.27399998,-1.177 2.024,1.181 4.221,1.537 ' +
  4032. '4.124,0.965 -0.098,-0.57 -0.117,-3.79099999 -4.191,-4.13599999 -3.57499998,0.001 ' +
  4033. '-4.20799998,3.36699999 -4.20699998,4.34799999 z'
  4034. },
  4035. 'TASK_TYPE_MANUAL': {
  4036. d: 'm {mx},{my} c 0.234,-0.01 5.604,0.008 8.029,0.004 0.808,0 1.271,-0.172 1.417,-0.752 0.227,-0.898 ' +
  4037. '-0.334,-1.314 -1.338,-1.316 -2.467,-0.01 -7.886,-0.004 -8.108,-0.004 -0.014,-0.079 0.016,-0.533 0,-0.61 ' +
  4038. '0.195,-0.042 8.507,0.006 9.616,0.002 0.877,-0.007 1.35,-0.438 1.353,-1.208 0.003,-0.768 -0.479,-1.09 ' +
  4039. '-1.35,-1.091 -2.968,-0.002 -9.619,-0.013 -9.619,-0.013 v -0.591 c 0,0 5.052,-0.016 7.225,-0.016 ' +
  4040. '0.888,-0.002 1.354,-0.416 1.351,-1.193 -0.006,-0.761 -0.492,-1.196 -1.361,-1.196 -3.473,-0.005 ' +
  4041. '-10.86,-0.003 -11.0829995,-0.003 -0.022,-0.047 -0.045,-0.094 -0.069,-0.139 0.3939995,-0.319 ' +
  4042. '2.0409995,-1.626 2.4149995,-2.017 0.469,-0.4870005 0.519,-1.1650005 0.162,-1.6040005 -0.414,-0.511 ' +
  4043. '-0.973,-0.5 -1.48,-0.236 -1.4609995,0.764 -6.5999995,3.6430005 -7.7329995,4.2710005 -0.9,0.499 ' +
  4044. '-1.516,1.253 -1.882,2.19 -0.37000002,0.95 -0.17,2.01 -0.166,2.979 0.004,0.718 -0.27300002,1.345 ' +
  4045. '-0.055,2.063 0.629,2.087 2.425,3.312 4.859,3.318 4.6179995,0.014 9.2379995,-0.139 13.8569995,-0.158 ' +
  4046. '0.755,-0.004 1.171,-0.301 1.182,-1.033 0.012,-0.754 -0.423,-0.969 -1.183,-0.973 -1.778,-0.01 ' +
  4047. '-5.824,-0.004 -6.04,-0.004 10e-4,-0.084 0.003,-0.586 10e-4,-0.67 z'
  4048. },
  4049. 'TASK_TYPE_INSTANTIATING_SEND': {
  4050. d: 'm {mx},{my} l 0,8.4 l 12.6,0 l 0,-8.4 z l 6.3,3.6 l 6.3,-3.6'
  4051. },
  4052. 'TASK_TYPE_SERVICE': {
  4053. d: 'm {mx},{my} v -1.71335 c 0.352326,-0.0705 0.703932,-0.17838 1.047628,-0.32133 ' +
  4054. '0.344416,-0.14465 0.665822,-0.32133 0.966377,-0.52145 l 1.19431,1.18005 1.567487,-1.57688 ' +
  4055. '-1.195028,-1.18014 c 0.403376,-0.61394 0.683079,-1.29908 0.825447,-2.01824 l 1.622133,-0.01 ' +
  4056. 'v -2.2196 l -1.636514,0.01 c -0.07333,-0.35153 -0.178319,-0.70024 -0.323564,-1.04372 ' +
  4057. '-0.145244,-0.34406 -0.321407,-0.6644 -0.522735,-0.96217 l 1.131035,-1.13631 -1.583305,-1.56293 ' +
  4058. '-1.129598,1.13589 c -0.614052,-0.40108 -1.302883,-0.68093 -2.022633,-0.82247 l 0.0093,-1.61852 ' +
  4059. 'h -2.241173 l 0.0042,1.63124 c -0.353763,0.0736 -0.705369,0.17977 -1.049785,0.32371 -0.344415,0.14437 ' +
  4060. '-0.665102,0.32092 -0.9635006,0.52046 l -1.1698628,-1.15823 -1.5667691,1.5792 1.1684265,1.15669 ' +
  4061. 'c -0.4026573,0.61283 -0.68308,1.29797 -0.8247287,2.01713 l -1.6588041,0.003 v 2.22174 ' +
  4062. 'l 1.6724648,-0.006 c 0.073327,0.35077 0.1797598,0.70243 0.3242851,1.04472 0.1452428,0.34448 ' +
  4063. '0.3214064,0.6644 0.5227339,0.96066 l -1.1993431,1.19723 1.5840256,1.56011 1.1964668,-1.19348 ' +
  4064. 'c 0.6140517,0.40346 1.3028827,0.68232 2.0233517,0.82331 l 7.19e-4,1.69892 h 2.226848 z ' +
  4065. 'm 0.221462,-3.9957 c -1.788948,0.7502 -3.8576,-0.0928 -4.6097055,-1.87438 -0.7521065,-1.78321 ' +
  4066. '0.090598,-3.84627 1.8802645,-4.59604 1.78823,-0.74936 3.856881,0.0929 4.608987,1.87437 ' +
  4067. '0.752106,1.78165 -0.0906,3.84612 -1.879546,4.59605 z'
  4068. },
  4069. 'TASK_TYPE_SERVICE_FILL': {
  4070. d: 'm {mx},{my} c -1.788948,0.7502 -3.8576,-0.0928 -4.6097055,-1.87438 -0.7521065,-1.78321 ' +
  4071. '0.090598,-3.84627 1.8802645,-4.59604 1.78823,-0.74936 3.856881,0.0929 4.608987,1.87437 ' +
  4072. '0.752106,1.78165 -0.0906,3.84612 -1.879546,4.59605 z'
  4073. },
  4074. 'TASK_TYPE_BUSINESS_RULE_HEADER': {
  4075. d: 'm {mx},{my} 0,4 20,0 0,-4 z'
  4076. },
  4077. 'TASK_TYPE_BUSINESS_RULE_MAIN': {
  4078. d: 'm {mx},{my} 0,12 20,0 0,-12 z' +
  4079. 'm 0,8 l 20,0 ' +
  4080. 'm -13,-4 l 0,8'
  4081. },
  4082. 'MESSAGE_FLOW_MARKER': {
  4083. d: 'm {mx},{my} m -10.5 ,-7 l 0,14 l 21,0 l 0,-14 z l 10.5,6 l 10.5,-6'
  4084. }
  4085. };
  4086. this.getRawPath = function getRawPath(pathId) {
  4087. return this.pathMap[pathId].d;
  4088. };
  4089. /**
  4090. * Scales the path to the given height and width.
  4091. * <h1>Use case</h1>
  4092. * <p>Use case is to scale the content of elements (event, gateways) based
  4093. * on the element bounding box's size.
  4094. * </p>
  4095. * <h1>Why not transform</h1>
  4096. * <p>Scaling a path with transform() will also scale the stroke and IE does not support
  4097. * the option 'non-scaling-stroke' to prevent this.
  4098. * Also there are use cases where only some parts of a path should be
  4099. * scaled.</p>
  4100. *
  4101. * @param {string} pathId The ID of the path.
  4102. * @param {Object} param <p>
  4103. * Example param object scales the path to 60% size of the container (data.width, data.height).
  4104. * <pre>
  4105. * {
  4106. * xScaleFactor: 0.6,
  4107. * yScaleFactor:0.6,
  4108. * containerWidth: data.width,
  4109. * containerHeight: data.height,
  4110. * position: {
  4111. * mx: 0.46,
  4112. * my: 0.2,
  4113. * }
  4114. * }
  4115. * </pre>
  4116. * <ul>
  4117. * <li>targetpathwidth = xScaleFactor * containerWidth</li>
  4118. * <li>targetpathheight = yScaleFactor * containerHeight</li>
  4119. * <li>Position is used to set the starting coordinate of the path. M is computed:
  4120. * <ul>
  4121. * <li>position.x * containerWidth</li>
  4122. * <li>position.y * containerHeight</li>
  4123. * </ul>
  4124. * Center of the container <pre> position: {
  4125. * mx: 0.5,
  4126. * my: 0.5,
  4127. * }</pre>
  4128. * Upper left corner of the container
  4129. * <pre> position: {
  4130. * mx: 0.0,
  4131. * my: 0.0,
  4132. * }</pre>
  4133. * </li>
  4134. * </ul>
  4135. * </p>
  4136. *
  4137. */
  4138. this.getScaledPath = function getScaledPath(pathId, param) {
  4139. var rawPath = this.pathMap[pathId];
  4140. // positioning
  4141. // compute the start point of the path
  4142. var mx, my;
  4143. if (param.abspos) {
  4144. mx = param.abspos.x;
  4145. my = param.abspos.y;
  4146. } else {
  4147. mx = param.containerWidth * param.position.mx;
  4148. my = param.containerHeight * param.position.my;
  4149. }
  4150. var coordinates = {}; // map for the scaled coordinates
  4151. if (param.position) {
  4152. // path
  4153. var heightRatio = (param.containerHeight / rawPath.height) * param.yScaleFactor;
  4154. var widthRatio = (param.containerWidth / rawPath.width) * param.xScaleFactor;
  4155. // Apply height ratio
  4156. for (var heightIndex = 0; heightIndex < rawPath.heightElements.length; heightIndex++) {
  4157. coordinates['y' + heightIndex] = rawPath.heightElements[heightIndex] * heightRatio;
  4158. }
  4159. // Apply width ratio
  4160. for (var widthIndex = 0; widthIndex < rawPath.widthElements.length; widthIndex++) {
  4161. coordinates['x' + widthIndex] = rawPath.widthElements[widthIndex] * widthRatio;
  4162. }
  4163. }
  4164. // Apply value to raw path
  4165. var path = format(
  4166. rawPath.d, {
  4167. mx: mx,
  4168. my: my,
  4169. e: coordinates
  4170. }
  4171. );
  4172. return path;
  4173. };
  4174. }
  4175. // helpers //////////////////////
  4176. // copied from https://github.com/adobe-webplatform/Snap.svg/blob/master/src/svg.js
  4177. var tokenRegex = /\{([^}]+)\}/g,
  4178. objNotationRegex = /(?:(?:^|\.)(.+?)(?=\[|\.|$|\()|\[('|")(.+?)\2\])(\(\))?/g; // matches .xxxxx or ["xxxxx"] to run over object properties
  4179. function replacer(all, key, obj) {
  4180. var res = obj;
  4181. key.replace(objNotationRegex, function (all, name, quote, quotedName, isFunc) {
  4182. name = name || quotedName;
  4183. if (res) {
  4184. if (name in res) {
  4185. res = res[name];
  4186. }
  4187. typeof res == 'function' && isFunc && (res = res());
  4188. }
  4189. });
  4190. res = (res == null || res == obj ? all : res) + '';
  4191. return res;
  4192. }
  4193. function format(str, obj) {
  4194. return String(str).replace(tokenRegex, function (all, key) {
  4195. return replacer(all, key, obj);
  4196. });
  4197. }
  4198. var DrawModule = {
  4199. __init__: ['bpmnRenderer'],
  4200. bpmnRenderer: ['type', BpmnRenderer],
  4201. textRenderer: ['type', TextRenderer],
  4202. pathMap: ['type', PathMap]
  4203. };
  4204. /**
  4205. * A simple translation stub to be used for multi-language support
  4206. * in diagrams. Can be easily replaced with a more sophisticated
  4207. * solution.
  4208. *
  4209. * @example
  4210. *
  4211. * // use it inside any diagram component by injecting `translate`.
  4212. *
  4213. * function MyService(translate) {
  4214. * alert(translate('HELLO {you}', { you: 'You!' }));
  4215. * }
  4216. *
  4217. * @param {string} template to interpolate
  4218. * @param {Object} [replacements] a map with substitutes
  4219. *
  4220. * @return {string} the translated string
  4221. */
  4222. function translate$1(template, replacements) {
  4223. replacements = replacements || {};
  4224. return template.replace(/{([^}]+)}/g, function (_, key) {
  4225. return replacements[key] || '{' + key + '}';
  4226. });
  4227. }
  4228. var TranslateModule = {
  4229. translate: ['value', translate$1]
  4230. };
  4231. var DEFAULT_LABEL_SIZE$1 = {
  4232. width: 90,
  4233. height: 20
  4234. };
  4235. var FLOW_LABEL_INDENT = 15;
  4236. /**
  4237. * Returns true if the given semantic has an external label
  4238. *
  4239. * @param {BpmnElement} semantic
  4240. * @return {boolean} true if has label
  4241. */
  4242. function isLabelExternal(semantic) {
  4243. return is(semantic, 'bpmn:Event') ||
  4244. is(semantic, 'bpmn:Gateway') ||
  4245. is(semantic, 'bpmn:DataStoreReference') ||
  4246. is(semantic, 'bpmn:DataObjectReference') ||
  4247. is(semantic, 'bpmn:DataInput') ||
  4248. is(semantic, 'bpmn:DataOutput') ||
  4249. is(semantic, 'bpmn:SequenceFlow') ||
  4250. is(semantic, 'bpmn:MessageFlow') ||
  4251. is(semantic, 'bpmn:Group');
  4252. }
  4253. /**
  4254. * Get the position for sequence flow labels
  4255. *
  4256. * @param {Array<Point>} waypoints
  4257. * @return {Point} the label position
  4258. */
  4259. function getFlowLabelPosition(waypoints) {
  4260. // get the waypoints mid
  4261. var mid = waypoints.length / 2 - 1;
  4262. var first = waypoints[Math.floor(mid)];
  4263. var second = waypoints[Math.ceil(mid + 0.01)];
  4264. // get position
  4265. var position = getWaypointsMid(waypoints);
  4266. // calculate angle
  4267. var angle = Math.atan((second.y - first.y) / (second.x - first.x));
  4268. var x = position.x,
  4269. y = position.y;
  4270. if (Math.abs(angle) < Math.PI / 2) {
  4271. y -= FLOW_LABEL_INDENT;
  4272. } else {
  4273. x += FLOW_LABEL_INDENT;
  4274. }
  4275. return {x: x, y: y};
  4276. }
  4277. /**
  4278. * Get the middle of a number of waypoints
  4279. *
  4280. * @param {Array<Point>} waypoints
  4281. * @return {Point} the mid point
  4282. */
  4283. function getWaypointsMid(waypoints) {
  4284. var mid = waypoints.length / 2 - 1;
  4285. var first = waypoints[Math.floor(mid)];
  4286. var second = waypoints[Math.ceil(mid + 0.01)];
  4287. return {
  4288. x: first.x + (second.x - first.x) / 2,
  4289. y: first.y + (second.y - first.y) / 2
  4290. };
  4291. }
  4292. function getExternalLabelMid(element) {
  4293. if (element.waypoints) {
  4294. return getFlowLabelPosition(element.waypoints);
  4295. } else if (is(element, 'bpmn:Group')) {
  4296. return {
  4297. x: element.x + element.width / 2,
  4298. y: element.y + DEFAULT_LABEL_SIZE$1.height / 2
  4299. };
  4300. } else {
  4301. return {
  4302. x: element.x + element.width / 2,
  4303. y: element.y + element.height + DEFAULT_LABEL_SIZE$1.height / 2
  4304. };
  4305. }
  4306. }
  4307. /**
  4308. * Returns the bounds of an elements label, parsed from the elements DI or
  4309. * generated from its bounds.
  4310. *
  4311. * @param {BpmnElement} semantic
  4312. * @param {djs.model.Base} element
  4313. */
  4314. function getExternalLabelBounds(semantic, element) {
  4315. var mid,
  4316. size,
  4317. bounds,
  4318. di = semantic.di,
  4319. label = di.label;
  4320. if (label && label.bounds) {
  4321. bounds = label.bounds;
  4322. size = {
  4323. width: Math.max(DEFAULT_LABEL_SIZE$1.width, bounds.width),
  4324. height: bounds.height
  4325. };
  4326. mid = {
  4327. x: bounds.x + bounds.width / 2,
  4328. y: bounds.y + bounds.height / 2
  4329. };
  4330. } else {
  4331. mid = getExternalLabelMid(element);
  4332. size = DEFAULT_LABEL_SIZE$1;
  4333. }
  4334. return assign({
  4335. x: mid.x - size.width / 2,
  4336. y: mid.y - size.height / 2
  4337. }, size);
  4338. }
  4339. /**
  4340. * This file contains source code adapted from Snap.svg (licensed Apache-2.0).
  4341. *
  4342. * @see https://github.com/adobe-webplatform/Snap.svg/blob/master/src/path.js
  4343. */
  4344. /* eslint no-fallthrough: "off" */
  4345. var math = Math,
  4346. PI = math.PI;
  4347. function roundPoint(point) {
  4348. return {
  4349. x: Math.round(point.x),
  4350. y: Math.round(point.y)
  4351. };
  4352. }
  4353. /**
  4354. * Get the mid of the given bounds or point.
  4355. *
  4356. * @param {Bounds|Point} bounds
  4357. *
  4358. * @return {Point}
  4359. */
  4360. function getMid(bounds) {
  4361. return roundPoint({
  4362. x: bounds.x + (bounds.width || 0) / 2,
  4363. y: bounds.y + (bounds.height || 0) / 2
  4364. });
  4365. }
  4366. function elementToString(e) {
  4367. if (!e) {
  4368. return '<null>';
  4369. }
  4370. return '<' + e.$type + (e.id ? ' id="' + e.id : '') + '" />';
  4371. }
  4372. function elementData(semantic, attrs) {
  4373. return assign({
  4374. id: semantic.id,
  4375. type: semantic.$type,
  4376. businessObject: semantic
  4377. }, attrs);
  4378. }
  4379. function getWaypoints(bo, source, target) {
  4380. var waypoints = bo.di.waypoint;
  4381. if (!waypoints || waypoints.length < 2) {
  4382. return [getMid(source), getMid(target)];
  4383. }
  4384. return waypoints.map(function (p) {
  4385. return {x: p.x, y: p.y};
  4386. });
  4387. }
  4388. function notYetDrawn(translate, semantic, refSemantic, property) {
  4389. return new Error(translate('element {element} referenced by {referenced}#{property} not yet drawn', {
  4390. element: elementToString(refSemantic),
  4391. referenced: elementToString(semantic),
  4392. property: property
  4393. }));
  4394. }
  4395. /**
  4396. * An importer that adds bpmn elements to the canvas
  4397. *
  4398. * @param {EventBus} eventBus
  4399. * @param {Canvas} canvas
  4400. * @param {ElementFactory} elementFactory
  4401. * @param {ElementRegistry} elementRegistry
  4402. * @param {Function} translate
  4403. * @param {TextRenderer} textRenderer
  4404. */
  4405. function BpmnImporter(
  4406. eventBus, canvas, elementFactory,
  4407. elementRegistry, translate, textRenderer) {
  4408. this._eventBus = eventBus;
  4409. this._canvas = canvas;
  4410. this._elementFactory = elementFactory;
  4411. this._elementRegistry = elementRegistry;
  4412. this._translate = translate;
  4413. this._textRenderer = textRenderer;
  4414. }
  4415. BpmnImporter.$inject = [
  4416. 'eventBus',
  4417. 'canvas',
  4418. 'elementFactory',
  4419. 'elementRegistry',
  4420. 'translate',
  4421. 'textRenderer'
  4422. ];
  4423. /**
  4424. * Add bpmn element (semantic) to the canvas onto the
  4425. * specified parent shape.
  4426. */
  4427. BpmnImporter.prototype.add = function (semantic, parentElement) {
  4428. var di = semantic.di,
  4429. element,
  4430. translate = this._translate,
  4431. hidden;
  4432. var parentIndex;
  4433. // ROOT ELEMENT
  4434. // handle the special case that we deal with a
  4435. // invisible root element (process or collaboration)
  4436. if (is(di, 'bpmndi:BPMNPlane')) {
  4437. // add a virtual element (not being drawn)
  4438. element = this._elementFactory.createRoot(elementData(semantic));
  4439. this._canvas.setRootElement(element);
  4440. }
  4441. // SHAPE
  4442. else if (is(di, 'bpmndi:BPMNShape')) {
  4443. var collapsed = !isExpanded(semantic),
  4444. isFrame = isFrameElement(semantic);
  4445. hidden = parentElement && (parentElement.hidden || parentElement.collapsed);
  4446. var bounds = semantic.di.bounds;
  4447. element = this._elementFactory.createShape(elementData(semantic, {
  4448. collapsed: collapsed,
  4449. hidden: hidden,
  4450. x: Math.round(bounds.x),
  4451. y: Math.round(bounds.y),
  4452. width: Math.round(bounds.width),
  4453. height: Math.round(bounds.height),
  4454. isFrame: isFrame
  4455. }));
  4456. if (is(semantic, 'bpmn:BoundaryEvent')) {
  4457. this._attachBoundary(semantic, element);
  4458. }
  4459. // insert lanes behind other flow nodes (cf. #727)
  4460. if (is(semantic, 'bpmn:Lane')) {
  4461. parentIndex = 0;
  4462. }
  4463. if (is(semantic, 'bpmn:DataStoreReference')) {
  4464. // check whether data store is inside our outside of its semantic parent
  4465. if (!isPointInsideBBox(parentElement, getMid(bounds))) {
  4466. parentElement = this._canvas.getRootElement();
  4467. }
  4468. }
  4469. this._canvas.addShape(element, parentElement, parentIndex);
  4470. }
  4471. // CONNECTION
  4472. else if (is(di, 'bpmndi:BPMNEdge')) {
  4473. var source = this._getSource(semantic),
  4474. target = this._getTarget(semantic);
  4475. hidden = parentElement && (parentElement.hidden || parentElement.collapsed);
  4476. element = this._elementFactory.createConnection(elementData(semantic, {
  4477. hidden: hidden,
  4478. source: source,
  4479. target: target,
  4480. waypoints: getWaypoints(semantic, source, target)
  4481. }));
  4482. if (is(semantic, 'bpmn:DataAssociation')) {
  4483. // render always on top; this ensures DataAssociations
  4484. // are rendered correctly across different "hacks" people
  4485. // love to model such as cross participant / sub process
  4486. // associations
  4487. parentElement = null;
  4488. }
  4489. // insert sequence flows behind other flow nodes (cf. #727)
  4490. if (is(semantic, 'bpmn:SequenceFlow')) {
  4491. parentIndex = 0;
  4492. }
  4493. this._canvas.addConnection(element, parentElement, parentIndex);
  4494. } else {
  4495. throw new Error(translate('unknown di {di} for element {semantic}', {
  4496. di: elementToString(di),
  4497. semantic: elementToString(semantic)
  4498. }));
  4499. }
  4500. // (optional) LABEL
  4501. if (isLabelExternal(semantic) && getLabel(element)) {
  4502. this.addLabel(semantic, element);
  4503. }
  4504. this._eventBus.fire('bpmnElement.added', {element: element});
  4505. return element;
  4506. };
  4507. /**
  4508. * Attach the boundary element to the given host
  4509. *
  4510. * @param {ModdleElement} boundarySemantic
  4511. * @param {djs.model.Base} boundaryElement
  4512. */
  4513. BpmnImporter.prototype._attachBoundary = function (boundarySemantic, boundaryElement) {
  4514. var translate = this._translate;
  4515. var hostSemantic = boundarySemantic.attachedToRef;
  4516. if (!hostSemantic) {
  4517. throw new Error(translate('missing {semantic}#attachedToRef', {
  4518. semantic: elementToString(boundarySemantic)
  4519. }));
  4520. }
  4521. var host = this._elementRegistry.get(hostSemantic.id),
  4522. attachers = host && host.attachers;
  4523. if (!host) {
  4524. throw notYetDrawn(translate, boundarySemantic, hostSemantic, 'attachedToRef');
  4525. }
  4526. // wire element.host <> host.attachers
  4527. boundaryElement.host = host;
  4528. if (!attachers) {
  4529. host.attachers = attachers = [];
  4530. }
  4531. if (attachers.indexOf(boundaryElement) === -1) {
  4532. attachers.push(boundaryElement);
  4533. }
  4534. };
  4535. /**
  4536. * add label for an element
  4537. */
  4538. BpmnImporter.prototype.addLabel = function (semantic, element) {
  4539. var bounds,
  4540. text,
  4541. label;
  4542. bounds = getExternalLabelBounds(semantic, element);
  4543. text = getLabel(element);
  4544. if (text) {
  4545. // get corrected bounds from actual layouted text
  4546. bounds = this._textRenderer.getExternalLabelBounds(bounds, text);
  4547. }
  4548. label = this._elementFactory.createLabel(elementData(semantic, {
  4549. id: semantic.id + '_label',
  4550. labelTarget: element,
  4551. type: 'label',
  4552. hidden: element.hidden || !getLabel(element),
  4553. x: Math.round(bounds.x),
  4554. y: Math.round(bounds.y),
  4555. width: Math.round(bounds.width),
  4556. height: Math.round(bounds.height)
  4557. }));
  4558. return this._canvas.addShape(label, element.parent);
  4559. };
  4560. /**
  4561. * Return the drawn connection end based on the given side.
  4562. *
  4563. * @throws {Error} if the end is not yet drawn
  4564. */
  4565. BpmnImporter.prototype._getEnd = function (semantic, side) {
  4566. var element,
  4567. refSemantic,
  4568. type = semantic.$type,
  4569. translate = this._translate;
  4570. refSemantic = semantic[side + 'Ref'];
  4571. // handle mysterious isMany DataAssociation#sourceRef
  4572. if (side === 'source' && type === 'bpmn:DataInputAssociation') {
  4573. refSemantic = refSemantic && refSemantic[0];
  4574. }
  4575. // fix source / target for DataInputAssociation / DataOutputAssociation
  4576. if (side === 'source' && type === 'bpmn:DataOutputAssociation' ||
  4577. side === 'target' && type === 'bpmn:DataInputAssociation') {
  4578. refSemantic = semantic.$parent;
  4579. }
  4580. element = refSemantic && this._getElement(refSemantic);
  4581. if (element) {
  4582. return element;
  4583. }
  4584. if (refSemantic) {
  4585. throw notYetDrawn(translate, semantic, refSemantic, side + 'Ref');
  4586. } else {
  4587. throw new Error(translate('{semantic}#{side} Ref not specified', {
  4588. semantic: elementToString(semantic),
  4589. side: side
  4590. }));
  4591. }
  4592. };
  4593. BpmnImporter.prototype._getSource = function (semantic) {
  4594. return this._getEnd(semantic, 'source');
  4595. };
  4596. BpmnImporter.prototype._getTarget = function (semantic) {
  4597. return this._getEnd(semantic, 'target');
  4598. };
  4599. BpmnImporter.prototype._getElement = function (semantic) {
  4600. return this._elementRegistry.get(semantic.id);
  4601. };
  4602. // helpers ////////////////////
  4603. function isPointInsideBBox(bbox, point) {
  4604. var x = point.x,
  4605. y = point.y;
  4606. return x >= bbox.x &&
  4607. x <= bbox.x + bbox.width &&
  4608. y >= bbox.y &&
  4609. y <= bbox.y + bbox.height;
  4610. }
  4611. function isFrameElement(semantic) {
  4612. return is(semantic, 'bpmn:Group');
  4613. }
  4614. var ImportModule = {
  4615. __depends__: [
  4616. TranslateModule
  4617. ],
  4618. bpmnImporter: ['type', BpmnImporter]
  4619. };
  4620. var CoreModule = {
  4621. __depends__: [
  4622. DrawModule,
  4623. ImportModule
  4624. ]
  4625. };
  4626. function getOriginal(event) {
  4627. return event.originalEvent || event.srcEvent;
  4628. }
  4629. function toPoint(event) {
  4630. if (event.pointers && event.pointers.length) {
  4631. event = event.pointers[0];
  4632. }
  4633. if (event.touches && event.touches.length) {
  4634. event = event.touches[0];
  4635. }
  4636. return event ? {
  4637. x: event.clientX,
  4638. y: event.clientY
  4639. } : null;
  4640. }
  4641. function isMac() {
  4642. return (/mac/i).test(navigator.platform);
  4643. }
  4644. function isPrimaryButton(event) {
  4645. // button === 0 -> left áka primary mouse button
  4646. return !(getOriginal(event) || event).button;
  4647. }
  4648. function hasPrimaryModifier(event) {
  4649. var originalEvent = getOriginal(event) || event;
  4650. if (!isPrimaryButton(event)) {
  4651. return false;
  4652. }
  4653. // Use alt as primary modifier key for mac OS
  4654. if (isMac()) {
  4655. return originalEvent.metaKey;
  4656. } else {
  4657. return originalEvent.ctrlKey;
  4658. }
  4659. }
  4660. function allowAll(e) {
  4661. return true;
  4662. }
  4663. var LOW_PRIORITY = 500;
  4664. /**
  4665. * A plugin that provides interaction events for diagram elements.
  4666. *
  4667. * It emits the following events:
  4668. *
  4669. * * element.click
  4670. * * element.contextmenu
  4671. * * element.dblclick
  4672. * * element.hover
  4673. * * element.mousedown
  4674. * * element.mousemove
  4675. * * element.mouseup
  4676. * * element.out
  4677. *
  4678. * Each event is a tuple { element, gfx, originalEvent }.
  4679. *
  4680. * Canceling the event via Event#preventDefault()
  4681. * prevents the original DOM operation.
  4682. *
  4683. * @param {EventBus} eventBus
  4684. */
  4685. function InteractionEvents(eventBus, elementRegistry, styles) {
  4686. var self = this;
  4687. /**
  4688. * Fire an interaction event.
  4689. *
  4690. * @param {string} type local event name, e.g. element.click.
  4691. * @param {DOMEvent} event native event
  4692. * @param {djs.model.Base} [element] the diagram element to emit the event on;
  4693. * defaults to the event target
  4694. */
  4695. function fire(type, event, element) {
  4696. if (isIgnored(type, event)) {
  4697. return;
  4698. }
  4699. var target, gfx, returnValue;
  4700. if (!element) {
  4701. target = event.delegateTarget || event.target;
  4702. if (target) {
  4703. gfx = target;
  4704. element = elementRegistry.get(gfx);
  4705. }
  4706. } else {
  4707. gfx = elementRegistry.getGraphics(element);
  4708. }
  4709. if (!gfx || !element) {
  4710. return;
  4711. }
  4712. returnValue = eventBus.fire(type, {
  4713. element: element,
  4714. gfx: gfx,
  4715. originalEvent: event
  4716. });
  4717. if (returnValue === false) {
  4718. event.stopPropagation();
  4719. event.preventDefault();
  4720. }
  4721. }
  4722. // TODO(nikku): document this
  4723. var handlers = {};
  4724. function mouseHandler(localEventName) {
  4725. return handlers[localEventName];
  4726. }
  4727. function isIgnored(localEventName, event) {
  4728. var filter = ignoredFilters[localEventName] || isPrimaryButton;
  4729. // only react on left mouse button interactions
  4730. // except for interaction events that are enabled
  4731. // for secundary mouse button
  4732. return !filter(event);
  4733. }
  4734. var bindings = {
  4735. click: 'element.click',
  4736. contextmenu: 'element.contextmenu',
  4737. dblclick: 'element.dblclick',
  4738. mousedown: 'element.mousedown',
  4739. mousemove: 'element.mousemove',
  4740. mouseover: 'element.hover',
  4741. mouseout: 'element.out',
  4742. mouseup: 'element.mouseup',
  4743. };
  4744. var ignoredFilters = {
  4745. 'element.contextmenu': allowAll
  4746. };
  4747. // manual event trigger //////////
  4748. /**
  4749. * Trigger an interaction event (based on a native dom event)
  4750. * on the target shape or connection.
  4751. *
  4752. * @param {string} eventName the name of the triggered DOM event
  4753. * @param {MouseEvent} event
  4754. * @param {djs.model.Base} targetElement
  4755. */
  4756. function triggerMouseEvent(eventName, event, targetElement) {
  4757. // i.e. element.mousedown...
  4758. var localEventName = bindings[eventName];
  4759. if (!localEventName) {
  4760. throw new Error('unmapped DOM event name <' + eventName + '>');
  4761. }
  4762. return fire(localEventName, event, targetElement);
  4763. }
  4764. var ELEMENT_SELECTOR = 'svg, .djs-element';
  4765. // event handling ///////
  4766. function registerEvent(node, event, localEvent, ignoredFilter) {
  4767. var handler = handlers[localEvent] = function (event) {
  4768. fire(localEvent, event);
  4769. };
  4770. if (ignoredFilter) {
  4771. ignoredFilters[localEvent] = ignoredFilter;
  4772. }
  4773. handler.$delegate = delegateEvents.bind(node, ELEMENT_SELECTOR, event, handler);
  4774. }
  4775. function unregisterEvent(node, event, localEvent) {
  4776. var handler = mouseHandler(localEvent);
  4777. if (!handler) {
  4778. return;
  4779. }
  4780. delegateEvents.unbind(node, event, handler.$delegate);
  4781. }
  4782. function registerEvents(svg) {
  4783. forEach(bindings, function (val, key) {
  4784. registerEvent(svg, key, val);
  4785. });
  4786. }
  4787. function unregisterEvents(svg) {
  4788. forEach(bindings, function (val, key) {
  4789. unregisterEvent(svg, key, val);
  4790. });
  4791. }
  4792. eventBus.on('canvas.destroy', function (event) {
  4793. unregisterEvents(event.svg);
  4794. });
  4795. eventBus.on('canvas.init', function (event) {
  4796. registerEvents(event.svg);
  4797. });
  4798. // hit box updating ////////////////
  4799. eventBus.on(['shape.added', 'connection.added'], function (event) {
  4800. var element = event.element,
  4801. gfx = event.gfx;
  4802. eventBus.fire('interactionEvents.createHit', {element: element, gfx: gfx});
  4803. });
  4804. // Update djs-hit on change.
  4805. // A low priortity is necessary, because djs-hit of labels has to be updated
  4806. // after the label bounds have been updated in the renderer.
  4807. eventBus.on([
  4808. 'shape.changed',
  4809. 'connection.changed'
  4810. ], LOW_PRIORITY, function (event) {
  4811. var element = event.element,
  4812. gfx = event.gfx;
  4813. eventBus.fire('interactionEvents.updateHit', {element: element, gfx: gfx});
  4814. });
  4815. eventBus.on('interactionEvents.createHit', LOW_PRIORITY, function (event) {
  4816. var element = event.element,
  4817. gfx = event.gfx;
  4818. self.createDefaultHit(element, gfx);
  4819. });
  4820. eventBus.on('interactionEvents.updateHit', function (event) {
  4821. var element = event.element,
  4822. gfx = event.gfx;
  4823. self.updateDefaultHit(element, gfx);
  4824. });
  4825. // hit styles ////////////
  4826. var STROKE_HIT_STYLE = createHitStyle('djs-hit djs-hit-stroke');
  4827. var CLICK_STROKE_HIT_STYLE = createHitStyle('djs-hit djs-hit-click-stroke');
  4828. var ALL_HIT_STYLE = createHitStyle('djs-hit djs-hit-all');
  4829. var HIT_TYPES = {
  4830. 'all': ALL_HIT_STYLE,
  4831. 'click-stroke': CLICK_STROKE_HIT_STYLE,
  4832. 'stroke': STROKE_HIT_STYLE
  4833. };
  4834. function createHitStyle(classNames, attrs) {
  4835. attrs = assign({
  4836. stroke: 'white',
  4837. strokeWidth: 15
  4838. }, attrs || {});
  4839. return styles.cls(classNames, ['no-fill', 'no-border'], attrs);
  4840. }
  4841. // style helpers ///////////////
  4842. function applyStyle(hit, type) {
  4843. var attrs = HIT_TYPES[type];
  4844. if (!attrs) {
  4845. throw new Error('invalid hit type <' + type + '>');
  4846. }
  4847. attr(hit, attrs);
  4848. return hit;
  4849. }
  4850. function appendHit(gfx, hit) {
  4851. append(gfx, hit);
  4852. }
  4853. // API
  4854. /**
  4855. * Remove hints on the given graphics.
  4856. *
  4857. * @param {SVGElement} gfx
  4858. */
  4859. this.removeHits = function (gfx) {
  4860. var hits = all('.djs-hit', gfx);
  4861. forEach(hits, remove);
  4862. };
  4863. /**
  4864. * Create default hit for the given element.
  4865. *
  4866. * @param {djs.model.Base} element
  4867. * @param {SVGElement} gfx
  4868. *
  4869. * @return {SVGElement} created hit
  4870. */
  4871. this.createDefaultHit = function (element, gfx) {
  4872. var waypoints = element.waypoints,
  4873. isFrame = element.isFrame,
  4874. boxType;
  4875. if (waypoints) {
  4876. return this.createWaypointsHit(gfx, waypoints);
  4877. } else {
  4878. boxType = isFrame ? 'stroke' : 'all';
  4879. return this.createBoxHit(gfx, boxType, {
  4880. width: element.width,
  4881. height: element.height
  4882. });
  4883. }
  4884. };
  4885. /**
  4886. * Create hits for the given waypoints.
  4887. *
  4888. * @param {SVGElement} gfx
  4889. * @param {Array<Point>} waypoints
  4890. *
  4891. * @return {SVGElement}
  4892. */
  4893. this.createWaypointsHit = function (gfx, waypoints) {
  4894. var hit = createLine(waypoints);
  4895. applyStyle(hit, 'stroke');
  4896. appendHit(gfx, hit);
  4897. return hit;
  4898. };
  4899. /**
  4900. * Create hits for a box.
  4901. *
  4902. * @param {SVGElement} gfx
  4903. * @param {string} hitType
  4904. * @param {Object} attrs
  4905. *
  4906. * @return {SVGElement}
  4907. */
  4908. this.createBoxHit = function (gfx, type, attrs) {
  4909. attrs = assign({
  4910. x: 0,
  4911. y: 0
  4912. }, attrs);
  4913. var hit = create('rect');
  4914. applyStyle(hit, type);
  4915. attr(hit, attrs);
  4916. appendHit(gfx, hit);
  4917. return hit;
  4918. };
  4919. /**
  4920. * Update default hit of the element.
  4921. *
  4922. * @param {djs.model.Base} element
  4923. * @param {SVGElement} gfx
  4924. *
  4925. * @return {SVGElement} updated hit
  4926. */
  4927. this.updateDefaultHit = function (element, gfx) {
  4928. var hit = query('.djs-hit', gfx);
  4929. if (!hit) {
  4930. return;
  4931. }
  4932. if (element.waypoints) {
  4933. updateLine(hit, element.waypoints);
  4934. } else {
  4935. attr(hit, {
  4936. width: element.width,
  4937. height: element.height
  4938. });
  4939. }
  4940. return hit;
  4941. };
  4942. this.fire = fire;
  4943. this.triggerMouseEvent = triggerMouseEvent;
  4944. this.mouseHandler = mouseHandler;
  4945. this.registerEvent = registerEvent;
  4946. this.unregisterEvent = unregisterEvent;
  4947. }
  4948. InteractionEvents.$inject = [
  4949. 'eventBus',
  4950. 'elementRegistry',
  4951. 'styles'
  4952. ];
  4953. /**
  4954. * An event indicating that the mouse hovered over an element
  4955. *
  4956. * @event element.hover
  4957. *
  4958. * @type {Object}
  4959. * @property {djs.model.Base} element
  4960. * @property {SVGElement} gfx
  4961. * @property {Event} originalEvent
  4962. */
  4963. /**
  4964. * An event indicating that the mouse has left an element
  4965. *
  4966. * @event element.out
  4967. *
  4968. * @type {Object}
  4969. * @property {djs.model.Base} element
  4970. * @property {SVGElement} gfx
  4971. * @property {Event} originalEvent
  4972. */
  4973. /**
  4974. * An event indicating that the mouse has clicked an element
  4975. *
  4976. * @event element.click
  4977. *
  4978. * @type {Object}
  4979. * @property {djs.model.Base} element
  4980. * @property {SVGElement} gfx
  4981. * @property {Event} originalEvent
  4982. */
  4983. /**
  4984. * An event indicating that the mouse has double clicked an element
  4985. *
  4986. * @event element.dblclick
  4987. *
  4988. * @type {Object}
  4989. * @property {djs.model.Base} element
  4990. * @property {SVGElement} gfx
  4991. * @property {Event} originalEvent
  4992. */
  4993. /**
  4994. * An event indicating that the mouse has gone down on an element.
  4995. *
  4996. * @event element.mousedown
  4997. *
  4998. * @type {Object}
  4999. * @property {djs.model.Base} element
  5000. * @property {SVGElement} gfx
  5001. * @property {Event} originalEvent
  5002. */
  5003. /**
  5004. * An event indicating that the mouse has gone up on an element.
  5005. *
  5006. * @event element.mouseup
  5007. *
  5008. * @type {Object}
  5009. * @property {djs.model.Base} element
  5010. * @property {SVGElement} gfx
  5011. * @property {Event} originalEvent
  5012. */
  5013. /**
  5014. * An event indicating that the context menu action is triggered
  5015. * via mouse or touch controls.
  5016. *
  5017. * @event element.contextmenu
  5018. *
  5019. * @type {Object}
  5020. * @property {djs.model.Base} element
  5021. * @property {SVGElement} gfx
  5022. * @property {Event} originalEvent
  5023. */
  5024. var InteractionEventsModule = {
  5025. __init__: ['interactionEvents'],
  5026. interactionEvents: ['type', InteractionEvents]
  5027. };
  5028. /**
  5029. * Returns the surrounding bbox for all elements in
  5030. * the array or the element primitive.
  5031. *
  5032. * @param {Array<djs.model.Shape>|djs.model.Shape} elements
  5033. * @param {boolean} stopRecursion
  5034. */
  5035. function getBBox(elements, stopRecursion) {
  5036. stopRecursion = !!stopRecursion;
  5037. if (!isArray(elements)) {
  5038. elements = [elements];
  5039. }
  5040. var minX,
  5041. minY,
  5042. maxX,
  5043. maxY;
  5044. forEach(elements, function (element) {
  5045. // If element is a connection the bbox must be computed first
  5046. var bbox = element;
  5047. if (element.waypoints && !stopRecursion) {
  5048. bbox = getBBox(element.waypoints, true);
  5049. }
  5050. var x = bbox.x,
  5051. y = bbox.y,
  5052. height = bbox.height || 0,
  5053. width = bbox.width || 0;
  5054. if (x < minX || minX === undefined) {
  5055. minX = x;
  5056. }
  5057. if (y < minY || minY === undefined) {
  5058. minY = y;
  5059. }
  5060. if ((x + width) > maxX || maxX === undefined) {
  5061. maxX = x + width;
  5062. }
  5063. if ((y + height) > maxY || maxY === undefined) {
  5064. maxY = y + height;
  5065. }
  5066. });
  5067. return {
  5068. x: minX,
  5069. y: minY,
  5070. height: maxY - minY,
  5071. width: maxX - minX
  5072. };
  5073. }
  5074. function getType(element) {
  5075. if ('waypoints' in element) {
  5076. return 'connection';
  5077. }
  5078. if ('x' in element) {
  5079. return 'shape';
  5080. }
  5081. return 'root';
  5082. }
  5083. function isFrameElement$1(element) {
  5084. return !!(element && element.isFrame);
  5085. }
  5086. var LOW_PRIORITY$1 = 500;
  5087. /**
  5088. * @class
  5089. *
  5090. * A plugin that adds an outline to shapes and connections that may be activated and styled
  5091. * via CSS classes.
  5092. *
  5093. * @param {EventBus} eventBus
  5094. * @param {Styles} styles
  5095. * @param {ElementRegistry} elementRegistry
  5096. */
  5097. function Outline(eventBus, styles, elementRegistry) {
  5098. this.offset = 6;
  5099. var OUTLINE_STYLE = styles.cls('djs-outline', ['no-fill']);
  5100. var self = this;
  5101. function createOutline(gfx, bounds) {
  5102. var outline = create('rect');
  5103. attr(outline, assign({
  5104. x: 10,
  5105. y: 10,
  5106. width: 100,
  5107. height: 100
  5108. }, OUTLINE_STYLE));
  5109. append(gfx, outline);
  5110. return outline;
  5111. }
  5112. // A low priortity is necessary, because outlines of labels have to be updated
  5113. // after the label bounds have been updated in the renderer.
  5114. eventBus.on(['shape.added', 'shape.changed'], LOW_PRIORITY$1, function (event) {
  5115. var element = event.element,
  5116. gfx = event.gfx;
  5117. var outline = query('.djs-outline', gfx);
  5118. if (!outline) {
  5119. outline = createOutline(gfx);
  5120. }
  5121. self.updateShapeOutline(outline, element);
  5122. });
  5123. eventBus.on(['connection.added', 'connection.changed'], function (event) {
  5124. var element = event.element,
  5125. gfx = event.gfx;
  5126. var outline = query('.djs-outline', gfx);
  5127. if (!outline) {
  5128. outline = createOutline(gfx);
  5129. }
  5130. self.updateConnectionOutline(outline, element);
  5131. });
  5132. }
  5133. /**
  5134. * Updates the outline of a shape respecting the dimension of the
  5135. * element and an outline offset.
  5136. *
  5137. * @param {SVGElement} outline
  5138. * @param {djs.model.Base} element
  5139. */
  5140. Outline.prototype.updateShapeOutline = function (outline, element) {
  5141. attr(outline, {
  5142. x: -this.offset,
  5143. y: -this.offset,
  5144. width: element.width + this.offset * 2,
  5145. height: element.height + this.offset * 2
  5146. });
  5147. };
  5148. /**
  5149. * Updates the outline of a connection respecting the bounding box of
  5150. * the connection and an outline offset.
  5151. *
  5152. * @param {SVGElement} outline
  5153. * @param {djs.model.Base} element
  5154. */
  5155. Outline.prototype.updateConnectionOutline = function (outline, connection) {
  5156. var bbox = getBBox(connection);
  5157. attr(outline, {
  5158. x: bbox.x - this.offset,
  5159. y: bbox.y - this.offset,
  5160. width: bbox.width + this.offset * 2,
  5161. height: bbox.height + this.offset * 2
  5162. });
  5163. };
  5164. Outline.$inject = ['eventBus', 'styles', 'elementRegistry'];
  5165. var OutlineModule = {
  5166. __init__: ['outline'],
  5167. outline: ['type', Outline]
  5168. };
  5169. /**
  5170. * A service that offers the current selection in a diagram.
  5171. * Offers the api to control the selection, too.
  5172. *
  5173. * @class
  5174. *
  5175. * @param {EventBus} eventBus the event bus
  5176. */
  5177. function Selection(eventBus) {
  5178. this._eventBus = eventBus;
  5179. this._selectedElements = [];
  5180. var self = this;
  5181. eventBus.on(['shape.remove', 'connection.remove'], function (e) {
  5182. var element = e.element;
  5183. self.deselect(element);
  5184. });
  5185. eventBus.on(['diagram.clear'], function (e) {
  5186. self.select(null);
  5187. });
  5188. }
  5189. Selection.$inject = ['eventBus'];
  5190. Selection.prototype.deselect = function (element) {
  5191. var selectedElements = this._selectedElements;
  5192. var idx = selectedElements.indexOf(element);
  5193. if (idx !== -1) {
  5194. var oldSelection = selectedElements.slice();
  5195. selectedElements.splice(idx, 1);
  5196. this._eventBus.fire('selection.changed', {oldSelection: oldSelection, newSelection: selectedElements});
  5197. }
  5198. };
  5199. Selection.prototype.get = function () {
  5200. return this._selectedElements;
  5201. };
  5202. Selection.prototype.isSelected = function (element) {
  5203. return this._selectedElements.indexOf(element) !== -1;
  5204. };
  5205. /**
  5206. * This method selects one or more elements on the diagram.
  5207. *
  5208. * By passing an additional add parameter you can decide whether or not the element(s)
  5209. * should be added to the already existing selection or not.
  5210. *
  5211. * @method Selection#select
  5212. *
  5213. * @param {Object|Object[]} elements element or array of elements to be selected
  5214. * @param {boolean} [add] whether the element(s) should be appended to the current selection, defaults to false
  5215. */
  5216. Selection.prototype.select = function (elements, add) {
  5217. var selectedElements = this._selectedElements,
  5218. oldSelection = selectedElements.slice();
  5219. if (!isArray(elements)) {
  5220. elements = elements ? [elements] : [];
  5221. }
  5222. // selection may be cleared by passing an empty array or null
  5223. // to the method
  5224. if (add) {
  5225. forEach(elements, function (element) {
  5226. if (selectedElements.indexOf(element) !== -1) {
  5227. // already selected
  5228. return;
  5229. } else {
  5230. selectedElements.push(element);
  5231. }
  5232. });
  5233. } else {
  5234. this._selectedElements = selectedElements = elements.slice();
  5235. }
  5236. this._eventBus.fire('selection.changed', {oldSelection: oldSelection, newSelection: selectedElements});
  5237. };
  5238. var MARKER_HOVER = 'hover',
  5239. MARKER_SELECTED = 'selected';
  5240. /**
  5241. * A plugin that adds a visible selection UI to shapes and connections
  5242. * by appending the <code>hover</code> and <code>selected</code> classes to them.
  5243. *
  5244. * @class
  5245. *
  5246. * Makes elements selectable, too.
  5247. *
  5248. * @param {EventBus} events
  5249. * @param {SelectionService} selection
  5250. * @param {Canvas} canvas
  5251. */
  5252. function SelectionVisuals(events, canvas, selection, styles) {
  5253. this._multiSelectionBox = null;
  5254. function addMarker(e, cls) {
  5255. canvas.addMarker(e, cls);
  5256. }
  5257. function removeMarker(e, cls) {
  5258. canvas.removeMarker(e, cls);
  5259. }
  5260. events.on('element.hover', function (event) {
  5261. addMarker(event.element, MARKER_HOVER);
  5262. });
  5263. events.on('element.out', function (event) {
  5264. removeMarker(event.element, MARKER_HOVER);
  5265. });
  5266. events.on('selection.changed', function (event) {
  5267. function deselect(s) {
  5268. removeMarker(s, MARKER_SELECTED);
  5269. }
  5270. function select(s) {
  5271. angular.element(document.body).scope().ctl.getItemNode(s);
  5272. addMarker(s, MARKER_SELECTED);
  5273. }
  5274. var oldSelection = event.oldSelection,
  5275. newSelection = event.newSelection;
  5276. forEach(oldSelection, function (e) {
  5277. if (newSelection.indexOf(e) === -1) {
  5278. deselect(e);
  5279. }
  5280. });
  5281. forEach(newSelection, function (e) {
  5282. if (oldSelection.indexOf(e) === -1) {
  5283. select(e);
  5284. }
  5285. });
  5286. });
  5287. }
  5288. SelectionVisuals.$inject = [
  5289. 'eventBus',
  5290. 'canvas',
  5291. 'selection',
  5292. 'styles'
  5293. ];
  5294. function SelectionBehavior(
  5295. eventBus, selection, canvas,
  5296. elementRegistry) {
  5297. eventBus.on('create.end', 500, function (e) {
  5298. var context = e.context,
  5299. canExecute = context.canExecute,
  5300. elements = context.elements,
  5301. hints = context.hints || {},
  5302. autoSelect = hints.autoSelect;
  5303. // select elements after they have been created
  5304. if (canExecute) {
  5305. if (autoSelect === false) {
  5306. // select no elements
  5307. return;
  5308. }
  5309. if (isArray(autoSelect)) {
  5310. selection.select(autoSelect);
  5311. } else {
  5312. // select all elements by default
  5313. selection.select(elements.filter(isShown));
  5314. }
  5315. }
  5316. });
  5317. eventBus.on('connect.end', 500, function (e) {
  5318. // select the connect end target
  5319. // after a connect operation
  5320. if (e.context.canExecute && e.context.hover) {
  5321. selection.select(e.context.hover);
  5322. }
  5323. });
  5324. eventBus.on('shape.move.end', 500, function (e) {
  5325. var previousSelection = e.previousSelection || [];
  5326. var shape = elementRegistry.get(e.context.shape.id);
  5327. // make sure at least the main moved element is being
  5328. // selected after a move operation
  5329. var inSelection = find(previousSelection, function (selectedShape) {
  5330. return shape.id === selectedShape.id;
  5331. });
  5332. if (!inSelection) {
  5333. selection.select(shape);
  5334. }
  5335. });
  5336. // Shift + click selection
  5337. eventBus.on('element.click', function (event) {
  5338. var element = event.element;
  5339. // do not select the root element
  5340. // or connections
  5341. if (element === canvas.getRootElement()) {
  5342. element = null;
  5343. }
  5344. var isSelected = selection.isSelected(element),
  5345. isMultiSelect = selection.get().length > 1;
  5346. // mouse-event: SELECTION_KEY
  5347. var add = hasPrimaryModifier(event);
  5348. // select OR deselect element in multi selection
  5349. if (isSelected && isMultiSelect) {
  5350. if (add) {
  5351. return selection.deselect(element);
  5352. } else {
  5353. return selection.select(element);
  5354. }
  5355. } else if (!isSelected) {
  5356. selection.select(element, add);
  5357. } else {
  5358. selection.deselect(element);
  5359. }
  5360. });
  5361. }
  5362. SelectionBehavior.$inject = [
  5363. 'eventBus',
  5364. 'selection',
  5365. 'canvas',
  5366. 'elementRegistry'
  5367. ];
  5368. function isShown(element) {
  5369. return !element.hidden;
  5370. }
  5371. var SelectionModule = {
  5372. __init__: ['selectionVisuals', 'selectionBehavior'],
  5373. __depends__: [
  5374. InteractionEventsModule,
  5375. OutlineModule
  5376. ],
  5377. selection: ['type', Selection],
  5378. selectionVisuals: ['type', SelectionVisuals],
  5379. selectionBehavior: ['type', SelectionBehavior]
  5380. };
  5381. /**
  5382. * Util that provides unique IDs.
  5383. *
  5384. * @class djs.util.IdGenerator
  5385. * @constructor
  5386. * @memberOf djs.util
  5387. *
  5388. * The ids can be customized via a given prefix and contain a random value to avoid collisions.
  5389. *
  5390. * @param {string} prefix a prefix to prepend to generated ids (for better readability)
  5391. */
  5392. function IdGenerator(prefix) {
  5393. this._counter = 0;
  5394. this._prefix = (prefix ? prefix + '-' : '') + Math.floor(Math.random() * 1000000000) + '-';
  5395. }
  5396. /**
  5397. * Returns a next unique ID.
  5398. *
  5399. * @method djs.util.IdGenerator#next
  5400. *
  5401. * @returns {string} the id
  5402. */
  5403. IdGenerator.prototype.next = function () {
  5404. return this._prefix + (++this._counter);
  5405. };
  5406. // document wide unique overlay ids
  5407. var ids = new IdGenerator('ov');
  5408. var LOW_PRIORITY$2 = 500;
  5409. /**
  5410. * A service that allows users to attach overlays to diagram elements.
  5411. *
  5412. * The overlay service will take care of overlay positioning during updates.
  5413. *
  5414. * @example
  5415. *
  5416. * // add a pink badge on the top left of the shape
  5417. * overlays.add(someShape, {
  5418. * position: {
  5419. * top: -5,
  5420. * left: -5
  5421. * },
  5422. * html: '<div style="width: 10px; background: fuchsia; color: white;">0</div>'
  5423. * });
  5424. *
  5425. * // or add via shape id
  5426. *
  5427. * overlays.add('some-element-id', {
  5428. * position: {
  5429. * top: -5,
  5430. * left: -5
  5431. * }
  5432. * html: '<div style="width: 10px; background: fuchsia; color: white;">0</div>'
  5433. * });
  5434. *
  5435. * // or add with optional type
  5436. *
  5437. * overlays.add(someShape, 'badge', {
  5438. * position: {
  5439. * top: -5,
  5440. * left: -5
  5441. * }
  5442. * html: '<div style="width: 10px; background: fuchsia; color: white;">0</div>'
  5443. * });
  5444. *
  5445. *
  5446. * // remove an overlay
  5447. *
  5448. * var id = overlays.add(...);
  5449. * overlays.remove(id);
  5450. *
  5451. *
  5452. * You may configure overlay defaults during tool by providing a `config` module
  5453. * with `overlays.defaults` as an entry:
  5454. *
  5455. * {
  5456. * overlays: {
  5457. * defaults: {
  5458. * show: {
  5459. * minZoom: 0.7,
  5460. * maxZoom: 5.0
  5461. * },
  5462. * scale: {
  5463. * min: 1
  5464. * }
  5465. * }
  5466. * }
  5467. *
  5468. * @param {Object} config
  5469. * @param {EventBus} eventBus
  5470. * @param {Canvas} canvas
  5471. * @param {ElementRegistry} elementRegistry
  5472. */
  5473. function Overlays(config, eventBus, canvas, elementRegistry) {
  5474. this._eventBus = eventBus;
  5475. this._canvas = canvas;
  5476. this._elementRegistry = elementRegistry;
  5477. this._ids = ids;
  5478. this._overlayDefaults = assign({
  5479. // no show constraints
  5480. show: null,
  5481. // always scale
  5482. scale: true
  5483. }, config && config.defaults);
  5484. /**
  5485. * Mapping overlayId -> overlay
  5486. */
  5487. this._overlays = {};
  5488. /**
  5489. * Mapping elementId -> overlay container
  5490. */
  5491. this._overlayContainers = [];
  5492. // root html element for all overlays
  5493. this._overlayRoot = createRoot(canvas.getContainer());
  5494. this._init();
  5495. }
  5496. Overlays.$inject = [
  5497. 'config.overlays',
  5498. 'eventBus',
  5499. 'canvas',
  5500. 'elementRegistry'
  5501. ];
  5502. /**
  5503. * Returns the overlay with the specified id or a list of overlays
  5504. * for an element with a given type.
  5505. *
  5506. * @example
  5507. *
  5508. * // return the single overlay with the given id
  5509. * overlays.get('some-id');
  5510. *
  5511. * // return all overlays for the shape
  5512. * overlays.get({ element: someShape });
  5513. *
  5514. * // return all overlays on shape with type 'badge'
  5515. * overlays.get({ element: someShape, type: 'badge' });
  5516. *
  5517. * // shape can also be specified as id
  5518. * overlays.get({ element: 'element-id', type: 'badge' });
  5519. *
  5520. *
  5521. * @param {Object} search
  5522. * @param {string} [search.id]
  5523. * @param {string|djs.model.Base} [search.element]
  5524. * @param {string} [search.type]
  5525. *
  5526. * @return {Object|Array<Object>} the overlay(s)
  5527. */
  5528. Overlays.prototype.get = function (search) {
  5529. if (isString(search)) {
  5530. search = {id: search};
  5531. }
  5532. if (isString(search.element)) {
  5533. search.element = this._elementRegistry.get(search.element);
  5534. }
  5535. if (search.element) {
  5536. var container = this._getOverlayContainer(search.element, true);
  5537. // return a list of overlays when searching by element (+type)
  5538. if (container) {
  5539. return search.type ? filter(container.overlays, matchPattern({type: search.type})) : container.overlays.slice();
  5540. } else {
  5541. return [];
  5542. }
  5543. } else if (search.type) {
  5544. return filter(this._overlays, matchPattern({type: search.type}));
  5545. } else {
  5546. // return single element when searching by id
  5547. return search.id ? this._overlays[search.id] : null;
  5548. }
  5549. };
  5550. /**
  5551. * Adds a HTML overlay to an element.
  5552. *
  5553. * @param {string|djs.model.Base} element attach overlay to this shape
  5554. * @param {string} [type] optional type to assign to the overlay
  5555. * @param {Object} overlay the overlay configuration
  5556. *
  5557. * @param {string|DOMElement} overlay.html html element to use as an overlay
  5558. * @param {Object} [overlay.show] show configuration
  5559. * @param {number} [overlay.show.minZoom] minimal zoom level to show the overlay
  5560. * @param {number} [overlay.show.maxZoom] maximum zoom level to show the overlay
  5561. * @param {Object} overlay.position where to attach the overlay
  5562. * @param {number} [overlay.position.left] relative to element bbox left attachment
  5563. * @param {number} [overlay.position.top] relative to element bbox top attachment
  5564. * @param {number} [overlay.position.bottom] relative to element bbox bottom attachment
  5565. * @param {number} [overlay.position.right] relative to element bbox right attachment
  5566. * @param {boolean|Object} [overlay.scale=true] false to preserve the same size regardless of
  5567. * diagram zoom
  5568. * @param {number} [overlay.scale.min]
  5569. * @param {number} [overlay.scale.max]
  5570. *
  5571. * @return {string} id that may be used to reference the overlay for update or removal
  5572. */
  5573. Overlays.prototype.add = function (element, type, overlay) {
  5574. if (isObject(type)) {
  5575. overlay = type;
  5576. type = null;
  5577. }
  5578. if (!element.id) {
  5579. element = this._elementRegistry.get(element);
  5580. }
  5581. if (!overlay.position) {
  5582. throw new Error('must specifiy overlay position');
  5583. }
  5584. if (!overlay.html) {
  5585. throw new Error('must specifiy overlay html');
  5586. }
  5587. if (!element) {
  5588. throw new Error('invalid element specified');
  5589. }
  5590. var id = this._ids.next();
  5591. overlay = assign({}, this._overlayDefaults, overlay, {
  5592. id: id,
  5593. type: type,
  5594. element: element,
  5595. html: overlay.html
  5596. });
  5597. this._addOverlay(overlay);
  5598. return id;
  5599. };
  5600. /**
  5601. * Remove an overlay with the given id or all overlays matching the given filter.
  5602. *
  5603. * @see Overlays#get for filter options.
  5604. *
  5605. * @param {string} [id]
  5606. * @param {Object} [filter]
  5607. */
  5608. Overlays.prototype.remove = function (filter) {
  5609. var overlays = this.get(filter) || [];
  5610. if (!isArray(overlays)) {
  5611. overlays = [overlays];
  5612. }
  5613. var self = this;
  5614. forEach(overlays, function (overlay) {
  5615. var container = self._getOverlayContainer(overlay.element, true);
  5616. if (overlay) {
  5617. remove$1(overlay.html);
  5618. remove$1(overlay.htmlContainer);
  5619. delete overlay.htmlContainer;
  5620. delete overlay.element;
  5621. delete self._overlays[overlay.id];
  5622. }
  5623. if (container) {
  5624. var idx = container.overlays.indexOf(overlay);
  5625. if (idx !== -1) {
  5626. container.overlays.splice(idx, 1);
  5627. }
  5628. }
  5629. });
  5630. };
  5631. Overlays.prototype.show = function () {
  5632. setVisible(this._overlayRoot);
  5633. };
  5634. Overlays.prototype.hide = function () {
  5635. setVisible(this._overlayRoot, false);
  5636. };
  5637. Overlays.prototype.clear = function () {
  5638. this._overlays = {};
  5639. this._overlayContainers = [];
  5640. clear$1(this._overlayRoot);
  5641. };
  5642. Overlays.prototype._updateOverlayContainer = function (container) {
  5643. var element = container.element,
  5644. html = container.html;
  5645. // update container left,top according to the elements x,y coordinates
  5646. // this ensures we can attach child elements relative to this container
  5647. var x = element.x,
  5648. y = element.y;
  5649. if (element.waypoints) {
  5650. var bbox = getBBox(element);
  5651. x = bbox.x;
  5652. y = bbox.y;
  5653. }
  5654. setPosition(html, x, y);
  5655. attr$1(container.html, 'data-container-id', element.id);
  5656. };
  5657. Overlays.prototype._updateOverlay = function (overlay) {
  5658. var position = overlay.position,
  5659. htmlContainer = overlay.htmlContainer,
  5660. element = overlay.element;
  5661. // update overlay html relative to shape because
  5662. // it is already positioned on the element
  5663. // update relative
  5664. var left = position.left,
  5665. top = position.top;
  5666. if (position.right !== undefined) {
  5667. var width;
  5668. if (element.waypoints) {
  5669. width = getBBox(element).width;
  5670. } else {
  5671. width = element.width;
  5672. }
  5673. left = position.right * -1 + width;
  5674. }
  5675. if (position.bottom !== undefined) {
  5676. var height;
  5677. if (element.waypoints) {
  5678. height = getBBox(element).height;
  5679. } else {
  5680. height = element.height;
  5681. }
  5682. top = position.bottom * -1 + height;
  5683. }
  5684. setPosition(htmlContainer, left || 0, top || 0);
  5685. };
  5686. Overlays.prototype._createOverlayContainer = function (element) {
  5687. var html = domify('<div class="djs-overlays" style="position: absolute" />');
  5688. this._overlayRoot.appendChild(html);
  5689. var container = {
  5690. html: html,
  5691. element: element,
  5692. overlays: []
  5693. };
  5694. this._updateOverlayContainer(container);
  5695. this._overlayContainers.push(container);
  5696. return container;
  5697. };
  5698. Overlays.prototype._updateRoot = function (viewbox) {
  5699. var scale = viewbox.scale || 1;
  5700. var matrix = 'matrix(' +
  5701. [
  5702. scale,
  5703. 0,
  5704. 0,
  5705. scale,
  5706. -1 * viewbox.x * scale,
  5707. -1 * viewbox.y * scale
  5708. ].join(',') +
  5709. ')';
  5710. setTransform(this._overlayRoot, matrix);
  5711. };
  5712. Overlays.prototype._getOverlayContainer = function (element, raw) {
  5713. var container = find(this._overlayContainers, function (c) {
  5714. return c.element === element;
  5715. });
  5716. if (!container && !raw) {
  5717. return this._createOverlayContainer(element);
  5718. }
  5719. return container;
  5720. };
  5721. Overlays.prototype._addOverlay = function (overlay) {
  5722. var id = overlay.id,
  5723. element = overlay.element,
  5724. html = overlay.html,
  5725. htmlContainer,
  5726. overlayContainer;
  5727. // unwrap jquery (for those who need it)
  5728. if (html.get && html.constructor.prototype.jquery) {
  5729. html = html.get(0);
  5730. }
  5731. // create proper html elements from
  5732. // overlay HTML strings
  5733. if (isString(html)) {
  5734. html = domify(html);
  5735. }
  5736. overlayContainer = this._getOverlayContainer(element);
  5737. htmlContainer = domify('<div class="djs-overlay" data-overlay-id="' + id + '" style="position: absolute">');
  5738. htmlContainer.appendChild(html);
  5739. if (overlay.type) {
  5740. classes$1(htmlContainer).add('djs-overlay-' + overlay.type);
  5741. }
  5742. overlay.htmlContainer = htmlContainer;
  5743. overlayContainer.overlays.push(overlay);
  5744. overlayContainer.html.appendChild(htmlContainer);
  5745. this._overlays[id] = overlay;
  5746. this._updateOverlay(overlay);
  5747. this._updateOverlayVisibilty(overlay, this._canvas.viewbox());
  5748. };
  5749. Overlays.prototype._updateOverlayVisibilty = function (overlay, viewbox) {
  5750. var show = overlay.show,
  5751. minZoom = show && show.minZoom,
  5752. maxZoom = show && show.maxZoom,
  5753. htmlContainer = overlay.htmlContainer,
  5754. visible = true;
  5755. if (show) {
  5756. if (
  5757. (isDefined(minZoom) && minZoom > viewbox.scale) ||
  5758. (isDefined(maxZoom) && maxZoom < viewbox.scale)
  5759. ) {
  5760. visible = false;
  5761. }
  5762. setVisible(htmlContainer, visible);
  5763. }
  5764. this._updateOverlayScale(overlay, viewbox);
  5765. };
  5766. Overlays.prototype._updateOverlayScale = function (overlay, viewbox) {
  5767. var shouldScale = overlay.scale,
  5768. minScale,
  5769. maxScale,
  5770. htmlContainer = overlay.htmlContainer;
  5771. var scale, transform = '';
  5772. if (shouldScale !== true) {
  5773. if (shouldScale === false) {
  5774. minScale = 1;
  5775. maxScale = 1;
  5776. } else {
  5777. minScale = shouldScale.min;
  5778. maxScale = shouldScale.max;
  5779. }
  5780. if (isDefined(minScale) && viewbox.scale < minScale) {
  5781. scale = (1 / viewbox.scale || 1) * minScale;
  5782. }
  5783. if (isDefined(maxScale) && viewbox.scale > maxScale) {
  5784. scale = (1 / viewbox.scale || 1) * maxScale;
  5785. }
  5786. }
  5787. if (isDefined(scale)) {
  5788. transform = 'scale(' + scale + ',' + scale + ')';
  5789. }
  5790. setTransform(htmlContainer, transform);
  5791. };
  5792. Overlays.prototype._updateOverlaysVisibilty = function (viewbox) {
  5793. var self = this;
  5794. forEach(this._overlays, function (overlay) {
  5795. self._updateOverlayVisibilty(overlay, viewbox);
  5796. });
  5797. };
  5798. Overlays.prototype._init = function () {
  5799. var eventBus = this._eventBus;
  5800. var self = this;
  5801. // scroll/zoom integration
  5802. function updateViewbox(viewbox) {
  5803. self._updateRoot(viewbox);
  5804. self._updateOverlaysVisibilty(viewbox);
  5805. self.show();
  5806. }
  5807. eventBus.on('canvas.viewbox.changing', function (event) {
  5808. self.hide();
  5809. });
  5810. eventBus.on('canvas.viewbox.changed', function (event) {
  5811. updateViewbox(event.viewbox);
  5812. });
  5813. // remove integration
  5814. eventBus.on(['shape.remove', 'connection.remove'], function (e) {
  5815. var element = e.element;
  5816. var overlays = self.get({element: element});
  5817. forEach(overlays, function (o) {
  5818. self.remove(o.id);
  5819. });
  5820. var container = self._getOverlayContainer(element);
  5821. if (container) {
  5822. remove$1(container.html);
  5823. var i = self._overlayContainers.indexOf(container);
  5824. if (i !== -1) {
  5825. self._overlayContainers.splice(i, 1);
  5826. }
  5827. }
  5828. });
  5829. // move integration
  5830. eventBus.on('element.changed', LOW_PRIORITY$2, function (e) {
  5831. var element = e.element;
  5832. var container = self._getOverlayContainer(element, true);
  5833. if (container) {
  5834. forEach(container.overlays, function (overlay) {
  5835. self._updateOverlay(overlay);
  5836. });
  5837. self._updateOverlayContainer(container);
  5838. }
  5839. });
  5840. // marker integration, simply add them on the overlays as classes, too.
  5841. eventBus.on('element.marker.update', function (e) {
  5842. var container = self._getOverlayContainer(e.element, true);
  5843. if (container) {
  5844. classes$1(container.html)[e.add ? 'add' : 'remove'](e.marker);
  5845. }
  5846. });
  5847. // clear overlays with diagram
  5848. eventBus.on('diagram.clear', this.clear, this);
  5849. };
  5850. // helpers /////////////////////////////
  5851. function createRoot(parentNode) {
  5852. var root = domify(
  5853. '<div class="djs-overlay-container" style="position: absolute; width: 0; height: 0;" />'
  5854. );
  5855. parentNode.insertBefore(root, parentNode.firstChild);
  5856. return root;
  5857. }
  5858. function setPosition(el, x, y) {
  5859. assign(el.style, {left: x + 'px', top: y + 'px'});
  5860. }
  5861. function setVisible(el, visible) {
  5862. el.style.display = visible === false ? 'none' : '';
  5863. }
  5864. function setTransform(el, transform) {
  5865. el.style['transform-origin'] = 'top left';
  5866. ['', '-ms-', '-webkit-'].forEach(function (prefix) {
  5867. el.style[prefix + 'transform'] = transform;
  5868. });
  5869. }
  5870. var OverlaysModule = {
  5871. __init__: ['overlays'],
  5872. overlays: ['type', Overlays]
  5873. };
  5874. var CLASS_PATTERN = /^class /;
  5875. function isClass(fn) {
  5876. return CLASS_PATTERN.test(fn.toString());
  5877. }
  5878. function isArray$1(obj) {
  5879. return Object.prototype.toString.call(obj) === '[object Array]';
  5880. }
  5881. function annotate() {
  5882. var args = Array.prototype.slice.call(arguments);
  5883. if (args.length === 1 && isArray$1(args[0])) {
  5884. args = args[0];
  5885. }
  5886. var fn = args.pop();
  5887. fn.$inject = args;
  5888. return fn;
  5889. }
  5890. // Current limitations:
  5891. // - can't put into "function arg" comments
  5892. // function /* (no parenthesis like this) */ (){}
  5893. // function abc( /* xx (no parenthesis like this) */ a, b) {}
  5894. //
  5895. // Just put the comment before function or inside:
  5896. // /* (((this is fine))) */ function(a, b) {}
  5897. // function abc(a) { /* (((this is fine))) */}
  5898. //
  5899. // - can't reliably auto-annotate constructor; we'll match the
  5900. // first constructor(...) pattern found which may be the one
  5901. // of a nested class, too.
  5902. var CONSTRUCTOR_ARGS = /constructor\s*[^(]*\(\s*([^)]*)\)/m;
  5903. var FN_ARGS = /^function\s*[^(]*\(\s*([^)]*)\)/m;
  5904. var FN_ARG = /\/\*([^*]*)\*\//m;
  5905. function parse$2(fn) {
  5906. if (typeof fn !== 'function') {
  5907. throw new Error('Cannot annotate "' + fn + '". Expected a function!');
  5908. }
  5909. var match = fn.toString().match(isClass(fn) ? CONSTRUCTOR_ARGS : FN_ARGS);
  5910. // may parse class without constructor
  5911. if (!match) {
  5912. return [];
  5913. }
  5914. return match[1] && match[1].split(',').map(function (arg) {
  5915. match = arg.match(FN_ARG);
  5916. return match ? match[1].trim() : arg.trim();
  5917. }) || [];
  5918. }
  5919. function Module() {
  5920. var providers = [];
  5921. this.factory = function (name, factory) {
  5922. providers.push([name, 'factory', factory]);
  5923. return this;
  5924. };
  5925. this.value = function (name, value) {
  5926. providers.push([name, 'value', value]);
  5927. return this;
  5928. };
  5929. this.type = function (name, type) {
  5930. providers.push([name, 'type', type]);
  5931. return this;
  5932. };
  5933. this.forEach = function (iterator) {
  5934. providers.forEach(iterator);
  5935. };
  5936. }
  5937. var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) {
  5938. return typeof obj;
  5939. } : function (obj) {
  5940. return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
  5941. };
  5942. function _toConsumableArray(arr) {
  5943. if (Array.isArray(arr)) {
  5944. for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) {
  5945. arr2[i] = arr[i];
  5946. }
  5947. return arr2;
  5948. } else {
  5949. return Array.from(arr);
  5950. }
  5951. }
  5952. function Injector(modules, parent) {
  5953. parent = parent || {
  5954. get: function get(name, strict) {
  5955. currentlyResolving.push(name);
  5956. if (strict === false) {
  5957. return null;
  5958. } else {
  5959. throw error('No provider for "' + name + '"!');
  5960. }
  5961. }
  5962. };
  5963. var currentlyResolving = [];
  5964. var providers = this._providers = Object.create(parent._providers || null);
  5965. var instances = this._instances = Object.create(null);
  5966. var self = instances.injector = this;
  5967. var error = function error(msg) {
  5968. var stack = currentlyResolving.join(' -> ');
  5969. currentlyResolving.length = 0;
  5970. return new Error(stack ? msg + ' (Resolving: ' + stack + ')' : msg);
  5971. };
  5972. /**
  5973. * Return a named service.
  5974. *
  5975. * @param {String} name
  5976. * @param {Boolean} [strict=true] if false, resolve missing services to null
  5977. *
  5978. * @return {Object}
  5979. */
  5980. var get = function get(name, strict) {
  5981. if (!providers[name] && name.indexOf('.') !== -1) {
  5982. var parts = name.split('.');
  5983. var pivot = get(parts.shift());
  5984. while (parts.length) {
  5985. pivot = pivot[parts.shift()];
  5986. }
  5987. return pivot;
  5988. }
  5989. if (hasProp(instances, name)) {
  5990. return instances[name];
  5991. }
  5992. if (hasProp(providers, name)) {
  5993. if (currentlyResolving.indexOf(name) !== -1) {
  5994. currentlyResolving.push(name);
  5995. throw error('Cannot resolve circular dependency!');
  5996. }
  5997. currentlyResolving.push(name);
  5998. instances[name] = providers[name][0](providers[name][1]);
  5999. currentlyResolving.pop();
  6000. return instances[name];
  6001. }
  6002. return parent.get(name, strict);
  6003. };
  6004. var fnDef = function fnDef(fn) {
  6005. var locals = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  6006. if (typeof fn !== 'function') {
  6007. if (isArray$1(fn)) {
  6008. fn = annotate(fn.slice());
  6009. } else {
  6010. throw new Error('Cannot invoke "' + fn + '". Expected a function!');
  6011. }
  6012. }
  6013. var inject = fn.$inject || parse$2(fn);
  6014. var dependencies = inject.map(function (dep) {
  6015. if (hasProp(locals, dep)) {
  6016. return locals[dep];
  6017. } else {
  6018. return get(dep);
  6019. }
  6020. });
  6021. return {
  6022. fn: fn,
  6023. dependencies: dependencies
  6024. };
  6025. };
  6026. var instantiate = function instantiate(Type) {
  6027. var _fnDef = fnDef(Type),
  6028. dependencies = _fnDef.dependencies,
  6029. fn = _fnDef.fn;
  6030. return new (Function.prototype.bind.apply(fn, [null].concat(_toConsumableArray(dependencies))))();
  6031. };
  6032. var invoke = function invoke(func, context, locals) {
  6033. var _fnDef2 = fnDef(func, locals),
  6034. dependencies = _fnDef2.dependencies,
  6035. fn = _fnDef2.fn;
  6036. return fn.call.apply(fn, [context].concat(_toConsumableArray(dependencies)));
  6037. };
  6038. var createPrivateInjectorFactory = function createPrivateInjectorFactory(privateChildInjector) {
  6039. return annotate(function (key) {
  6040. return privateChildInjector.get(key);
  6041. });
  6042. };
  6043. var createChild = function createChild(modules, forceNewInstances) {
  6044. if (forceNewInstances && forceNewInstances.length) {
  6045. var fromParentModule = Object.create(null);
  6046. var matchedScopes = Object.create(null);
  6047. var privateInjectorsCache = [];
  6048. var privateChildInjectors = [];
  6049. var privateChildFactories = [];
  6050. var provider;
  6051. var cacheIdx;
  6052. var privateChildInjector;
  6053. var privateChildInjectorFactory;
  6054. for (var name in providers) {
  6055. provider = providers[name];
  6056. if (forceNewInstances.indexOf(name) !== -1) {
  6057. if (provider[2] === 'private') {
  6058. cacheIdx = privateInjectorsCache.indexOf(provider[3]);
  6059. if (cacheIdx === -1) {
  6060. privateChildInjector = provider[3].createChild([], forceNewInstances);
  6061. privateChildInjectorFactory = createPrivateInjectorFactory(privateChildInjector);
  6062. privateInjectorsCache.push(provider[3]);
  6063. privateChildInjectors.push(privateChildInjector);
  6064. privateChildFactories.push(privateChildInjectorFactory);
  6065. fromParentModule[name] = [privateChildInjectorFactory, name, 'private', privateChildInjector];
  6066. } else {
  6067. fromParentModule[name] = [privateChildFactories[cacheIdx], name, 'private', privateChildInjectors[cacheIdx]];
  6068. }
  6069. } else {
  6070. fromParentModule[name] = [provider[2], provider[1]];
  6071. }
  6072. matchedScopes[name] = true;
  6073. }
  6074. if ((provider[2] === 'factory' || provider[2] === 'type') && provider[1].$scope) {
  6075. /* jshint -W083 */
  6076. forceNewInstances.forEach(function (scope) {
  6077. if (provider[1].$scope.indexOf(scope) !== -1) {
  6078. fromParentModule[name] = [provider[2], provider[1]];
  6079. matchedScopes[scope] = true;
  6080. }
  6081. });
  6082. }
  6083. }
  6084. forceNewInstances.forEach(function (scope) {
  6085. if (!matchedScopes[scope]) {
  6086. throw new Error('No provider for "' + scope + '". Cannot use provider from the parent!');
  6087. }
  6088. });
  6089. modules.unshift(fromParentModule);
  6090. }
  6091. return new Injector(modules, self);
  6092. };
  6093. var factoryMap = {
  6094. factory: invoke,
  6095. type: instantiate,
  6096. value: function value(_value) {
  6097. return _value;
  6098. }
  6099. };
  6100. modules.forEach(function (module) {
  6101. function arrayUnwrap(type, value) {
  6102. if (type !== 'value' && isArray$1(value)) {
  6103. value = annotate(value.slice());
  6104. }
  6105. return value;
  6106. }
  6107. // TODO(vojta): handle wrong inputs (modules)
  6108. if (module instanceof Module) {
  6109. module.forEach(function (provider) {
  6110. var name = provider[0];
  6111. var type = provider[1];
  6112. var value = provider[2];
  6113. providers[name] = [factoryMap[type], arrayUnwrap(type, value), type];
  6114. });
  6115. } else if ((typeof module === 'undefined' ? 'undefined' : _typeof(module)) === 'object') {
  6116. if (module.__exports__) {
  6117. var clonedModule = Object.keys(module).reduce(function (m, key) {
  6118. if (key.substring(0, 2) !== '__') {
  6119. m[key] = module[key];
  6120. }
  6121. return m;
  6122. }, Object.create(null));
  6123. var privateInjector = new Injector((module.__modules__ || []).concat([clonedModule]), self);
  6124. var getFromPrivateInjector = annotate(function (key) {
  6125. return privateInjector.get(key);
  6126. });
  6127. module.__exports__.forEach(function (key) {
  6128. providers[key] = [getFromPrivateInjector, key, 'private', privateInjector];
  6129. });
  6130. } else {
  6131. Object.keys(module).forEach(function (name) {
  6132. if (module[name][2] === 'private') {
  6133. providers[name] = module[name];
  6134. return;
  6135. }
  6136. var type = module[name][0];
  6137. var value = module[name][1];
  6138. providers[name] = [factoryMap[type], arrayUnwrap(type, value), type];
  6139. });
  6140. }
  6141. }
  6142. });
  6143. // public API
  6144. this.get = get;
  6145. this.invoke = invoke;
  6146. this.instantiate = instantiate;
  6147. this.createChild = createChild;
  6148. }
  6149. // helpers /////////////////
  6150. function hasProp(obj, prop) {
  6151. return Object.hasOwnProperty.call(obj, prop);
  6152. }
  6153. // apply default renderer with lowest possible priority
  6154. // so that it only kicks in if noone else could render
  6155. var DEFAULT_RENDER_PRIORITY$1 = 1;
  6156. /**
  6157. * The default renderer used for shapes and connections.
  6158. *
  6159. * @param {EventBus} eventBus
  6160. * @param {Styles} styles
  6161. */
  6162. function DefaultRenderer(eventBus, styles) {
  6163. //
  6164. BaseRenderer.call(this, eventBus, DEFAULT_RENDER_PRIORITY$1);
  6165. this.CONNECTION_STYLE = styles.style(['no-fill'], {strokeWidth: 5, stroke: 'fuchsia'});
  6166. this.SHAPE_STYLE = styles.style({fill: 'white', stroke: 'fuchsia', strokeWidth: 2});
  6167. this.FRAME_STYLE = styles.style(['no-fill'], {stroke: 'fuchsia', strokeDasharray: 4, strokeWidth: 2});
  6168. }
  6169. inherits_browser(DefaultRenderer, BaseRenderer);
  6170. DefaultRenderer.prototype.canRender = function () {
  6171. return true;
  6172. };
  6173. DefaultRenderer.prototype.drawShape = function drawShape(visuals, element) {
  6174. var rect = create('rect');
  6175. attr(rect, {
  6176. x: 0,
  6177. y: 0,
  6178. width: element.width || 0,
  6179. height: element.height || 0
  6180. });
  6181. if (isFrameElement$1(element)) {
  6182. attr(rect, this.FRAME_STYLE);
  6183. } else {
  6184. attr(rect, this.SHAPE_STYLE);
  6185. }
  6186. append(visuals, rect);
  6187. return rect;
  6188. };
  6189. DefaultRenderer.prototype.drawConnection = function drawConnection(visuals, connection) {
  6190. var line = createLine(connection.waypoints, this.CONNECTION_STYLE);
  6191. append(visuals, line);
  6192. return line;
  6193. };
  6194. DefaultRenderer.prototype.getShapePath = function getShapePath(shape) {
  6195. var x = shape.x,
  6196. y = shape.y,
  6197. width = shape.width,
  6198. height = shape.height;
  6199. var shapePath = [
  6200. ['M', x, y],
  6201. ['l', width, 0],
  6202. ['l', 0, height],
  6203. ['l', -width, 0],
  6204. ['z']
  6205. ];
  6206. return componentsToPath(shapePath);
  6207. };
  6208. DefaultRenderer.prototype.getConnectionPath = function getConnectionPath(connection) {
  6209. var waypoints = connection.waypoints;
  6210. var idx, point, connectionPath = [];
  6211. for (idx = 0; (point = waypoints[idx]); idx++) {
  6212. // take invisible docking into account
  6213. // when creating the path
  6214. point = point.original || point;
  6215. connectionPath.push([idx === 0 ? 'M' : 'L', point.x, point.y]);
  6216. }
  6217. return componentsToPath(connectionPath);
  6218. };
  6219. DefaultRenderer.$inject = ['eventBus', 'styles'];
  6220. /**
  6221. * A component that manages shape styles
  6222. */
  6223. function Styles() {
  6224. var defaultTraits = {
  6225. 'no-fill': {
  6226. fill: 'none'
  6227. },
  6228. 'no-border': {
  6229. strokeOpacity: 0.0
  6230. },
  6231. 'no-events': {
  6232. pointerEvents: 'none'
  6233. }
  6234. };
  6235. var self = this;
  6236. /**
  6237. * Builds a style definition from a className, a list of traits and an object of additional attributes.
  6238. *
  6239. * @param {string} className
  6240. * @param {Array<string>} traits
  6241. * @param {Object} additionalAttrs
  6242. *
  6243. * @return {Object} the style defintion
  6244. */
  6245. this.cls = function (className, traits, additionalAttrs) {
  6246. var attrs = this.style(traits, additionalAttrs);
  6247. return assign(attrs, {'class': className});
  6248. };
  6249. /**
  6250. * Builds a style definition from a list of traits and an object of additional attributes.
  6251. *
  6252. * @param {Array<string>} traits
  6253. * @param {Object} additionalAttrs
  6254. *
  6255. * @return {Object} the style defintion
  6256. */
  6257. this.style = function (traits, additionalAttrs) {
  6258. if (!isArray(traits) && !additionalAttrs) {
  6259. additionalAttrs = traits;
  6260. traits = [];
  6261. }
  6262. var attrs = reduce(traits, function (attrs, t) {
  6263. return assign(attrs, defaultTraits[t] || {});
  6264. }, {});
  6265. return additionalAttrs ? assign(attrs, additionalAttrs) : attrs;
  6266. };
  6267. this.computeStyle = function (custom, traits, defaultStyles) {
  6268. if (!isArray(traits)) {
  6269. defaultStyles = traits;
  6270. traits = [];
  6271. }
  6272. return self.style(traits || [], assign({}, defaultStyles, custom || {}));
  6273. };
  6274. }
  6275. var DrawModule$1 = {
  6276. __init__: ['defaultRenderer'],
  6277. defaultRenderer: ['type', DefaultRenderer],
  6278. styles: ['type', Styles]
  6279. };
  6280. /**
  6281. * Failsafe remove an element from a collection
  6282. *
  6283. * @param {Array<Object>} [collection]
  6284. * @param {Object} [element]
  6285. *
  6286. * @return {number} the previous index of the element
  6287. */
  6288. function remove$2(collection, element) {
  6289. if (!collection || !element) {
  6290. return -1;
  6291. }
  6292. var idx = collection.indexOf(element);
  6293. if (idx !== -1) {
  6294. collection.splice(idx, 1);
  6295. }
  6296. return idx;
  6297. }
  6298. /**
  6299. * Fail save add an element to the given connection, ensuring
  6300. * it does not yet exist.
  6301. *
  6302. * @param {Array<Object>} collection
  6303. * @param {Object} element
  6304. * @param {number} idx
  6305. */
  6306. function add(collection, element, idx) {
  6307. if (!collection || !element) {
  6308. return;
  6309. }
  6310. if (typeof idx !== 'number') {
  6311. idx = -1;
  6312. }
  6313. var currentIdx = collection.indexOf(element);
  6314. if (currentIdx !== -1) {
  6315. if (currentIdx === idx) {
  6316. // nothing to do, position has not changed
  6317. return;
  6318. } else {
  6319. if (idx !== -1) {
  6320. // remove from current position
  6321. collection.splice(currentIdx, 1);
  6322. } else {
  6323. // already exists in collection
  6324. return;
  6325. }
  6326. }
  6327. }
  6328. if (idx !== -1) {
  6329. // insert at specified position
  6330. collection.splice(idx, 0, element);
  6331. } else {
  6332. // push to end
  6333. collection.push(element);
  6334. }
  6335. }
  6336. function round(number, resolution) {
  6337. return Math.round(number * resolution) / resolution;
  6338. }
  6339. function ensurePx(number) {
  6340. return isNumber(number) ? number + 'px' : number;
  6341. }
  6342. /**
  6343. * Creates a HTML container element for a SVG element with
  6344. * the given configuration
  6345. *
  6346. * @param {Object} options
  6347. * @return {HTMLElement} the container element
  6348. */
  6349. function createContainer(options) {
  6350. options = assign({}, {width: '100%', height: '100%'}, options);
  6351. var container = options.container || document.body;
  6352. // create a <div> around the svg element with the respective size
  6353. // this way we can always get the correct container size
  6354. // (this is impossible for <svg> elements at the moment)
  6355. var parent = document.createElement('div');
  6356. parent.setAttribute('class', 'djs-container');
  6357. assign(parent.style, {
  6358. position: 'relative',
  6359. overflow: 'hidden',
  6360. width: ensurePx(options.width),
  6361. height: ensurePx(options.height)
  6362. });
  6363. container.appendChild(parent);
  6364. return parent;
  6365. }
  6366. function createGroup(parent, cls, childIndex) {
  6367. var group = create('g');
  6368. classes(group).add(cls);
  6369. var index = childIndex !== undefined ? childIndex : parent.childNodes.length - 1;
  6370. // must ensure second argument is node or _null_
  6371. // cf. https://developer.mozilla.org/en-US/docs/Web/API/Node/insertBefore
  6372. parent.insertBefore(group, parent.childNodes[index] || null);
  6373. return group;
  6374. }
  6375. var BASE_LAYER = 'base';
  6376. var REQUIRED_MODEL_ATTRS = {
  6377. shape: ['x', 'y', 'width', 'height'],
  6378. connection: ['waypoints']
  6379. };
  6380. /**
  6381. * The main drawing canvas.
  6382. *
  6383. * @class
  6384. * @constructor
  6385. *
  6386. * @emits Canvas#canvas.init
  6387. *
  6388. * @param {Object} config
  6389. * @param {EventBus} eventBus
  6390. * @param {GraphicsFactory} graphicsFactory
  6391. * @param {ElementRegistry} elementRegistry
  6392. */
  6393. function Canvas(config, eventBus, graphicsFactory, elementRegistry) {
  6394. this._eventBus = eventBus;
  6395. this._elementRegistry = elementRegistry;
  6396. this._graphicsFactory = graphicsFactory;
  6397. this._init(config || {});
  6398. }
  6399. Canvas.$inject = [
  6400. 'config.canvas',
  6401. 'eventBus',
  6402. 'graphicsFactory',
  6403. 'elementRegistry'
  6404. ];
  6405. Canvas.prototype._init = function (config) {
  6406. var eventBus = this._eventBus;
  6407. // Creates a <svg> element that is wrapped into a <div>.
  6408. // This way we are always able to correctly figure out the size of the svg element
  6409. // by querying the parent node.
  6410. //
  6411. // (It is not possible to get the size of a svg element cross browser @ 2014-04-01)
  6412. //
  6413. // <div class="djs-container" style="width: {desired-width}, height: {desired-height}">
  6414. // <svg width="100%" height="100%">
  6415. // ...
  6416. // </svg>
  6417. // </div>
  6418. // html container
  6419. var container = this._container = createContainer(config);
  6420. var svg = this._svg = create('svg');
  6421. attr(svg, {width: '100%', height: '100%'});
  6422. append(container, svg);
  6423. var viewport = this._viewport = createGroup(svg, 'viewport');
  6424. this._layers = {};
  6425. // debounce canvas.viewbox.changed events
  6426. // for smoother diagram interaction
  6427. if (config.deferUpdate !== false) {
  6428. this._viewboxChanged = debounce(bind(this._viewboxChanged, this), 300);
  6429. }
  6430. eventBus.on('diagram.init', function () {
  6431. /**
  6432. * An event indicating that the canvas is ready to be drawn on.
  6433. *
  6434. * @memberOf Canvas
  6435. *
  6436. * @event canvas.init
  6437. *
  6438. * @type {Object}
  6439. * @property {SVGElement} svg the created svg element
  6440. * @property {SVGElement} viewport the direct parent of diagram elements and shapes
  6441. */
  6442. eventBus.fire('canvas.init', {
  6443. svg: svg,
  6444. viewport: viewport
  6445. });
  6446. }, this);
  6447. // reset viewbox on shape changes to
  6448. // recompute the viewbox
  6449. eventBus.on([
  6450. 'shape.added',
  6451. 'connection.added',
  6452. 'shape.removed',
  6453. 'connection.removed',
  6454. 'elements.changed'
  6455. ], function () {
  6456. delete this._cachedViewbox;
  6457. }, this);
  6458. eventBus.on('diagram.destroy', 500, this._destroy, this);
  6459. eventBus.on('diagram.clear', 500, this._clear, this);
  6460. };
  6461. Canvas.prototype._destroy = function (emit) {
  6462. this._eventBus.fire('canvas.destroy', {
  6463. svg: this._svg,
  6464. viewport: this._viewport
  6465. });
  6466. var parent = this._container.parentNode;
  6467. if (parent) {
  6468. parent.removeChild(this._container);
  6469. }
  6470. delete this._svg;
  6471. delete this._container;
  6472. delete this._layers;
  6473. delete this._rootElement;
  6474. delete this._viewport;
  6475. };
  6476. Canvas.prototype._clear = function () {
  6477. var self = this;
  6478. var allElements = this._elementRegistry.getAll();
  6479. // remove all elements
  6480. allElements.forEach(function (element) {
  6481. var type = getType(element);
  6482. if (type === 'root') {
  6483. self.setRootElement(null, true);
  6484. } else {
  6485. self._removeElement(element, type);
  6486. }
  6487. });
  6488. // force recomputation of view box
  6489. delete this._cachedViewbox;
  6490. };
  6491. /**
  6492. * Returns the default layer on which
  6493. * all elements are drawn.
  6494. *
  6495. * @returns {SVGElement}
  6496. */
  6497. Canvas.prototype.getDefaultLayer = function () {
  6498. return this.getLayer(BASE_LAYER, 0);
  6499. };
  6500. /**
  6501. * Returns a layer that is used to draw elements
  6502. * or annotations on it.
  6503. *
  6504. * Non-existing layers retrieved through this method
  6505. * will be created. During creation, the optional index
  6506. * may be used to create layers below or above existing layers.
  6507. * A layer with a certain index is always created above all
  6508. * existing layers with the same index.
  6509. *
  6510. * @param {string} name
  6511. * @param {number} index
  6512. *
  6513. * @returns {SVGElement}
  6514. */
  6515. Canvas.prototype.getLayer = function (name, index) {
  6516. if (!name) {
  6517. throw new Error('must specify a name');
  6518. }
  6519. var layer = this._layers[name];
  6520. if (!layer) {
  6521. layer = this._layers[name] = this._createLayer(name, index);
  6522. }
  6523. // throw an error if layer creation / retrival is
  6524. // requested on different index
  6525. if (typeof index !== 'undefined' && layer.index !== index) {
  6526. throw new Error('layer <' + name + '> already created at index <' + index + '>');
  6527. }
  6528. return layer.group;
  6529. };
  6530. /**
  6531. * Creates a given layer and returns it.
  6532. *
  6533. * @param {string} name
  6534. * @param {number} [index=0]
  6535. *
  6536. * @return {Object} layer descriptor with { index, group: SVGGroup }
  6537. */
  6538. Canvas.prototype._createLayer = function (name, index) {
  6539. if (!index) {
  6540. index = 0;
  6541. }
  6542. var childIndex = reduce(this._layers, function (childIndex, layer) {
  6543. if (index >= layer.index) {
  6544. childIndex++;
  6545. }
  6546. return childIndex;
  6547. }, 0);
  6548. return {
  6549. group: createGroup(this._viewport, 'layer-' + name, childIndex),
  6550. index: index
  6551. };
  6552. };
  6553. /**
  6554. * Returns the html element that encloses the
  6555. * drawing canvas.
  6556. *
  6557. * @return {DOMNode}
  6558. */
  6559. Canvas.prototype.getContainer = function () {
  6560. return this._container;
  6561. };
  6562. // markers //////////////////////
  6563. Canvas.prototype._updateMarker = function (element, marker, add) {
  6564. var container;
  6565. if (!element.id) {
  6566. element = this._elementRegistry.get(element);
  6567. }
  6568. // we need to access all
  6569. container = this._elementRegistry._elements[element.id];
  6570. if (!container) {
  6571. return;
  6572. }
  6573. forEach([container.gfx, container.secondaryGfx], function (gfx) {
  6574. if (gfx) {
  6575. // invoke either addClass or removeClass based on mode
  6576. if (add) {
  6577. classes(gfx).add(marker);
  6578. } else {
  6579. classes(gfx).remove(marker);
  6580. }
  6581. }
  6582. });
  6583. /**
  6584. * An event indicating that a marker has been updated for an element
  6585. *
  6586. * @event element.marker.update
  6587. * @type {Object}
  6588. * @property {djs.model.Element} element the shape
  6589. * @property {Object} gfx the graphical representation of the shape
  6590. * @property {string} marker
  6591. * @property {boolean} add true if the marker was added, false if it got removed
  6592. */
  6593. this._eventBus.fire('element.marker.update', {
  6594. element: element,
  6595. gfx: container.gfx,
  6596. marker: marker,
  6597. add: !!add
  6598. });
  6599. };
  6600. /**
  6601. * Adds a marker to an element (basically a css class).
  6602. *
  6603. * Fires the element.marker.update event, making it possible to
  6604. * integrate extension into the marker life-cycle, too.
  6605. *
  6606. * @example
  6607. * canvas.addMarker('foo', 'some-marker');
  6608. *
  6609. * var fooGfx = canvas.getGraphics('foo');
  6610. *
  6611. * fooGfx; // <g class="... some-marker"> ... </g>
  6612. *
  6613. * @param {string|djs.model.Base} element
  6614. * @param {string} marker
  6615. */
  6616. Canvas.prototype.addMarker = function (element, marker) {
  6617. this._updateMarker(element, marker, true);
  6618. };
  6619. /**
  6620. * Remove a marker from an element.
  6621. *
  6622. * Fires the element.marker.update event, making it possible to
  6623. * integrate extension into the marker life-cycle, too.
  6624. *
  6625. * @param {string|djs.model.Base} element
  6626. * @param {string} marker
  6627. */
  6628. Canvas.prototype.removeMarker = function (element, marker) {
  6629. this._updateMarker(element, marker, false);
  6630. };
  6631. /**
  6632. * Check the existence of a marker on element.
  6633. *
  6634. * @param {string|djs.model.Base} element
  6635. * @param {string} marker
  6636. */
  6637. Canvas.prototype.hasMarker = function (element, marker) {
  6638. if (!element.id) {
  6639. element = this._elementRegistry.get(element);
  6640. }
  6641. var gfx = this.getGraphics(element);
  6642. return classes(gfx).has(marker);
  6643. };
  6644. /**
  6645. * Toggles a marker on an element.
  6646. *
  6647. * Fires the element.marker.update event, making it possible to
  6648. * integrate extension into the marker life-cycle, too.
  6649. *
  6650. * @param {string|djs.model.Base} element
  6651. * @param {string} marker
  6652. */
  6653. Canvas.prototype.toggleMarker = function (element, marker) {
  6654. if (this.hasMarker(element, marker)) {
  6655. this.removeMarker(element, marker);
  6656. } else {
  6657. this.addMarker(element, marker);
  6658. }
  6659. };
  6660. Canvas.prototype.getRootElement = function () {
  6661. if (!this._rootElement) {
  6662. this.setRootElement({id: '__implicitroot', children: []});
  6663. }
  6664. return this._rootElement;
  6665. };
  6666. // root element handling //////////////////////
  6667. /**
  6668. * Sets a given element as the new root element for the canvas
  6669. * and returns the new root element.
  6670. *
  6671. * @param {Object|djs.model.Root} element
  6672. * @param {boolean} [override] whether to override the current root element, if any
  6673. *
  6674. * @return {Object|djs.model.Root} new root element
  6675. */
  6676. Canvas.prototype.setRootElement = function (element, override) {
  6677. if (element) {
  6678. this._ensureValid('root', element);
  6679. }
  6680. var currentRoot = this._rootElement,
  6681. elementRegistry = this._elementRegistry,
  6682. eventBus = this._eventBus;
  6683. if (currentRoot) {
  6684. if (!override) {
  6685. throw new Error('rootElement already set, need to specify override');
  6686. }
  6687. // simulate element remove event sequence
  6688. eventBus.fire('root.remove', {element: currentRoot});
  6689. eventBus.fire('root.removed', {element: currentRoot});
  6690. elementRegistry.remove(currentRoot);
  6691. }
  6692. if (element) {
  6693. var gfx = this.getDefaultLayer();
  6694. // resemble element add event sequence
  6695. eventBus.fire('root.add', {element: element});
  6696. elementRegistry.add(element, gfx, this._svg);
  6697. eventBus.fire('root.added', {element: element, gfx: gfx});
  6698. }
  6699. this._rootElement = element;
  6700. return element;
  6701. };
  6702. // add functionality //////////////////////
  6703. Canvas.prototype._ensureValid = function (type, element) {
  6704. if (!element.id) {
  6705. throw new Error('element must have an id');
  6706. }
  6707. if (this._elementRegistry.get(element.id)) {
  6708. throw new Error('element with id ' + element.id + ' already exists');
  6709. }
  6710. var requiredAttrs = REQUIRED_MODEL_ATTRS[type];
  6711. var valid = every(requiredAttrs, function (attr) {
  6712. return typeof element[attr] !== 'undefined';
  6713. });
  6714. if (!valid) {
  6715. throw new Error(
  6716. 'must supply { ' + requiredAttrs.join(', ') + ' } with ' + type);
  6717. }
  6718. };
  6719. Canvas.prototype._setParent = function (element, parent, parentIndex) {
  6720. add(parent.children, element, parentIndex);
  6721. element.parent = parent;
  6722. };
  6723. /**
  6724. * Adds an element to the canvas.
  6725. *
  6726. * This wires the parent <-> child relationship between the element and
  6727. * a explicitly specified parent or an implicit root element.
  6728. *
  6729. * During add it emits the events
  6730. *
  6731. * * <{type}.add> (element, parent)
  6732. * * <{type}.added> (element, gfx)
  6733. *
  6734. * Extensions may hook into these events to perform their magic.
  6735. *
  6736. * @param {string} type
  6737. * @param {Object|djs.model.Base} element
  6738. * @param {Object|djs.model.Base} [parent]
  6739. * @param {number} [parentIndex]
  6740. *
  6741. * @return {Object|djs.model.Base} the added element
  6742. */
  6743. Canvas.prototype._addElement = function (type, element, parent, parentIndex) {
  6744. parent = parent || this.getRootElement();
  6745. var eventBus = this._eventBus,
  6746. graphicsFactory = this._graphicsFactory;
  6747. this._ensureValid(type, element);
  6748. eventBus.fire(type + '.add', {element: element, parent: parent});
  6749. this._setParent(element, parent, parentIndex);
  6750. // create graphics
  6751. var gfx = graphicsFactory.create(type, element, parentIndex);
  6752. this._elementRegistry.add(element, gfx);
  6753. // update its visual
  6754. graphicsFactory.update(type, element, gfx);
  6755. eventBus.fire(type + '.added', {element: element, gfx: gfx});
  6756. return element;
  6757. };
  6758. /**
  6759. * Adds a shape to the canvas
  6760. *
  6761. * @param {Object|djs.model.Shape} shape to add to the diagram
  6762. * @param {djs.model.Base} [parent]
  6763. * @param {number} [parentIndex]
  6764. *
  6765. * @return {djs.model.Shape} the added shape
  6766. */
  6767. Canvas.prototype.addShape = function (shape, parent, parentIndex) {
  6768. return this._addElement('shape', shape, parent, parentIndex);
  6769. };
  6770. /**
  6771. * Adds a connection to the canvas
  6772. *
  6773. * @param {Object|djs.model.Connection} connection to add to the diagram
  6774. * @param {djs.model.Base} [parent]
  6775. * @param {number} [parentIndex]
  6776. *
  6777. * @return {djs.model.Connection} the added connection
  6778. */
  6779. Canvas.prototype.addConnection = function (connection, parent, parentIndex) {
  6780. return this._addElement('connection', connection, parent, parentIndex);
  6781. };
  6782. /**
  6783. * Internal remove element
  6784. */
  6785. Canvas.prototype._removeElement = function (element, type) {
  6786. var elementRegistry = this._elementRegistry,
  6787. graphicsFactory = this._graphicsFactory,
  6788. eventBus = this._eventBus;
  6789. element = elementRegistry.get(element.id || element);
  6790. if (!element) {
  6791. // element was removed already
  6792. return;
  6793. }
  6794. eventBus.fire(type + '.remove', {element: element});
  6795. graphicsFactory.remove(element);
  6796. // unset parent <-> child relationship
  6797. remove$2(element.parent && element.parent.children, element);
  6798. element.parent = null;
  6799. eventBus.fire(type + '.removed', {element: element});
  6800. elementRegistry.remove(element);
  6801. return element;
  6802. };
  6803. /**
  6804. * Removes a shape from the canvas
  6805. *
  6806. * @param {string|djs.model.Shape} shape or shape id to be removed
  6807. *
  6808. * @return {djs.model.Shape} the removed shape
  6809. */
  6810. Canvas.prototype.removeShape = function (shape) {
  6811. /**
  6812. * An event indicating that a shape is about to be removed from the canvas.
  6813. *
  6814. * @memberOf Canvas
  6815. *
  6816. * @event shape.remove
  6817. * @type {Object}
  6818. * @property {djs.model.Shape} element the shape descriptor
  6819. * @property {Object} gfx the graphical representation of the shape
  6820. */
  6821. /**
  6822. * An event indicating that a shape has been removed from the canvas.
  6823. *
  6824. * @memberOf Canvas
  6825. *
  6826. * @event shape.removed
  6827. * @type {Object}
  6828. * @property {djs.model.Shape} element the shape descriptor
  6829. * @property {Object} gfx the graphical representation of the shape
  6830. */
  6831. return this._removeElement(shape, 'shape');
  6832. };
  6833. /**
  6834. * Removes a connection from the canvas
  6835. *
  6836. * @param {string|djs.model.Connection} connection or connection id to be removed
  6837. *
  6838. * @return {djs.model.Connection} the removed connection
  6839. */
  6840. Canvas.prototype.removeConnection = function (connection) {
  6841. /**
  6842. * An event indicating that a connection is about to be removed from the canvas.
  6843. *
  6844. * @memberOf Canvas
  6845. *
  6846. * @event connection.remove
  6847. * @type {Object}
  6848. * @property {djs.model.Connection} element the connection descriptor
  6849. * @property {Object} gfx the graphical representation of the connection
  6850. */
  6851. /**
  6852. * An event indicating that a connection has been removed from the canvas.
  6853. *
  6854. * @memberOf Canvas
  6855. *
  6856. * @event connection.removed
  6857. * @type {Object}
  6858. * @property {djs.model.Connection} element the connection descriptor
  6859. * @property {Object} gfx the graphical representation of the connection
  6860. */
  6861. return this._removeElement(connection, 'connection');
  6862. };
  6863. /**
  6864. * Return the graphical object underlaying a certain diagram element
  6865. *
  6866. * @param {string|djs.model.Base} element descriptor of the element
  6867. * @param {boolean} [secondary=false] whether to return the secondary connected element
  6868. *
  6869. * @return {SVGElement}
  6870. */
  6871. Canvas.prototype.getGraphics = function (element, secondary) {
  6872. return this._elementRegistry.getGraphics(element, secondary);
  6873. };
  6874. /**
  6875. * Perform a viewbox update via a given change function.
  6876. *
  6877. * @param {Function} changeFn
  6878. */
  6879. Canvas.prototype._changeViewbox = function (changeFn) {
  6880. // notify others of the upcoming viewbox change
  6881. this._eventBus.fire('canvas.viewbox.changing');
  6882. // perform actual change
  6883. changeFn.apply(this);
  6884. // reset the cached viewbox so that
  6885. // a new get operation on viewbox or zoom
  6886. // triggers a viewbox re-computation
  6887. this._cachedViewbox = null;
  6888. // notify others of the change; this step
  6889. // may or may not be debounced
  6890. this._viewboxChanged();
  6891. };
  6892. Canvas.prototype._viewboxChanged = function () {
  6893. this._eventBus.fire('canvas.viewbox.changed', {viewbox: this.viewbox()});
  6894. };
  6895. /**
  6896. * Gets or sets the view box of the canvas, i.e. the
  6897. * area that is currently displayed.
  6898. *
  6899. * The getter may return a cached viewbox (if it is currently
  6900. * changing). To force a recomputation, pass `false` as the first argument.
  6901. *
  6902. * @example
  6903. *
  6904. * canvas.viewbox({ x: 100, y: 100, width: 500, height: 500 })
  6905. *
  6906. * // sets the visible area of the diagram to (100|100) -> (600|100)
  6907. * // and and scales it according to the diagram width
  6908. *
  6909. * var viewbox = canvas.viewbox(); // pass `false` to force recomputing the box.
  6910. *
  6911. * console.log(viewbox);
  6912. * // {
  6913. * // inner: Dimensions,
  6914. * // outer: Dimensions,
  6915. * // scale,
  6916. * // x, y,
  6917. * // width, height
  6918. * // }
  6919. *
  6920. * // if the current diagram is zoomed and scrolled, you may reset it to the
  6921. * // default zoom via this method, too:
  6922. *
  6923. * var zoomedAndScrolledViewbox = canvas.viewbox();
  6924. *
  6925. * canvas.viewbox({
  6926. * x: 0,
  6927. * y: 0,
  6928. * width: zoomedAndScrolledViewbox.outer.width,
  6929. * height: zoomedAndScrolledViewbox.outer.height
  6930. * });
  6931. *
  6932. * @param {Object} [box] the new view box to set
  6933. * @param {number} box.x the top left X coordinate of the canvas visible in view box
  6934. * @param {number} box.y the top left Y coordinate of the canvas visible in view box
  6935. * @param {number} box.width the visible width
  6936. * @param {number} box.height
  6937. *
  6938. * @return {Object} the current view box
  6939. */
  6940. Canvas.prototype.viewbox = function (box) {
  6941. if (box === undefined && this._cachedViewbox) {
  6942. return this._cachedViewbox;
  6943. }
  6944. var viewport = this._viewport,
  6945. innerBox,
  6946. outerBox = this.getSize(),
  6947. matrix,
  6948. transform$1,
  6949. scale,
  6950. x, y;
  6951. if (!box) {
  6952. // compute the inner box based on the
  6953. // diagrams default layer. This allows us to exclude
  6954. // external components, such as overlays
  6955. innerBox = this.getDefaultLayer().getBBox();
  6956. transform$1 = transform(viewport);
  6957. matrix = transform$1 ? transform$1.matrix : createMatrix();
  6958. scale = round(matrix.a, 1000);
  6959. x = round(-matrix.e || 0, 1000);
  6960. y = round(-matrix.f || 0, 1000);
  6961. box = this._cachedViewbox = {
  6962. x: x ? x / scale : 0,
  6963. y: y ? y / scale : 0,
  6964. width: outerBox.width / scale,
  6965. height: outerBox.height / scale,
  6966. scale: scale,
  6967. inner: {
  6968. width: innerBox.width,
  6969. height: innerBox.height,
  6970. x: innerBox.x,
  6971. y: innerBox.y
  6972. },
  6973. outer: outerBox
  6974. };
  6975. return box;
  6976. } else {
  6977. this._changeViewbox(function () {
  6978. scale = Math.min(outerBox.width / box.width, outerBox.height / box.height);
  6979. var matrix = this._svg.createSVGMatrix()
  6980. .scale(scale)
  6981. .translate(-box.x, -box.y);
  6982. transform(viewport, matrix);
  6983. });
  6984. }
  6985. return box;
  6986. };
  6987. /**
  6988. * Gets or sets the scroll of the canvas.
  6989. *
  6990. * @param {Object} [delta] the new scroll to apply.
  6991. *
  6992. * @param {number} [delta.dx]
  6993. * @param {number} [delta.dy]
  6994. */
  6995. Canvas.prototype.scroll = function (delta) {
  6996. var node = this._viewport;
  6997. var matrix = node.getCTM();
  6998. if (delta) {
  6999. this._changeViewbox(function () {
  7000. delta = assign({dx: 0, dy: 0}, delta || {});
  7001. matrix = this._svg.createSVGMatrix().translate(delta.dx, delta.dy).multiply(matrix);
  7002. setCTM(node, matrix);
  7003. });
  7004. }
  7005. return {x: matrix.e, y: matrix.f};
  7006. };
  7007. /**
  7008. * Gets or sets the current zoom of the canvas, optionally zooming
  7009. * to the specified position.
  7010. *
  7011. * The getter may return a cached zoom level. Call it with `false` as
  7012. * the first argument to force recomputation of the current level.
  7013. *
  7014. * @param {string|number} [newScale] the new zoom level, either a number, i.e. 0.9,
  7015. * or `fit-viewport` to adjust the size to fit the current viewport
  7016. * @param {string|Point} [center] the reference point { x: .., y: ..} to zoom to, 'auto' to zoom into mid or null
  7017. *
  7018. * @return {number} the current scale
  7019. */
  7020. Canvas.prototype.zoom = function (newScale, center) {
  7021. if (!newScale) {
  7022. return this.viewbox(newScale).scale;
  7023. }
  7024. if (newScale === 'fit-viewport') {
  7025. return this._fitViewport(center);
  7026. }
  7027. var outer,
  7028. matrix;
  7029. this._changeViewbox(function () {
  7030. if (typeof center !== 'object') {
  7031. outer = this.viewbox().outer;
  7032. center = {
  7033. x: outer.width / 2,
  7034. y: outer.height / 2
  7035. };
  7036. }
  7037. matrix = this._setZoom(newScale, center);
  7038. });
  7039. return round(matrix.a, 1000);
  7040. };
  7041. function setCTM(node, m) {
  7042. var mstr = 'matrix(' + m.a + ',' + m.b + ',' + m.c + ',' + m.d + ',' + m.e + ',' + m.f + ')';
  7043. node.setAttribute('transform', mstr);
  7044. }
  7045. Canvas.prototype._fitViewport = function (center) {
  7046. var vbox = this.viewbox(),
  7047. outer = vbox.outer,
  7048. inner = vbox.inner,
  7049. newScale,
  7050. newViewbox;
  7051. // display the complete diagram without zooming in.
  7052. // instead of relying on internal zoom, we perform a
  7053. // hard reset on the canvas viewbox to realize this
  7054. //
  7055. // if diagram does not need to be zoomed in, we focus it around
  7056. // the diagram origin instead
  7057. if (inner.x >= 0 &&
  7058. inner.y >= 0 &&
  7059. inner.x + inner.width <= outer.width &&
  7060. inner.y + inner.height <= outer.height &&
  7061. !center) {
  7062. newViewbox = {
  7063. x: 0,
  7064. y: 0,
  7065. width: Math.max(inner.width + inner.x, outer.width),
  7066. height: Math.max(inner.height + inner.y, outer.height)
  7067. };
  7068. } else {
  7069. newScale = Math.min(1, outer.width / inner.width, outer.height / inner.height);
  7070. newViewbox = {
  7071. x: inner.x + (center ? inner.width / 2 - outer.width / newScale / 2 : 0),
  7072. y: inner.y + (center ? inner.height / 2 - outer.height / newScale / 2 : 0),
  7073. width: outer.width / newScale,
  7074. height: outer.height / newScale
  7075. };
  7076. }
  7077. this.viewbox(newViewbox);
  7078. return this.viewbox(false).scale;
  7079. };
  7080. Canvas.prototype._setZoom = function (scale, center) {
  7081. var svg = this._svg,
  7082. viewport = this._viewport;
  7083. var matrix = svg.createSVGMatrix();
  7084. var point = svg.createSVGPoint();
  7085. var centerPoint,
  7086. originalPoint,
  7087. currentMatrix,
  7088. scaleMatrix,
  7089. newMatrix;
  7090. currentMatrix = viewport.getCTM();
  7091. var currentScale = currentMatrix.a;
  7092. if (center) {
  7093. centerPoint = assign(point, center);
  7094. // revert applied viewport transformations
  7095. originalPoint = centerPoint.matrixTransform(currentMatrix.inverse());
  7096. // create scale matrix
  7097. scaleMatrix = matrix
  7098. .translate(originalPoint.x, originalPoint.y)
  7099. .scale(1 / currentScale * scale)
  7100. .translate(-originalPoint.x, -originalPoint.y);
  7101. newMatrix = currentMatrix.multiply(scaleMatrix);
  7102. } else {
  7103. newMatrix = matrix.scale(scale);
  7104. }
  7105. setCTM(this._viewport, newMatrix);
  7106. return newMatrix;
  7107. };
  7108. /**
  7109. * Returns the size of the canvas
  7110. *
  7111. * @return {Dimensions}
  7112. */
  7113. Canvas.prototype.getSize = function () {
  7114. return {
  7115. width: this._container.clientWidth,
  7116. height: this._container.clientHeight
  7117. };
  7118. };
  7119. /**
  7120. * Return the absolute bounding box for the given element
  7121. *
  7122. * The absolute bounding box may be used to display overlays in the
  7123. * callers (browser) coordinate system rather than the zoomed in/out
  7124. * canvas coordinates.
  7125. *
  7126. * @param {ElementDescriptor} element
  7127. * @return {Bounds} the absolute bounding box
  7128. */
  7129. Canvas.prototype.getAbsoluteBBox = function (element) {
  7130. var vbox = this.viewbox();
  7131. var bbox;
  7132. // connection
  7133. // use svg bbox
  7134. if (element.waypoints) {
  7135. var gfx = this.getGraphics(element);
  7136. bbox = gfx.getBBox();
  7137. }
  7138. // shapes
  7139. // use data
  7140. else {
  7141. bbox = element;
  7142. }
  7143. var x = bbox.x * vbox.scale - vbox.x * vbox.scale;
  7144. var y = bbox.y * vbox.scale - vbox.y * vbox.scale;
  7145. var width = bbox.width * vbox.scale;
  7146. var height = bbox.height * vbox.scale;
  7147. return {
  7148. x: x,
  7149. y: y,
  7150. width: width,
  7151. height: height
  7152. };
  7153. };
  7154. /**
  7155. * Fires an event in order other modules can react to the
  7156. * canvas resizing
  7157. */
  7158. Canvas.prototype.resized = function () {
  7159. // force recomputation of view box
  7160. delete this._cachedViewbox;
  7161. this._eventBus.fire('canvas.resized');
  7162. };
  7163. var ELEMENT_ID = 'data-element-id';
  7164. /**
  7165. * @class
  7166. *
  7167. * A registry that keeps track of all shapes in the diagram.
  7168. */
  7169. function ElementRegistry(eventBus) {
  7170. this._elements = {};
  7171. this._eventBus = eventBus;
  7172. }
  7173. ElementRegistry.$inject = ['eventBus'];
  7174. /**
  7175. * Register a pair of (element, gfx, (secondaryGfx)).
  7176. *
  7177. * @param {djs.model.Base} element
  7178. * @param {SVGElement} gfx
  7179. * @param {SVGElement} [secondaryGfx] optional other element to register, too
  7180. */
  7181. ElementRegistry.prototype.add = function (element, gfx, secondaryGfx) {
  7182. var id = element.id;
  7183. this._validateId(id);
  7184. // associate dom node with element
  7185. attr(gfx, ELEMENT_ID, id);
  7186. if (secondaryGfx) {
  7187. attr(secondaryGfx, ELEMENT_ID, id);
  7188. }
  7189. this._elements[id] = {element: element, gfx: gfx, secondaryGfx: secondaryGfx};
  7190. };
  7191. /**
  7192. * Removes an element from the registry.
  7193. *
  7194. * @param {djs.model.Base} element
  7195. */
  7196. ElementRegistry.prototype.remove = function (element) {
  7197. var elements = this._elements,
  7198. id = element.id || element,
  7199. container = id && elements[id];
  7200. if (container) {
  7201. // unset element id on gfx
  7202. attr(container.gfx, ELEMENT_ID, '');
  7203. if (container.secondaryGfx) {
  7204. attr(container.secondaryGfx, ELEMENT_ID, '');
  7205. }
  7206. delete elements[id];
  7207. }
  7208. };
  7209. /**
  7210. * Update the id of an element
  7211. *
  7212. * @param {djs.model.Base} element
  7213. * @param {string} newId
  7214. */
  7215. ElementRegistry.prototype.updateId = function (element, newId) {
  7216. this._validateId(newId);
  7217. if (typeof element === 'string') {
  7218. element = this.get(element);
  7219. }
  7220. this._eventBus.fire('element.updateId', {
  7221. element: element,
  7222. newId: newId
  7223. });
  7224. var gfx = this.getGraphics(element),
  7225. secondaryGfx = this.getGraphics(element, true);
  7226. this.remove(element);
  7227. element.id = newId;
  7228. this.add(element, gfx, secondaryGfx);
  7229. };
  7230. /**
  7231. * Return the model element for a given id or graphics.
  7232. *
  7233. * @example
  7234. *
  7235. * elementRegistry.get('SomeElementId_1');
  7236. * elementRegistry.get(gfx);
  7237. *
  7238. *
  7239. * @param {string|SVGElement} filter for selecting the element
  7240. *
  7241. * @return {djs.model.Base}
  7242. */
  7243. ElementRegistry.prototype.get = function (filter) {
  7244. var id;
  7245. if (typeof filter === 'string') {
  7246. id = filter;
  7247. } else {
  7248. id = filter && attr(filter, ELEMENT_ID);
  7249. }
  7250. var container = this._elements[id];
  7251. return container && container.element;
  7252. };
  7253. /**
  7254. * Return all elements that match a given filter function.
  7255. *
  7256. * @param {Function} fn
  7257. *
  7258. * @return {Array<djs.model.Base>}
  7259. */
  7260. ElementRegistry.prototype.filter = function (fn) {
  7261. var filtered = [];
  7262. this.forEach(function (element, gfx) {
  7263. if (fn(element, gfx)) {
  7264. filtered.push(element);
  7265. }
  7266. });
  7267. return filtered;
  7268. };
  7269. /**
  7270. * Return all rendered model elements.
  7271. *
  7272. * @return {Array<djs.model.Base>}
  7273. */
  7274. ElementRegistry.prototype.getAll = function () {
  7275. return this.filter(function (e) {
  7276. return e;
  7277. });
  7278. };
  7279. /**
  7280. * Iterate over all diagram elements.
  7281. *
  7282. * @param {Function} fn
  7283. */
  7284. ElementRegistry.prototype.forEach = function (fn) {
  7285. var map = this._elements;
  7286. Object.keys(map).forEach(function (id) {
  7287. var container = map[id],
  7288. element = container.element,
  7289. gfx = container.gfx;
  7290. return fn(element, gfx);
  7291. });
  7292. };
  7293. /**
  7294. * Return the graphical representation of an element or its id.
  7295. *
  7296. * @example
  7297. * elementRegistry.getGraphics('SomeElementId_1');
  7298. * elementRegistry.getGraphics(rootElement); // <g ...>
  7299. *
  7300. * elementRegistry.getGraphics(rootElement, true); // <svg ...>
  7301. *
  7302. *
  7303. * @param {string|djs.model.Base} filter
  7304. * @param {boolean} [secondary=false] whether to return the secondary connected element
  7305. *
  7306. * @return {SVGElement}
  7307. */
  7308. ElementRegistry.prototype.getGraphics = function (filter, secondary) {
  7309. var id = filter.id || filter;
  7310. var container = this._elements[id];
  7311. return container && (secondary ? container.secondaryGfx : container.gfx);
  7312. };
  7313. /**
  7314. * Validate the suitability of the given id and signals a problem
  7315. * with an exception.
  7316. *
  7317. * @param {string} id
  7318. *
  7319. * @throws {Error} if id is empty or already assigned
  7320. */
  7321. ElementRegistry.prototype._validateId = function (id) {
  7322. if (!id) {
  7323. throw new Error('element must have an id');
  7324. }
  7325. if (this._elements[id]) {
  7326. throw new Error('element with id ' + id + ' already added');
  7327. }
  7328. };
  7329. /**
  7330. * An empty collection stub. Use {@link RefsCollection.extend} to extend a
  7331. * collection with ref semantics.
  7332. *
  7333. * @class RefsCollection
  7334. */
  7335. /**
  7336. * Extends a collection with {@link Refs} aware methods
  7337. *
  7338. * @memberof RefsCollection
  7339. * @static
  7340. *
  7341. * @param {Array<Object>} collection
  7342. * @param {Refs} refs instance
  7343. * @param {Object} property represented by the collection
  7344. * @param {Object} target object the collection is attached to
  7345. *
  7346. * @return {RefsCollection<Object>} the extended array
  7347. */
  7348. function extend$1(collection, refs, property, target) {
  7349. var inverseProperty = property.inverse;
  7350. /**
  7351. * Removes the given element from the array and returns it.
  7352. *
  7353. * @method RefsCollection#remove
  7354. *
  7355. * @param {Object} element the element to remove
  7356. */
  7357. Object.defineProperty(collection, 'remove', {
  7358. value: function (element) {
  7359. var idx = this.indexOf(element);
  7360. if (idx !== -1) {
  7361. this.splice(idx, 1);
  7362. // unset inverse
  7363. refs.unset(element, inverseProperty, target);
  7364. }
  7365. return element;
  7366. }
  7367. });
  7368. /**
  7369. * Returns true if the collection contains the given element
  7370. *
  7371. * @method RefsCollection#contains
  7372. *
  7373. * @param {Object} element the element to check for
  7374. */
  7375. Object.defineProperty(collection, 'contains', {
  7376. value: function (element) {
  7377. return this.indexOf(element) !== -1;
  7378. }
  7379. });
  7380. /**
  7381. * Adds an element to the array, unless it exists already (set semantics).
  7382. *
  7383. * @method RefsCollection#add
  7384. *
  7385. * @param {Object} element the element to add
  7386. * @param {Number} optional index to add element to
  7387. * (possibly moving other elements around)
  7388. */
  7389. Object.defineProperty(collection, 'add', {
  7390. value: function (element, idx) {
  7391. var currentIdx = this.indexOf(element);
  7392. if (typeof idx === 'undefined') {
  7393. if (currentIdx !== -1) {
  7394. // element already in collection (!)
  7395. return;
  7396. }
  7397. // add to end of array, as no idx is specified
  7398. idx = this.length;
  7399. }
  7400. // handle already in collection
  7401. if (currentIdx !== -1) {
  7402. // remove element from currentIdx
  7403. this.splice(currentIdx, 1);
  7404. }
  7405. // add element at idx
  7406. this.splice(idx, 0, element);
  7407. if (currentIdx === -1) {
  7408. // set inverse, unless element was
  7409. // in collection already
  7410. refs.set(element, inverseProperty, target);
  7411. }
  7412. }
  7413. });
  7414. // a simple marker, identifying this element
  7415. // as being a refs collection
  7416. Object.defineProperty(collection, '__refs_collection', {
  7417. value: true
  7418. });
  7419. return collection;
  7420. }
  7421. function isExtended(collection) {
  7422. return collection.__refs_collection === true;
  7423. }
  7424. var extend_1 = extend$1;
  7425. var isExtended_1 = isExtended;
  7426. var collection = {
  7427. extend: extend_1,
  7428. isExtended: isExtended_1
  7429. };
  7430. function hasOwnProperty(e, property) {
  7431. return Object.prototype.hasOwnProperty.call(e, property.name || property);
  7432. }
  7433. function defineCollectionProperty(ref, property, target) {
  7434. var collection$1 = collection.extend(target[property.name] || [], ref, property, target);
  7435. Object.defineProperty(target, property.name, {
  7436. enumerable: property.enumerable,
  7437. value: collection$1
  7438. });
  7439. if (collection$1.length) {
  7440. collection$1.forEach(function (o) {
  7441. ref.set(o, property.inverse, target);
  7442. });
  7443. }
  7444. }
  7445. function defineProperty(ref, property, target) {
  7446. var inverseProperty = property.inverse;
  7447. var _value = target[property.name];
  7448. Object.defineProperty(target, property.name, {
  7449. configurable: property.configurable,
  7450. enumerable: property.enumerable,
  7451. get: function () {
  7452. return _value;
  7453. },
  7454. set: function (value) {
  7455. // return if we already performed all changes
  7456. if (value === _value) {
  7457. return;
  7458. }
  7459. var old = _value;
  7460. // temporary set null
  7461. _value = null;
  7462. if (old) {
  7463. ref.unset(old, inverseProperty, target);
  7464. }
  7465. // set new value
  7466. _value = value;
  7467. // set inverse value
  7468. ref.set(_value, inverseProperty, target);
  7469. }
  7470. });
  7471. }
  7472. /**
  7473. * Creates a new references object defining two inversly related
  7474. * attribute descriptors a and b.
  7475. *
  7476. * <p>
  7477. * When bound to an object using {@link Refs#bind} the references
  7478. * get activated and ensure that add and remove operations are applied
  7479. * reversely, too.
  7480. * </p>
  7481. *
  7482. * <p>
  7483. * For attributes represented as collections {@link Refs} provides the
  7484. * {@link RefsCollection#add}, {@link RefsCollection#remove} and {@link RefsCollection#contains} extensions
  7485. * that must be used to properly hook into the inverse change mechanism.
  7486. * </p>
  7487. *
  7488. * @class Refs
  7489. *
  7490. * @classdesc A bi-directional reference between two attributes.
  7491. *
  7492. * @param {Refs.AttributeDescriptor} a property descriptor
  7493. * @param {Refs.AttributeDescriptor} b property descriptor
  7494. *
  7495. * @example
  7496. *
  7497. * var refs = Refs({ name: 'wheels', collection: true, enumerable: true }, { name: 'car' });
  7498. *
  7499. * var car = { name: 'toyota' };
  7500. * var wheels = [{ pos: 'front-left' }, { pos: 'front-right' }];
  7501. *
  7502. * refs.bind(car, 'wheels');
  7503. *
  7504. * car.wheels // []
  7505. * car.wheels.add(wheels[0]);
  7506. * car.wheels.add(wheels[1]);
  7507. *
  7508. * car.wheels // [{ pos: 'front-left' }, { pos: 'front-right' }]
  7509. *
  7510. * wheels[0].car // { name: 'toyota' };
  7511. * car.wheels.remove(wheels[0]);
  7512. *
  7513. * wheels[0].car // undefined
  7514. */
  7515. function Refs(a, b) {
  7516. if (!(this instanceof Refs)) {
  7517. return new Refs(a, b);
  7518. }
  7519. // link
  7520. a.inverse = b;
  7521. b.inverse = a;
  7522. this.props = {};
  7523. this.props[a.name] = a;
  7524. this.props[b.name] = b;
  7525. }
  7526. /**
  7527. * Binds one side of a bi-directional reference to a
  7528. * target object.
  7529. *
  7530. * @memberOf Refs
  7531. *
  7532. * @param {Object} target
  7533. * @param {String} property
  7534. */
  7535. Refs.prototype.bind = function (target, property) {
  7536. if (typeof property === 'string') {
  7537. if (!this.props[property]) {
  7538. throw new Error('no property <' + property + '> in ref');
  7539. }
  7540. property = this.props[property];
  7541. }
  7542. if (property.collection) {
  7543. defineCollectionProperty(this, property, target);
  7544. } else {
  7545. defineProperty(this, property, target);
  7546. }
  7547. };
  7548. Refs.prototype.ensureRefsCollection = function (target, property) {
  7549. var collection$1 = target[property.name];
  7550. if (!collection.isExtended(collection$1)) {
  7551. defineCollectionProperty(this, property, target);
  7552. }
  7553. return collection$1;
  7554. };
  7555. Refs.prototype.ensureBound = function (target, property) {
  7556. if (!hasOwnProperty(target, property)) {
  7557. this.bind(target, property);
  7558. }
  7559. };
  7560. Refs.prototype.unset = function (target, property, value) {
  7561. if (target) {
  7562. this.ensureBound(target, property);
  7563. if (property.collection) {
  7564. this.ensureRefsCollection(target, property).remove(value);
  7565. } else {
  7566. target[property.name] = undefined;
  7567. }
  7568. }
  7569. };
  7570. Refs.prototype.set = function (target, property, value) {
  7571. if (target) {
  7572. this.ensureBound(target, property);
  7573. if (property.collection) {
  7574. this.ensureRefsCollection(target, property).add(value);
  7575. } else {
  7576. target[property.name] = value;
  7577. }
  7578. }
  7579. };
  7580. var refs = Refs;
  7581. var objectRefs = refs;
  7582. var Collection = collection;
  7583. objectRefs.Collection = Collection;
  7584. var parentRefs = new objectRefs({name: 'children', enumerable: true, collection: true}, {name: 'parent'}),
  7585. labelRefs = new objectRefs({name: 'labels', enumerable: true, collection: true}, {name: 'labelTarget'}),
  7586. attacherRefs = new objectRefs({name: 'attachers', collection: true}, {name: 'host'}),
  7587. outgoingRefs = new objectRefs({name: 'outgoing', collection: true}, {name: 'source'}),
  7588. incomingRefs = new objectRefs({name: 'incoming', collection: true}, {name: 'target'});
  7589. /**
  7590. * @namespace djs.model
  7591. */
  7592. /**
  7593. * @memberOf djs.model
  7594. */
  7595. /**
  7596. * The basic graphical representation
  7597. *
  7598. * @class
  7599. *
  7600. * @abstract
  7601. */
  7602. function Base() {
  7603. /**
  7604. * The object that backs up the shape
  7605. *
  7606. * @name Base#businessObject
  7607. * @type Object
  7608. */
  7609. Object.defineProperty(this, 'businessObject', {
  7610. writable: true
  7611. });
  7612. /**
  7613. * Single label support, will mapped to multi label array
  7614. *
  7615. * @name Base#label
  7616. * @type Object
  7617. */
  7618. Object.defineProperty(this, 'label', {
  7619. get: function () {
  7620. return this.labels[0];
  7621. },
  7622. set: function (newLabel) {
  7623. var label = this.label,
  7624. labels = this.labels;
  7625. if (!newLabel && label) {
  7626. labels.remove(label);
  7627. } else {
  7628. labels.add(newLabel, 0);
  7629. }
  7630. }
  7631. });
  7632. /**
  7633. * The parent shape
  7634. *
  7635. * @name Base#parent
  7636. * @type Shape
  7637. */
  7638. parentRefs.bind(this, 'parent');
  7639. /**
  7640. * The list of labels
  7641. *
  7642. * @name Base#labels
  7643. * @type Label
  7644. */
  7645. labelRefs.bind(this, 'labels');
  7646. /**
  7647. * The list of outgoing connections
  7648. *
  7649. * @name Base#outgoing
  7650. * @type Array<Connection>
  7651. */
  7652. outgoingRefs.bind(this, 'outgoing');
  7653. /**
  7654. * The list of incoming connections
  7655. *
  7656. * @name Base#incoming
  7657. * @type Array<Connection>
  7658. */
  7659. incomingRefs.bind(this, 'incoming');
  7660. }
  7661. /**
  7662. * A graphical object
  7663. *
  7664. * @class
  7665. * @constructor
  7666. *
  7667. * @extends Base
  7668. */
  7669. function Shape() {
  7670. Base.call(this);
  7671. /**
  7672. * Indicates frame shapes
  7673. *
  7674. * @name Shape#isFrame
  7675. * @type boolean
  7676. */
  7677. /**
  7678. * The list of children
  7679. *
  7680. * @name Shape#children
  7681. * @type Array<Base>
  7682. */
  7683. parentRefs.bind(this, 'children');
  7684. /**
  7685. * @name Shape#host
  7686. * @type Shape
  7687. */
  7688. attacherRefs.bind(this, 'host');
  7689. /**
  7690. * @name Shape#attachers
  7691. * @type Shape
  7692. */
  7693. attacherRefs.bind(this, 'attachers');
  7694. }
  7695. inherits_browser(Shape, Base);
  7696. /**
  7697. * A root graphical object
  7698. *
  7699. * @class
  7700. * @constructor
  7701. *
  7702. * @extends Shape
  7703. */
  7704. function Root() {
  7705. Shape.call(this);
  7706. }
  7707. inherits_browser(Root, Shape);
  7708. /**
  7709. * A label for an element
  7710. *
  7711. * @class
  7712. * @constructor
  7713. *
  7714. * @extends Shape
  7715. */
  7716. function Label() {
  7717. Shape.call(this);
  7718. /**
  7719. * The labeled element
  7720. *
  7721. * @name Label#labelTarget
  7722. * @type Base
  7723. */
  7724. labelRefs.bind(this, 'labelTarget');
  7725. }
  7726. inherits_browser(Label, Shape);
  7727. /**
  7728. * A connection between two elements
  7729. *
  7730. * @class
  7731. * @constructor
  7732. *
  7733. * @extends Base
  7734. */
  7735. function Connection() {
  7736. Base.call(this);
  7737. /**
  7738. * The element this connection originates from
  7739. *
  7740. * @name Connection#source
  7741. * @type Base
  7742. */
  7743. outgoingRefs.bind(this, 'source');
  7744. /**
  7745. * The element this connection points to
  7746. *
  7747. * @name Connection#target
  7748. * @type Base
  7749. */
  7750. incomingRefs.bind(this, 'target');
  7751. }
  7752. inherits_browser(Connection, Base);
  7753. var types = {
  7754. connection: Connection,
  7755. shape: Shape,
  7756. label: Label,
  7757. root: Root
  7758. };
  7759. /**
  7760. * Creates a new model element of the specified type
  7761. *
  7762. * @method create
  7763. *
  7764. * @example
  7765. *
  7766. * var shape1 = Model.create('shape', { x: 10, y: 10, width: 100, height: 100 });
  7767. * var shape2 = Model.create('shape', { x: 210, y: 210, width: 100, height: 100 });
  7768. *
  7769. * var connection = Model.create('connection', { waypoints: [ { x: 110, y: 55 }, {x: 210, y: 55 } ] });
  7770. *
  7771. * @param {string} type lower-cased model name
  7772. * @param {Object} attrs attributes to initialize the new model instance with
  7773. *
  7774. * @return {Base} the new model instance
  7775. */
  7776. function create$1(type, attrs) {
  7777. var Type = types[type];
  7778. if (!Type) {
  7779. throw new Error('unknown type: <' + type + '>');
  7780. }
  7781. return assign(new Type(), attrs);
  7782. }
  7783. /**
  7784. * A factory for diagram-js shapes
  7785. */
  7786. function ElementFactory() {
  7787. this._uid = 12;
  7788. }
  7789. ElementFactory.prototype.createRoot = function (attrs) {
  7790. return this.create('root', attrs);
  7791. };
  7792. ElementFactory.prototype.createLabel = function (attrs) {
  7793. return this.create('label', attrs);
  7794. };
  7795. ElementFactory.prototype.createShape = function (attrs) {
  7796. return this.create('shape', attrs);
  7797. };
  7798. ElementFactory.prototype.createConnection = function (attrs) {
  7799. return this.create('connection', attrs);
  7800. };
  7801. /**
  7802. * Create a model element with the given type and
  7803. * a number of pre-set attributes.
  7804. *
  7805. * @param {string} type
  7806. * @param {Object} attrs
  7807. * @return {djs.model.Base} the newly created model instance
  7808. */
  7809. ElementFactory.prototype.create = function (type, attrs) {
  7810. attrs = assign({}, attrs || {});
  7811. if (!attrs.id) {
  7812. attrs.id = type + '_' + (this._uid++);
  7813. }
  7814. return create$1(type, attrs);
  7815. };
  7816. var FN_REF = '__fn';
  7817. var DEFAULT_PRIORITY = 1000;
  7818. var slice$1 = Array.prototype.slice;
  7819. /**
  7820. * A general purpose event bus.
  7821. *
  7822. * This component is used to communicate across a diagram instance.
  7823. * Other parts of a diagram can use it to listen to and broadcast events.
  7824. *
  7825. *
  7826. * ## Registering for Events
  7827. *
  7828. * The event bus provides the {@link EventBus#on} and {@link EventBus#once}
  7829. * methods to register for events. {@link EventBus#off} can be used to
  7830. * remove event registrations. Listeners receive an instance of {@link Event}
  7831. * as the first argument. It allows them to hook into the event execution.
  7832. *
  7833. * ```javascript
  7834. *
  7835. * // listen for event
  7836. * eventBus.on('foo', function(event) {
  7837. *
  7838. * // access event type
  7839. * event.type; // 'foo'
  7840. *
  7841. * // stop propagation to other listeners
  7842. * event.stopPropagation();
  7843. *
  7844. * // prevent event default
  7845. * event.preventDefault();
  7846. * });
  7847. *
  7848. * // listen for event with custom payload
  7849. * eventBus.on('bar', function(event, payload) {
  7850. * console.log(payload);
  7851. * });
  7852. *
  7853. * // listen for event returning value
  7854. * eventBus.on('foobar', function(event) {
  7855. *
  7856. * // stop event propagation + prevent default
  7857. * return false;
  7858. *
  7859. * // stop event propagation + return custom result
  7860. * return {
  7861. * complex: 'listening result'
  7862. * };
  7863. * });
  7864. *
  7865. *
  7866. * // listen with custom priority (default=1000, higher is better)
  7867. * eventBus.on('priorityfoo', 1500, function(event) {
  7868. * console.log('invoked first!');
  7869. * });
  7870. *
  7871. *
  7872. * // listen for event and pass the context (`this`)
  7873. * eventBus.on('foobar', function(event) {
  7874. * this.foo();
  7875. * }, this);
  7876. * ```
  7877. *
  7878. *
  7879. * ## Emitting Events
  7880. *
  7881. * Events can be emitted via the event bus using {@link EventBus#fire}.
  7882. *
  7883. * ```javascript
  7884. *
  7885. * // false indicates that the default action
  7886. * // was prevented by listeners
  7887. * if (eventBus.fire('foo') === false) {
  7888. * console.log('default has been prevented!');
  7889. * };
  7890. *
  7891. *
  7892. * // custom args + return value listener
  7893. * eventBus.on('sum', function(event, a, b) {
  7894. * return a + b;
  7895. * });
  7896. *
  7897. * // you can pass custom arguments + retrieve result values.
  7898. * var sum = eventBus.fire('sum', 1, 2);
  7899. * console.log(sum); // 3
  7900. * ```
  7901. */
  7902. function EventBus() {
  7903. this._listeners = {};
  7904. // cleanup on destroy on lowest priority to allow
  7905. // message passing until the bitter end
  7906. this.on('diagram.destroy', 1, this._destroy, this);
  7907. }
  7908. /**
  7909. * Register an event listener for events with the given name.
  7910. *
  7911. * The callback will be invoked with `event, ...additionalArguments`
  7912. * that have been passed to {@link EventBus#fire}.
  7913. *
  7914. * Returning false from a listener will prevent the events default action
  7915. * (if any is specified). To stop an event from being processed further in
  7916. * other listeners execute {@link Event#stopPropagation}.
  7917. *
  7918. * Returning anything but `undefined` from a listener will stop the listener propagation.
  7919. *
  7920. * @param {string|Array<string>} events
  7921. * @param {number} [priority=1000] the priority in which this listener is called, larger is higher
  7922. * @param {Function} callback
  7923. * @param {Object} [that] Pass context (`this`) to the callback
  7924. */
  7925. EventBus.prototype.on = function (events, priority, callback, that) {
  7926. events = isArray(events) ? events : [events];
  7927. if (isFunction(priority)) {
  7928. that = callback;
  7929. callback = priority;
  7930. priority = DEFAULT_PRIORITY;
  7931. }
  7932. if (!isNumber(priority)) {
  7933. throw new Error('priority must be a number');
  7934. }
  7935. var actualCallback = callback;
  7936. if (that) {
  7937. actualCallback = bind(callback, that);
  7938. // make sure we remember and are able to remove
  7939. // bound callbacks via {@link #off} using the original
  7940. // callback
  7941. actualCallback[FN_REF] = callback[FN_REF] || callback;
  7942. }
  7943. var self = this;
  7944. events.forEach(function (e) {
  7945. self._addListener(e, {
  7946. priority: priority,
  7947. callback: actualCallback,
  7948. next: null
  7949. });
  7950. });
  7951. };
  7952. /**
  7953. * Register an event listener that is executed only once.
  7954. *
  7955. * @param {string} event the event name to register for
  7956. * @param {number} [priority=1000] the priority in which this listener is called, larger is higher
  7957. * @param {Function} callback the callback to execute
  7958. * @param {Object} [that] Pass context (`this`) to the callback
  7959. */
  7960. EventBus.prototype.once = function (event, priority, callback, that) {
  7961. var self = this;
  7962. if (isFunction(priority)) {
  7963. that = callback;
  7964. callback = priority;
  7965. priority = DEFAULT_PRIORITY;
  7966. }
  7967. if (!isNumber(priority)) {
  7968. throw new Error('priority must be a number');
  7969. }
  7970. function wrappedCallback() {
  7971. var result = callback.apply(that, arguments);
  7972. self.off(event, wrappedCallback);
  7973. return result;
  7974. }
  7975. // make sure we remember and are able to remove
  7976. // bound callbacks via {@link #off} using the original
  7977. // callback
  7978. wrappedCallback[FN_REF] = callback;
  7979. this.on(event, priority, wrappedCallback);
  7980. };
  7981. /**
  7982. * Removes event listeners by event and callback.
  7983. *
  7984. * If no callback is given, all listeners for a given event name are being removed.
  7985. *
  7986. * @param {string|Array<string>} events
  7987. * @param {Function} [callback]
  7988. */
  7989. EventBus.prototype.off = function (events, callback) {
  7990. events = isArray(events) ? events : [events];
  7991. var self = this;
  7992. events.forEach(function (event) {
  7993. self._removeListener(event, callback);
  7994. });
  7995. };
  7996. /**
  7997. * Create an EventBus event.
  7998. *
  7999. * @param {Object} data
  8000. *
  8001. * @return {Object} event, recognized by the eventBus
  8002. */
  8003. EventBus.prototype.createEvent = function (data) {
  8004. var event = new InternalEvent();
  8005. event.init(data);
  8006. return event;
  8007. };
  8008. /**
  8009. * Fires a named event.
  8010. *
  8011. * @example
  8012. *
  8013. * // fire event by name
  8014. * events.fire('foo');
  8015. *
  8016. * // fire event object with nested type
  8017. * var event = { type: 'foo' };
  8018. * events.fire(event);
  8019. *
  8020. * // fire event with explicit type
  8021. * var event = { x: 10, y: 20 };
  8022. * events.fire('element.moved', event);
  8023. *
  8024. * // pass additional arguments to the event
  8025. * events.on('foo', function(event, bar) {
  8026. * alert(bar);
  8027. * });
  8028. *
  8029. * events.fire({ type: 'foo' }, 'I am bar!');
  8030. *
  8031. * @param {string} [name] the optional event name
  8032. * @param {Object} [event] the event object
  8033. * @param {...Object} additional arguments to be passed to the callback functions
  8034. *
  8035. * @return {boolean} the events return value, if specified or false if the
  8036. * default action was prevented by listeners
  8037. */
  8038. EventBus.prototype.fire = function (type, data) {
  8039. var event,
  8040. firstListener,
  8041. returnValue,
  8042. args;
  8043. args = slice$1.call(arguments);
  8044. if (typeof type === 'object') {
  8045. data = type;
  8046. type = data.type;
  8047. }
  8048. if (!type) {
  8049. throw new Error('no event type specified');
  8050. }
  8051. firstListener = this._listeners[type];
  8052. if (!firstListener) {
  8053. return;
  8054. }
  8055. // we make sure we fire instances of our home made
  8056. // events here. We wrap them only once, though
  8057. if (data instanceof InternalEvent) {
  8058. // we are fine, we alread have an event
  8059. event = data;
  8060. } else {
  8061. event = this.createEvent(data);
  8062. }
  8063. // ensure we pass the event as the first parameter
  8064. args[0] = event;
  8065. // original event type (in case we delegate)
  8066. var originalType = event.type;
  8067. // update event type before delegation
  8068. if (type !== originalType) {
  8069. event.type = type;
  8070. }
  8071. try {
  8072. returnValue = this._invokeListeners(event, args, firstListener);
  8073. } finally {
  8074. // reset event type after delegation
  8075. if (type !== originalType) {
  8076. event.type = originalType;
  8077. }
  8078. }
  8079. // set the return value to false if the event default
  8080. // got prevented and no other return value exists
  8081. if (returnValue === undefined && event.defaultPrevented) {
  8082. returnValue = false;
  8083. }
  8084. return returnValue;
  8085. };
  8086. EventBus.prototype.handleError = function (error) {
  8087. return this.fire('error', {error: error}) === false;
  8088. };
  8089. EventBus.prototype._destroy = function () {
  8090. this._listeners = {};
  8091. };
  8092. EventBus.prototype._invokeListeners = function (event, args, listener) {
  8093. var returnValue;
  8094. while (listener) {
  8095. // handle stopped propagation
  8096. if (event.cancelBubble) {
  8097. break;
  8098. }
  8099. returnValue = this._invokeListener(event, args, listener);
  8100. listener = listener.next;
  8101. }
  8102. return returnValue;
  8103. };
  8104. EventBus.prototype._invokeListener = function (event, args, listener) {
  8105. var returnValue;
  8106. try {
  8107. // returning false prevents the default action
  8108. returnValue = invokeFunction(listener.callback, args);
  8109. // stop propagation on return value
  8110. if (returnValue !== undefined) {
  8111. event.returnValue = returnValue;
  8112. event.stopPropagation();
  8113. }
  8114. // prevent default on return false
  8115. if (returnValue === false) {
  8116. event.preventDefault();
  8117. }
  8118. } catch (e) {
  8119. if (!this.handleError(e)) {
  8120. console.error('unhandled error in event listener');
  8121. console.error(e.stack);
  8122. throw e;
  8123. }
  8124. }
  8125. return returnValue;
  8126. };
  8127. /*
  8128. * Add new listener with a certain priority to the list
  8129. * of listeners (for the given event).
  8130. *
  8131. * The semantics of listener registration / listener execution are
  8132. * first register, first serve: New listeners will always be inserted
  8133. * after existing listeners with the same priority.
  8134. *
  8135. * Example: Inserting two listeners with priority 1000 and 1300
  8136. *
  8137. * * before: [ 1500, 1500, 1000, 1000 ]
  8138. * * after: [ 1500, 1500, (new=1300), 1000, 1000, (new=1000) ]
  8139. *
  8140. * @param {string} event
  8141. * @param {Object} listener { priority, callback }
  8142. */
  8143. EventBus.prototype._addListener = function (event, newListener) {
  8144. var listener = this._getListeners(event),
  8145. previousListener;
  8146. // no prior listeners
  8147. if (!listener) {
  8148. this._setListeners(event, newListener);
  8149. return;
  8150. }
  8151. // ensure we order listeners by priority from
  8152. // 0 (high) to n > 0 (low)
  8153. while (listener) {
  8154. if (listener.priority < newListener.priority) {
  8155. newListener.next = listener;
  8156. if (previousListener) {
  8157. previousListener.next = newListener;
  8158. } else {
  8159. this._setListeners(event, newListener);
  8160. }
  8161. return;
  8162. }
  8163. previousListener = listener;
  8164. listener = listener.next;
  8165. }
  8166. // add new listener to back
  8167. previousListener.next = newListener;
  8168. };
  8169. EventBus.prototype._getListeners = function (name) {
  8170. return this._listeners[name];
  8171. };
  8172. EventBus.prototype._setListeners = function (name, listener) {
  8173. this._listeners[name] = listener;
  8174. };
  8175. EventBus.prototype._removeListener = function (event, callback) {
  8176. var listener = this._getListeners(event),
  8177. nextListener,
  8178. previousListener,
  8179. listenerCallback;
  8180. if (!callback) {
  8181. // clear listeners
  8182. this._setListeners(event, null);
  8183. return;
  8184. }
  8185. while (listener) {
  8186. nextListener = listener.next;
  8187. listenerCallback = listener.callback;
  8188. if (listenerCallback === callback || listenerCallback[FN_REF] === callback) {
  8189. if (previousListener) {
  8190. previousListener.next = nextListener;
  8191. } else {
  8192. // new first listener
  8193. this._setListeners(event, nextListener);
  8194. }
  8195. }
  8196. previousListener = listener;
  8197. listener = nextListener;
  8198. }
  8199. };
  8200. /**
  8201. * A event that is emitted via the event bus.
  8202. */
  8203. function InternalEvent() {
  8204. }
  8205. InternalEvent.prototype.stopPropagation = function () {
  8206. this.cancelBubble = true;
  8207. };
  8208. InternalEvent.prototype.preventDefault = function () {
  8209. this.defaultPrevented = true;
  8210. };
  8211. InternalEvent.prototype.init = function (data) {
  8212. assign(this, data || {});
  8213. };
  8214. /**
  8215. * Invoke function. Be fast...
  8216. *
  8217. * @param {Function} fn
  8218. * @param {Array<Object>} args
  8219. *
  8220. * @return {Any}
  8221. */
  8222. function invokeFunction(fn, args) {
  8223. return fn.apply(null, args);
  8224. }
  8225. /**
  8226. * SVGs for elements are generated by the {@link GraphicsFactory}.
  8227. *
  8228. * This utility gives quick access to the important semantic
  8229. * parts of an element.
  8230. */
  8231. /**
  8232. * Returns the visual part of a diagram element
  8233. *
  8234. * @param {Snap<SVGElement>} gfx
  8235. *
  8236. * @return {Snap<SVGElement>}
  8237. */
  8238. function getVisual(gfx) {
  8239. return gfx.childNodes[0];
  8240. }
  8241. /**
  8242. * Returns the children for a given diagram element.
  8243. *
  8244. * @param {Snap<SVGElement>} gfx
  8245. * @return {Snap<SVGElement>}
  8246. */
  8247. function getChildren(gfx) {
  8248. return gfx.parentNode.childNodes[1];
  8249. }
  8250. /**
  8251. * A factory that creates graphical elements
  8252. *
  8253. * @param {EventBus} eventBus
  8254. * @param {ElementRegistry} elementRegistry
  8255. */
  8256. function GraphicsFactory(eventBus, elementRegistry) {
  8257. this._eventBus = eventBus;
  8258. this._elementRegistry = elementRegistry;
  8259. }
  8260. GraphicsFactory.$inject = ['eventBus', 'elementRegistry'];
  8261. GraphicsFactory.prototype._getChildrenContainer = function (element) {
  8262. var gfx = this._elementRegistry.getGraphics(element);
  8263. var childrenGfx;
  8264. // root element
  8265. if (!element.parent) {
  8266. childrenGfx = gfx;
  8267. } else {
  8268. childrenGfx = getChildren(gfx);
  8269. if (!childrenGfx) {
  8270. childrenGfx = create('g');
  8271. classes(childrenGfx).add('djs-children');
  8272. append(gfx.parentNode, childrenGfx);
  8273. }
  8274. }
  8275. return childrenGfx;
  8276. };
  8277. /**
  8278. * Clears the graphical representation of the element and returns the
  8279. * cleared visual (the <g class="djs-visual" /> element).
  8280. */
  8281. GraphicsFactory.prototype._clear = function (gfx) {
  8282. var visual = getVisual(gfx);
  8283. clear$1(visual);
  8284. return visual;
  8285. };
  8286. /**
  8287. * Creates a gfx container for shapes and connections
  8288. *
  8289. * The layout is as follows:
  8290. *
  8291. * <g class="djs-group">
  8292. *
  8293. * <!-- the gfx -->
  8294. * <g class="djs-element djs-(shape|connection|frame)">
  8295. * <g class="djs-visual">
  8296. * <!-- the renderer draws in here -->
  8297. * </g>
  8298. *
  8299. * <!-- extensions (overlays, click box, ...) goes here
  8300. * </g>
  8301. *
  8302. * <!-- the gfx child nodes -->
  8303. * <g class="djs-children"></g>
  8304. * </g>
  8305. *
  8306. * @param {string} type the type of the element, i.e. shape | connection
  8307. * @param {SVGElement} [childrenGfx]
  8308. * @param {number} [parentIndex] position to create container in parent
  8309. * @param {boolean} [isFrame] is frame element
  8310. *
  8311. * @return {SVGElement}
  8312. */
  8313. GraphicsFactory.prototype._createContainer = function (
  8314. type, childrenGfx, parentIndex, isFrame
  8315. ) {
  8316. var outerGfx = create('g');
  8317. classes(outerGfx).add('djs-group');
  8318. // insert node at position
  8319. if (typeof parentIndex !== 'undefined') {
  8320. prependTo(outerGfx, childrenGfx, childrenGfx.childNodes[parentIndex]);
  8321. } else {
  8322. append(childrenGfx, outerGfx);
  8323. }
  8324. var gfx = create('g');
  8325. classes(gfx).add('djs-element');
  8326. classes(gfx).add('djs-' + type);
  8327. if (isFrame) {
  8328. classes(gfx).add('djs-frame');
  8329. }
  8330. append(outerGfx, gfx);
  8331. // create visual
  8332. var visual = create('g');
  8333. classes(visual).add('djs-visual');
  8334. append(gfx, visual);
  8335. return gfx;
  8336. };
  8337. GraphicsFactory.prototype.create = function (type, element, parentIndex) {
  8338. var childrenGfx = this._getChildrenContainer(element.parent);
  8339. return this._createContainer(type, childrenGfx, parentIndex, isFrameElement$1(element));
  8340. };
  8341. GraphicsFactory.prototype.updateContainments = function (elements) {
  8342. var self = this,
  8343. elementRegistry = this._elementRegistry,
  8344. parents;
  8345. parents = reduce(elements, function (map, e) {
  8346. if (e.parent) {
  8347. map[e.parent.id] = e.parent;
  8348. }
  8349. return map;
  8350. }, {});
  8351. // update all parents of changed and reorganized their children
  8352. // in the correct order (as indicated in our model)
  8353. forEach(parents, function (parent) {
  8354. var children = parent.children;
  8355. if (!children) {
  8356. return;
  8357. }
  8358. var childrenGfx = self._getChildrenContainer(parent);
  8359. forEach(children.slice().reverse(), function (child) {
  8360. var childGfx = elementRegistry.getGraphics(child);
  8361. prependTo(childGfx.parentNode, childrenGfx);
  8362. });
  8363. });
  8364. };
  8365. GraphicsFactory.prototype.drawShape = function (visual, element) {
  8366. var eventBus = this._eventBus;
  8367. return eventBus.fire('render.shape', {gfx: visual, element: element});
  8368. };
  8369. GraphicsFactory.prototype.getShapePath = function (element) {
  8370. var eventBus = this._eventBus;
  8371. return eventBus.fire('render.getShapePath', element);
  8372. };
  8373. GraphicsFactory.prototype.drawConnection = function (visual, element) {
  8374. var eventBus = this._eventBus;
  8375. return eventBus.fire('render.connection', {gfx: visual, element: element});
  8376. };
  8377. GraphicsFactory.prototype.getConnectionPath = function (waypoints) {
  8378. var eventBus = this._eventBus;
  8379. return eventBus.fire('render.getConnectionPath', waypoints);
  8380. };
  8381. GraphicsFactory.prototype.update = function (type, element, gfx) {
  8382. // do NOT update root element
  8383. if (!element.parent) {
  8384. return;
  8385. }
  8386. var visual = this._clear(gfx);
  8387. // redraw
  8388. if (type === 'shape') {
  8389. this.drawShape(visual, element);
  8390. // update positioning
  8391. translate(gfx, element.x, element.y);
  8392. } else if (type === 'connection') {
  8393. this.drawConnection(visual, element);
  8394. } else {
  8395. throw new Error('unknown type: ' + type);
  8396. }
  8397. if (element.hidden) {
  8398. attr(gfx, 'display', 'none');
  8399. } else {
  8400. attr(gfx, 'display', 'block');
  8401. }
  8402. };
  8403. GraphicsFactory.prototype.remove = function (element) {
  8404. var gfx = this._elementRegistry.getGraphics(element);
  8405. // remove
  8406. remove(gfx.parentNode);
  8407. };
  8408. // helpers //////////
  8409. function prependTo(newNode, parentNode, siblingNode) {
  8410. var node = siblingNode || parentNode.firstChild;
  8411. // do not prepend node to itself to prevent IE from crashing
  8412. // https://github.com/bpmn-io/bpmn-js/issues/746
  8413. if (newNode === node) {
  8414. return;
  8415. }
  8416. parentNode.insertBefore(newNode, node);
  8417. }
  8418. var CoreModule$1 = {
  8419. __depends__: [DrawModule$1],
  8420. __init__: ['canvas'],
  8421. canvas: ['type', Canvas],
  8422. elementRegistry: ['type', ElementRegistry],
  8423. elementFactory: ['type', ElementFactory],
  8424. eventBus: ['type', EventBus],
  8425. graphicsFactory: ['type', GraphicsFactory]
  8426. };
  8427. /**
  8428. * Bootstrap an injector from a list of modules, instantiating a number of default components
  8429. *
  8430. * @ignore
  8431. * @param {Array<didi.Module>} bootstrapModules
  8432. *
  8433. * @return {didi.Injector} a injector to use to access the components
  8434. */
  8435. function bootstrap(bootstrapModules) {
  8436. var modules = [],
  8437. components = [];
  8438. function hasModule(m) {
  8439. return modules.indexOf(m) >= 0;
  8440. }
  8441. function addModule(m) {
  8442. modules.push(m);
  8443. }
  8444. function visit(m) {
  8445. if (hasModule(m)) {
  8446. return;
  8447. }
  8448. (m.__depends__ || []).forEach(visit);
  8449. if (hasModule(m)) {
  8450. return;
  8451. }
  8452. addModule(m);
  8453. (m.__init__ || []).forEach(function (c) {
  8454. components.push(c);
  8455. });
  8456. }
  8457. bootstrapModules.forEach(visit);
  8458. var injector = new Injector(modules);
  8459. components.forEach(function (c) {
  8460. try {
  8461. // eagerly resolve component (fn or string)
  8462. injector[typeof c === 'string' ? 'get' : 'invoke'](c);
  8463. } catch (e) {
  8464. console.error('Failed to instantiate component');
  8465. console.error(e.stack);
  8466. throw e;
  8467. }
  8468. });
  8469. return injector;
  8470. }
  8471. /**
  8472. * Creates an injector from passed options.
  8473. *
  8474. * @ignore
  8475. * @param {Object} options
  8476. * @return {didi.Injector}
  8477. */
  8478. function createInjector(options) {
  8479. options = options || {};
  8480. var configModule = {
  8481. 'config': ['value', options]
  8482. };
  8483. var modules = [configModule, CoreModule$1].concat(options.modules || []);
  8484. return bootstrap(modules);
  8485. }
  8486. /**
  8487. * The main diagram-js entry point that bootstraps the diagram with the given
  8488. * configuration.
  8489. *
  8490. * To register extensions with the diagram, pass them as Array<didi.Module> to the constructor.
  8491. *
  8492. * @class djs.Diagram
  8493. * @memberOf djs
  8494. * @constructor
  8495. *
  8496. * @example
  8497. *
  8498. * <caption>Creating a plug-in that logs whenever a shape is added to the canvas.</caption>
  8499. *
  8500. * // plug-in implemenentation
  8501. * function MyLoggingPlugin(eventBus) {
  8502. * eventBus.on('shape.added', function(event) {
  8503. * console.log('shape ', event.shape, ' was added to the diagram');
  8504. * });
  8505. * }
  8506. *
  8507. * // export as module
  8508. * export default {
  8509. * __init__: [ 'myLoggingPlugin' ],
  8510. * myLoggingPlugin: [ 'type', MyLoggingPlugin ]
  8511. * };
  8512. *
  8513. *
  8514. * // instantiate the diagram with the new plug-in
  8515. *
  8516. * import MyLoggingModule from 'path-to-my-logging-plugin';
  8517. *
  8518. * var diagram = new Diagram({
  8519. * modules: [
  8520. * MyLoggingModule
  8521. * ]
  8522. * });
  8523. *
  8524. * diagram.invoke([ 'canvas', function(canvas) {
  8525. * // add shape to drawing canvas
  8526. * canvas.addShape({ x: 10, y: 10 });
  8527. * });
  8528. *
  8529. * // 'shape ... was added to the diagram' logged to console
  8530. *
  8531. * @param {Object} options
  8532. * @param {Array<didi.Module>} [options.modules] external modules to instantiate with the diagram
  8533. * @param {didi.Injector} [injector] an (optional) injector to bootstrap the diagram with
  8534. */
  8535. function Diagram(options, injector) {
  8536. // create injector unless explicitly specified
  8537. this.injector = injector = injector || createInjector(options);
  8538. // API
  8539. /**
  8540. * Resolves a diagram service
  8541. *
  8542. * @method Diagram#get
  8543. *
  8544. * @param {string} name the name of the diagram service to be retrieved
  8545. * @param {boolean} [strict=true] if false, resolve missing services to null
  8546. */
  8547. this.get = injector.get;
  8548. /**
  8549. * Executes a function into which diagram services are injected
  8550. *
  8551. * @method Diagram#invoke
  8552. *
  8553. * @param {Function|Object[]} fn the function to resolve
  8554. * @param {Object} locals a number of locals to use to resolve certain dependencies
  8555. */
  8556. this.invoke = injector.invoke;
  8557. // init
  8558. // indicate via event
  8559. /**
  8560. * An event indicating that all plug-ins are loaded.
  8561. *
  8562. * Use this event to fire other events to interested plug-ins
  8563. *
  8564. * @memberOf Diagram
  8565. *
  8566. * @event diagram.init
  8567. *
  8568. * @example
  8569. *
  8570. * eventBus.on('diagram.init', function() {
  8571. * eventBus.fire('my-custom-event', { foo: 'BAR' });
  8572. * });
  8573. *
  8574. * @type {Object}
  8575. */
  8576. this.get('eventBus').fire('diagram.init');
  8577. }
  8578. /**
  8579. * Destroys the diagram
  8580. *
  8581. * @method Diagram#destroy
  8582. */
  8583. Diagram.prototype.destroy = function () {
  8584. this.get('eventBus').fire('diagram.destroy');
  8585. };
  8586. /**
  8587. * Clear the diagram, removing all contents.
  8588. */
  8589. Diagram.prototype.clear = function () {
  8590. this.get('eventBus').fire('diagram.clear');
  8591. };
  8592. /**
  8593. * Moddle base element.
  8594. */
  8595. function Base$1() {
  8596. }
  8597. Base$1.prototype.get = function (name) {
  8598. return this.$model.properties.get(this, name);
  8599. };
  8600. Base$1.prototype.set = function (name, value) {
  8601. this.$model.properties.set(this, name, value);
  8602. };
  8603. /**
  8604. * A model element factory.
  8605. *
  8606. * @param {Moddle} model
  8607. * @param {Properties} properties
  8608. */
  8609. function Factory(model, properties) {
  8610. this.model = model;
  8611. this.properties = properties;
  8612. }
  8613. Factory.prototype.createType = function (descriptor) {
  8614. var model = this.model;
  8615. var props = this.properties,
  8616. prototype = Object.create(Base$1.prototype);
  8617. // initialize default values
  8618. forEach(descriptor.properties, function (p) {
  8619. if (!p.isMany && p.default !== undefined) {
  8620. prototype[p.name] = p.default;
  8621. }
  8622. });
  8623. props.defineModel(prototype, model);
  8624. props.defineDescriptor(prototype, descriptor);
  8625. var name = descriptor.ns.name;
  8626. /**
  8627. * The new type constructor
  8628. */
  8629. function ModdleElement(attrs) {
  8630. props.define(this, '$type', {value: name, enumerable: true});
  8631. props.define(this, '$attrs', {value: {}});
  8632. props.define(this, '$parent', {writable: true});
  8633. forEach(attrs, bind(function (val, key) {
  8634. this.set(key, val);
  8635. }, this));
  8636. }
  8637. ModdleElement.prototype = prototype;
  8638. ModdleElement.hasType = prototype.$instanceOf = this.model.hasType;
  8639. // static links
  8640. props.defineModel(ModdleElement, model);
  8641. props.defineDescriptor(ModdleElement, descriptor);
  8642. return ModdleElement;
  8643. };
  8644. /**
  8645. * Built-in moddle types
  8646. */
  8647. var BUILTINS = {
  8648. String: true,
  8649. Boolean: true,
  8650. Integer: true,
  8651. Real: true,
  8652. Element: true
  8653. };
  8654. /**
  8655. * Converters for built in types from string representations
  8656. */
  8657. var TYPE_CONVERTERS = {
  8658. String: function (s) {
  8659. return s;
  8660. },
  8661. Boolean: function (s) {
  8662. return s === 'true';
  8663. },
  8664. Integer: function (s) {
  8665. return parseInt(s, 10);
  8666. },
  8667. Real: function (s) {
  8668. return parseFloat(s, 10);
  8669. }
  8670. };
  8671. /**
  8672. * Convert a type to its real representation
  8673. */
  8674. function coerceType(type, value) {
  8675. var converter = TYPE_CONVERTERS[type];
  8676. if (converter) {
  8677. return converter(value);
  8678. } else {
  8679. return value;
  8680. }
  8681. }
  8682. /**
  8683. * Return whether the given type is built-in
  8684. */
  8685. function isBuiltIn(type) {
  8686. return !!BUILTINS[type];
  8687. }
  8688. /**
  8689. * Return whether the given type is simple
  8690. */
  8691. function isSimple(type) {
  8692. return !!TYPE_CONVERTERS[type];
  8693. }
  8694. /**
  8695. * Parses a namespaced attribute name of the form (ns:)localName to an object,
  8696. * given a default prefix to assume in case no explicit namespace is given.
  8697. *
  8698. * @param {String} name
  8699. * @param {String} [defaultPrefix] the default prefix to take, if none is present.
  8700. *
  8701. * @return {Object} the parsed name
  8702. */
  8703. function parseName(name, defaultPrefix) {
  8704. var parts = name.split(/:/),
  8705. localName, prefix;
  8706. // no prefix (i.e. only local name)
  8707. if (parts.length === 1) {
  8708. localName = name;
  8709. prefix = defaultPrefix;
  8710. } else
  8711. // prefix + local name
  8712. if (parts.length === 2) {
  8713. localName = parts[1];
  8714. prefix = parts[0];
  8715. } else {
  8716. throw new Error('expected <prefix:localName> or <localName>, got ' + name);
  8717. }
  8718. name = (prefix ? prefix + ':' : '') + localName;
  8719. return {
  8720. name: name,
  8721. prefix: prefix,
  8722. localName: localName
  8723. };
  8724. }
  8725. /**
  8726. * A utility to build element descriptors.
  8727. */
  8728. function DescriptorBuilder(nameNs) {
  8729. this.ns = nameNs;
  8730. this.name = nameNs.name;
  8731. this.allTypes = [];
  8732. this.allTypesByName = {};
  8733. this.properties = [];
  8734. this.propertiesByName = {};
  8735. }
  8736. DescriptorBuilder.prototype.build = function () {
  8737. return pick(this, [
  8738. 'ns',
  8739. 'name',
  8740. 'allTypes',
  8741. 'allTypesByName',
  8742. 'properties',
  8743. 'propertiesByName',
  8744. 'bodyProperty',
  8745. 'idProperty'
  8746. ]);
  8747. };
  8748. /**
  8749. * Add property at given index.
  8750. *
  8751. * @param {Object} p
  8752. * @param {Number} [idx]
  8753. * @param {Boolean} [validate=true]
  8754. */
  8755. DescriptorBuilder.prototype.addProperty = function (p, idx, validate) {
  8756. if (typeof idx === 'boolean') {
  8757. validate = idx;
  8758. idx = undefined;
  8759. }
  8760. this.addNamedProperty(p, validate !== false);
  8761. var properties = this.properties;
  8762. if (idx !== undefined) {
  8763. properties.splice(idx, 0, p);
  8764. } else {
  8765. properties.push(p);
  8766. }
  8767. };
  8768. DescriptorBuilder.prototype.replaceProperty = function (oldProperty, newProperty, replace) {
  8769. var oldNameNs = oldProperty.ns;
  8770. var props = this.properties,
  8771. propertiesByName = this.propertiesByName,
  8772. rename = oldProperty.name !== newProperty.name;
  8773. if (oldProperty.isId) {
  8774. if (!newProperty.isId) {
  8775. throw new Error(
  8776. 'property <' + newProperty.ns.name + '> must be id property ' +
  8777. 'to refine <' + oldProperty.ns.name + '>');
  8778. }
  8779. this.setIdProperty(newProperty, false);
  8780. }
  8781. if (oldProperty.isBody) {
  8782. if (!newProperty.isBody) {
  8783. throw new Error(
  8784. 'property <' + newProperty.ns.name + '> must be body property ' +
  8785. 'to refine <' + oldProperty.ns.name + '>');
  8786. }
  8787. // TODO: Check compatibility
  8788. this.setBodyProperty(newProperty, false);
  8789. }
  8790. // validate existence and get location of old property
  8791. var idx = props.indexOf(oldProperty);
  8792. if (idx === -1) {
  8793. throw new Error('property <' + oldNameNs.name + '> not found in property list');
  8794. }
  8795. // remove old property
  8796. props.splice(idx, 1);
  8797. // replacing the named property is intentional
  8798. //
  8799. // * validate only if this is a "rename" operation
  8800. // * add at specific index unless we "replace"
  8801. //
  8802. this.addProperty(newProperty, replace ? undefined : idx, rename);
  8803. // make new property available under old name
  8804. propertiesByName[oldNameNs.name] = propertiesByName[oldNameNs.localName] = newProperty;
  8805. };
  8806. DescriptorBuilder.prototype.redefineProperty = function (p, targetPropertyName, replace) {
  8807. var nsPrefix = p.ns.prefix;
  8808. var parts = targetPropertyName.split('#');
  8809. var name = parseName(parts[0], nsPrefix);
  8810. var attrName = parseName(parts[1], name.prefix).name;
  8811. var redefinedProperty = this.propertiesByName[attrName];
  8812. if (!redefinedProperty) {
  8813. throw new Error('refined property <' + attrName + '> not found');
  8814. } else {
  8815. this.replaceProperty(redefinedProperty, p, replace);
  8816. }
  8817. delete p.redefines;
  8818. };
  8819. DescriptorBuilder.prototype.addNamedProperty = function (p, validate) {
  8820. var ns = p.ns,
  8821. propsByName = this.propertiesByName;
  8822. if (validate) {
  8823. this.assertNotDefined(p, ns.name);
  8824. this.assertNotDefined(p, ns.localName);
  8825. }
  8826. propsByName[ns.name] = propsByName[ns.localName] = p;
  8827. };
  8828. DescriptorBuilder.prototype.removeNamedProperty = function (p) {
  8829. var ns = p.ns,
  8830. propsByName = this.propertiesByName;
  8831. delete propsByName[ns.name];
  8832. delete propsByName[ns.localName];
  8833. };
  8834. DescriptorBuilder.prototype.setBodyProperty = function (p, validate) {
  8835. if (validate && this.bodyProperty) {
  8836. throw new Error(
  8837. 'body property defined multiple times ' +
  8838. '(<' + this.bodyProperty.ns.name + '>, <' + p.ns.name + '>)');
  8839. }
  8840. this.bodyProperty = p;
  8841. };
  8842. DescriptorBuilder.prototype.setIdProperty = function (p, validate) {
  8843. if (validate && this.idProperty) {
  8844. throw new Error(
  8845. 'id property defined multiple times ' +
  8846. '(<' + this.idProperty.ns.name + '>, <' + p.ns.name + '>)');
  8847. }
  8848. this.idProperty = p;
  8849. };
  8850. DescriptorBuilder.prototype.assertNotDefined = function (p, name) {
  8851. var propertyName = p.name,
  8852. definedProperty = this.propertiesByName[propertyName];
  8853. if (definedProperty) {
  8854. throw new Error(
  8855. 'property <' + propertyName + '> already defined; ' +
  8856. 'override of <' + definedProperty.definedBy.ns.name + '#' + definedProperty.ns.name + '> by ' +
  8857. '<' + p.definedBy.ns.name + '#' + p.ns.name + '> not allowed without redefines');
  8858. }
  8859. };
  8860. DescriptorBuilder.prototype.hasProperty = function (name) {
  8861. return this.propertiesByName[name];
  8862. };
  8863. DescriptorBuilder.prototype.addTrait = function (t, inherited) {
  8864. var typesByName = this.allTypesByName,
  8865. types = this.allTypes;
  8866. var typeName = t.name;
  8867. if (typeName in typesByName) {
  8868. return;
  8869. }
  8870. forEach(t.properties, bind(function (p) {
  8871. // clone property to allow extensions
  8872. p = assign({}, p, {
  8873. name: p.ns.localName,
  8874. inherited: inherited
  8875. });
  8876. Object.defineProperty(p, 'definedBy', {
  8877. value: t
  8878. });
  8879. var replaces = p.replaces,
  8880. redefines = p.redefines;
  8881. // add replace/redefine support
  8882. if (replaces || redefines) {
  8883. this.redefineProperty(p, replaces || redefines, replaces);
  8884. } else {
  8885. if (p.isBody) {
  8886. this.setBodyProperty(p);
  8887. }
  8888. if (p.isId) {
  8889. this.setIdProperty(p);
  8890. }
  8891. this.addProperty(p);
  8892. }
  8893. }, this));
  8894. types.push(t);
  8895. typesByName[typeName] = t;
  8896. };
  8897. /**
  8898. * A registry of Moddle packages.
  8899. *
  8900. * @param {Array<Package>} packages
  8901. * @param {Properties} properties
  8902. */
  8903. function Registry(packages, properties) {
  8904. this.packageMap = {};
  8905. this.typeMap = {};
  8906. this.packages = [];
  8907. this.properties = properties;
  8908. forEach(packages, bind(this.registerPackage, this));
  8909. }
  8910. Registry.prototype.getPackage = function (uriOrPrefix) {
  8911. return this.packageMap[uriOrPrefix];
  8912. };
  8913. Registry.prototype.getPackages = function () {
  8914. return this.packages;
  8915. };
  8916. Registry.prototype.registerPackage = function (pkg) {
  8917. // copy package
  8918. pkg = assign({}, pkg);
  8919. var pkgMap = this.packageMap;
  8920. ensureAvailable(pkgMap, pkg, 'prefix');
  8921. ensureAvailable(pkgMap, pkg, 'uri');
  8922. // register types
  8923. forEach(pkg.types, bind(function (descriptor) {
  8924. this.registerType(descriptor, pkg);
  8925. }, this));
  8926. pkgMap[pkg.uri] = pkgMap[pkg.prefix] = pkg;
  8927. this.packages.push(pkg);
  8928. };
  8929. /**
  8930. * Register a type from a specific package with us
  8931. */
  8932. Registry.prototype.registerType = function (type, pkg) {
  8933. type = assign({}, type, {
  8934. superClass: (type.superClass || []).slice(),
  8935. extends: (type.extends || []).slice(),
  8936. properties: (type.properties || []).slice(),
  8937. meta: assign((type.meta || {}))
  8938. });
  8939. var ns = parseName(type.name, pkg.prefix),
  8940. name = ns.name,
  8941. propertiesByName = {};
  8942. // parse properties
  8943. forEach(type.properties, bind(function (p) {
  8944. // namespace property names
  8945. var propertyNs = parseName(p.name, ns.prefix),
  8946. propertyName = propertyNs.name;
  8947. // namespace property types
  8948. if (!isBuiltIn(p.type)) {
  8949. p.type = parseName(p.type, propertyNs.prefix).name;
  8950. }
  8951. assign(p, {
  8952. ns: propertyNs,
  8953. name: propertyName
  8954. });
  8955. propertiesByName[propertyName] = p;
  8956. }, this));
  8957. // update ns + name
  8958. assign(type, {
  8959. ns: ns,
  8960. name: name,
  8961. propertiesByName: propertiesByName
  8962. });
  8963. forEach(type.extends, bind(function (extendsName) {
  8964. var extended = this.typeMap[extendsName];
  8965. extended.traits = extended.traits || [];
  8966. extended.traits.push(name);
  8967. }, this));
  8968. // link to package
  8969. this.definePackage(type, pkg);
  8970. // register
  8971. this.typeMap[name] = type;
  8972. };
  8973. /**
  8974. * Traverse the type hierarchy from bottom to top,
  8975. * calling iterator with (type, inherited) for all elements in
  8976. * the inheritance chain.
  8977. *
  8978. * @param {Object} nsName
  8979. * @param {Function} iterator
  8980. * @param {Boolean} [trait=false]
  8981. */
  8982. Registry.prototype.mapTypes = function (nsName, iterator, trait) {
  8983. var type = isBuiltIn(nsName.name) ? {name: nsName.name} : this.typeMap[nsName.name];
  8984. var self = this;
  8985. /**
  8986. * Traverse the selected trait.
  8987. *
  8988. * @param {String} cls
  8989. */
  8990. function traverseTrait(cls) {
  8991. return traverseSuper(cls, true);
  8992. }
  8993. /**
  8994. * Traverse the selected super type or trait
  8995. *
  8996. * @param {String} cls
  8997. * @param {Boolean} [trait=false]
  8998. */
  8999. function traverseSuper(cls, trait) {
  9000. var parentNs = parseName(cls, isBuiltIn(cls) ? '' : nsName.prefix);
  9001. self.mapTypes(parentNs, iterator, trait);
  9002. }
  9003. if (!type) {
  9004. throw new Error('unknown type <' + nsName.name + '>');
  9005. }
  9006. forEach(type.superClass, trait ? traverseTrait : traverseSuper);
  9007. // call iterator with (type, inherited=!trait)
  9008. iterator(type, !trait);
  9009. forEach(type.traits, traverseTrait);
  9010. };
  9011. /**
  9012. * Returns the effective descriptor for a type.
  9013. *
  9014. * @param {String} type the namespaced name (ns:localName) of the type
  9015. *
  9016. * @return {Descriptor} the resulting effective descriptor
  9017. */
  9018. Registry.prototype.getEffectiveDescriptor = function (name) {
  9019. var nsName = parseName(name);
  9020. var builder = new DescriptorBuilder(nsName);
  9021. this.mapTypes(nsName, function (type, inherited) {
  9022. builder.addTrait(type, inherited);
  9023. });
  9024. var descriptor = builder.build();
  9025. // define package link
  9026. this.definePackage(descriptor, descriptor.allTypes[descriptor.allTypes.length - 1].$pkg);
  9027. return descriptor;
  9028. };
  9029. Registry.prototype.definePackage = function (target, pkg) {
  9030. this.properties.define(target, '$pkg', {value: pkg});
  9031. };
  9032. ///////// helpers ////////////////////////////
  9033. function ensureAvailable(packageMap, pkg, identifierKey) {
  9034. var value = pkg[identifierKey];
  9035. if (value in packageMap) {
  9036. throw new Error('package with ' + identifierKey + ' <' + value + '> already defined');
  9037. }
  9038. }
  9039. /**
  9040. * A utility that gets and sets properties of model elements.
  9041. *
  9042. * @param {Model} model
  9043. */
  9044. function Properties(model) {
  9045. this.model = model;
  9046. }
  9047. /**
  9048. * Sets a named property on the target element.
  9049. * If the value is undefined, the property gets deleted.
  9050. *
  9051. * @param {Object} target
  9052. * @param {String} name
  9053. * @param {Object} value
  9054. */
  9055. Properties.prototype.set = function (target, name, value) {
  9056. var property = this.model.getPropertyDescriptor(target, name);
  9057. var propertyName = property && property.name;
  9058. if (isUndefined$1(value)) {
  9059. // unset the property, if the specified value is undefined;
  9060. // delete from $attrs (for extensions) or the target itself
  9061. if (property) {
  9062. delete target[propertyName];
  9063. } else {
  9064. delete target.$attrs[name];
  9065. }
  9066. } else {
  9067. // set the property, defining well defined properties on the fly
  9068. // or simply updating them in target.$attrs (for extensions)
  9069. if (property) {
  9070. if (propertyName in target) {
  9071. target[propertyName] = value;
  9072. } else {
  9073. defineProperty$1(target, property, value);
  9074. }
  9075. } else {
  9076. target.$attrs[name] = value;
  9077. }
  9078. }
  9079. };
  9080. /**
  9081. * Returns the named property of the given element
  9082. *
  9083. * @param {Object} target
  9084. * @param {String} name
  9085. *
  9086. * @return {Object}
  9087. */
  9088. Properties.prototype.get = function (target, name) {
  9089. var property = this.model.getPropertyDescriptor(target, name);
  9090. if (!property) {
  9091. return target.$attrs[name];
  9092. }
  9093. var propertyName = property.name;
  9094. // check if access to collection property and lazily initialize it
  9095. if (!target[propertyName] && property.isMany) {
  9096. defineProperty$1(target, property, []);
  9097. }
  9098. return target[propertyName];
  9099. };
  9100. /**
  9101. * Define a property on the target element
  9102. *
  9103. * @param {Object} target
  9104. * @param {String} name
  9105. * @param {Object} options
  9106. */
  9107. Properties.prototype.define = function (target, name, options) {
  9108. Object.defineProperty(target, name, options);
  9109. };
  9110. /**
  9111. * Define the descriptor for an element
  9112. */
  9113. Properties.prototype.defineDescriptor = function (target, descriptor) {
  9114. this.define(target, '$descriptor', {value: descriptor});
  9115. };
  9116. /**
  9117. * Define the model for an element
  9118. */
  9119. Properties.prototype.defineModel = function (target, model) {
  9120. this.define(target, '$model', {value: model});
  9121. };
  9122. function isUndefined$1(val) {
  9123. return typeof val === 'undefined';
  9124. }
  9125. function defineProperty$1(target, property, value) {
  9126. Object.defineProperty(target, property.name, {
  9127. enumerable: !property.isReference,
  9128. writable: true,
  9129. value: value,
  9130. configurable: true
  9131. });
  9132. }
  9133. //// Moddle implementation /////////////////////////////////////////////////
  9134. /**
  9135. * @class Moddle
  9136. *
  9137. * A model that can be used to create elements of a specific type.
  9138. *
  9139. * @example
  9140. *
  9141. * var Moddle = require('moddle');
  9142. *
  9143. * var pkg = {
  9144. * name: 'mypackage',
  9145. * prefix: 'my',
  9146. * types: [
  9147. * { name: 'Root' }
  9148. * ]
  9149. * };
  9150. *
  9151. * var moddle = new Moddle([pkg]);
  9152. *
  9153. * @param {Array<Package>} packages the packages to contain
  9154. */
  9155. function Moddle(packages) {
  9156. this.properties = new Properties(this);
  9157. this.factory = new Factory(this, this.properties);
  9158. this.registry = new Registry(packages, this.properties);
  9159. this.typeCache = {};
  9160. }
  9161. /**
  9162. * Create an instance of the specified type.
  9163. *
  9164. * @method Moddle#create
  9165. *
  9166. * @example
  9167. *
  9168. * var foo = moddle.create('my:Foo');
  9169. * var bar = moddle.create('my:Bar', { id: 'BAR_1' });
  9170. *
  9171. * @param {String|Object} descriptor the type descriptor or name know to the model
  9172. * @param {Object} attrs a number of attributes to initialize the model instance with
  9173. * @return {Object} model instance
  9174. */
  9175. Moddle.prototype.create = function (descriptor, attrs) {
  9176. var Type = this.getType(descriptor);
  9177. if (!Type) {
  9178. throw new Error('unknown type <' + descriptor + '>');
  9179. }
  9180. return new Type(attrs);
  9181. };
  9182. /**
  9183. * Returns the type representing a given descriptor
  9184. *
  9185. * @method Moddle#getType
  9186. *
  9187. * @example
  9188. *
  9189. * var Foo = moddle.getType('my:Foo');
  9190. * var foo = new Foo({ 'id' : 'FOO_1' });
  9191. *
  9192. * @param {String|Object} descriptor the type descriptor or name know to the model
  9193. * @return {Object} the type representing the descriptor
  9194. */
  9195. Moddle.prototype.getType = function (descriptor) {
  9196. var cache = this.typeCache;
  9197. var name = isString(descriptor) ? descriptor : descriptor.ns.name;
  9198. var type = cache[name];
  9199. if (!type) {
  9200. descriptor = this.registry.getEffectiveDescriptor(name);
  9201. type = cache[name] = this.factory.createType(descriptor);
  9202. }
  9203. return type;
  9204. };
  9205. /**
  9206. * Creates an any-element type to be used within model instances.
  9207. *
  9208. * This can be used to create custom elements that lie outside the meta-model.
  9209. * The created element contains all the meta-data required to serialize it
  9210. * as part of meta-model elements.
  9211. *
  9212. * @method Moddle#createAny
  9213. *
  9214. * @example
  9215. *
  9216. * var foo = moddle.createAny('vendor:Foo', 'http://vendor', {
  9217. * value: 'bar'
  9218. * });
  9219. *
  9220. * var container = moddle.create('my:Container', 'http://my', {
  9221. * any: [ foo ]
  9222. * });
  9223. *
  9224. * // go ahead and serialize the stuff
  9225. *
  9226. *
  9227. * @param {String} name the name of the element
  9228. * @param {String} nsUri the namespace uri of the element
  9229. * @param {Object} [properties] a map of properties to initialize the instance with
  9230. * @return {Object} the any type instance
  9231. */
  9232. Moddle.prototype.createAny = function (name, nsUri, properties) {
  9233. var nameNs = parseName(name);
  9234. var element = {
  9235. $type: name,
  9236. $instanceOf: function (type) {
  9237. return type === this.$type;
  9238. }
  9239. };
  9240. var descriptor = {
  9241. name: name,
  9242. isGeneric: true,
  9243. ns: {
  9244. prefix: nameNs.prefix,
  9245. localName: nameNs.localName,
  9246. uri: nsUri
  9247. }
  9248. };
  9249. this.properties.defineDescriptor(element, descriptor);
  9250. this.properties.defineModel(element, this);
  9251. this.properties.define(element, '$parent', {enumerable: false, writable: true});
  9252. forEach(properties, function (a, key) {
  9253. if (isObject(a) && a.value !== undefined) {
  9254. element[a.name] = a.value;
  9255. } else {
  9256. element[key] = a;
  9257. }
  9258. });
  9259. return element;
  9260. };
  9261. /**
  9262. * Returns a registered package by uri or prefix
  9263. *
  9264. * @return {Object} the package
  9265. */
  9266. Moddle.prototype.getPackage = function (uriOrPrefix) {
  9267. return this.registry.getPackage(uriOrPrefix);
  9268. };
  9269. /**
  9270. * Returns a snapshot of all known packages
  9271. *
  9272. * @return {Object} the package
  9273. */
  9274. Moddle.prototype.getPackages = function () {
  9275. return this.registry.getPackages();
  9276. };
  9277. /**
  9278. * Returns the descriptor for an element
  9279. */
  9280. Moddle.prototype.getElementDescriptor = function (element) {
  9281. return element.$descriptor;
  9282. };
  9283. /**
  9284. * Returns true if the given descriptor or instance
  9285. * represents the given type.
  9286. *
  9287. * May be applied to this, if element is omitted.
  9288. */
  9289. Moddle.prototype.hasType = function (element, type) {
  9290. if (type === undefined) {
  9291. type = element;
  9292. element = this;
  9293. }
  9294. var descriptor = element.$model.getElementDescriptor(element);
  9295. return (type in descriptor.allTypesByName);
  9296. };
  9297. /**
  9298. * Returns the descriptor of an elements named property
  9299. */
  9300. Moddle.prototype.getPropertyDescriptor = function (element, property) {
  9301. return this.getElementDescriptor(element).propertiesByName[property];
  9302. };
  9303. /**
  9304. * Returns a mapped type's descriptor
  9305. */
  9306. Moddle.prototype.getTypeDescriptor = function (type) {
  9307. return this.registry.typeMap[type];
  9308. };
  9309. var fromCharCode = String.fromCharCode;
  9310. var hasOwnProperty$1 = Object.prototype.hasOwnProperty;
  9311. var ENTITY_PATTERN = /&#(\d+);|&#x([0-9a-f]+);|&(\w+);/ig;
  9312. var ENTITY_MAPPING = {
  9313. 'amp': '&',
  9314. 'apos': '\'',
  9315. 'gt': '>',
  9316. 'lt': '<',
  9317. 'quot': '"'
  9318. };
  9319. // map UPPERCASE variants of supported special chars
  9320. Object.keys(ENTITY_MAPPING).forEach(function (k) {
  9321. ENTITY_MAPPING[k.toUpperCase()] = ENTITY_MAPPING[k];
  9322. });
  9323. function replaceEntities(_, d, x, z) {
  9324. // reserved names, i.e. &nbsp;
  9325. if (z) {
  9326. if (hasOwnProperty$1.call(ENTITY_MAPPING, z)) {
  9327. return ENTITY_MAPPING[z];
  9328. } else {
  9329. // fall back to original value
  9330. return '&' + z + ';';
  9331. }
  9332. }
  9333. // decimal encoded char
  9334. if (d) {
  9335. return fromCharCode(d);
  9336. }
  9337. // hex encoded char
  9338. return fromCharCode(parseInt(x, 16));
  9339. }
  9340. /**
  9341. * A basic entity decoder that can decode a minimal
  9342. * sub-set of reserved names (&amp;) as well as
  9343. * hex (&#xaaf;) and decimal (&#1231;) encoded characters.
  9344. *
  9345. * @param {string} str
  9346. *
  9347. * @return {string} decoded string
  9348. */
  9349. function decodeEntities(s) {
  9350. if (s.length > 3 && s.indexOf('&') !== -1) {
  9351. return s.replace(ENTITY_PATTERN, replaceEntities);
  9352. }
  9353. return s;
  9354. }
  9355. var XSI_URI = 'http://www.w3.org/2001/XMLSchema-instance';
  9356. var XSI_PREFIX = 'xsi';
  9357. var XSI_TYPE = 'xsi:type';
  9358. var NON_WHITESPACE_OUTSIDE_ROOT_NODE = 'non-whitespace outside of root node';
  9359. function error(msg) {
  9360. return new Error(msg);
  9361. }
  9362. function missingNamespaceForPrefix(prefix) {
  9363. return 'missing namespace for prefix <' + prefix + '>';
  9364. }
  9365. function getter(getFn) {
  9366. return {
  9367. 'get': getFn,
  9368. 'enumerable': true
  9369. };
  9370. }
  9371. function cloneNsMatrix(nsMatrix) {
  9372. var clone = {}, key;
  9373. for (key in nsMatrix) {
  9374. clone[key] = nsMatrix[key];
  9375. }
  9376. return clone;
  9377. }
  9378. function uriPrefix(prefix) {
  9379. return prefix + '$uri';
  9380. }
  9381. function buildNsMatrix(nsUriToPrefix) {
  9382. var nsMatrix = {},
  9383. uri,
  9384. prefix;
  9385. for (uri in nsUriToPrefix) {
  9386. prefix = nsUriToPrefix[uri];
  9387. nsMatrix[prefix] = prefix;
  9388. nsMatrix[uriPrefix(prefix)] = uri;
  9389. }
  9390. return nsMatrix;
  9391. }
  9392. function noopGetContext() {
  9393. return {'line': 0, 'column': 0};
  9394. }
  9395. function throwFunc(err) {
  9396. throw err;
  9397. }
  9398. /**
  9399. * Creates a new parser with the given options.
  9400. *
  9401. * @constructor
  9402. *
  9403. * @param {!Object<string, ?>=} options
  9404. */
  9405. function Parser(options) {
  9406. if (!this) {
  9407. return new Parser(options);
  9408. }
  9409. var proxy = options && options['proxy'];
  9410. var onText,
  9411. onOpenTag,
  9412. onCloseTag,
  9413. onCDATA,
  9414. onError = throwFunc,
  9415. onWarning,
  9416. onComment,
  9417. onQuestion,
  9418. onAttention;
  9419. var getContext = noopGetContext;
  9420. /**
  9421. * Do we need to parse the current elements attributes for namespaces?
  9422. *
  9423. * @type {boolean}
  9424. */
  9425. var maybeNS = false;
  9426. /**
  9427. * Do we process namespaces at all?
  9428. *
  9429. * @type {boolean}
  9430. */
  9431. var isNamespace = false;
  9432. /**
  9433. * The caught error returned on parse end
  9434. *
  9435. * @type {Error}
  9436. */
  9437. var returnError = null;
  9438. /**
  9439. * Should we stop parsing?
  9440. *
  9441. * @type {boolean}
  9442. */
  9443. var parseStop = false;
  9444. /**
  9445. * A map of { uri: prefix } used by the parser.
  9446. *
  9447. * This map will ensure we can normalize prefixes during processing;
  9448. * for each uri, only one prefix will be exposed to the handlers.
  9449. *
  9450. * @type {!Object<string, string>}}
  9451. */
  9452. var nsUriToPrefix;
  9453. /**
  9454. * Handle parse error.
  9455. *
  9456. * @param {string|Error} err
  9457. */
  9458. function handleError(err) {
  9459. if (!(err instanceof Error)) {
  9460. err = error(err);
  9461. }
  9462. returnError = err;
  9463. onError(err, getContext);
  9464. }
  9465. /**
  9466. * Handle parse error.
  9467. *
  9468. * @param {string|Error} err
  9469. */
  9470. function handleWarning(err) {
  9471. if (!onWarning) {
  9472. return;
  9473. }
  9474. if (!(err instanceof Error)) {
  9475. err = error(err);
  9476. }
  9477. onWarning(err, getContext);
  9478. }
  9479. /**
  9480. * Register parse listener.
  9481. *
  9482. * @param {string} name
  9483. * @param {Function} cb
  9484. *
  9485. * @return {Parser}
  9486. */
  9487. this['on'] = function (name, cb) {
  9488. if (typeof cb !== 'function') {
  9489. throw error('required args <name, cb>');
  9490. }
  9491. switch (name) {
  9492. case 'openTag':
  9493. onOpenTag = cb;
  9494. break;
  9495. case 'text':
  9496. onText = cb;
  9497. break;
  9498. case 'closeTag':
  9499. onCloseTag = cb;
  9500. break;
  9501. case 'error':
  9502. onError = cb;
  9503. break;
  9504. case 'warn':
  9505. onWarning = cb;
  9506. break;
  9507. case 'cdata':
  9508. onCDATA = cb;
  9509. break;
  9510. case 'attention':
  9511. onAttention = cb;
  9512. break; // <!XXXXX zzzz="eeee">
  9513. case 'question':
  9514. onQuestion = cb;
  9515. break; // <? .... ?>
  9516. case 'comment':
  9517. onComment = cb;
  9518. break;
  9519. default:
  9520. throw error('unsupported event: ' + name);
  9521. }
  9522. return this;
  9523. };
  9524. /**
  9525. * Set the namespace to prefix mapping.
  9526. *
  9527. * @example
  9528. *
  9529. * parser.ns({
  9530. * 'http://foo': 'foo',
  9531. * 'http://bar': 'bar'
  9532. * });
  9533. *
  9534. * @param {!Object<string, string>} nsMap
  9535. *
  9536. * @return {Parser}
  9537. */
  9538. this['ns'] = function (nsMap) {
  9539. if (typeof nsMap === 'undefined') {
  9540. nsMap = {};
  9541. }
  9542. if (typeof nsMap !== 'object') {
  9543. throw error('required args <nsMap={}>');
  9544. }
  9545. var _nsUriToPrefix = {}, k;
  9546. for (k in nsMap) {
  9547. _nsUriToPrefix[k] = nsMap[k];
  9548. }
  9549. // FORCE default mapping for schema instance
  9550. _nsUriToPrefix[XSI_URI] = XSI_PREFIX;
  9551. isNamespace = true;
  9552. nsUriToPrefix = _nsUriToPrefix;
  9553. return this;
  9554. };
  9555. /**
  9556. * Parse xml string.
  9557. *
  9558. * @param {string} xml
  9559. *
  9560. * @return {Error} returnError, if not thrown
  9561. */
  9562. this['parse'] = function (xml) {
  9563. if (typeof xml !== 'string') {
  9564. throw error('required args <xml=string>');
  9565. }
  9566. returnError = null;
  9567. parse(xml);
  9568. getContext = noopGetContext;
  9569. parseStop = false;
  9570. return returnError;
  9571. };
  9572. /**
  9573. * Stop parsing.
  9574. */
  9575. this['stop'] = function () {
  9576. parseStop = true;
  9577. };
  9578. /**
  9579. * Parse string, invoking configured listeners on element.
  9580. *
  9581. * @param {string} xml
  9582. */
  9583. function parse(xml) {
  9584. var nsMatrixStack = isNamespace ? [] : null,
  9585. nsMatrix = isNamespace ? buildNsMatrix(nsUriToPrefix) : null,
  9586. _nsMatrix,
  9587. nodeStack = [],
  9588. anonymousNsCount = 0,
  9589. tagStart = false,
  9590. tagEnd = false,
  9591. i = 0, j = 0,
  9592. x, y, q, w, v,
  9593. xmlns,
  9594. elementName,
  9595. _elementName,
  9596. elementProxy
  9597. ;
  9598. var attrsString = '',
  9599. attrsStart = 0,
  9600. cachedAttrs // false = parsed with errors, null = needs parsing
  9601. ;
  9602. /**
  9603. * Parse attributes on demand and returns the parsed attributes.
  9604. *
  9605. * Return semantics: (1) `false` on attribute parse error,
  9606. * (2) object hash on extracted attrs.
  9607. *
  9608. * @return {boolean|Object}
  9609. */
  9610. function getAttrs() {
  9611. if (cachedAttrs !== null) {
  9612. return cachedAttrs;
  9613. }
  9614. var nsUri,
  9615. nsUriPrefix,
  9616. nsName,
  9617. defaultAlias = isNamespace && nsMatrix['xmlns'],
  9618. attrList = isNamespace && maybeNS ? [] : null,
  9619. i = attrsStart,
  9620. s = attrsString,
  9621. l = s.length,
  9622. hasNewMatrix,
  9623. newalias,
  9624. value,
  9625. alias,
  9626. name,
  9627. attrs = {},
  9628. seenAttrs = {},
  9629. skipAttr,
  9630. w,
  9631. j;
  9632. parseAttr:
  9633. for (; i < l; i++) {
  9634. skipAttr = false;
  9635. w = s.charCodeAt(i);
  9636. if (w === 32 || (w < 14 && w > 8)) { // WHITESPACE={ \f\n\r\t\v}
  9637. continue;
  9638. }
  9639. // wait for non whitespace character
  9640. if (w < 65 || w > 122 || (w > 90 && w < 97)) {
  9641. if (w !== 95 && w !== 58) { // char 95"_" 58":"
  9642. handleWarning('illegal first char attribute name');
  9643. skipAttr = true;
  9644. }
  9645. }
  9646. // parse attribute name
  9647. for (j = i + 1; j < l; j++) {
  9648. w = s.charCodeAt(j);
  9649. if (
  9650. w > 96 && w < 123 ||
  9651. w > 64 && w < 91 ||
  9652. w > 47 && w < 59 ||
  9653. w === 46 || // '.'
  9654. w === 45 || // '-'
  9655. w === 95 // '_'
  9656. ) {
  9657. continue;
  9658. }
  9659. // unexpected whitespace
  9660. if (w === 32 || (w < 14 && w > 8)) { // WHITESPACE
  9661. handleWarning('missing attribute value');
  9662. i = j;
  9663. continue parseAttr;
  9664. }
  9665. // expected "="
  9666. if (w === 61) { // "=" == 61
  9667. break;
  9668. }
  9669. handleWarning('illegal attribute name char');
  9670. skipAttr = true;
  9671. }
  9672. name = s.substring(i, j);
  9673. if (name === 'xmlns:xmlns') {
  9674. handleWarning('illegal declaration of xmlns');
  9675. skipAttr = true;
  9676. }
  9677. w = s.charCodeAt(j + 1);
  9678. if (w === 34) { // '"'
  9679. j = s.indexOf('"', i = j + 2);
  9680. if (j === -1) {
  9681. j = s.indexOf('\'', i);
  9682. if (j !== -1) {
  9683. handleWarning('attribute value quote missmatch');
  9684. skipAttr = true;
  9685. }
  9686. }
  9687. } else if (w === 39) { // "'"
  9688. j = s.indexOf('\'', i = j + 2);
  9689. if (j === -1) {
  9690. j = s.indexOf('"', i);
  9691. if (j !== -1) {
  9692. handleWarning('attribute value quote missmatch');
  9693. skipAttr = true;
  9694. }
  9695. }
  9696. } else {
  9697. handleWarning('missing attribute value quotes');
  9698. skipAttr = true;
  9699. // skip to next space
  9700. for (j = j + 1; j < l; j++) {
  9701. w = s.charCodeAt(j + 1);
  9702. if (w === 32 || (w < 14 && w > 8)) { // WHITESPACE
  9703. break;
  9704. }
  9705. }
  9706. }
  9707. if (j === -1) {
  9708. handleWarning('missing closing quotes');
  9709. j = l;
  9710. skipAttr = true;
  9711. }
  9712. if (!skipAttr) {
  9713. value = s.substring(i, j);
  9714. }
  9715. i = j;
  9716. // ensure SPACE follows attribute
  9717. // skip illegal content otherwise
  9718. // example a="b"c
  9719. for (; j + 1 < l; j++) {
  9720. w = s.charCodeAt(j + 1);
  9721. if (w === 32 || (w < 14 && w > 8)) { // WHITESPACE
  9722. break;
  9723. }
  9724. // FIRST ILLEGAL CHAR
  9725. if (i === j) {
  9726. handleWarning('illegal character after attribute end');
  9727. skipAttr = true;
  9728. }
  9729. }
  9730. // advance cursor to next attribute
  9731. i = j + 1;
  9732. if (skipAttr) {
  9733. continue parseAttr;
  9734. }
  9735. // check attribute re-declaration
  9736. if (name in seenAttrs) {
  9737. handleWarning('attribute <' + name + '> already defined');
  9738. continue;
  9739. }
  9740. seenAttrs[name] = true;
  9741. if (!isNamespace) {
  9742. attrs[name] = value;
  9743. continue;
  9744. }
  9745. // try to extract namespace information
  9746. if (maybeNS) {
  9747. newalias = (
  9748. name === 'xmlns'
  9749. ? 'xmlns'
  9750. : (name.charCodeAt(0) === 120 && name.substr(0, 6) === 'xmlns:')
  9751. ? name.substr(6)
  9752. : null
  9753. );
  9754. // handle xmlns(:alias) assignment
  9755. if (newalias !== null) {
  9756. nsUri = decodeEntities(value);
  9757. nsUriPrefix = uriPrefix(newalias);
  9758. alias = nsUriToPrefix[nsUri];
  9759. if (!alias) {
  9760. // no prefix defined or prefix collision
  9761. if (
  9762. (newalias === 'xmlns') ||
  9763. (nsUriPrefix in nsMatrix && nsMatrix[nsUriPrefix] !== nsUri)
  9764. ) {
  9765. // alocate free ns prefix
  9766. do {
  9767. alias = 'ns' + (anonymousNsCount++);
  9768. } while (typeof nsMatrix[alias] !== 'undefined');
  9769. } else {
  9770. alias = newalias;
  9771. }
  9772. nsUriToPrefix[nsUri] = alias;
  9773. }
  9774. if (nsMatrix[newalias] !== alias) {
  9775. if (!hasNewMatrix) {
  9776. nsMatrix = cloneNsMatrix(nsMatrix);
  9777. hasNewMatrix = true;
  9778. }
  9779. nsMatrix[newalias] = alias;
  9780. if (newalias === 'xmlns') {
  9781. nsMatrix[uriPrefix(alias)] = nsUri;
  9782. defaultAlias = alias;
  9783. }
  9784. nsMatrix[nsUriPrefix] = nsUri;
  9785. }
  9786. // expose xmlns(:asd)="..." in attributes
  9787. attrs[name] = value;
  9788. continue;
  9789. }
  9790. // collect attributes until all namespace
  9791. // declarations are processed
  9792. attrList.push(name, value);
  9793. continue;
  9794. }
  9795. /** end if (maybeNs) */
  9796. // handle attributes on element without
  9797. // namespace declarations
  9798. w = name.indexOf(':');
  9799. if (w === -1) {
  9800. attrs[name] = value;
  9801. continue;
  9802. }
  9803. // normalize ns attribute name
  9804. if (!(nsName = nsMatrix[name.substring(0, w)])) {
  9805. handleWarning(missingNamespaceForPrefix(name.substring(0, w)));
  9806. continue;
  9807. }
  9808. name = defaultAlias === nsName
  9809. ? name.substr(w + 1)
  9810. : nsName + name.substr(w);
  9811. // end: normalize ns attribute name
  9812. // normalize xsi:type ns attribute value
  9813. if (name === XSI_TYPE) {
  9814. w = value.indexOf(':');
  9815. if (w !== -1) {
  9816. nsName = value.substring(0, w);
  9817. // handle default prefixes, i.e. xs:String gracefully
  9818. nsName = nsMatrix[nsName] || nsName;
  9819. value = nsName + value.substring(w);
  9820. } else {
  9821. value = defaultAlias + ':' + value;
  9822. }
  9823. }
  9824. // end: normalize xsi:type ns attribute value
  9825. attrs[name] = value;
  9826. }
  9827. // handle deferred, possibly namespaced attributes
  9828. if (maybeNS) {
  9829. // normalize captured attributes
  9830. for (i = 0, l = attrList.length; i < l; i++) {
  9831. name = attrList[i++];
  9832. value = attrList[i];
  9833. w = name.indexOf(':');
  9834. if (w !== -1) {
  9835. // normalize ns attribute name
  9836. if (!(nsName = nsMatrix[name.substring(0, w)])) {
  9837. handleWarning(missingNamespaceForPrefix(name.substring(0, w)));
  9838. continue;
  9839. }
  9840. name = defaultAlias === nsName
  9841. ? name.substr(w + 1)
  9842. : nsName + name.substr(w);
  9843. // end: normalize ns attribute name
  9844. // normalize xsi:type ns attribute value
  9845. if (name === XSI_TYPE) {
  9846. w = value.indexOf(':');
  9847. if (w !== -1) {
  9848. nsName = value.substring(0, w);
  9849. // handle default prefixes, i.e. xs:String gracefully
  9850. nsName = nsMatrix[nsName] || nsName;
  9851. value = nsName + value.substring(w);
  9852. } else {
  9853. value = defaultAlias + ':' + value;
  9854. }
  9855. }
  9856. // end: normalize xsi:type ns attribute value
  9857. }
  9858. attrs[name] = value;
  9859. }
  9860. // end: normalize captured attributes
  9861. }
  9862. return cachedAttrs = attrs;
  9863. }
  9864. /**
  9865. * Extract the parse context { line, column, part }
  9866. * from the current parser position.
  9867. *
  9868. * @return {Object} parse context
  9869. */
  9870. function getParseContext() {
  9871. var splitsRe = /(\r\n|\r|\n)/g;
  9872. var line = 0;
  9873. var column = 0;
  9874. var startOfLine = 0;
  9875. var endOfLine = j;
  9876. var match;
  9877. var data;
  9878. while (i >= startOfLine) {
  9879. match = splitsRe.exec(xml);
  9880. if (!match) {
  9881. break;
  9882. }
  9883. // end of line = (break idx + break chars)
  9884. endOfLine = match[0].length + match.index;
  9885. if (endOfLine > i) {
  9886. break;
  9887. }
  9888. // advance to next line
  9889. line += 1;
  9890. startOfLine = endOfLine;
  9891. }
  9892. // EOF errors
  9893. if (i == -1) {
  9894. column = endOfLine;
  9895. data = xml.substring(j);
  9896. } else
  9897. // start errors
  9898. if (j === 0) {
  9899. data = xml.substring(j, i);
  9900. }
  9901. // other errors
  9902. else {
  9903. column = i - startOfLine;
  9904. data = (j == -1 ? xml.substring(i) : xml.substring(i, j + 1));
  9905. }
  9906. return {
  9907. 'data': data,
  9908. 'line': line,
  9909. 'column': column
  9910. };
  9911. }
  9912. getContext = getParseContext;
  9913. if (proxy) {
  9914. elementProxy = Object.create({}, {
  9915. 'name': getter(function () {
  9916. return elementName;
  9917. }),
  9918. 'originalName': getter(function () {
  9919. return _elementName;
  9920. }),
  9921. 'attrs': getter(getAttrs),
  9922. 'ns': getter(function () {
  9923. return nsMatrix;
  9924. })
  9925. });
  9926. }
  9927. // actual parse logic
  9928. while (j !== -1) {
  9929. if (xml.charCodeAt(j) === 60) { // "<"
  9930. i = j;
  9931. } else {
  9932. i = xml.indexOf('<', j);
  9933. }
  9934. // parse end
  9935. if (i === -1) {
  9936. if (nodeStack.length) {
  9937. return handleError('unexpected end of file');
  9938. }
  9939. if (j === 0) {
  9940. return handleError('missing start tag');
  9941. }
  9942. if (j < xml.length) {
  9943. if (xml.substring(j).trim()) {
  9944. handleWarning(NON_WHITESPACE_OUTSIDE_ROOT_NODE);
  9945. }
  9946. }
  9947. return;
  9948. }
  9949. // parse text
  9950. if (j !== i) {
  9951. if (nodeStack.length) {
  9952. if (onText) {
  9953. onText(xml.substring(j, i), decodeEntities, getContext);
  9954. if (parseStop) {
  9955. return;
  9956. }
  9957. }
  9958. } else {
  9959. if (xml.substring(j, i).trim()) {
  9960. handleWarning(NON_WHITESPACE_OUTSIDE_ROOT_NODE);
  9961. if (parseStop) {
  9962. return;
  9963. }
  9964. }
  9965. }
  9966. }
  9967. w = xml.charCodeAt(i + 1);
  9968. // parse comments + CDATA
  9969. if (w === 33) { // "!"
  9970. q = xml.charCodeAt(i + 2);
  9971. // CDATA section
  9972. if (q === 91 && xml.substr(i + 3, 6) === 'CDATA[') { // 91 == "["
  9973. j = xml.indexOf(']]>', i);
  9974. if (j === -1) {
  9975. return handleError('unclosed cdata');
  9976. }
  9977. if (onCDATA) {
  9978. onCDATA(xml.substring(i + 9, j), getContext);
  9979. if (parseStop) {
  9980. return;
  9981. }
  9982. }
  9983. j += 3;
  9984. continue;
  9985. }
  9986. // comment
  9987. if (q === 45 && xml.charCodeAt(i + 3) === 45) { // 45 == "-"
  9988. j = xml.indexOf('-->', i);
  9989. if (j === -1) {
  9990. return handleError('unclosed comment');
  9991. }
  9992. if (onComment) {
  9993. onComment(xml.substring(i + 4, j), decodeEntities, getContext);
  9994. if (parseStop) {
  9995. return;
  9996. }
  9997. }
  9998. j += 3;
  9999. continue;
  10000. }
  10001. }
  10002. // parse question <? ... ?>
  10003. if (w === 63) { // "?"
  10004. j = xml.indexOf('?>', i);
  10005. if (j === -1) {
  10006. return handleError('unclosed question');
  10007. }
  10008. if (onQuestion) {
  10009. onQuestion(xml.substring(i, j + 2), getContext);
  10010. if (parseStop) {
  10011. return;
  10012. }
  10013. }
  10014. j += 2;
  10015. continue;
  10016. }
  10017. // find matching closing tag for attention or standard tags
  10018. // for that we must skip through attribute values
  10019. // (enclosed in single or double quotes)
  10020. for (x = i + 1; ; x++) {
  10021. v = xml.charCodeAt(x);
  10022. if (isNaN(v)) {
  10023. j = -1;
  10024. return handleError('unclosed tag');
  10025. }
  10026. // [10] AttValue ::= '"' ([^<&"] | Reference)* '"' | "'" ([^<&'] | Reference)* "'"
  10027. // skips the quoted string
  10028. // (double quotes) does not appear in a literal enclosed by (double quotes)
  10029. // (single quote) does not appear in a literal enclosed by (single quote)
  10030. if (v === 34) { // '"'
  10031. q = xml.indexOf('"', x + 1);
  10032. x = q !== -1 ? q : x;
  10033. } else if (v === 39) { // "'"
  10034. q = xml.indexOf("'", x + 1);
  10035. x = q !== -1 ? q : x;
  10036. } else if (v === 62) { // '>'
  10037. j = x;
  10038. break;
  10039. }
  10040. }
  10041. // parse attention <! ...>
  10042. // previously comment and CDATA have already been parsed
  10043. if (w === 33) { // "!"
  10044. if (onAttention) {
  10045. onAttention(xml.substring(i, j + 1), decodeEntities, getContext);
  10046. if (parseStop) {
  10047. return;
  10048. }
  10049. }
  10050. j += 1;
  10051. continue;
  10052. }
  10053. // don't process attributes;
  10054. // there are none
  10055. cachedAttrs = {};
  10056. // if (xml.charCodeAt(i+1) === 47) { // </...
  10057. if (w === 47) { // </...
  10058. tagStart = false;
  10059. tagEnd = true;
  10060. if (!nodeStack.length) {
  10061. return handleError('missing open tag');
  10062. }
  10063. // verify open <-> close tag match
  10064. x = elementName = nodeStack.pop();
  10065. q = i + 2 + x.length;
  10066. if (xml.substring(i + 2, q) !== x) {
  10067. return handleError('closing tag mismatch');
  10068. }
  10069. // verify chars in close tag
  10070. for (; q < j; q++) {
  10071. w = xml.charCodeAt(q);
  10072. if (w === 32 || (w > 8 && w < 14)) { // \f\n\r\t\v space
  10073. continue;
  10074. }
  10075. return handleError('close tag');
  10076. }
  10077. } else {
  10078. if (xml.charCodeAt(j - 1) === 47) { // .../>
  10079. x = elementName = xml.substring(i + 1, j - 1);
  10080. tagStart = true;
  10081. tagEnd = true;
  10082. } else {
  10083. x = elementName = xml.substring(i + 1, j);
  10084. tagStart = true;
  10085. tagEnd = false;
  10086. }
  10087. if (!(w > 96 && w < 123 || w > 64 && w < 91 || w === 95 || w === 58)) { // char 95"_" 58":"
  10088. return handleError('illegal first char nodeName');
  10089. }
  10090. for (q = 1, y = x.length; q < y; q++) {
  10091. w = x.charCodeAt(q);
  10092. if (w > 96 && w < 123 || w > 64 && w < 91 || w > 47 && w < 59 || w === 45 || w === 95 || w == 46) {
  10093. continue;
  10094. }
  10095. if (w === 32 || (w < 14 && w > 8)) { // \f\n\r\t\v space
  10096. elementName = x.substring(0, q);
  10097. // maybe there are attributes
  10098. cachedAttrs = null;
  10099. break;
  10100. }
  10101. return handleError('invalid nodeName');
  10102. }
  10103. if (!tagEnd) {
  10104. nodeStack.push(elementName);
  10105. }
  10106. }
  10107. if (isNamespace) {
  10108. _nsMatrix = nsMatrix;
  10109. if (tagStart) {
  10110. // remember old namespace
  10111. // unless we're self-closing
  10112. if (!tagEnd) {
  10113. nsMatrixStack.push(_nsMatrix);
  10114. }
  10115. if (cachedAttrs === null) {
  10116. // quick check, whether there may be namespace
  10117. // declarations on the node; if that is the case
  10118. // we need to eagerly parse the node attributes
  10119. if ((maybeNS = x.indexOf('xmlns', q) !== -1)) {
  10120. attrsStart = q;
  10121. attrsString = x;
  10122. getAttrs();
  10123. maybeNS = false;
  10124. }
  10125. }
  10126. }
  10127. _elementName = elementName;
  10128. w = elementName.indexOf(':');
  10129. if (w !== -1) {
  10130. xmlns = nsMatrix[elementName.substring(0, w)];
  10131. // prefix given; namespace must exist
  10132. if (!xmlns) {
  10133. return handleError('missing namespace on <' + _elementName + '>');
  10134. }
  10135. elementName = elementName.substr(w + 1);
  10136. } else {
  10137. xmlns = nsMatrix['xmlns'];
  10138. // if no default namespace is defined,
  10139. // we'll import the element as anonymous.
  10140. //
  10141. // it is up to users to correct that to the document defined
  10142. // targetNamespace, or whatever their undersanding of the
  10143. // XML spec mandates.
  10144. }
  10145. // adjust namespace prefixs as configured
  10146. if (xmlns) {
  10147. elementName = xmlns + ':' + elementName;
  10148. }
  10149. }
  10150. if (tagStart) {
  10151. attrsStart = q;
  10152. attrsString = x;
  10153. if (onOpenTag) {
  10154. if (proxy) {
  10155. onOpenTag(elementProxy, decodeEntities, tagEnd, getContext);
  10156. } else {
  10157. onOpenTag(elementName, getAttrs, decodeEntities, tagEnd, getContext);
  10158. }
  10159. if (parseStop) {
  10160. return;
  10161. }
  10162. }
  10163. }
  10164. if (tagEnd) {
  10165. if (onCloseTag) {
  10166. onCloseTag(proxy ? elementProxy : elementName, decodeEntities, tagStart, getContext);
  10167. if (parseStop) {
  10168. return;
  10169. }
  10170. }
  10171. // restore old namespace
  10172. if (isNamespace) {
  10173. if (!tagStart) {
  10174. nsMatrix = nsMatrixStack.pop();
  10175. } else {
  10176. nsMatrix = _nsMatrix;
  10177. }
  10178. }
  10179. }
  10180. j += 1;
  10181. }
  10182. } /** end parse */
  10183. }
  10184. function hasLowerCaseAlias(pkg) {
  10185. return pkg.xml && pkg.xml.tagAlias === 'lowerCase';
  10186. }
  10187. var DEFAULT_NS_MAP = {
  10188. 'xsi': 'http://www.w3.org/2001/XMLSchema-instance'
  10189. };
  10190. var XSI_TYPE$1 = 'xsi:type';
  10191. function serializeFormat(element) {
  10192. return element.xml && element.xml.serialize;
  10193. }
  10194. function serializeAsType(element) {
  10195. return serializeFormat(element) === XSI_TYPE$1;
  10196. }
  10197. function serializeAsProperty(element) {
  10198. return serializeFormat(element) === 'property';
  10199. }
  10200. function capitalize(str) {
  10201. return str.charAt(0).toUpperCase() + str.slice(1);
  10202. }
  10203. function aliasToName(aliasNs, pkg) {
  10204. if (!hasLowerCaseAlias(pkg)) {
  10205. return aliasNs.name;
  10206. }
  10207. return aliasNs.prefix + ':' + capitalize(aliasNs.localName);
  10208. }
  10209. function prefixedToName(nameNs, pkg) {
  10210. var name = nameNs.name,
  10211. localName = nameNs.localName;
  10212. var typePrefix = pkg.xml && pkg.xml.typePrefix;
  10213. if (typePrefix && localName.indexOf(typePrefix) === 0) {
  10214. return nameNs.prefix + ':' + localName.slice(typePrefix.length);
  10215. } else {
  10216. return name;
  10217. }
  10218. }
  10219. function normalizeXsiTypeName(name, model) {
  10220. var nameNs = parseName(name);
  10221. var pkg = model.getPackage(nameNs.prefix);
  10222. return prefixedToName(nameNs, pkg);
  10223. }
  10224. function error$1(message) {
  10225. return new Error(message);
  10226. }
  10227. /**
  10228. * Get the moddle descriptor for a given instance or type.
  10229. *
  10230. * @param {ModdleElement|Function} element
  10231. *
  10232. * @return {Object} the moddle descriptor
  10233. */
  10234. function getModdleDescriptor(element) {
  10235. return element.$descriptor;
  10236. }
  10237. function defer(fn) {
  10238. setTimeout(fn, 0);
  10239. }
  10240. /**
  10241. * A parse context.
  10242. *
  10243. * @class
  10244. *
  10245. * @param {Object} options
  10246. * @param {ElementHandler} options.rootHandler the root handler for parsing a document
  10247. * @param {boolean} [options.lax=false] whether or not to ignore invalid elements
  10248. */
  10249. function Context(options) {
  10250. /**
  10251. * @property {ElementHandler} rootHandler
  10252. */
  10253. /**
  10254. * @property {Boolean} lax
  10255. */
  10256. assign(this, options);
  10257. this.elementsById = {};
  10258. this.references = [];
  10259. this.warnings = [];
  10260. /**
  10261. * Add an unresolved reference.
  10262. *
  10263. * @param {Object} reference
  10264. */
  10265. this.addReference = function (reference) {
  10266. this.references.push(reference);
  10267. };
  10268. /**
  10269. * Add a processed element.
  10270. *
  10271. * @param {ModdleElement} element
  10272. */
  10273. this.addElement = function (element) {
  10274. if (!element) {
  10275. throw error$1('expected element');
  10276. }
  10277. var elementsById = this.elementsById;
  10278. var descriptor = getModdleDescriptor(element);
  10279. var idProperty = descriptor.idProperty,
  10280. id;
  10281. if (idProperty) {
  10282. id = element.get(idProperty.name);
  10283. if (id) {
  10284. // for QName validation as per http://www.w3.org/TR/REC-xml/#NT-NameChar
  10285. if (!/^([a-z][\w-.]*:)?[a-z_][\w-.]*$/i.test(id)) {
  10286. throw new Error('illegal ID <' + id + '>');
  10287. }
  10288. if (elementsById[id]) {
  10289. throw error$1('duplicate ID <' + id + '>');
  10290. }
  10291. elementsById[id] = element;
  10292. }
  10293. }
  10294. };
  10295. /**
  10296. * Add an import warning.
  10297. *
  10298. * @param {Object} warning
  10299. * @param {String} warning.message
  10300. * @param {Error} [warning.error]
  10301. */
  10302. this.addWarning = function (warning) {
  10303. this.warnings.push(warning);
  10304. };
  10305. }
  10306. function BaseHandler() {
  10307. }
  10308. BaseHandler.prototype.handleEnd = function () {
  10309. };
  10310. BaseHandler.prototype.handleText = function () {
  10311. };
  10312. BaseHandler.prototype.handleNode = function () {
  10313. };
  10314. /**
  10315. * A simple pass through handler that does nothing except for
  10316. * ignoring all input it receives.
  10317. *
  10318. * This is used to ignore unknown elements and
  10319. * attributes.
  10320. */
  10321. function NoopHandler() {
  10322. }
  10323. NoopHandler.prototype = Object.create(BaseHandler.prototype);
  10324. NoopHandler.prototype.handleNode = function () {
  10325. return this;
  10326. };
  10327. function BodyHandler() {
  10328. }
  10329. BodyHandler.prototype = Object.create(BaseHandler.prototype);
  10330. BodyHandler.prototype.handleText = function (text) {
  10331. this.body = (this.body || '') + text;
  10332. };
  10333. function ReferenceHandler(property, context) {
  10334. this.property = property;
  10335. this.context = context;
  10336. }
  10337. ReferenceHandler.prototype = Object.create(BodyHandler.prototype);
  10338. ReferenceHandler.prototype.handleNode = function (node) {
  10339. if (this.element) {
  10340. throw error$1('expected no sub nodes');
  10341. } else {
  10342. this.element = this.createReference(node);
  10343. }
  10344. return this;
  10345. };
  10346. ReferenceHandler.prototype.handleEnd = function () {
  10347. this.element.id = this.body;
  10348. };
  10349. ReferenceHandler.prototype.createReference = function (node) {
  10350. return {
  10351. property: this.property.ns.name,
  10352. id: ''
  10353. };
  10354. };
  10355. function ValueHandler(propertyDesc, element) {
  10356. this.element = element;
  10357. this.propertyDesc = propertyDesc;
  10358. }
  10359. ValueHandler.prototype = Object.create(BodyHandler.prototype);
  10360. ValueHandler.prototype.handleEnd = function () {
  10361. var value = this.body || '',
  10362. element = this.element,
  10363. propertyDesc = this.propertyDesc;
  10364. value = coerceType(propertyDesc.type, value);
  10365. if (propertyDesc.isMany) {
  10366. element.get(propertyDesc.name).push(value);
  10367. } else {
  10368. element.set(propertyDesc.name, value);
  10369. }
  10370. };
  10371. function BaseElementHandler() {
  10372. }
  10373. BaseElementHandler.prototype = Object.create(BodyHandler.prototype);
  10374. BaseElementHandler.prototype.handleNode = function (node) {
  10375. var parser = this,
  10376. element = this.element;
  10377. if (!element) {
  10378. element = this.element = this.createElement(node);
  10379. this.context.addElement(element);
  10380. } else {
  10381. parser = this.handleChild(node);
  10382. }
  10383. return parser;
  10384. };
  10385. /**
  10386. * @class Reader.ElementHandler
  10387. *
  10388. */
  10389. function ElementHandler(model, typeName, context) {
  10390. this.model = model;
  10391. this.type = model.getType(typeName);
  10392. this.context = context;
  10393. }
  10394. ElementHandler.prototype = Object.create(BaseElementHandler.prototype);
  10395. ElementHandler.prototype.addReference = function (reference) {
  10396. this.context.addReference(reference);
  10397. };
  10398. ElementHandler.prototype.handleText = function (text) {
  10399. var element = this.element,
  10400. descriptor = getModdleDescriptor(element),
  10401. bodyProperty = descriptor.bodyProperty;
  10402. if (!bodyProperty) {
  10403. throw error$1('unexpected body text <' + text + '>');
  10404. }
  10405. BodyHandler.prototype.handleText.call(this, text);
  10406. };
  10407. ElementHandler.prototype.handleEnd = function () {
  10408. var value = this.body,
  10409. element = this.element,
  10410. descriptor = getModdleDescriptor(element),
  10411. bodyProperty = descriptor.bodyProperty;
  10412. if (bodyProperty && value !== undefined) {
  10413. value = coerceType(bodyProperty.type, value);
  10414. element.set(bodyProperty.name, value);
  10415. }
  10416. };
  10417. /**
  10418. * Create an instance of the model from the given node.
  10419. *
  10420. * @param {Element} node the xml node
  10421. */
  10422. ElementHandler.prototype.createElement = function (node) {
  10423. var attributes = node.attributes,
  10424. Type = this.type,
  10425. descriptor = getModdleDescriptor(Type),
  10426. context = this.context,
  10427. instance = new Type({}),
  10428. model = this.model,
  10429. propNameNs;
  10430. forEach(attributes, function (value, name) {
  10431. var prop = descriptor.propertiesByName[name],
  10432. values;
  10433. if (prop && prop.isReference) {
  10434. if (!prop.isMany) {
  10435. context.addReference({
  10436. element: instance,
  10437. property: prop.ns.name,
  10438. id: value
  10439. });
  10440. } else {
  10441. // IDREFS: parse references as whitespace-separated list
  10442. values = value.split(' ');
  10443. forEach(values, function (v) {
  10444. context.addReference({
  10445. element: instance,
  10446. property: prop.ns.name,
  10447. id: v
  10448. });
  10449. });
  10450. }
  10451. } else {
  10452. if (prop) {
  10453. value = coerceType(prop.type, value);
  10454. } else if (name !== 'xmlns') {
  10455. propNameNs = parseName(name, descriptor.ns.prefix);
  10456. // check whether attribute is defined in a well-known namespace
  10457. // if that is the case we emit a warning to indicate potential misuse
  10458. if (model.getPackage(propNameNs.prefix)) {
  10459. context.addWarning({
  10460. message: 'unknown attribute <' + name + '>',
  10461. element: instance,
  10462. property: name,
  10463. value: value
  10464. });
  10465. }
  10466. }
  10467. instance.set(name, value);
  10468. }
  10469. });
  10470. return instance;
  10471. };
  10472. ElementHandler.prototype.getPropertyForNode = function (node) {
  10473. var name = node.name;
  10474. var nameNs = parseName(name);
  10475. var type = this.type,
  10476. model = this.model,
  10477. descriptor = getModdleDescriptor(type);
  10478. var propertyName = nameNs.name,
  10479. property = descriptor.propertiesByName[propertyName],
  10480. elementTypeName,
  10481. elementType;
  10482. // search for properties by name first
  10483. if (property && !property.isAttr) {
  10484. if (serializeAsType(property)) {
  10485. elementTypeName = node.attributes[XSI_TYPE$1];
  10486. // xsi type is optional, if it does not exists the
  10487. // default type is assumed
  10488. if (elementTypeName) {
  10489. // take possible type prefixes from XML
  10490. // into account, i.e.: xsi:type="t{ActualType}"
  10491. elementTypeName = normalizeXsiTypeName(elementTypeName, model);
  10492. elementType = model.getType(elementTypeName);
  10493. return assign({}, property, {
  10494. effectiveType: getModdleDescriptor(elementType).name
  10495. });
  10496. }
  10497. }
  10498. // search for properties by name first
  10499. return property;
  10500. }
  10501. var pkg = model.getPackage(nameNs.prefix);
  10502. if (pkg) {
  10503. elementTypeName = aliasToName(nameNs, pkg);
  10504. elementType = model.getType(elementTypeName);
  10505. // search for collection members later
  10506. property = find(descriptor.properties, function (p) {
  10507. return !p.isVirtual && !p.isReference && !p.isAttribute && elementType.hasType(p.type);
  10508. });
  10509. if (property) {
  10510. return assign({}, property, {
  10511. effectiveType: getModdleDescriptor(elementType).name
  10512. });
  10513. }
  10514. } else {
  10515. // parse unknown element (maybe extension)
  10516. property = find(descriptor.properties, function (p) {
  10517. return !p.isReference && !p.isAttribute && p.type === 'Element';
  10518. });
  10519. if (property) {
  10520. return property;
  10521. }
  10522. }
  10523. throw error$1('unrecognized element <' + nameNs.name + '>');
  10524. };
  10525. ElementHandler.prototype.toString = function () {
  10526. return 'ElementDescriptor[' + getModdleDescriptor(this.type).name + ']';
  10527. };
  10528. ElementHandler.prototype.valueHandler = function (propertyDesc, element) {
  10529. return new ValueHandler(propertyDesc, element);
  10530. };
  10531. ElementHandler.prototype.referenceHandler = function (propertyDesc) {
  10532. return new ReferenceHandler(propertyDesc, this.context);
  10533. };
  10534. ElementHandler.prototype.handler = function (type) {
  10535. if (type === 'Element') {
  10536. return new GenericElementHandler(this.model, type, this.context);
  10537. } else {
  10538. return new ElementHandler(this.model, type, this.context);
  10539. }
  10540. };
  10541. /**
  10542. * Handle the child element parsing
  10543. *
  10544. * @param {Element} node the xml node
  10545. */
  10546. ElementHandler.prototype.handleChild = function (node) {
  10547. var propertyDesc, type, element, childHandler;
  10548. propertyDesc = this.getPropertyForNode(node);
  10549. element = this.element;
  10550. type = propertyDesc.effectiveType || propertyDesc.type;
  10551. if (isSimple(type)) {
  10552. return this.valueHandler(propertyDesc, element);
  10553. }
  10554. if (propertyDesc.isReference) {
  10555. childHandler = this.referenceHandler(propertyDesc).handleNode(node);
  10556. } else {
  10557. childHandler = this.handler(type).handleNode(node);
  10558. }
  10559. var newElement = childHandler.element;
  10560. // child handles may decide to skip elements
  10561. // by not returning anything
  10562. if (newElement !== undefined) {
  10563. if (propertyDesc.isMany) {
  10564. element.get(propertyDesc.name).push(newElement);
  10565. } else {
  10566. element.set(propertyDesc.name, newElement);
  10567. }
  10568. if (propertyDesc.isReference) {
  10569. assign(newElement, {
  10570. element: element
  10571. });
  10572. this.context.addReference(newElement);
  10573. } else {
  10574. // establish child -> parent relationship
  10575. newElement.$parent = element;
  10576. }
  10577. }
  10578. return childHandler;
  10579. };
  10580. /**
  10581. * An element handler that performs special validation
  10582. * to ensure the node it gets initialized with matches
  10583. * the handlers type (namespace wise).
  10584. *
  10585. * @param {Moddle} model
  10586. * @param {String} typeName
  10587. * @param {Context} context
  10588. */
  10589. function RootElementHandler(model, typeName, context) {
  10590. ElementHandler.call(this, model, typeName, context);
  10591. }
  10592. RootElementHandler.prototype = Object.create(ElementHandler.prototype);
  10593. RootElementHandler.prototype.createElement = function (node) {
  10594. var name = node.name,
  10595. nameNs = parseName(name),
  10596. model = this.model,
  10597. type = this.type,
  10598. pkg = model.getPackage(nameNs.prefix),
  10599. typeName = pkg && aliasToName(nameNs, pkg) || name;
  10600. // verify the correct namespace if we parse
  10601. // the first element in the handler tree
  10602. //
  10603. // this ensures we don't mistakenly import wrong namespace elements
  10604. if (!type.hasType(typeName)) {
  10605. throw error$1('unexpected element <' + node.originalName + '>');
  10606. }
  10607. return ElementHandler.prototype.createElement.call(this, node);
  10608. };
  10609. function GenericElementHandler(model, typeName, context) {
  10610. this.model = model;
  10611. this.context = context;
  10612. }
  10613. GenericElementHandler.prototype = Object.create(BaseElementHandler.prototype);
  10614. GenericElementHandler.prototype.createElement = function (node) {
  10615. var name = node.name,
  10616. ns = parseName(name),
  10617. prefix = ns.prefix,
  10618. uri = node.ns[prefix + '$uri'],
  10619. attributes = node.attributes;
  10620. return this.model.createAny(name, uri, attributes);
  10621. };
  10622. GenericElementHandler.prototype.handleChild = function (node) {
  10623. var handler = new GenericElementHandler(this.model, 'Element', this.context).handleNode(node),
  10624. element = this.element;
  10625. var newElement = handler.element,
  10626. children;
  10627. if (newElement !== undefined) {
  10628. children = element.$children = element.$children || [];
  10629. children.push(newElement);
  10630. // establish child -> parent relationship
  10631. newElement.$parent = element;
  10632. }
  10633. return handler;
  10634. };
  10635. GenericElementHandler.prototype.handleEnd = function () {
  10636. if (this.body) {
  10637. this.element.$body = this.body;
  10638. }
  10639. };
  10640. /**
  10641. * A reader for a meta-model
  10642. *
  10643. * @param {Object} options
  10644. * @param {Model} options.model used to read xml files
  10645. * @param {Boolean} options.lax whether to make parse errors warnings
  10646. */
  10647. function Reader(options) {
  10648. if (options instanceof Moddle) {
  10649. options = {
  10650. model: options
  10651. };
  10652. }
  10653. assign(this, {lax: false}, options);
  10654. }
  10655. /**
  10656. * Parse the given XML into a moddle document tree.
  10657. *
  10658. * @param {String} xml
  10659. * @param {ElementHandler|Object} options or rootHandler
  10660. * @param {Function} done
  10661. */
  10662. Reader.prototype.fromXML = function (xml, options, done) {
  10663. var rootHandler = options.rootHandler;
  10664. if (options instanceof ElementHandler) {
  10665. // root handler passed via (xml, { rootHandler: ElementHandler }, ...)
  10666. rootHandler = options;
  10667. options = {};
  10668. } else {
  10669. if (typeof options === 'string') {
  10670. // rootHandler passed via (xml, 'someString', ...)
  10671. rootHandler = this.handler(options);
  10672. options = {};
  10673. } else if (typeof rootHandler === 'string') {
  10674. // rootHandler passed via (xml, { rootHandler: 'someString' }, ...)
  10675. rootHandler = this.handler(rootHandler);
  10676. }
  10677. }
  10678. var model = this.model,
  10679. lax = this.lax;
  10680. var context = new Context(assign({}, options, {rootHandler: rootHandler})),
  10681. parser = new Parser({proxy: true}),
  10682. stack = createStack();
  10683. rootHandler.context = context;
  10684. // push root handler
  10685. stack.push(rootHandler);
  10686. /**
  10687. * Handle error.
  10688. *
  10689. * @param {Error} err
  10690. * @param {Function} getContext
  10691. * @param {boolean} lax
  10692. *
  10693. * @return {boolean} true if handled
  10694. */
  10695. function handleError(err, getContext, lax) {
  10696. var ctx = getContext();
  10697. var line = ctx.line,
  10698. column = ctx.column,
  10699. data = ctx.data;
  10700. // we receive the full context data here,
  10701. // for elements trim down the information
  10702. // to the tag name, only
  10703. if (data.charAt(0) === '<' && data.indexOf(' ') !== -1) {
  10704. data = data.slice(0, data.indexOf(' ')) + '>';
  10705. }
  10706. var message =
  10707. 'unparsable content ' + (data ? data + ' ' : '') + 'detected\n\t' +
  10708. 'line: ' + line + '\n\t' +
  10709. 'column: ' + column + '\n\t' +
  10710. 'nested error: ' + err.message;
  10711. if (lax) {
  10712. context.addWarning({
  10713. message: message,
  10714. error: err
  10715. });
  10716. return true;
  10717. } else {
  10718. throw error$1(message);
  10719. }
  10720. }
  10721. function handleWarning(err, getContext) {
  10722. // just like handling errors in <lax=true> mode
  10723. return handleError(err, getContext, true);
  10724. }
  10725. /**
  10726. * Resolve collected references on parse end.
  10727. */
  10728. function resolveReferences() {
  10729. var elementsById = context.elementsById;
  10730. var references = context.references;
  10731. var i, r;
  10732. for (i = 0; (r = references[i]); i++) {
  10733. var element = r.element;
  10734. var reference = elementsById[r.id];
  10735. var property = getModdleDescriptor(element).propertiesByName[r.property];
  10736. if (!reference) {
  10737. context.addWarning({
  10738. message: 'unresolved reference <' + r.id + '>',
  10739. element: r.element,
  10740. property: r.property,
  10741. value: r.id
  10742. });
  10743. }
  10744. if (property.isMany) {
  10745. var collection = element.get(property.name),
  10746. idx = collection.indexOf(r);
  10747. // we replace an existing place holder (idx != -1) or
  10748. // append to the collection instead
  10749. if (idx === -1) {
  10750. idx = collection.length;
  10751. }
  10752. if (!reference) {
  10753. // remove unresolvable reference
  10754. collection.splice(idx, 1);
  10755. } else {
  10756. // add or update reference in collection
  10757. collection[idx] = reference;
  10758. }
  10759. } else {
  10760. element.set(property.name, reference);
  10761. }
  10762. }
  10763. }
  10764. function handleClose() {
  10765. stack.pop().handleEnd();
  10766. }
  10767. var PREAMBLE_START_PATTERN = /^<\?xml /i;
  10768. var ENCODING_PATTERN = / encoding="([^"]+)"/i;
  10769. var UTF_8_PATTERN = /^utf-8$/i;
  10770. function handleQuestion(question) {
  10771. if (!PREAMBLE_START_PATTERN.test(question)) {
  10772. return;
  10773. }
  10774. var match = ENCODING_PATTERN.exec(question);
  10775. var encoding = match && match[1];
  10776. if (!encoding || UTF_8_PATTERN.test(encoding)) {
  10777. return;
  10778. }
  10779. context.addWarning({
  10780. message:
  10781. 'unsupported document encoding <' + encoding + '>, ' +
  10782. 'falling back to UTF-8'
  10783. });
  10784. }
  10785. function handleOpen(node, getContext) {
  10786. var handler = stack.peek();
  10787. try {
  10788. stack.push(handler.handleNode(node));
  10789. } catch (err) {
  10790. if (handleError(err, getContext, lax)) {
  10791. stack.push(new NoopHandler());
  10792. }
  10793. }
  10794. }
  10795. function handleCData(text, getContext) {
  10796. try {
  10797. stack.peek().handleText(text);
  10798. } catch (err) {
  10799. handleWarning(err, getContext);
  10800. }
  10801. }
  10802. function handleText(text, getContext) {
  10803. // strip whitespace only nodes, i.e. before
  10804. // <!CDATA[ ... ]> sections and in between tags
  10805. text = text.trim();
  10806. if (!text) {
  10807. return;
  10808. }
  10809. handleCData(text, getContext);
  10810. }
  10811. var uriMap = model.getPackages().reduce(function (uriMap, p) {
  10812. uriMap[p.uri] = p.prefix;
  10813. return uriMap;
  10814. }, {});
  10815. parser
  10816. .ns(uriMap)
  10817. .on('openTag', function (obj, decodeStr, selfClosing, getContext) {
  10818. // gracefully handle unparsable attributes (attrs=false)
  10819. var attrs = obj.attrs || {};
  10820. var decodedAttrs = Object.keys(attrs).reduce(function (d, key) {
  10821. var value = decodeStr(attrs[key]);
  10822. d[key] = value;
  10823. return d;
  10824. }, {});
  10825. var node = {
  10826. name: obj.name,
  10827. originalName: obj.originalName,
  10828. attributes: decodedAttrs,
  10829. ns: obj.ns
  10830. };
  10831. handleOpen(node, getContext);
  10832. })
  10833. .on('question', handleQuestion)
  10834. .on('closeTag', handleClose)
  10835. .on('cdata', handleCData)
  10836. .on('text', function (text, decodeEntities, getContext) {
  10837. handleText(decodeEntities(text), getContext);
  10838. })
  10839. .on('error', handleError)
  10840. .on('warn', handleWarning);
  10841. // deferred parse XML to make loading really ascnchronous
  10842. // this ensures the execution environment (node or browser)
  10843. // is kept responsive and that certain optimization strategies
  10844. // can kick in
  10845. defer(function () {
  10846. var err;
  10847. try {
  10848. parser.parse(xml);
  10849. resolveReferences();
  10850. } catch (e) {
  10851. err = e;
  10852. }
  10853. var element = rootHandler.element;
  10854. // handle the situation that we could not extract
  10855. // the desired root element from the document
  10856. if (!err && !element) {
  10857. err = error$1('failed to parse document as <' + rootHandler.type.$descriptor.name + '>');
  10858. }
  10859. done(err, err ? undefined : element, context);
  10860. });
  10861. };
  10862. Reader.prototype.handler = function (name) {
  10863. return new RootElementHandler(this.model, name);
  10864. };
  10865. // helpers //////////////////////////
  10866. function createStack() {
  10867. var stack = [];
  10868. Object.defineProperty(stack, 'peek', {
  10869. value: function () {
  10870. return this[this.length - 1];
  10871. }
  10872. });
  10873. return stack;
  10874. }
  10875. var XML_PREAMBLE = '<?xml version="1.0" encoding="UTF-8"?>\n';
  10876. var ESCAPE_ATTR_CHARS = /<|>|'|"|&|\n\r|\n/g;
  10877. var ESCAPE_CHARS = /<|>|&/g;
  10878. function Namespaces(parent) {
  10879. var prefixMap = {};
  10880. var uriMap = {};
  10881. var used = {};
  10882. var wellknown = [];
  10883. var custom = [];
  10884. // API
  10885. this.byUri = function (uri) {
  10886. return uriMap[uri] || (
  10887. parent && parent.byUri(uri)
  10888. );
  10889. };
  10890. this.add = function (ns, isWellknown) {
  10891. uriMap[ns.uri] = ns;
  10892. if (isWellknown) {
  10893. wellknown.push(ns);
  10894. } else {
  10895. custom.push(ns);
  10896. }
  10897. this.mapPrefix(ns.prefix, ns.uri);
  10898. };
  10899. this.uriByPrefix = function (prefix) {
  10900. return prefixMap[prefix || 'xmlns'];
  10901. };
  10902. this.mapPrefix = function (prefix, uri) {
  10903. prefixMap[prefix || 'xmlns'] = uri;
  10904. };
  10905. this.getNSKey = function (ns) {
  10906. return (ns.prefix !== undefined) ? (ns.uri + '|' + ns.prefix) : ns.uri;
  10907. };
  10908. this.logUsed = function (ns) {
  10909. var uri = ns.uri;
  10910. var nsKey = this.getNSKey(ns);
  10911. used[nsKey] = this.byUri(uri);
  10912. // Inform parent recursively about the usage of this NS
  10913. if (parent) {
  10914. parent.logUsed(ns);
  10915. }
  10916. };
  10917. this.getUsed = function (ns) {
  10918. function isUsed(ns) {
  10919. var nsKey = self.getNSKey(ns);
  10920. return used[nsKey];
  10921. }
  10922. var self = this;
  10923. var allNs = [].concat(wellknown, custom);
  10924. return allNs.filter(isUsed);
  10925. };
  10926. }
  10927. function lower(string) {
  10928. return string.charAt(0).toLowerCase() + string.slice(1);
  10929. }
  10930. function nameToAlias(name, pkg) {
  10931. if (hasLowerCaseAlias(pkg)) {
  10932. return lower(name);
  10933. } else {
  10934. return name;
  10935. }
  10936. }
  10937. function inherits(ctor, superCtor) {
  10938. ctor.super_ = superCtor;
  10939. ctor.prototype = Object.create(superCtor.prototype, {
  10940. constructor: {
  10941. value: ctor,
  10942. enumerable: false,
  10943. writable: true,
  10944. configurable: true
  10945. }
  10946. });
  10947. }
  10948. function nsName(ns) {
  10949. if (isString(ns)) {
  10950. return ns;
  10951. } else {
  10952. return (ns.prefix ? ns.prefix + ':' : '') + ns.localName;
  10953. }
  10954. }
  10955. function getNsAttrs(namespaces) {
  10956. return map(namespaces.getUsed(), function (ns) {
  10957. var name = 'xmlns' + (ns.prefix ? ':' + ns.prefix : '');
  10958. return {name: name, value: ns.uri};
  10959. });
  10960. }
  10961. function getElementNs(ns, descriptor) {
  10962. if (descriptor.isGeneric) {
  10963. return assign({localName: descriptor.ns.localName}, ns);
  10964. } else {
  10965. return assign({localName: nameToAlias(descriptor.ns.localName, descriptor.$pkg)}, ns);
  10966. }
  10967. }
  10968. function getPropertyNs(ns, descriptor) {
  10969. return assign({localName: descriptor.ns.localName}, ns);
  10970. }
  10971. function getSerializableProperties(element) {
  10972. var descriptor = element.$descriptor;
  10973. return filter(descriptor.properties, function (p) {
  10974. var name = p.name;
  10975. if (p.isVirtual) {
  10976. return false;
  10977. }
  10978. // do not serialize defaults
  10979. if (!element.hasOwnProperty(name)) {
  10980. return false;
  10981. }
  10982. var value = element[name];
  10983. // do not serialize default equals
  10984. if (value === p.default) {
  10985. return false;
  10986. }
  10987. // do not serialize null properties
  10988. if (value === null) {
  10989. return false;
  10990. }
  10991. return p.isMany ? value.length : true;
  10992. });
  10993. }
  10994. var ESCAPE_ATTR_MAP = {
  10995. '\n': '#10',
  10996. '\n\r': '#10',
  10997. '"': '#34',
  10998. '\'': '#39',
  10999. '<': '#60',
  11000. '>': '#62',
  11001. '&': '#38'
  11002. };
  11003. var ESCAPE_MAP = {
  11004. '<': 'lt',
  11005. '>': 'gt',
  11006. '&': 'amp'
  11007. };
  11008. function escape$1(str, charPattern, replaceMap) {
  11009. // ensure we are handling strings here
  11010. str = isString(str) ? str : '' + str;
  11011. return str.replace(charPattern, function (s) {
  11012. return '&' + replaceMap[s] + ';';
  11013. });
  11014. }
  11015. /**
  11016. * Escape a string attribute to not contain any bad values (line breaks, '"', ...)
  11017. *
  11018. * @param {String} str the string to escape
  11019. * @return {String} the escaped string
  11020. */
  11021. function escapeAttr(str) {
  11022. return escape$1(str, ESCAPE_ATTR_CHARS, ESCAPE_ATTR_MAP);
  11023. }
  11024. function escapeBody(str) {
  11025. return escape$1(str, ESCAPE_CHARS, ESCAPE_MAP);
  11026. }
  11027. function filterAttributes(props) {
  11028. return filter(props, function (p) {
  11029. return p.isAttr;
  11030. });
  11031. }
  11032. function filterContained(props) {
  11033. return filter(props, function (p) {
  11034. return !p.isAttr;
  11035. });
  11036. }
  11037. function ReferenceSerializer(tagName) {
  11038. this.tagName = tagName;
  11039. }
  11040. ReferenceSerializer.prototype.build = function (element) {
  11041. this.element = element;
  11042. return this;
  11043. };
  11044. ReferenceSerializer.prototype.serializeTo = function (writer) {
  11045. writer
  11046. .appendIndent()
  11047. .append('<' + this.tagName + '>' + this.element.id + '</' + this.tagName + '>')
  11048. .appendNewLine();
  11049. };
  11050. function BodySerializer() {
  11051. }
  11052. BodySerializer.prototype.serializeValue =
  11053. BodySerializer.prototype.serializeTo = function (writer) {
  11054. writer.append(
  11055. this.escape
  11056. ? escapeBody(this.value)
  11057. : this.value
  11058. );
  11059. };
  11060. BodySerializer.prototype.build = function (prop, value) {
  11061. this.value = value;
  11062. if (prop.type === 'String' && value.search(ESCAPE_CHARS) !== -1) {
  11063. this.escape = true;
  11064. }
  11065. return this;
  11066. };
  11067. function ValueSerializer(tagName) {
  11068. this.tagName = tagName;
  11069. }
  11070. inherits(ValueSerializer, BodySerializer);
  11071. ValueSerializer.prototype.serializeTo = function (writer) {
  11072. writer
  11073. .appendIndent()
  11074. .append('<' + this.tagName + '>');
  11075. this.serializeValue(writer);
  11076. writer
  11077. .append('</' + this.tagName + '>')
  11078. .appendNewLine();
  11079. };
  11080. function ElementSerializer(parent, propertyDescriptor) {
  11081. this.body = [];
  11082. this.attrs = [];
  11083. this.parent = parent;
  11084. this.propertyDescriptor = propertyDescriptor;
  11085. }
  11086. ElementSerializer.prototype.build = function (element) {
  11087. this.element = element;
  11088. var elementDescriptor = element.$descriptor,
  11089. propertyDescriptor = this.propertyDescriptor;
  11090. var otherAttrs,
  11091. properties;
  11092. var isGeneric = elementDescriptor.isGeneric;
  11093. if (isGeneric) {
  11094. otherAttrs = this.parseGeneric(element);
  11095. } else {
  11096. otherAttrs = this.parseNsAttributes(element);
  11097. }
  11098. if (propertyDescriptor) {
  11099. this.ns = this.nsPropertyTagName(propertyDescriptor);
  11100. } else {
  11101. this.ns = this.nsTagName(elementDescriptor);
  11102. }
  11103. // compute tag name
  11104. this.tagName = this.addTagName(this.ns);
  11105. if (!isGeneric) {
  11106. properties = getSerializableProperties(element);
  11107. this.parseAttributes(filterAttributes(properties));
  11108. this.parseContainments(filterContained(properties));
  11109. }
  11110. this.parseGenericAttributes(element, otherAttrs);
  11111. return this;
  11112. };
  11113. ElementSerializer.prototype.nsTagName = function (descriptor) {
  11114. var effectiveNs = this.logNamespaceUsed(descriptor.ns);
  11115. return getElementNs(effectiveNs, descriptor);
  11116. };
  11117. ElementSerializer.prototype.nsPropertyTagName = function (descriptor) {
  11118. var effectiveNs = this.logNamespaceUsed(descriptor.ns);
  11119. return getPropertyNs(effectiveNs, descriptor);
  11120. };
  11121. ElementSerializer.prototype.isLocalNs = function (ns) {
  11122. return ns.uri === this.ns.uri;
  11123. };
  11124. /**
  11125. * Get the actual ns attribute name for the given element.
  11126. *
  11127. * @param {Object} element
  11128. * @param {Boolean} [element.inherited=false]
  11129. *
  11130. * @return {Object} nsName
  11131. */
  11132. ElementSerializer.prototype.nsAttributeName = function (element) {
  11133. var ns;
  11134. if (isString(element)) {
  11135. ns = parseName(element);
  11136. } else {
  11137. ns = element.ns;
  11138. }
  11139. // return just local name for inherited attributes
  11140. if (element.inherited) {
  11141. return {localName: ns.localName};
  11142. }
  11143. // parse + log effective ns
  11144. var effectiveNs = this.logNamespaceUsed(ns);
  11145. // LOG ACTUAL namespace use
  11146. this.getNamespaces().logUsed(effectiveNs);
  11147. // strip prefix if same namespace like parent
  11148. if (this.isLocalNs(effectiveNs)) {
  11149. return {localName: ns.localName};
  11150. } else {
  11151. return assign({localName: ns.localName}, effectiveNs);
  11152. }
  11153. };
  11154. ElementSerializer.prototype.parseGeneric = function (element) {
  11155. var self = this,
  11156. body = this.body;
  11157. var attributes = [];
  11158. forEach(element, function (val, key) {
  11159. var nonNsAttr;
  11160. if (key === '$body') {
  11161. body.push(new BodySerializer().build({type: 'String'}, val));
  11162. } else if (key === '$children') {
  11163. forEach(val, function (child) {
  11164. body.push(new ElementSerializer(self).build(child));
  11165. });
  11166. } else if (key.indexOf('$') !== 0) {
  11167. nonNsAttr = self.parseNsAttribute(element, key, val);
  11168. if (nonNsAttr) {
  11169. attributes.push({name: key, value: val});
  11170. }
  11171. }
  11172. });
  11173. return attributes;
  11174. };
  11175. ElementSerializer.prototype.parseNsAttribute = function (element, name, value) {
  11176. var model = element.$model;
  11177. var nameNs = parseName(name);
  11178. var ns;
  11179. // parse xmlns:foo="http://foo.bar"
  11180. if (nameNs.prefix === 'xmlns') {
  11181. ns = {prefix: nameNs.localName, uri: value};
  11182. }
  11183. // parse xmlns="http://foo.bar"
  11184. if (!nameNs.prefix && nameNs.localName === 'xmlns') {
  11185. ns = {uri: value};
  11186. }
  11187. if (!ns) {
  11188. return {
  11189. name: name,
  11190. value: value
  11191. };
  11192. }
  11193. if (model && model.getPackage(value)) {
  11194. // register well known namespace
  11195. this.logNamespace(ns, true, true);
  11196. } else {
  11197. // log custom namespace directly as used
  11198. var actualNs = this.logNamespaceUsed(ns, true);
  11199. this.getNamespaces().logUsed(actualNs);
  11200. }
  11201. };
  11202. /**
  11203. * Parse namespaces and return a list of left over generic attributes
  11204. *
  11205. * @param {Object} element
  11206. * @return {Array<Object>}
  11207. */
  11208. ElementSerializer.prototype.parseNsAttributes = function (element, attrs) {
  11209. var self = this;
  11210. var genericAttrs = element.$attrs;
  11211. var attributes = [];
  11212. // parse namespace attributes first
  11213. // and log them. push non namespace attributes to a list
  11214. // and process them later
  11215. forEach(genericAttrs, function (value, name) {
  11216. var nonNsAttr = self.parseNsAttribute(element, name, value);
  11217. if (nonNsAttr) {
  11218. attributes.push(nonNsAttr);
  11219. }
  11220. });
  11221. return attributes;
  11222. };
  11223. ElementSerializer.prototype.parseGenericAttributes = function (element, attributes) {
  11224. var self = this;
  11225. forEach(attributes, function (attr) {
  11226. // do not serialize xsi:type attribute
  11227. // it is set manually based on the actual implementation type
  11228. if (attr.name === XSI_TYPE$1) {
  11229. return;
  11230. }
  11231. try {
  11232. self.addAttribute(self.nsAttributeName(attr.name), attr.value);
  11233. } catch (e) {
  11234. console.warn(
  11235. 'missing namespace information for ',
  11236. attr.name, '=', attr.value, 'on', element,
  11237. e);
  11238. }
  11239. });
  11240. };
  11241. ElementSerializer.prototype.parseContainments = function (properties) {
  11242. var self = this,
  11243. body = this.body,
  11244. element = this.element;
  11245. forEach(properties, function (p) {
  11246. var value = element.get(p.name),
  11247. isReference = p.isReference,
  11248. isMany = p.isMany;
  11249. if (!isMany) {
  11250. value = [value];
  11251. }
  11252. if (p.isBody) {
  11253. body.push(new BodySerializer().build(p, value[0]));
  11254. } else if (isSimple(p.type)) {
  11255. forEach(value, function (v) {
  11256. body.push(new ValueSerializer(self.addTagName(self.nsPropertyTagName(p))).build(p, v));
  11257. });
  11258. } else if (isReference) {
  11259. forEach(value, function (v) {
  11260. body.push(new ReferenceSerializer(self.addTagName(self.nsPropertyTagName(p))).build(v));
  11261. });
  11262. } else {
  11263. // allow serialization via type
  11264. // rather than element name
  11265. var asType = serializeAsType(p),
  11266. asProperty = serializeAsProperty(p);
  11267. forEach(value, function (v) {
  11268. var serializer;
  11269. if (asType) {
  11270. serializer = new TypeSerializer(self, p);
  11271. } else if (asProperty) {
  11272. serializer = new ElementSerializer(self, p);
  11273. } else {
  11274. serializer = new ElementSerializer(self);
  11275. }
  11276. body.push(serializer.build(v));
  11277. });
  11278. }
  11279. });
  11280. };
  11281. ElementSerializer.prototype.getNamespaces = function (local) {
  11282. var namespaces = this.namespaces,
  11283. parent = this.parent,
  11284. parentNamespaces;
  11285. if (!namespaces) {
  11286. parentNamespaces = parent && parent.getNamespaces();
  11287. if (local || !parentNamespaces) {
  11288. this.namespaces = namespaces = new Namespaces(parentNamespaces);
  11289. } else {
  11290. namespaces = parentNamespaces;
  11291. }
  11292. }
  11293. return namespaces;
  11294. };
  11295. ElementSerializer.prototype.logNamespace = function (ns, wellknown, local) {
  11296. var namespaces = this.getNamespaces(local);
  11297. var nsUri = ns.uri,
  11298. nsPrefix = ns.prefix;
  11299. var existing = namespaces.byUri(nsUri);
  11300. if (!existing || local) {
  11301. namespaces.add(ns, wellknown);
  11302. }
  11303. namespaces.mapPrefix(nsPrefix, nsUri);
  11304. return ns;
  11305. };
  11306. ElementSerializer.prototype.logNamespaceUsed = function (ns, local) {
  11307. var element = this.element,
  11308. model = element.$model,
  11309. namespaces = this.getNamespaces(local);
  11310. // ns may be
  11311. //
  11312. // * prefix only
  11313. // * prefix:uri
  11314. // * localName only
  11315. var prefix = ns.prefix,
  11316. uri = ns.uri,
  11317. newPrefix, idx,
  11318. wellknownUri;
  11319. // handle anonymous namespaces (elementForm=unqualified), cf. #23
  11320. if (!prefix && !uri) {
  11321. return {localName: ns.localName};
  11322. }
  11323. wellknownUri = DEFAULT_NS_MAP[prefix] || model && (model.getPackage(prefix) || {}).uri;
  11324. uri = uri || wellknownUri || namespaces.uriByPrefix(prefix);
  11325. if (!uri) {
  11326. throw new Error('no namespace uri given for prefix <' + prefix + '>');
  11327. }
  11328. ns = namespaces.byUri(uri);
  11329. if (!ns) {
  11330. newPrefix = prefix;
  11331. idx = 1;
  11332. // find a prefix that is not mapped yet
  11333. while (namespaces.uriByPrefix(newPrefix)) {
  11334. newPrefix = prefix + '_' + idx++;
  11335. }
  11336. ns = this.logNamespace({prefix: newPrefix, uri: uri}, wellknownUri === uri);
  11337. }
  11338. if (prefix) {
  11339. namespaces.mapPrefix(prefix, uri);
  11340. }
  11341. return ns;
  11342. };
  11343. ElementSerializer.prototype.parseAttributes = function (properties) {
  11344. var self = this,
  11345. element = this.element;
  11346. forEach(properties, function (p) {
  11347. var value = element.get(p.name);
  11348. if (p.isReference) {
  11349. if (!p.isMany) {
  11350. value = value.id;
  11351. } else {
  11352. var values = [];
  11353. forEach(value, function (v) {
  11354. values.push(v.id);
  11355. });
  11356. // IDREFS is a whitespace-separated list of references.
  11357. value = values.join(' ');
  11358. }
  11359. }
  11360. self.addAttribute(self.nsAttributeName(p), value);
  11361. });
  11362. };
  11363. ElementSerializer.prototype.addTagName = function (nsTagName) {
  11364. var actualNs = this.logNamespaceUsed(nsTagName);
  11365. this.getNamespaces().logUsed(actualNs);
  11366. return nsName(nsTagName);
  11367. };
  11368. ElementSerializer.prototype.addAttribute = function (name, value) {
  11369. var attrs = this.attrs;
  11370. if (isString(value)) {
  11371. value = escapeAttr(value);
  11372. }
  11373. attrs.push({name: name, value: value});
  11374. };
  11375. ElementSerializer.prototype.serializeAttributes = function (writer) {
  11376. var attrs = this.attrs,
  11377. namespaces = this.namespaces;
  11378. if (namespaces) {
  11379. attrs = getNsAttrs(namespaces).concat(attrs);
  11380. }
  11381. forEach(attrs, function (a) {
  11382. writer
  11383. .append(' ')
  11384. .append(nsName(a.name)).append('="').append(a.value).append('"');
  11385. });
  11386. };
  11387. ElementSerializer.prototype.serializeTo = function (writer) {
  11388. var firstBody = this.body[0],
  11389. indent = firstBody && firstBody.constructor !== BodySerializer;
  11390. writer
  11391. .appendIndent()
  11392. .append('<' + this.tagName);
  11393. this.serializeAttributes(writer);
  11394. writer.append(firstBody ? '>' : ' />');
  11395. if (firstBody) {
  11396. if (indent) {
  11397. writer
  11398. .appendNewLine()
  11399. .indent();
  11400. }
  11401. forEach(this.body, function (b) {
  11402. b.serializeTo(writer);
  11403. });
  11404. if (indent) {
  11405. writer
  11406. .unindent()
  11407. .appendIndent();
  11408. }
  11409. writer.append('</' + this.tagName + '>');
  11410. }
  11411. writer.appendNewLine();
  11412. };
  11413. /**
  11414. * A serializer for types that handles serialization of data types
  11415. */
  11416. function TypeSerializer(parent, propertyDescriptor) {
  11417. ElementSerializer.call(this, parent, propertyDescriptor);
  11418. }
  11419. inherits(TypeSerializer, ElementSerializer);
  11420. TypeSerializer.prototype.parseNsAttributes = function (element) {
  11421. // extracted attributes
  11422. var attributes = ElementSerializer.prototype.parseNsAttributes.call(this, element);
  11423. var descriptor = element.$descriptor;
  11424. // only serialize xsi:type if necessary
  11425. if (descriptor.name === this.propertyDescriptor.type) {
  11426. return attributes;
  11427. }
  11428. var typeNs = this.typeNs = this.nsTagName(descriptor);
  11429. this.getNamespaces().logUsed(this.typeNs);
  11430. // add xsi:type attribute to represent the elements
  11431. // actual type
  11432. var pkg = element.$model.getPackage(typeNs.uri),
  11433. typePrefix = (pkg.xml && pkg.xml.typePrefix) || '';
  11434. this.addAttribute(
  11435. this.nsAttributeName(XSI_TYPE$1),
  11436. (typeNs.prefix ? typeNs.prefix + ':' : '') + typePrefix + descriptor.ns.localName
  11437. );
  11438. return attributes;
  11439. };
  11440. TypeSerializer.prototype.isLocalNs = function (ns) {
  11441. return ns.uri === (this.typeNs || this.ns).uri;
  11442. };
  11443. function SavingWriter() {
  11444. this.value = '';
  11445. this.write = function (str) {
  11446. this.value += str;
  11447. };
  11448. }
  11449. function FormatingWriter(out, format) {
  11450. var indent = [''];
  11451. this.append = function (str) {
  11452. out.write(str);
  11453. return this;
  11454. };
  11455. this.appendNewLine = function () {
  11456. if (format) {
  11457. out.write('\n');
  11458. }
  11459. return this;
  11460. };
  11461. this.appendIndent = function () {
  11462. if (format) {
  11463. out.write(indent.join(' '));
  11464. }
  11465. return this;
  11466. };
  11467. this.indent = function () {
  11468. indent.push('');
  11469. return this;
  11470. };
  11471. this.unindent = function () {
  11472. indent.pop();
  11473. return this;
  11474. };
  11475. }
  11476. /**
  11477. * A writer for meta-model backed document trees
  11478. *
  11479. * @param {Object} options output options to pass into the writer
  11480. */
  11481. function Writer(options) {
  11482. options = assign({format: false, preamble: true}, options || {});
  11483. function toXML(tree, writer) {
  11484. var internalWriter = writer || new SavingWriter();
  11485. var formatingWriter = new FormatingWriter(internalWriter, options.format);
  11486. if (options.preamble) {
  11487. formatingWriter.append(XML_PREAMBLE);
  11488. }
  11489. new ElementSerializer().build(tree).serializeTo(formatingWriter);
  11490. if (!writer) {
  11491. return internalWriter.value;
  11492. }
  11493. }
  11494. return {
  11495. toXML: toXML
  11496. };
  11497. }
  11498. /**
  11499. * A sub class of {@link Moddle} with support for import and export of BPMN 2.0 xml files.
  11500. *
  11501. * @class BpmnModdle
  11502. * @extends Moddle
  11503. *
  11504. * @param {Object|Array} packages to use for instantiating the model
  11505. * @param {Object} [options] additional options to pass over
  11506. */
  11507. function BpmnModdle(packages, options) {
  11508. Moddle.call(this, packages, options);
  11509. }
  11510. BpmnModdle.prototype = Object.create(Moddle.prototype);
  11511. /**
  11512. * Instantiates a BPMN model tree from a given xml string.
  11513. *
  11514. * @param {String} xmlStr
  11515. * @param {String} [typeName='bpmn:Definitions'] name of the root element
  11516. * @param {Object} [options] options to pass to the underlying reader
  11517. * @param {Function} done callback that is invoked with (err, result, parseContext)
  11518. * once the import completes
  11519. */
  11520. BpmnModdle.prototype.fromXML = function (xmlStr, typeName, options, done) {
  11521. if (!isString(typeName)) {
  11522. done = options;
  11523. options = typeName;
  11524. typeName = 'bpmn:Definitions';
  11525. }
  11526. if (isFunction(options)) {
  11527. done = options;
  11528. options = {};
  11529. }
  11530. var reader = new Reader(assign({model: this, lax: true}, options));
  11531. var rootHandler = reader.handler(typeName);
  11532. reader.fromXML(xmlStr, rootHandler, done);
  11533. };
  11534. /**
  11535. * Serializes a BPMN 2.0 object tree to XML.
  11536. *
  11537. * @param {String} element the root element, typically an instance of `bpmn:Definitions`
  11538. * @param {Object} [options] to pass to the underlying writer
  11539. * @param {Function} done callback invoked with (err, xmlStr) once the import completes
  11540. */
  11541. BpmnModdle.prototype.toXML = function (element, options, done) {
  11542. if (isFunction(options)) {
  11543. done = options;
  11544. options = {};
  11545. }
  11546. var writer = new Writer(options);
  11547. var result;
  11548. var err;
  11549. try {
  11550. result = writer.toXML(element);
  11551. } catch (e) {
  11552. err = e;
  11553. }
  11554. return done(err, result);
  11555. };
  11556. var name = "BPMN20";
  11557. var uri = "http://www.omg.org/spec/BPMN/20100524/MODEL";
  11558. var prefix$1 = "bpmn";
  11559. var associations = [];
  11560. var types$1 = [
  11561. {
  11562. name: "Interface",
  11563. superClass: [
  11564. "RootElement"
  11565. ],
  11566. properties: [
  11567. {
  11568. name: "name",
  11569. isAttr: true,
  11570. type: "String"
  11571. },
  11572. {
  11573. name: "operations",
  11574. type: "Operation",
  11575. isMany: true
  11576. },
  11577. {
  11578. name: "implementationRef",
  11579. isAttr: true,
  11580. type: "String"
  11581. }
  11582. ]
  11583. },
  11584. {
  11585. name: "Operation",
  11586. superClass: [
  11587. "BaseElement"
  11588. ],
  11589. properties: [
  11590. {
  11591. name: "name",
  11592. isAttr: true,
  11593. type: "String"
  11594. },
  11595. {
  11596. name: "inMessageRef",
  11597. type: "Message",
  11598. isReference: true
  11599. },
  11600. {
  11601. name: "outMessageRef",
  11602. type: "Message",
  11603. isReference: true
  11604. },
  11605. {
  11606. name: "errorRef",
  11607. type: "Error",
  11608. isMany: true,
  11609. isReference: true
  11610. },
  11611. {
  11612. name: "implementationRef",
  11613. isAttr: true,
  11614. type: "String"
  11615. }
  11616. ]
  11617. },
  11618. {
  11619. name: "EndPoint",
  11620. superClass: [
  11621. "RootElement"
  11622. ]
  11623. },
  11624. {
  11625. name: "Auditing",
  11626. superClass: [
  11627. "BaseElement"
  11628. ]
  11629. },
  11630. {
  11631. name: "GlobalTask",
  11632. superClass: [
  11633. "CallableElement"
  11634. ],
  11635. properties: [
  11636. {
  11637. name: "resources",
  11638. type: "ResourceRole",
  11639. isMany: true
  11640. }
  11641. ]
  11642. },
  11643. {
  11644. name: "Monitoring",
  11645. superClass: [
  11646. "BaseElement"
  11647. ]
  11648. },
  11649. {
  11650. name: "Performer",
  11651. superClass: [
  11652. "ResourceRole"
  11653. ]
  11654. },
  11655. {
  11656. name: "Process",
  11657. superClass: [
  11658. "FlowElementsContainer",
  11659. "CallableElement"
  11660. ],
  11661. properties: [
  11662. {
  11663. name: "processType",
  11664. type: "ProcessType",
  11665. isAttr: true
  11666. },
  11667. {
  11668. name: "isClosed",
  11669. isAttr: true,
  11670. type: "Boolean"
  11671. },
  11672. {
  11673. name: "auditing",
  11674. type: "Auditing"
  11675. },
  11676. {
  11677. name: "monitoring",
  11678. type: "Monitoring"
  11679. },
  11680. {
  11681. name: "properties",
  11682. type: "Property",
  11683. isMany: true
  11684. },
  11685. {
  11686. name: "laneSets",
  11687. isMany: true,
  11688. replaces: "FlowElementsContainer#laneSets",
  11689. type: "LaneSet"
  11690. },
  11691. {
  11692. name: "flowElements",
  11693. isMany: true,
  11694. replaces: "FlowElementsContainer#flowElements",
  11695. type: "FlowElement"
  11696. },
  11697. {
  11698. name: "artifacts",
  11699. type: "Artifact",
  11700. isMany: true
  11701. },
  11702. {
  11703. name: "resources",
  11704. type: "ResourceRole",
  11705. isMany: true
  11706. },
  11707. {
  11708. name: "correlationSubscriptions",
  11709. type: "CorrelationSubscription",
  11710. isMany: true
  11711. },
  11712. {
  11713. name: "supports",
  11714. type: "Process",
  11715. isMany: true,
  11716. isReference: true
  11717. },
  11718. {
  11719. name: "definitionalCollaborationRef",
  11720. type: "Collaboration",
  11721. isAttr: true,
  11722. isReference: true
  11723. },
  11724. {
  11725. name: "isExecutable",
  11726. isAttr: true,
  11727. type: "Boolean"
  11728. }
  11729. ]
  11730. },
  11731. {
  11732. name: "LaneSet",
  11733. superClass: [
  11734. "BaseElement"
  11735. ],
  11736. properties: [
  11737. {
  11738. name: "lanes",
  11739. type: "Lane",
  11740. isMany: true
  11741. },
  11742. {
  11743. name: "name",
  11744. isAttr: true,
  11745. type: "String"
  11746. }
  11747. ]
  11748. },
  11749. {
  11750. name: "Lane",
  11751. superClass: [
  11752. "BaseElement"
  11753. ],
  11754. properties: [
  11755. {
  11756. name: "name",
  11757. isAttr: true,
  11758. type: "String"
  11759. },
  11760. {
  11761. name: "partitionElementRef",
  11762. type: "BaseElement",
  11763. isAttr: true,
  11764. isReference: true
  11765. },
  11766. {
  11767. name: "partitionElement",
  11768. type: "BaseElement"
  11769. },
  11770. {
  11771. name: "flowNodeRef",
  11772. type: "FlowNode",
  11773. isMany: true,
  11774. isReference: true
  11775. },
  11776. {
  11777. name: "childLaneSet",
  11778. type: "LaneSet",
  11779. xml: {
  11780. serialize: "xsi:type"
  11781. }
  11782. }
  11783. ]
  11784. },
  11785. {
  11786. name: "GlobalManualTask",
  11787. superClass: [
  11788. "GlobalTask"
  11789. ]
  11790. },
  11791. {
  11792. name: "ManualTask",
  11793. superClass: [
  11794. "Task"
  11795. ]
  11796. },
  11797. {
  11798. name: "UserTask",
  11799. superClass: [
  11800. "Task"
  11801. ],
  11802. properties: [
  11803. {
  11804. name: "renderings",
  11805. type: "Rendering",
  11806. isMany: true
  11807. },
  11808. {
  11809. name: "implementation",
  11810. isAttr: true,
  11811. type: "String"
  11812. }
  11813. ]
  11814. },
  11815. {
  11816. name: "Rendering",
  11817. superClass: [
  11818. "BaseElement"
  11819. ]
  11820. },
  11821. {
  11822. name: "HumanPerformer",
  11823. superClass: [
  11824. "Performer"
  11825. ]
  11826. },
  11827. {
  11828. name: "PotentialOwner",
  11829. superClass: [
  11830. "HumanPerformer"
  11831. ]
  11832. },
  11833. {
  11834. name: "GlobalUserTask",
  11835. superClass: [
  11836. "GlobalTask"
  11837. ],
  11838. properties: [
  11839. {
  11840. name: "implementation",
  11841. isAttr: true,
  11842. type: "String"
  11843. },
  11844. {
  11845. name: "renderings",
  11846. type: "Rendering",
  11847. isMany: true
  11848. }
  11849. ]
  11850. },
  11851. {
  11852. name: "Gateway",
  11853. isAbstract: true,
  11854. superClass: [
  11855. "FlowNode"
  11856. ],
  11857. properties: [
  11858. {
  11859. name: "gatewayDirection",
  11860. type: "GatewayDirection",
  11861. "default": "Unspecified",
  11862. isAttr: true
  11863. }
  11864. ]
  11865. },
  11866. {
  11867. name: "EventBasedGateway",
  11868. superClass: [
  11869. "Gateway"
  11870. ],
  11871. properties: [
  11872. {
  11873. name: "instantiate",
  11874. "default": false,
  11875. isAttr: true,
  11876. type: "Boolean"
  11877. },
  11878. {
  11879. name: "eventGatewayType",
  11880. type: "EventBasedGatewayType",
  11881. isAttr: true,
  11882. "default": "Exclusive"
  11883. }
  11884. ]
  11885. },
  11886. {
  11887. name: "ComplexGateway",
  11888. superClass: [
  11889. "Gateway"
  11890. ],
  11891. properties: [
  11892. {
  11893. name: "activationCondition",
  11894. type: "Expression",
  11895. xml: {
  11896. serialize: "xsi:type"
  11897. }
  11898. },
  11899. {
  11900. name: "default",
  11901. type: "SequenceFlow",
  11902. isAttr: true,
  11903. isReference: true
  11904. }
  11905. ]
  11906. },
  11907. {
  11908. name: "ExclusiveGateway",
  11909. superClass: [
  11910. "Gateway"
  11911. ],
  11912. properties: [
  11913. {
  11914. name: "default",
  11915. type: "SequenceFlow",
  11916. isAttr: true,
  11917. isReference: true
  11918. }
  11919. ]
  11920. },
  11921. {
  11922. name: "InclusiveGateway",
  11923. superClass: [
  11924. "Gateway"
  11925. ],
  11926. properties: [
  11927. {
  11928. name: "default",
  11929. type: "SequenceFlow",
  11930. isAttr: true,
  11931. isReference: true
  11932. }
  11933. ]
  11934. },
  11935. {
  11936. name: "ParallelGateway",
  11937. superClass: [
  11938. "Gateway"
  11939. ]
  11940. },
  11941. {
  11942. name: "RootElement",
  11943. isAbstract: true,
  11944. superClass: [
  11945. "BaseElement"
  11946. ]
  11947. },
  11948. {
  11949. name: "Relationship",
  11950. superClass: [
  11951. "BaseElement"
  11952. ],
  11953. properties: [
  11954. {
  11955. name: "type",
  11956. isAttr: true,
  11957. type: "String"
  11958. },
  11959. {
  11960. name: "direction",
  11961. type: "RelationshipDirection",
  11962. isAttr: true
  11963. },
  11964. {
  11965. name: "source",
  11966. isMany: true,
  11967. isReference: true,
  11968. type: "Element"
  11969. },
  11970. {
  11971. name: "target",
  11972. isMany: true,
  11973. isReference: true,
  11974. type: "Element"
  11975. }
  11976. ]
  11977. },
  11978. {
  11979. name: "BaseElement",
  11980. isAbstract: true,
  11981. properties: [
  11982. {
  11983. name: "id",
  11984. isAttr: true,
  11985. type: "String",
  11986. isId: true
  11987. },
  11988. {
  11989. name: "documentation",
  11990. type: "Documentation",
  11991. isMany: true
  11992. },
  11993. {
  11994. name: "extensionDefinitions",
  11995. type: "ExtensionDefinition",
  11996. isMany: true,
  11997. isReference: true
  11998. },
  11999. {
  12000. name: "extensionElements",
  12001. type: "ExtensionElements"
  12002. }
  12003. ]
  12004. },
  12005. {
  12006. name: "Extension",
  12007. properties: [
  12008. {
  12009. name: "mustUnderstand",
  12010. "default": false,
  12011. isAttr: true,
  12012. type: "Boolean"
  12013. },
  12014. {
  12015. name: "definition",
  12016. type: "ExtensionDefinition",
  12017. isAttr: true,
  12018. isReference: true
  12019. }
  12020. ]
  12021. },
  12022. {
  12023. name: "ExtensionDefinition",
  12024. properties: [
  12025. {
  12026. name: "name",
  12027. isAttr: true,
  12028. type: "String"
  12029. },
  12030. {
  12031. name: "extensionAttributeDefinitions",
  12032. type: "ExtensionAttributeDefinition",
  12033. isMany: true
  12034. }
  12035. ]
  12036. },
  12037. {
  12038. name: "ExtensionAttributeDefinition",
  12039. properties: [
  12040. {
  12041. name: "name",
  12042. isAttr: true,
  12043. type: "String"
  12044. },
  12045. {
  12046. name: "type",
  12047. isAttr: true,
  12048. type: "String"
  12049. },
  12050. {
  12051. name: "isReference",
  12052. "default": false,
  12053. isAttr: true,
  12054. type: "Boolean"
  12055. },
  12056. {
  12057. name: "extensionDefinition",
  12058. type: "ExtensionDefinition",
  12059. isAttr: true,
  12060. isReference: true
  12061. }
  12062. ]
  12063. },
  12064. {
  12065. name: "ExtensionElements",
  12066. properties: [
  12067. {
  12068. name: "valueRef",
  12069. isAttr: true,
  12070. isReference: true,
  12071. type: "Element"
  12072. },
  12073. {
  12074. name: "values",
  12075. type: "Element",
  12076. isMany: true
  12077. },
  12078. {
  12079. name: "extensionAttributeDefinition",
  12080. type: "ExtensionAttributeDefinition",
  12081. isAttr: true,
  12082. isReference: true
  12083. }
  12084. ]
  12085. },
  12086. {
  12087. name: "Documentation",
  12088. superClass: [
  12089. "BaseElement"
  12090. ],
  12091. properties: [
  12092. {
  12093. name: "text",
  12094. type: "String",
  12095. isBody: true
  12096. },
  12097. {
  12098. name: "textFormat",
  12099. "default": "text/plain",
  12100. isAttr: true,
  12101. type: "String"
  12102. }
  12103. ]
  12104. },
  12105. {
  12106. name: "Event",
  12107. isAbstract: true,
  12108. superClass: [
  12109. "FlowNode",
  12110. "InteractionNode"
  12111. ],
  12112. properties: [
  12113. {
  12114. name: "properties",
  12115. type: "Property",
  12116. isMany: true
  12117. }
  12118. ]
  12119. },
  12120. {
  12121. name: "IntermediateCatchEvent",
  12122. superClass: [
  12123. "CatchEvent"
  12124. ]
  12125. },
  12126. {
  12127. name: "IntermediateThrowEvent",
  12128. superClass: [
  12129. "ThrowEvent"
  12130. ]
  12131. },
  12132. {
  12133. name: "EndEvent",
  12134. superClass: [
  12135. "ThrowEvent"
  12136. ]
  12137. },
  12138. {
  12139. name: "StartEvent",
  12140. superClass: [
  12141. "CatchEvent"
  12142. ],
  12143. properties: [
  12144. {
  12145. name: "isInterrupting",
  12146. "default": true,
  12147. isAttr: true,
  12148. type: "Boolean"
  12149. }
  12150. ]
  12151. },
  12152. {
  12153. name: "ThrowEvent",
  12154. isAbstract: true,
  12155. superClass: [
  12156. "Event"
  12157. ],
  12158. properties: [
  12159. {
  12160. name: "dataInputs",
  12161. type: "DataInput",
  12162. isMany: true
  12163. },
  12164. {
  12165. name: "dataInputAssociations",
  12166. type: "DataInputAssociation",
  12167. isMany: true
  12168. },
  12169. {
  12170. name: "inputSet",
  12171. type: "InputSet"
  12172. },
  12173. {
  12174. name: "eventDefinitions",
  12175. type: "EventDefinition",
  12176. isMany: true
  12177. },
  12178. {
  12179. name: "eventDefinitionRef",
  12180. type: "EventDefinition",
  12181. isMany: true,
  12182. isReference: true
  12183. }
  12184. ]
  12185. },
  12186. {
  12187. name: "CatchEvent",
  12188. isAbstract: true,
  12189. superClass: [
  12190. "Event"
  12191. ],
  12192. properties: [
  12193. {
  12194. name: "parallelMultiple",
  12195. isAttr: true,
  12196. type: "Boolean",
  12197. "default": false
  12198. },
  12199. {
  12200. name: "dataOutputs",
  12201. type: "DataOutput",
  12202. isMany: true
  12203. },
  12204. {
  12205. name: "dataOutputAssociations",
  12206. type: "DataOutputAssociation",
  12207. isMany: true
  12208. },
  12209. {
  12210. name: "outputSet",
  12211. type: "OutputSet"
  12212. },
  12213. {
  12214. name: "eventDefinitions",
  12215. type: "EventDefinition",
  12216. isMany: true
  12217. },
  12218. {
  12219. name: "eventDefinitionRef",
  12220. type: "EventDefinition",
  12221. isMany: true,
  12222. isReference: true
  12223. }
  12224. ]
  12225. },
  12226. {
  12227. name: "BoundaryEvent",
  12228. superClass: [
  12229. "CatchEvent"
  12230. ],
  12231. properties: [
  12232. {
  12233. name: "cancelActivity",
  12234. "default": true,
  12235. isAttr: true,
  12236. type: "Boolean"
  12237. },
  12238. {
  12239. name: "attachedToRef",
  12240. type: "Activity",
  12241. isAttr: true,
  12242. isReference: true
  12243. }
  12244. ]
  12245. },
  12246. {
  12247. name: "EventDefinition",
  12248. isAbstract: true,
  12249. superClass: [
  12250. "RootElement"
  12251. ]
  12252. },
  12253. {
  12254. name: "CancelEventDefinition",
  12255. superClass: [
  12256. "EventDefinition"
  12257. ]
  12258. },
  12259. {
  12260. name: "ErrorEventDefinition",
  12261. superClass: [
  12262. "EventDefinition"
  12263. ],
  12264. properties: [
  12265. {
  12266. name: "errorRef",
  12267. type: "Error",
  12268. isAttr: true,
  12269. isReference: true
  12270. }
  12271. ]
  12272. },
  12273. {
  12274. name: "TerminateEventDefinition",
  12275. superClass: [
  12276. "EventDefinition"
  12277. ]
  12278. },
  12279. {
  12280. name: "EscalationEventDefinition",
  12281. superClass: [
  12282. "EventDefinition"
  12283. ],
  12284. properties: [
  12285. {
  12286. name: "escalationRef",
  12287. type: "Escalation",
  12288. isAttr: true,
  12289. isReference: true
  12290. }
  12291. ]
  12292. },
  12293. {
  12294. name: "Escalation",
  12295. properties: [
  12296. {
  12297. name: "structureRef",
  12298. type: "ItemDefinition",
  12299. isAttr: true,
  12300. isReference: true
  12301. },
  12302. {
  12303. name: "name",
  12304. isAttr: true,
  12305. type: "String"
  12306. },
  12307. {
  12308. name: "escalationCode",
  12309. isAttr: true,
  12310. type: "String"
  12311. }
  12312. ],
  12313. superClass: [
  12314. "RootElement"
  12315. ]
  12316. },
  12317. {
  12318. name: "CompensateEventDefinition",
  12319. superClass: [
  12320. "EventDefinition"
  12321. ],
  12322. properties: [
  12323. {
  12324. name: "waitForCompletion",
  12325. isAttr: true,
  12326. type: "Boolean",
  12327. "default": true
  12328. },
  12329. {
  12330. name: "activityRef",
  12331. type: "Activity",
  12332. isAttr: true,
  12333. isReference: true
  12334. }
  12335. ]
  12336. },
  12337. {
  12338. name: "TimerEventDefinition",
  12339. superClass: [
  12340. "EventDefinition"
  12341. ],
  12342. properties: [
  12343. {
  12344. name: "timeDate",
  12345. type: "Expression",
  12346. xml: {
  12347. serialize: "xsi:type"
  12348. }
  12349. },
  12350. {
  12351. name: "timeCycle",
  12352. type: "Expression",
  12353. xml: {
  12354. serialize: "xsi:type"
  12355. }
  12356. },
  12357. {
  12358. name: "timeDuration",
  12359. type: "Expression",
  12360. xml: {
  12361. serialize: "xsi:type"
  12362. }
  12363. }
  12364. ]
  12365. },
  12366. {
  12367. name: "LinkEventDefinition",
  12368. superClass: [
  12369. "EventDefinition"
  12370. ],
  12371. properties: [
  12372. {
  12373. name: "name",
  12374. isAttr: true,
  12375. type: "String"
  12376. },
  12377. {
  12378. name: "target",
  12379. type: "LinkEventDefinition",
  12380. isAttr: true,
  12381. isReference: true
  12382. },
  12383. {
  12384. name: "source",
  12385. type: "LinkEventDefinition",
  12386. isMany: true,
  12387. isReference: true
  12388. }
  12389. ]
  12390. },
  12391. {
  12392. name: "MessageEventDefinition",
  12393. superClass: [
  12394. "EventDefinition"
  12395. ],
  12396. properties: [
  12397. {
  12398. name: "messageRef",
  12399. type: "Message",
  12400. isAttr: true,
  12401. isReference: true
  12402. },
  12403. {
  12404. name: "operationRef",
  12405. type: "Operation",
  12406. isAttr: true,
  12407. isReference: true
  12408. }
  12409. ]
  12410. },
  12411. {
  12412. name: "ConditionalEventDefinition",
  12413. superClass: [
  12414. "EventDefinition"
  12415. ],
  12416. properties: [
  12417. {
  12418. name: "condition",
  12419. type: "Expression",
  12420. xml: {
  12421. serialize: "xsi:type"
  12422. }
  12423. }
  12424. ]
  12425. },
  12426. {
  12427. name: "SignalEventDefinition",
  12428. superClass: [
  12429. "EventDefinition"
  12430. ],
  12431. properties: [
  12432. {
  12433. name: "signalRef",
  12434. type: "Signal",
  12435. isAttr: true,
  12436. isReference: true
  12437. }
  12438. ]
  12439. },
  12440. {
  12441. name: "Signal",
  12442. superClass: [
  12443. "RootElement"
  12444. ],
  12445. properties: [
  12446. {
  12447. name: "structureRef",
  12448. type: "ItemDefinition",
  12449. isAttr: true,
  12450. isReference: true
  12451. },
  12452. {
  12453. name: "name",
  12454. isAttr: true,
  12455. type: "String"
  12456. }
  12457. ]
  12458. },
  12459. {
  12460. name: "ImplicitThrowEvent",
  12461. superClass: [
  12462. "ThrowEvent"
  12463. ]
  12464. },
  12465. {
  12466. name: "DataState",
  12467. superClass: [
  12468. "BaseElement"
  12469. ],
  12470. properties: [
  12471. {
  12472. name: "name",
  12473. isAttr: true,
  12474. type: "String"
  12475. }
  12476. ]
  12477. },
  12478. {
  12479. name: "ItemAwareElement",
  12480. superClass: [
  12481. "BaseElement"
  12482. ],
  12483. properties: [
  12484. {
  12485. name: "itemSubjectRef",
  12486. type: "ItemDefinition",
  12487. isAttr: true,
  12488. isReference: true
  12489. },
  12490. {
  12491. name: "dataState",
  12492. type: "DataState"
  12493. }
  12494. ]
  12495. },
  12496. {
  12497. name: "DataAssociation",
  12498. superClass: [
  12499. "BaseElement"
  12500. ],
  12501. properties: [
  12502. {
  12503. name: "sourceRef",
  12504. type: "ItemAwareElement",
  12505. isMany: true,
  12506. isReference: true
  12507. },
  12508. {
  12509. name: "targetRef",
  12510. type: "ItemAwareElement",
  12511. isReference: true
  12512. },
  12513. {
  12514. name: "transformation",
  12515. type: "FormalExpression",
  12516. xml: {
  12517. serialize: "property"
  12518. }
  12519. },
  12520. {
  12521. name: "assignment",
  12522. type: "Assignment",
  12523. isMany: true
  12524. }
  12525. ]
  12526. },
  12527. {
  12528. name: "DataInput",
  12529. superClass: [
  12530. "ItemAwareElement"
  12531. ],
  12532. properties: [
  12533. {
  12534. name: "name",
  12535. isAttr: true,
  12536. type: "String"
  12537. },
  12538. {
  12539. name: "isCollection",
  12540. "default": false,
  12541. isAttr: true,
  12542. type: "Boolean"
  12543. },
  12544. {
  12545. name: "inputSetRef",
  12546. type: "InputSet",
  12547. isMany: true,
  12548. isVirtual: true,
  12549. isReference: true
  12550. },
  12551. {
  12552. name: "inputSetWithOptional",
  12553. type: "InputSet",
  12554. isMany: true,
  12555. isVirtual: true,
  12556. isReference: true
  12557. },
  12558. {
  12559. name: "inputSetWithWhileExecuting",
  12560. type: "InputSet",
  12561. isMany: true,
  12562. isVirtual: true,
  12563. isReference: true
  12564. }
  12565. ]
  12566. },
  12567. {
  12568. name: "DataOutput",
  12569. superClass: [
  12570. "ItemAwareElement"
  12571. ],
  12572. properties: [
  12573. {
  12574. name: "name",
  12575. isAttr: true,
  12576. type: "String"
  12577. },
  12578. {
  12579. name: "isCollection",
  12580. "default": false,
  12581. isAttr: true,
  12582. type: "Boolean"
  12583. },
  12584. {
  12585. name: "outputSetRef",
  12586. type: "OutputSet",
  12587. isMany: true,
  12588. isVirtual: true,
  12589. isReference: true
  12590. },
  12591. {
  12592. name: "outputSetWithOptional",
  12593. type: "OutputSet",
  12594. isMany: true,
  12595. isVirtual: true,
  12596. isReference: true
  12597. },
  12598. {
  12599. name: "outputSetWithWhileExecuting",
  12600. type: "OutputSet",
  12601. isMany: true,
  12602. isVirtual: true,
  12603. isReference: true
  12604. }
  12605. ]
  12606. },
  12607. {
  12608. name: "InputSet",
  12609. superClass: [
  12610. "BaseElement"
  12611. ],
  12612. properties: [
  12613. {
  12614. name: "name",
  12615. isAttr: true,
  12616. type: "String"
  12617. },
  12618. {
  12619. name: "dataInputRefs",
  12620. type: "DataInput",
  12621. isMany: true,
  12622. isReference: true
  12623. },
  12624. {
  12625. name: "optionalInputRefs",
  12626. type: "DataInput",
  12627. isMany: true,
  12628. isReference: true
  12629. },
  12630. {
  12631. name: "whileExecutingInputRefs",
  12632. type: "DataInput",
  12633. isMany: true,
  12634. isReference: true
  12635. },
  12636. {
  12637. name: "outputSetRefs",
  12638. type: "OutputSet",
  12639. isMany: true,
  12640. isReference: true
  12641. }
  12642. ]
  12643. },
  12644. {
  12645. name: "OutputSet",
  12646. superClass: [
  12647. "BaseElement"
  12648. ],
  12649. properties: [
  12650. {
  12651. name: "dataOutputRefs",
  12652. type: "DataOutput",
  12653. isMany: true,
  12654. isReference: true
  12655. },
  12656. {
  12657. name: "name",
  12658. isAttr: true,
  12659. type: "String"
  12660. },
  12661. {
  12662. name: "inputSetRefs",
  12663. type: "InputSet",
  12664. isMany: true,
  12665. isReference: true
  12666. },
  12667. {
  12668. name: "optionalOutputRefs",
  12669. type: "DataOutput",
  12670. isMany: true,
  12671. isReference: true
  12672. },
  12673. {
  12674. name: "whileExecutingOutputRefs",
  12675. type: "DataOutput",
  12676. isMany: true,
  12677. isReference: true
  12678. }
  12679. ]
  12680. },
  12681. {
  12682. name: "Property",
  12683. superClass: [
  12684. "ItemAwareElement"
  12685. ],
  12686. properties: [
  12687. {
  12688. name: "name",
  12689. isAttr: true,
  12690. type: "String"
  12691. }
  12692. ]
  12693. },
  12694. {
  12695. name: "DataInputAssociation",
  12696. superClass: [
  12697. "DataAssociation"
  12698. ]
  12699. },
  12700. {
  12701. name: "DataOutputAssociation",
  12702. superClass: [
  12703. "DataAssociation"
  12704. ]
  12705. },
  12706. {
  12707. name: "InputOutputSpecification",
  12708. superClass: [
  12709. "BaseElement"
  12710. ],
  12711. properties: [
  12712. {
  12713. name: "dataInputs",
  12714. type: "DataInput",
  12715. isMany: true
  12716. },
  12717. {
  12718. name: "dataOutputs",
  12719. type: "DataOutput",
  12720. isMany: true
  12721. },
  12722. {
  12723. name: "inputSets",
  12724. type: "InputSet",
  12725. isMany: true
  12726. },
  12727. {
  12728. name: "outputSets",
  12729. type: "OutputSet",
  12730. isMany: true
  12731. }
  12732. ]
  12733. },
  12734. {
  12735. name: "DataObject",
  12736. superClass: [
  12737. "FlowElement",
  12738. "ItemAwareElement"
  12739. ],
  12740. properties: [
  12741. {
  12742. name: "isCollection",
  12743. "default": false,
  12744. isAttr: true,
  12745. type: "Boolean"
  12746. }
  12747. ]
  12748. },
  12749. {
  12750. name: "InputOutputBinding",
  12751. properties: [
  12752. {
  12753. name: "inputDataRef",
  12754. type: "InputSet",
  12755. isAttr: true,
  12756. isReference: true
  12757. },
  12758. {
  12759. name: "outputDataRef",
  12760. type: "OutputSet",
  12761. isAttr: true,
  12762. isReference: true
  12763. },
  12764. {
  12765. name: "operationRef",
  12766. type: "Operation",
  12767. isAttr: true,
  12768. isReference: true
  12769. }
  12770. ]
  12771. },
  12772. {
  12773. name: "Assignment",
  12774. superClass: [
  12775. "BaseElement"
  12776. ],
  12777. properties: [
  12778. {
  12779. name: "from",
  12780. type: "Expression",
  12781. xml: {
  12782. serialize: "xsi:type"
  12783. }
  12784. },
  12785. {
  12786. name: "to",
  12787. type: "Expression",
  12788. xml: {
  12789. serialize: "xsi:type"
  12790. }
  12791. }
  12792. ]
  12793. },
  12794. {
  12795. name: "DataStore",
  12796. superClass: [
  12797. "RootElement",
  12798. "ItemAwareElement"
  12799. ],
  12800. properties: [
  12801. {
  12802. name: "name",
  12803. isAttr: true,
  12804. type: "String"
  12805. },
  12806. {
  12807. name: "capacity",
  12808. isAttr: true,
  12809. type: "Integer"
  12810. },
  12811. {
  12812. name: "isUnlimited",
  12813. "default": true,
  12814. isAttr: true,
  12815. type: "Boolean"
  12816. }
  12817. ]
  12818. },
  12819. {
  12820. name: "DataStoreReference",
  12821. superClass: [
  12822. "ItemAwareElement",
  12823. "FlowElement"
  12824. ],
  12825. properties: [
  12826. {
  12827. name: "dataStoreRef",
  12828. type: "DataStore",
  12829. isAttr: true,
  12830. isReference: true
  12831. }
  12832. ]
  12833. },
  12834. {
  12835. name: "DataObjectReference",
  12836. superClass: [
  12837. "ItemAwareElement",
  12838. "FlowElement"
  12839. ],
  12840. properties: [
  12841. {
  12842. name: "dataObjectRef",
  12843. type: "DataObject",
  12844. isAttr: true,
  12845. isReference: true
  12846. }
  12847. ]
  12848. },
  12849. {
  12850. name: "ConversationLink",
  12851. superClass: [
  12852. "BaseElement"
  12853. ],
  12854. properties: [
  12855. {
  12856. name: "sourceRef",
  12857. type: "InteractionNode",
  12858. isAttr: true,
  12859. isReference: true
  12860. },
  12861. {
  12862. name: "targetRef",
  12863. type: "InteractionNode",
  12864. isAttr: true,
  12865. isReference: true
  12866. },
  12867. {
  12868. name: "name",
  12869. isAttr: true,
  12870. type: "String"
  12871. }
  12872. ]
  12873. },
  12874. {
  12875. name: "ConversationAssociation",
  12876. superClass: [
  12877. "BaseElement"
  12878. ],
  12879. properties: [
  12880. {
  12881. name: "innerConversationNodeRef",
  12882. type: "ConversationNode",
  12883. isAttr: true,
  12884. isReference: true
  12885. },
  12886. {
  12887. name: "outerConversationNodeRef",
  12888. type: "ConversationNode",
  12889. isAttr: true,
  12890. isReference: true
  12891. }
  12892. ]
  12893. },
  12894. {
  12895. name: "CallConversation",
  12896. superClass: [
  12897. "ConversationNode"
  12898. ],
  12899. properties: [
  12900. {
  12901. name: "calledCollaborationRef",
  12902. type: "Collaboration",
  12903. isAttr: true,
  12904. isReference: true
  12905. },
  12906. {
  12907. name: "participantAssociations",
  12908. type: "ParticipantAssociation",
  12909. isMany: true
  12910. }
  12911. ]
  12912. },
  12913. {
  12914. name: "Conversation",
  12915. superClass: [
  12916. "ConversationNode"
  12917. ]
  12918. },
  12919. {
  12920. name: "SubConversation",
  12921. superClass: [
  12922. "ConversationNode"
  12923. ],
  12924. properties: [
  12925. {
  12926. name: "conversationNodes",
  12927. type: "ConversationNode",
  12928. isMany: true
  12929. }
  12930. ]
  12931. },
  12932. {
  12933. name: "ConversationNode",
  12934. isAbstract: true,
  12935. superClass: [
  12936. "InteractionNode",
  12937. "BaseElement"
  12938. ],
  12939. properties: [
  12940. {
  12941. name: "name",
  12942. isAttr: true,
  12943. type: "String"
  12944. },
  12945. {
  12946. name: "participantRef",
  12947. type: "Participant",
  12948. isMany: true,
  12949. isReference: true
  12950. },
  12951. {
  12952. name: "messageFlowRefs",
  12953. type: "MessageFlow",
  12954. isMany: true,
  12955. isReference: true
  12956. },
  12957. {
  12958. name: "correlationKeys",
  12959. type: "CorrelationKey",
  12960. isMany: true
  12961. }
  12962. ]
  12963. },
  12964. {
  12965. name: "GlobalConversation",
  12966. superClass: [
  12967. "Collaboration"
  12968. ]
  12969. },
  12970. {
  12971. name: "PartnerEntity",
  12972. superClass: [
  12973. "RootElement"
  12974. ],
  12975. properties: [
  12976. {
  12977. name: "name",
  12978. isAttr: true,
  12979. type: "String"
  12980. },
  12981. {
  12982. name: "participantRef",
  12983. type: "Participant",
  12984. isMany: true,
  12985. isReference: true
  12986. }
  12987. ]
  12988. },
  12989. {
  12990. name: "PartnerRole",
  12991. superClass: [
  12992. "RootElement"
  12993. ],
  12994. properties: [
  12995. {
  12996. name: "name",
  12997. isAttr: true,
  12998. type: "String"
  12999. },
  13000. {
  13001. name: "participantRef",
  13002. type: "Participant",
  13003. isMany: true,
  13004. isReference: true
  13005. }
  13006. ]
  13007. },
  13008. {
  13009. name: "CorrelationProperty",
  13010. superClass: [
  13011. "RootElement"
  13012. ],
  13013. properties: [
  13014. {
  13015. name: "correlationPropertyRetrievalExpression",
  13016. type: "CorrelationPropertyRetrievalExpression",
  13017. isMany: true
  13018. },
  13019. {
  13020. name: "name",
  13021. isAttr: true,
  13022. type: "String"
  13023. },
  13024. {
  13025. name: "type",
  13026. type: "ItemDefinition",
  13027. isAttr: true,
  13028. isReference: true
  13029. }
  13030. ]
  13031. },
  13032. {
  13033. name: "Error",
  13034. superClass: [
  13035. "RootElement"
  13036. ],
  13037. properties: [
  13038. {
  13039. name: "structureRef",
  13040. type: "ItemDefinition",
  13041. isAttr: true,
  13042. isReference: true
  13043. },
  13044. {
  13045. name: "name",
  13046. isAttr: true,
  13047. type: "String"
  13048. },
  13049. {
  13050. name: "errorCode",
  13051. isAttr: true,
  13052. type: "String"
  13053. }
  13054. ]
  13055. },
  13056. {
  13057. name: "CorrelationKey",
  13058. superClass: [
  13059. "BaseElement"
  13060. ],
  13061. properties: [
  13062. {
  13063. name: "correlationPropertyRef",
  13064. type: "CorrelationProperty",
  13065. isMany: true,
  13066. isReference: true
  13067. },
  13068. {
  13069. name: "name",
  13070. isAttr: true,
  13071. type: "String"
  13072. }
  13073. ]
  13074. },
  13075. {
  13076. name: "Expression",
  13077. superClass: [
  13078. "BaseElement"
  13079. ],
  13080. isAbstract: false,
  13081. properties: [
  13082. {
  13083. name: "body",
  13084. isBody: true,
  13085. type: "String"
  13086. }
  13087. ]
  13088. },
  13089. {
  13090. name: "FormalExpression",
  13091. superClass: [
  13092. "Expression"
  13093. ],
  13094. properties: [
  13095. {
  13096. name: "language",
  13097. isAttr: true,
  13098. type: "String"
  13099. },
  13100. {
  13101. name: "evaluatesToTypeRef",
  13102. type: "ItemDefinition",
  13103. isAttr: true,
  13104. isReference: true
  13105. }
  13106. ]
  13107. },
  13108. {
  13109. name: "Message",
  13110. superClass: [
  13111. "RootElement"
  13112. ],
  13113. properties: [
  13114. {
  13115. name: "name",
  13116. isAttr: true,
  13117. type: "String"
  13118. },
  13119. {
  13120. name: "itemRef",
  13121. type: "ItemDefinition",
  13122. isAttr: true,
  13123. isReference: true
  13124. }
  13125. ]
  13126. },
  13127. {
  13128. name: "ItemDefinition",
  13129. superClass: [
  13130. "RootElement"
  13131. ],
  13132. properties: [
  13133. {
  13134. name: "itemKind",
  13135. type: "ItemKind",
  13136. isAttr: true
  13137. },
  13138. {
  13139. name: "structureRef",
  13140. isAttr: true,
  13141. type: "String"
  13142. },
  13143. {
  13144. name: "isCollection",
  13145. "default": false,
  13146. isAttr: true,
  13147. type: "Boolean"
  13148. },
  13149. {
  13150. name: "import",
  13151. type: "Import",
  13152. isAttr: true,
  13153. isReference: true
  13154. }
  13155. ]
  13156. },
  13157. {
  13158. name: "FlowElement",
  13159. isAbstract: true,
  13160. superClass: [
  13161. "BaseElement"
  13162. ],
  13163. properties: [
  13164. {
  13165. name: "name",
  13166. isAttr: true,
  13167. type: "String"
  13168. },
  13169. {
  13170. name: "auditing",
  13171. type: "Auditing"
  13172. },
  13173. {
  13174. name: "monitoring",
  13175. type: "Monitoring"
  13176. },
  13177. {
  13178. name: "categoryValueRef",
  13179. type: "CategoryValue",
  13180. isMany: true,
  13181. isReference: true
  13182. }
  13183. ]
  13184. },
  13185. {
  13186. name: "SequenceFlow",
  13187. superClass: [
  13188. "FlowElement"
  13189. ],
  13190. properties: [
  13191. {
  13192. name: "isImmediate",
  13193. isAttr: true,
  13194. type: "Boolean"
  13195. },
  13196. {
  13197. name: "conditionExpression",
  13198. type: "Expression",
  13199. xml: {
  13200. serialize: "xsi:type"
  13201. }
  13202. },
  13203. {
  13204. name: "sourceRef",
  13205. type: "FlowNode",
  13206. isAttr: true,
  13207. isReference: true
  13208. },
  13209. {
  13210. name: "targetRef",
  13211. type: "FlowNode",
  13212. isAttr: true,
  13213. isReference: true
  13214. }
  13215. ]
  13216. },
  13217. {
  13218. name: "FlowElementsContainer",
  13219. isAbstract: true,
  13220. superClass: [
  13221. "BaseElement"
  13222. ],
  13223. properties: [
  13224. {
  13225. name: "laneSets",
  13226. type: "LaneSet",
  13227. isMany: true
  13228. },
  13229. {
  13230. name: "flowElements",
  13231. type: "FlowElement",
  13232. isMany: true
  13233. }
  13234. ]
  13235. },
  13236. {
  13237. name: "CallableElement",
  13238. isAbstract: true,
  13239. superClass: [
  13240. "RootElement"
  13241. ],
  13242. properties: [
  13243. {
  13244. name: "name",
  13245. isAttr: true,
  13246. type: "String"
  13247. },
  13248. {
  13249. name: "ioSpecification",
  13250. type: "InputOutputSpecification",
  13251. xml: {
  13252. serialize: "property"
  13253. }
  13254. },
  13255. {
  13256. name: "supportedInterfaceRef",
  13257. type: "Interface",
  13258. isMany: true,
  13259. isReference: true
  13260. },
  13261. {
  13262. name: "ioBinding",
  13263. type: "InputOutputBinding",
  13264. isMany: true,
  13265. xml: {
  13266. serialize: "property"
  13267. }
  13268. }
  13269. ]
  13270. },
  13271. {
  13272. name: "FlowNode",
  13273. isAbstract: true,
  13274. superClass: [
  13275. "FlowElement"
  13276. ],
  13277. properties: [
  13278. {
  13279. name: "incoming",
  13280. type: "SequenceFlow",
  13281. isMany: true,
  13282. isReference: true
  13283. },
  13284. {
  13285. name: "outgoing",
  13286. type: "SequenceFlow",
  13287. isMany: true,
  13288. isReference: true
  13289. },
  13290. {
  13291. name: "lanes",
  13292. type: "Lane",
  13293. isMany: true,
  13294. isVirtual: true,
  13295. isReference: true
  13296. }
  13297. ]
  13298. },
  13299. {
  13300. name: "CorrelationPropertyRetrievalExpression",
  13301. superClass: [
  13302. "BaseElement"
  13303. ],
  13304. properties: [
  13305. {
  13306. name: "messagePath",
  13307. type: "FormalExpression"
  13308. },
  13309. {
  13310. name: "messageRef",
  13311. type: "Message",
  13312. isAttr: true,
  13313. isReference: true
  13314. }
  13315. ]
  13316. },
  13317. {
  13318. name: "CorrelationPropertyBinding",
  13319. superClass: [
  13320. "BaseElement"
  13321. ],
  13322. properties: [
  13323. {
  13324. name: "dataPath",
  13325. type: "FormalExpression"
  13326. },
  13327. {
  13328. name: "correlationPropertyRef",
  13329. type: "CorrelationProperty",
  13330. isAttr: true,
  13331. isReference: true
  13332. }
  13333. ]
  13334. },
  13335. {
  13336. name: "Resource",
  13337. superClass: [
  13338. "RootElement"
  13339. ],
  13340. properties: [
  13341. {
  13342. name: "name",
  13343. isAttr: true,
  13344. type: "String"
  13345. },
  13346. {
  13347. name: "resourceParameters",
  13348. type: "ResourceParameter",
  13349. isMany: true
  13350. }
  13351. ]
  13352. },
  13353. {
  13354. name: "ResourceParameter",
  13355. superClass: [
  13356. "BaseElement"
  13357. ],
  13358. properties: [
  13359. {
  13360. name: "name",
  13361. isAttr: true,
  13362. type: "String"
  13363. },
  13364. {
  13365. name: "isRequired",
  13366. isAttr: true,
  13367. type: "Boolean"
  13368. },
  13369. {
  13370. name: "type",
  13371. type: "ItemDefinition",
  13372. isAttr: true,
  13373. isReference: true
  13374. }
  13375. ]
  13376. },
  13377. {
  13378. name: "CorrelationSubscription",
  13379. superClass: [
  13380. "BaseElement"
  13381. ],
  13382. properties: [
  13383. {
  13384. name: "correlationKeyRef",
  13385. type: "CorrelationKey",
  13386. isAttr: true,
  13387. isReference: true
  13388. },
  13389. {
  13390. name: "correlationPropertyBinding",
  13391. type: "CorrelationPropertyBinding",
  13392. isMany: true
  13393. }
  13394. ]
  13395. },
  13396. {
  13397. name: "MessageFlow",
  13398. superClass: [
  13399. "BaseElement"
  13400. ],
  13401. properties: [
  13402. {
  13403. name: "name",
  13404. isAttr: true,
  13405. type: "String"
  13406. },
  13407. {
  13408. name: "sourceRef",
  13409. type: "InteractionNode",
  13410. isAttr: true,
  13411. isReference: true
  13412. },
  13413. {
  13414. name: "targetRef",
  13415. type: "InteractionNode",
  13416. isAttr: true,
  13417. isReference: true
  13418. },
  13419. {
  13420. name: "messageRef",
  13421. type: "Message",
  13422. isAttr: true,
  13423. isReference: true
  13424. }
  13425. ]
  13426. },
  13427. {
  13428. name: "MessageFlowAssociation",
  13429. superClass: [
  13430. "BaseElement"
  13431. ],
  13432. properties: [
  13433. {
  13434. name: "innerMessageFlowRef",
  13435. type: "MessageFlow",
  13436. isAttr: true,
  13437. isReference: true
  13438. },
  13439. {
  13440. name: "outerMessageFlowRef",
  13441. type: "MessageFlow",
  13442. isAttr: true,
  13443. isReference: true
  13444. }
  13445. ]
  13446. },
  13447. {
  13448. name: "InteractionNode",
  13449. isAbstract: true,
  13450. properties: [
  13451. {
  13452. name: "incomingConversationLinks",
  13453. type: "ConversationLink",
  13454. isMany: true,
  13455. isVirtual: true,
  13456. isReference: true
  13457. },
  13458. {
  13459. name: "outgoingConversationLinks",
  13460. type: "ConversationLink",
  13461. isMany: true,
  13462. isVirtual: true,
  13463. isReference: true
  13464. }
  13465. ]
  13466. },
  13467. {
  13468. name: "Participant",
  13469. superClass: [
  13470. "InteractionNode",
  13471. "BaseElement"
  13472. ],
  13473. properties: [
  13474. {
  13475. name: "name",
  13476. isAttr: true,
  13477. type: "String"
  13478. },
  13479. {
  13480. name: "interfaceRef",
  13481. type: "Interface",
  13482. isMany: true,
  13483. isReference: true
  13484. },
  13485. {
  13486. name: "participantMultiplicity",
  13487. type: "ParticipantMultiplicity"
  13488. },
  13489. {
  13490. name: "endPointRefs",
  13491. type: "EndPoint",
  13492. isMany: true,
  13493. isReference: true
  13494. },
  13495. {
  13496. name: "processRef",
  13497. type: "Process",
  13498. isAttr: true,
  13499. isReference: true
  13500. }
  13501. ]
  13502. },
  13503. {
  13504. name: "ParticipantAssociation",
  13505. superClass: [
  13506. "BaseElement"
  13507. ],
  13508. properties: [
  13509. {
  13510. name: "innerParticipantRef",
  13511. type: "Participant",
  13512. isAttr: true,
  13513. isReference: true
  13514. },
  13515. {
  13516. name: "outerParticipantRef",
  13517. type: "Participant",
  13518. isAttr: true,
  13519. isReference: true
  13520. }
  13521. ]
  13522. },
  13523. {
  13524. name: "ParticipantMultiplicity",
  13525. properties: [
  13526. {
  13527. name: "minimum",
  13528. "default": 0,
  13529. isAttr: true,
  13530. type: "Integer"
  13531. },
  13532. {
  13533. name: "maximum",
  13534. "default": 1,
  13535. isAttr: true,
  13536. type: "Integer"
  13537. }
  13538. ],
  13539. superClass: [
  13540. "BaseElement"
  13541. ]
  13542. },
  13543. {
  13544. name: "Collaboration",
  13545. superClass: [
  13546. "RootElement"
  13547. ],
  13548. properties: [
  13549. {
  13550. name: "name",
  13551. isAttr: true,
  13552. type: "String"
  13553. },
  13554. {
  13555. name: "isClosed",
  13556. isAttr: true,
  13557. type: "Boolean"
  13558. },
  13559. {
  13560. name: "participants",
  13561. type: "Participant",
  13562. isMany: true
  13563. },
  13564. {
  13565. name: "messageFlows",
  13566. type: "MessageFlow",
  13567. isMany: true
  13568. },
  13569. {
  13570. name: "artifacts",
  13571. type: "Artifact",
  13572. isMany: true
  13573. },
  13574. {
  13575. name: "conversations",
  13576. type: "ConversationNode",
  13577. isMany: true
  13578. },
  13579. {
  13580. name: "conversationAssociations",
  13581. type: "ConversationAssociation"
  13582. },
  13583. {
  13584. name: "participantAssociations",
  13585. type: "ParticipantAssociation",
  13586. isMany: true
  13587. },
  13588. {
  13589. name: "messageFlowAssociations",
  13590. type: "MessageFlowAssociation",
  13591. isMany: true
  13592. },
  13593. {
  13594. name: "correlationKeys",
  13595. type: "CorrelationKey",
  13596. isMany: true
  13597. },
  13598. {
  13599. name: "choreographyRef",
  13600. type: "Choreography",
  13601. isMany: true,
  13602. isReference: true
  13603. },
  13604. {
  13605. name: "conversationLinks",
  13606. type: "ConversationLink",
  13607. isMany: true
  13608. }
  13609. ]
  13610. },
  13611. {
  13612. name: "ChoreographyActivity",
  13613. isAbstract: true,
  13614. superClass: [
  13615. "FlowNode"
  13616. ],
  13617. properties: [
  13618. {
  13619. name: "participantRef",
  13620. type: "Participant",
  13621. isMany: true,
  13622. isReference: true
  13623. },
  13624. {
  13625. name: "initiatingParticipantRef",
  13626. type: "Participant",
  13627. isAttr: true,
  13628. isReference: true
  13629. },
  13630. {
  13631. name: "correlationKeys",
  13632. type: "CorrelationKey",
  13633. isMany: true
  13634. },
  13635. {
  13636. name: "loopType",
  13637. type: "ChoreographyLoopType",
  13638. "default": "None",
  13639. isAttr: true
  13640. }
  13641. ]
  13642. },
  13643. {
  13644. name: "CallChoreography",
  13645. superClass: [
  13646. "ChoreographyActivity"
  13647. ],
  13648. properties: [
  13649. {
  13650. name: "calledChoreographyRef",
  13651. type: "Choreography",
  13652. isAttr: true,
  13653. isReference: true
  13654. },
  13655. {
  13656. name: "participantAssociations",
  13657. type: "ParticipantAssociation",
  13658. isMany: true
  13659. }
  13660. ]
  13661. },
  13662. {
  13663. name: "SubChoreography",
  13664. superClass: [
  13665. "ChoreographyActivity",
  13666. "FlowElementsContainer"
  13667. ],
  13668. properties: [
  13669. {
  13670. name: "artifacts",
  13671. type: "Artifact",
  13672. isMany: true
  13673. }
  13674. ]
  13675. },
  13676. {
  13677. name: "ChoreographyTask",
  13678. superClass: [
  13679. "ChoreographyActivity"
  13680. ],
  13681. properties: [
  13682. {
  13683. name: "messageFlowRef",
  13684. type: "MessageFlow",
  13685. isMany: true,
  13686. isReference: true
  13687. }
  13688. ]
  13689. },
  13690. {
  13691. name: "Choreography",
  13692. superClass: [
  13693. "Collaboration",
  13694. "FlowElementsContainer"
  13695. ]
  13696. },
  13697. {
  13698. name: "GlobalChoreographyTask",
  13699. superClass: [
  13700. "Choreography"
  13701. ],
  13702. properties: [
  13703. {
  13704. name: "initiatingParticipantRef",
  13705. type: "Participant",
  13706. isAttr: true,
  13707. isReference: true
  13708. }
  13709. ]
  13710. },
  13711. {
  13712. name: "TextAnnotation",
  13713. superClass: [
  13714. "Artifact"
  13715. ],
  13716. properties: [
  13717. {
  13718. name: "text",
  13719. type: "String"
  13720. },
  13721. {
  13722. name: "textFormat",
  13723. "default": "text/plain",
  13724. isAttr: true,
  13725. type: "String"
  13726. }
  13727. ]
  13728. },
  13729. {
  13730. name: "Group",
  13731. superClass: [
  13732. "Artifact"
  13733. ],
  13734. properties: [
  13735. {
  13736. name: "categoryValueRef",
  13737. type: "CategoryValue",
  13738. isAttr: true,
  13739. isReference: true
  13740. }
  13741. ]
  13742. },
  13743. {
  13744. name: "Association",
  13745. superClass: [
  13746. "Artifact"
  13747. ],
  13748. properties: [
  13749. {
  13750. name: "associationDirection",
  13751. type: "AssociationDirection",
  13752. isAttr: true
  13753. },
  13754. {
  13755. name: "sourceRef",
  13756. type: "BaseElement",
  13757. isAttr: true,
  13758. isReference: true
  13759. },
  13760. {
  13761. name: "targetRef",
  13762. type: "BaseElement",
  13763. isAttr: true,
  13764. isReference: true
  13765. }
  13766. ]
  13767. },
  13768. {
  13769. name: "Category",
  13770. superClass: [
  13771. "RootElement"
  13772. ],
  13773. properties: [
  13774. {
  13775. name: "categoryValue",
  13776. type: "CategoryValue",
  13777. isMany: true
  13778. },
  13779. {
  13780. name: "name",
  13781. isAttr: true,
  13782. type: "String"
  13783. }
  13784. ]
  13785. },
  13786. {
  13787. name: "Artifact",
  13788. isAbstract: true,
  13789. superClass: [
  13790. "BaseElement"
  13791. ]
  13792. },
  13793. {
  13794. name: "CategoryValue",
  13795. superClass: [
  13796. "BaseElement"
  13797. ],
  13798. properties: [
  13799. {
  13800. name: "categorizedFlowElements",
  13801. type: "FlowElement",
  13802. isMany: true,
  13803. isVirtual: true,
  13804. isReference: true
  13805. },
  13806. {
  13807. name: "value",
  13808. isAttr: true,
  13809. type: "String"
  13810. }
  13811. ]
  13812. },
  13813. {
  13814. name: "Activity",
  13815. isAbstract: true,
  13816. superClass: [
  13817. "FlowNode"
  13818. ],
  13819. properties: [
  13820. {
  13821. name: "isForCompensation",
  13822. "default": false,
  13823. isAttr: true,
  13824. type: "Boolean"
  13825. },
  13826. {
  13827. name: "default",
  13828. type: "SequenceFlow",
  13829. isAttr: true,
  13830. isReference: true
  13831. },
  13832. {
  13833. name: "ioSpecification",
  13834. type: "InputOutputSpecification",
  13835. xml: {
  13836. serialize: "property"
  13837. }
  13838. },
  13839. {
  13840. name: "boundaryEventRefs",
  13841. type: "BoundaryEvent",
  13842. isMany: true,
  13843. isReference: true
  13844. },
  13845. {
  13846. name: "properties",
  13847. type: "Property",
  13848. isMany: true
  13849. },
  13850. {
  13851. name: "dataInputAssociations",
  13852. type: "DataInputAssociation",
  13853. isMany: true
  13854. },
  13855. {
  13856. name: "dataOutputAssociations",
  13857. type: "DataOutputAssociation",
  13858. isMany: true
  13859. },
  13860. {
  13861. name: "startQuantity",
  13862. "default": 1,
  13863. isAttr: true,
  13864. type: "Integer"
  13865. },
  13866. {
  13867. name: "resources",
  13868. type: "ResourceRole",
  13869. isMany: true
  13870. },
  13871. {
  13872. name: "completionQuantity",
  13873. "default": 1,
  13874. isAttr: true,
  13875. type: "Integer"
  13876. },
  13877. {
  13878. name: "loopCharacteristics",
  13879. type: "LoopCharacteristics"
  13880. }
  13881. ]
  13882. },
  13883. {
  13884. name: "ServiceTask",
  13885. superClass: [
  13886. "Task"
  13887. ],
  13888. properties: [
  13889. {
  13890. name: "implementation",
  13891. isAttr: true,
  13892. type: "String"
  13893. },
  13894. {
  13895. name: "operationRef",
  13896. type: "Operation",
  13897. isAttr: true,
  13898. isReference: true
  13899. }
  13900. ]
  13901. },
  13902. {
  13903. name: "SubProcess",
  13904. superClass: [
  13905. "Activity",
  13906. "FlowElementsContainer",
  13907. "InteractionNode"
  13908. ],
  13909. properties: [
  13910. {
  13911. name: "triggeredByEvent",
  13912. "default": false,
  13913. isAttr: true,
  13914. type: "Boolean"
  13915. },
  13916. {
  13917. name: "artifacts",
  13918. type: "Artifact",
  13919. isMany: true
  13920. }
  13921. ]
  13922. },
  13923. {
  13924. name: "LoopCharacteristics",
  13925. isAbstract: true,
  13926. superClass: [
  13927. "BaseElement"
  13928. ]
  13929. },
  13930. {
  13931. name: "MultiInstanceLoopCharacteristics",
  13932. superClass: [
  13933. "LoopCharacteristics"
  13934. ],
  13935. properties: [
  13936. {
  13937. name: "isSequential",
  13938. "default": false,
  13939. isAttr: true,
  13940. type: "Boolean"
  13941. },
  13942. {
  13943. name: "behavior",
  13944. type: "MultiInstanceBehavior",
  13945. "default": "All",
  13946. isAttr: true
  13947. },
  13948. {
  13949. name: "loopCardinality",
  13950. type: "Expression",
  13951. xml: {
  13952. serialize: "xsi:type"
  13953. }
  13954. },
  13955. {
  13956. name: "loopDataInputRef",
  13957. type: "ItemAwareElement",
  13958. isReference: true
  13959. },
  13960. {
  13961. name: "loopDataOutputRef",
  13962. type: "ItemAwareElement",
  13963. isReference: true
  13964. },
  13965. {
  13966. name: "inputDataItem",
  13967. type: "DataInput",
  13968. xml: {
  13969. serialize: "property"
  13970. }
  13971. },
  13972. {
  13973. name: "outputDataItem",
  13974. type: "DataOutput",
  13975. xml: {
  13976. serialize: "property"
  13977. }
  13978. },
  13979. {
  13980. name: "complexBehaviorDefinition",
  13981. type: "ComplexBehaviorDefinition",
  13982. isMany: true
  13983. },
  13984. {
  13985. name: "completionCondition",
  13986. type: "Expression",
  13987. xml: {
  13988. serialize: "xsi:type"
  13989. }
  13990. },
  13991. {
  13992. name: "oneBehaviorEventRef",
  13993. type: "EventDefinition",
  13994. isAttr: true,
  13995. isReference: true
  13996. },
  13997. {
  13998. name: "noneBehaviorEventRef",
  13999. type: "EventDefinition",
  14000. isAttr: true,
  14001. isReference: true
  14002. }
  14003. ]
  14004. },
  14005. {
  14006. name: "StandardLoopCharacteristics",
  14007. superClass: [
  14008. "LoopCharacteristics"
  14009. ],
  14010. properties: [
  14011. {
  14012. name: "testBefore",
  14013. "default": false,
  14014. isAttr: true,
  14015. type: "Boolean"
  14016. },
  14017. {
  14018. name: "loopCondition",
  14019. type: "Expression",
  14020. xml: {
  14021. serialize: "xsi:type"
  14022. }
  14023. },
  14024. {
  14025. name: "loopMaximum",
  14026. type: "Integer",
  14027. isAttr: true
  14028. }
  14029. ]
  14030. },
  14031. {
  14032. name: "CallActivity",
  14033. superClass: [
  14034. "Activity"
  14035. ],
  14036. properties: [
  14037. {
  14038. name: "calledElement",
  14039. type: "String",
  14040. isAttr: true
  14041. }
  14042. ]
  14043. },
  14044. {
  14045. name: "Task",
  14046. superClass: [
  14047. "Activity",
  14048. "InteractionNode"
  14049. ]
  14050. },
  14051. {
  14052. name: "SendTask",
  14053. superClass: [
  14054. "Task"
  14055. ],
  14056. properties: [
  14057. {
  14058. name: "implementation",
  14059. isAttr: true,
  14060. type: "String"
  14061. },
  14062. {
  14063. name: "operationRef",
  14064. type: "Operation",
  14065. isAttr: true,
  14066. isReference: true
  14067. },
  14068. {
  14069. name: "messageRef",
  14070. type: "Message",
  14071. isAttr: true,
  14072. isReference: true
  14073. }
  14074. ]
  14075. },
  14076. {
  14077. name: "ReceiveTask",
  14078. superClass: [
  14079. "Task"
  14080. ],
  14081. properties: [
  14082. {
  14083. name: "implementation",
  14084. isAttr: true,
  14085. type: "String"
  14086. },
  14087. {
  14088. name: "instantiate",
  14089. "default": false,
  14090. isAttr: true,
  14091. type: "Boolean"
  14092. },
  14093. {
  14094. name: "operationRef",
  14095. type: "Operation",
  14096. isAttr: true,
  14097. isReference: true
  14098. },
  14099. {
  14100. name: "messageRef",
  14101. type: "Message",
  14102. isAttr: true,
  14103. isReference: true
  14104. }
  14105. ]
  14106. },
  14107. {
  14108. name: "ScriptTask",
  14109. superClass: [
  14110. "Task"
  14111. ],
  14112. properties: [
  14113. {
  14114. name: "scriptFormat",
  14115. isAttr: true,
  14116. type: "String"
  14117. },
  14118. {
  14119. name: "script",
  14120. type: "String"
  14121. }
  14122. ]
  14123. },
  14124. {
  14125. name: "BusinessRuleTask",
  14126. superClass: [
  14127. "Task"
  14128. ],
  14129. properties: [
  14130. {
  14131. name: "implementation",
  14132. isAttr: true,
  14133. type: "String"
  14134. }
  14135. ]
  14136. },
  14137. {
  14138. name: "AdHocSubProcess",
  14139. superClass: [
  14140. "SubProcess"
  14141. ],
  14142. properties: [
  14143. {
  14144. name: "completionCondition",
  14145. type: "Expression",
  14146. xml: {
  14147. serialize: "xsi:type"
  14148. }
  14149. },
  14150. {
  14151. name: "ordering",
  14152. type: "AdHocOrdering",
  14153. isAttr: true
  14154. },
  14155. {
  14156. name: "cancelRemainingInstances",
  14157. "default": true,
  14158. isAttr: true,
  14159. type: "Boolean"
  14160. }
  14161. ]
  14162. },
  14163. {
  14164. name: "Transaction",
  14165. superClass: [
  14166. "SubProcess"
  14167. ],
  14168. properties: [
  14169. {
  14170. name: "protocol",
  14171. isAttr: true,
  14172. type: "String"
  14173. },
  14174. {
  14175. name: "method",
  14176. isAttr: true,
  14177. type: "String"
  14178. }
  14179. ]
  14180. },
  14181. {
  14182. name: "GlobalScriptTask",
  14183. superClass: [
  14184. "GlobalTask"
  14185. ],
  14186. properties: [
  14187. {
  14188. name: "scriptLanguage",
  14189. isAttr: true,
  14190. type: "String"
  14191. },
  14192. {
  14193. name: "script",
  14194. isAttr: true,
  14195. type: "String"
  14196. }
  14197. ]
  14198. },
  14199. {
  14200. name: "GlobalBusinessRuleTask",
  14201. superClass: [
  14202. "GlobalTask"
  14203. ],
  14204. properties: [
  14205. {
  14206. name: "implementation",
  14207. isAttr: true,
  14208. type: "String"
  14209. }
  14210. ]
  14211. },
  14212. {
  14213. name: "ComplexBehaviorDefinition",
  14214. superClass: [
  14215. "BaseElement"
  14216. ],
  14217. properties: [
  14218. {
  14219. name: "condition",
  14220. type: "FormalExpression"
  14221. },
  14222. {
  14223. name: "event",
  14224. type: "ImplicitThrowEvent"
  14225. }
  14226. ]
  14227. },
  14228. {
  14229. name: "ResourceRole",
  14230. superClass: [
  14231. "BaseElement"
  14232. ],
  14233. properties: [
  14234. {
  14235. name: "resourceRef",
  14236. type: "Resource",
  14237. isReference: true
  14238. },
  14239. {
  14240. name: "resourceParameterBindings",
  14241. type: "ResourceParameterBinding",
  14242. isMany: true
  14243. },
  14244. {
  14245. name: "resourceAssignmentExpression",
  14246. type: "ResourceAssignmentExpression"
  14247. },
  14248. {
  14249. name: "name",
  14250. isAttr: true,
  14251. type: "String"
  14252. }
  14253. ]
  14254. },
  14255. {
  14256. name: "ResourceParameterBinding",
  14257. properties: [
  14258. {
  14259. name: "expression",
  14260. type: "Expression",
  14261. xml: {
  14262. serialize: "xsi:type"
  14263. }
  14264. },
  14265. {
  14266. name: "parameterRef",
  14267. type: "ResourceParameter",
  14268. isAttr: true,
  14269. isReference: true
  14270. }
  14271. ],
  14272. superClass: [
  14273. "BaseElement"
  14274. ]
  14275. },
  14276. {
  14277. name: "ResourceAssignmentExpression",
  14278. properties: [
  14279. {
  14280. name: "expression",
  14281. type: "Expression",
  14282. xml: {
  14283. serialize: "xsi:type"
  14284. }
  14285. }
  14286. ],
  14287. superClass: [
  14288. "BaseElement"
  14289. ]
  14290. },
  14291. {
  14292. name: "Import",
  14293. properties: [
  14294. {
  14295. name: "importType",
  14296. isAttr: true,
  14297. type: "String"
  14298. },
  14299. {
  14300. name: "location",
  14301. isAttr: true,
  14302. type: "String"
  14303. },
  14304. {
  14305. name: "namespace",
  14306. isAttr: true,
  14307. type: "String"
  14308. }
  14309. ]
  14310. },
  14311. {
  14312. name: "Definitions",
  14313. superClass: [
  14314. "BaseElement"
  14315. ],
  14316. properties: [
  14317. {
  14318. name: "name",
  14319. isAttr: true,
  14320. type: "String"
  14321. },
  14322. {
  14323. name: "targetNamespace",
  14324. isAttr: true,
  14325. type: "String"
  14326. },
  14327. {
  14328. name: "expressionLanguage",
  14329. "default": "http://www.w3.org/1999/XPath",
  14330. isAttr: true,
  14331. type: "String"
  14332. },
  14333. {
  14334. name: "typeLanguage",
  14335. "default": "http://www.w3.org/2001/XMLSchema",
  14336. isAttr: true,
  14337. type: "String"
  14338. },
  14339. {
  14340. name: "imports",
  14341. type: "Import",
  14342. isMany: true
  14343. },
  14344. {
  14345. name: "extensions",
  14346. type: "Extension",
  14347. isMany: true
  14348. },
  14349. {
  14350. name: "rootElements",
  14351. type: "RootElement",
  14352. isMany: true
  14353. },
  14354. {
  14355. name: "diagrams",
  14356. isMany: true,
  14357. type: "bpmndi:BPMNDiagram"
  14358. },
  14359. {
  14360. name: "exporter",
  14361. isAttr: true,
  14362. type: "String"
  14363. },
  14364. {
  14365. name: "relationships",
  14366. type: "Relationship",
  14367. isMany: true
  14368. },
  14369. {
  14370. name: "exporterVersion",
  14371. isAttr: true,
  14372. type: "String"
  14373. }
  14374. ]
  14375. }
  14376. ];
  14377. var enumerations = [
  14378. {
  14379. name: "ProcessType",
  14380. literalValues: [
  14381. {
  14382. name: "None"
  14383. },
  14384. {
  14385. name: "Public"
  14386. },
  14387. {
  14388. name: "Private"
  14389. }
  14390. ]
  14391. },
  14392. {
  14393. name: "GatewayDirection",
  14394. literalValues: [
  14395. {
  14396. name: "Unspecified"
  14397. },
  14398. {
  14399. name: "Converging"
  14400. },
  14401. {
  14402. name: "Diverging"
  14403. },
  14404. {
  14405. name: "Mixed"
  14406. }
  14407. ]
  14408. },
  14409. {
  14410. name: "EventBasedGatewayType",
  14411. literalValues: [
  14412. {
  14413. name: "Parallel"
  14414. },
  14415. {
  14416. name: "Exclusive"
  14417. }
  14418. ]
  14419. },
  14420. {
  14421. name: "RelationshipDirection",
  14422. literalValues: [
  14423. {
  14424. name: "None"
  14425. },
  14426. {
  14427. name: "Forward"
  14428. },
  14429. {
  14430. name: "Backward"
  14431. },
  14432. {
  14433. name: "Both"
  14434. }
  14435. ]
  14436. },
  14437. {
  14438. name: "ItemKind",
  14439. literalValues: [
  14440. {
  14441. name: "Physical"
  14442. },
  14443. {
  14444. name: "Information"
  14445. }
  14446. ]
  14447. },
  14448. {
  14449. name: "ChoreographyLoopType",
  14450. literalValues: [
  14451. {
  14452. name: "None"
  14453. },
  14454. {
  14455. name: "Standard"
  14456. },
  14457. {
  14458. name: "MultiInstanceSequential"
  14459. },
  14460. {
  14461. name: "MultiInstanceParallel"
  14462. }
  14463. ]
  14464. },
  14465. {
  14466. name: "AssociationDirection",
  14467. literalValues: [
  14468. {
  14469. name: "None"
  14470. },
  14471. {
  14472. name: "One"
  14473. },
  14474. {
  14475. name: "Both"
  14476. }
  14477. ]
  14478. },
  14479. {
  14480. name: "MultiInstanceBehavior",
  14481. literalValues: [
  14482. {
  14483. name: "None"
  14484. },
  14485. {
  14486. name: "One"
  14487. },
  14488. {
  14489. name: "All"
  14490. },
  14491. {
  14492. name: "Complex"
  14493. }
  14494. ]
  14495. },
  14496. {
  14497. name: "AdHocOrdering",
  14498. literalValues: [
  14499. {
  14500. name: "Parallel"
  14501. },
  14502. {
  14503. name: "Sequential"
  14504. }
  14505. ]
  14506. }
  14507. ];
  14508. var xml = {
  14509. tagAlias: "lowerCase",
  14510. typePrefix: "t"
  14511. };
  14512. var BpmnPackage = {
  14513. name: name,
  14514. uri: uri,
  14515. prefix: prefix$1,
  14516. associations: associations,
  14517. types: types$1,
  14518. enumerations: enumerations,
  14519. xml: xml
  14520. };
  14521. var name$1 = "BPMNDI";
  14522. var uri$1 = "http://www.omg.org/spec/BPMN/20100524/DI";
  14523. var prefix$1$1 = "bpmndi";
  14524. var types$1$1 = [
  14525. {
  14526. name: "BPMNDiagram",
  14527. properties: [
  14528. {
  14529. name: "plane",
  14530. type: "BPMNPlane",
  14531. redefines: "di:Diagram#rootElement"
  14532. },
  14533. {
  14534. name: "labelStyle",
  14535. type: "BPMNLabelStyle",
  14536. isMany: true
  14537. }
  14538. ],
  14539. superClass: [
  14540. "di:Diagram"
  14541. ]
  14542. },
  14543. {
  14544. name: "BPMNPlane",
  14545. properties: [
  14546. {
  14547. name: "bpmnElement",
  14548. isAttr: true,
  14549. isReference: true,
  14550. type: "bpmn:BaseElement",
  14551. redefines: "di:DiagramElement#modelElement"
  14552. }
  14553. ],
  14554. superClass: [
  14555. "di:Plane"
  14556. ]
  14557. },
  14558. {
  14559. name: "BPMNShape",
  14560. properties: [
  14561. {
  14562. name: "bpmnElement",
  14563. isAttr: true,
  14564. isReference: true,
  14565. type: "bpmn:BaseElement",
  14566. redefines: "di:DiagramElement#modelElement"
  14567. },
  14568. {
  14569. name: "isHorizontal",
  14570. isAttr: true,
  14571. type: "Boolean"
  14572. },
  14573. {
  14574. name: "isExpanded",
  14575. isAttr: true,
  14576. type: "Boolean"
  14577. },
  14578. {
  14579. name: "isMarkerVisible",
  14580. isAttr: true,
  14581. type: "Boolean"
  14582. },
  14583. {
  14584. name: "label",
  14585. type: "BPMNLabel"
  14586. },
  14587. {
  14588. name: "isMessageVisible",
  14589. isAttr: true,
  14590. type: "Boolean"
  14591. },
  14592. {
  14593. name: "participantBandKind",
  14594. type: "ParticipantBandKind",
  14595. isAttr: true
  14596. },
  14597. {
  14598. name: "choreographyActivityShape",
  14599. type: "BPMNShape",
  14600. isAttr: true,
  14601. isReference: true
  14602. }
  14603. ],
  14604. superClass: [
  14605. "di:LabeledShape"
  14606. ]
  14607. },
  14608. {
  14609. name: "BPMNEdge",
  14610. properties: [
  14611. {
  14612. name: "label",
  14613. type: "BPMNLabel"
  14614. },
  14615. {
  14616. name: "bpmnElement",
  14617. isAttr: true,
  14618. isReference: true,
  14619. type: "bpmn:BaseElement",
  14620. redefines: "di:DiagramElement#modelElement"
  14621. },
  14622. {
  14623. name: "sourceElement",
  14624. isAttr: true,
  14625. isReference: true,
  14626. type: "di:DiagramElement",
  14627. redefines: "di:Edge#source"
  14628. },
  14629. {
  14630. name: "targetElement",
  14631. isAttr: true,
  14632. isReference: true,
  14633. type: "di:DiagramElement",
  14634. redefines: "di:Edge#target"
  14635. },
  14636. {
  14637. name: "messageVisibleKind",
  14638. type: "MessageVisibleKind",
  14639. isAttr: true,
  14640. "default": "initiating"
  14641. }
  14642. ],
  14643. superClass: [
  14644. "di:LabeledEdge"
  14645. ]
  14646. },
  14647. {
  14648. name: "BPMNLabel",
  14649. properties: [
  14650. {
  14651. name: "labelStyle",
  14652. type: "BPMNLabelStyle",
  14653. isAttr: true,
  14654. isReference: true,
  14655. redefines: "di:DiagramElement#style"
  14656. }
  14657. ],
  14658. superClass: [
  14659. "di:Label"
  14660. ]
  14661. },
  14662. {
  14663. name: "BPMNLabelStyle",
  14664. properties: [
  14665. {
  14666. name: "font",
  14667. type: "dc:Font"
  14668. }
  14669. ],
  14670. superClass: [
  14671. "di:Style"
  14672. ]
  14673. }
  14674. ];
  14675. var enumerations$1 = [
  14676. {
  14677. name: "ParticipantBandKind",
  14678. literalValues: [
  14679. {
  14680. name: "top_initiating"
  14681. },
  14682. {
  14683. name: "middle_initiating"
  14684. },
  14685. {
  14686. name: "bottom_initiating"
  14687. },
  14688. {
  14689. name: "top_non_initiating"
  14690. },
  14691. {
  14692. name: "middle_non_initiating"
  14693. },
  14694. {
  14695. name: "bottom_non_initiating"
  14696. }
  14697. ]
  14698. },
  14699. {
  14700. name: "MessageVisibleKind",
  14701. literalValues: [
  14702. {
  14703. name: "initiating"
  14704. },
  14705. {
  14706. name: "non_initiating"
  14707. }
  14708. ]
  14709. }
  14710. ];
  14711. var associations$1 = [];
  14712. var BpmnDiPackage = {
  14713. name: name$1,
  14714. uri: uri$1,
  14715. prefix: prefix$1$1,
  14716. types: types$1$1,
  14717. enumerations: enumerations$1,
  14718. associations: associations$1
  14719. };
  14720. var name$2 = "DC";
  14721. var uri$2 = "http://www.omg.org/spec/DD/20100524/DC";
  14722. var prefix$2 = "dc";
  14723. var types$2 = [
  14724. {
  14725. name: "Boolean"
  14726. },
  14727. {
  14728. name: "Integer"
  14729. },
  14730. {
  14731. name: "Real"
  14732. },
  14733. {
  14734. name: "String"
  14735. },
  14736. {
  14737. name: "Font",
  14738. properties: [
  14739. {
  14740. name: "name",
  14741. type: "String",
  14742. isAttr: true
  14743. },
  14744. {
  14745. name: "size",
  14746. type: "Real",
  14747. isAttr: true
  14748. },
  14749. {
  14750. name: "isBold",
  14751. type: "Boolean",
  14752. isAttr: true
  14753. },
  14754. {
  14755. name: "isItalic",
  14756. type: "Boolean",
  14757. isAttr: true
  14758. },
  14759. {
  14760. name: "isUnderline",
  14761. type: "Boolean",
  14762. isAttr: true
  14763. },
  14764. {
  14765. name: "isStrikeThrough",
  14766. type: "Boolean",
  14767. isAttr: true
  14768. }
  14769. ]
  14770. },
  14771. {
  14772. name: "Point",
  14773. properties: [
  14774. {
  14775. name: "x",
  14776. type: "Real",
  14777. "default": "0",
  14778. isAttr: true
  14779. },
  14780. {
  14781. name: "y",
  14782. type: "Real",
  14783. "default": "0",
  14784. isAttr: true
  14785. }
  14786. ]
  14787. },
  14788. {
  14789. name: "Bounds",
  14790. properties: [
  14791. {
  14792. name: "x",
  14793. type: "Real",
  14794. "default": "0",
  14795. isAttr: true
  14796. },
  14797. {
  14798. name: "y",
  14799. type: "Real",
  14800. "default": "0",
  14801. isAttr: true
  14802. },
  14803. {
  14804. name: "width",
  14805. type: "Real",
  14806. isAttr: true
  14807. },
  14808. {
  14809. name: "height",
  14810. type: "Real",
  14811. isAttr: true
  14812. }
  14813. ]
  14814. }
  14815. ];
  14816. var associations$2 = [];
  14817. var DcPackage = {
  14818. name: name$2,
  14819. uri: uri$2,
  14820. prefix: prefix$2,
  14821. types: types$2,
  14822. associations: associations$2
  14823. };
  14824. var name$3 = "DI";
  14825. var uri$3 = "http://www.omg.org/spec/DD/20100524/DI";
  14826. var prefix$3 = "di";
  14827. var types$3 = [
  14828. {
  14829. name: "DiagramElement",
  14830. isAbstract: true,
  14831. properties: [
  14832. {
  14833. name: "id",
  14834. isAttr: true,
  14835. isId: true,
  14836. type: "String"
  14837. },
  14838. {
  14839. name: "extension",
  14840. type: "Extension"
  14841. },
  14842. {
  14843. name: "owningDiagram",
  14844. type: "Diagram",
  14845. isReadOnly: true,
  14846. isVirtual: true,
  14847. isReference: true
  14848. },
  14849. {
  14850. name: "owningElement",
  14851. type: "DiagramElement",
  14852. isReadOnly: true,
  14853. isVirtual: true,
  14854. isReference: true
  14855. },
  14856. {
  14857. name: "modelElement",
  14858. isReadOnly: true,
  14859. isVirtual: true,
  14860. isReference: true,
  14861. type: "Element"
  14862. },
  14863. {
  14864. name: "style",
  14865. type: "Style",
  14866. isReadOnly: true,
  14867. isVirtual: true,
  14868. isReference: true
  14869. },
  14870. {
  14871. name: "ownedElement",
  14872. type: "DiagramElement",
  14873. isReadOnly: true,
  14874. isMany: true,
  14875. isVirtual: true
  14876. }
  14877. ]
  14878. },
  14879. {
  14880. name: "Node",
  14881. isAbstract: true,
  14882. superClass: [
  14883. "DiagramElement"
  14884. ]
  14885. },
  14886. {
  14887. name: "Edge",
  14888. isAbstract: true,
  14889. superClass: [
  14890. "DiagramElement"
  14891. ],
  14892. properties: [
  14893. {
  14894. name: "source",
  14895. type: "DiagramElement",
  14896. isReadOnly: true,
  14897. isVirtual: true,
  14898. isReference: true
  14899. },
  14900. {
  14901. name: "target",
  14902. type: "DiagramElement",
  14903. isReadOnly: true,
  14904. isVirtual: true,
  14905. isReference: true
  14906. },
  14907. {
  14908. name: "waypoint",
  14909. isUnique: false,
  14910. isMany: true,
  14911. type: "dc:Point",
  14912. xml: {
  14913. serialize: "xsi:type"
  14914. }
  14915. }
  14916. ]
  14917. },
  14918. {
  14919. name: "Diagram",
  14920. isAbstract: true,
  14921. properties: [
  14922. {
  14923. name: "id",
  14924. isAttr: true,
  14925. isId: true,
  14926. type: "String"
  14927. },
  14928. {
  14929. name: "rootElement",
  14930. type: "DiagramElement",
  14931. isReadOnly: true,
  14932. isVirtual: true
  14933. },
  14934. {
  14935. name: "name",
  14936. isAttr: true,
  14937. type: "String"
  14938. },
  14939. {
  14940. name: "documentation",
  14941. isAttr: true,
  14942. type: "String"
  14943. },
  14944. {
  14945. name: "resolution",
  14946. isAttr: true,
  14947. type: "Real"
  14948. },
  14949. {
  14950. name: "ownedStyle",
  14951. type: "Style",
  14952. isReadOnly: true,
  14953. isMany: true,
  14954. isVirtual: true
  14955. }
  14956. ]
  14957. },
  14958. {
  14959. name: "Shape",
  14960. isAbstract: true,
  14961. superClass: [
  14962. "Node"
  14963. ],
  14964. properties: [
  14965. {
  14966. name: "bounds",
  14967. type: "dc:Bounds"
  14968. }
  14969. ]
  14970. },
  14971. {
  14972. name: "Plane",
  14973. isAbstract: true,
  14974. superClass: [
  14975. "Node"
  14976. ],
  14977. properties: [
  14978. {
  14979. name: "planeElement",
  14980. type: "DiagramElement",
  14981. subsettedProperty: "DiagramElement-ownedElement",
  14982. isMany: true
  14983. }
  14984. ]
  14985. },
  14986. {
  14987. name: "LabeledEdge",
  14988. isAbstract: true,
  14989. superClass: [
  14990. "Edge"
  14991. ],
  14992. properties: [
  14993. {
  14994. name: "ownedLabel",
  14995. type: "Label",
  14996. isReadOnly: true,
  14997. subsettedProperty: "DiagramElement-ownedElement",
  14998. isMany: true,
  14999. isVirtual: true
  15000. }
  15001. ]
  15002. },
  15003. {
  15004. name: "LabeledShape",
  15005. isAbstract: true,
  15006. superClass: [
  15007. "Shape"
  15008. ],
  15009. properties: [
  15010. {
  15011. name: "ownedLabel",
  15012. type: "Label",
  15013. isReadOnly: true,
  15014. subsettedProperty: "DiagramElement-ownedElement",
  15015. isMany: true,
  15016. isVirtual: true
  15017. }
  15018. ]
  15019. },
  15020. {
  15021. name: "Label",
  15022. isAbstract: true,
  15023. superClass: [
  15024. "Node"
  15025. ],
  15026. properties: [
  15027. {
  15028. name: "bounds",
  15029. type: "dc:Bounds"
  15030. }
  15031. ]
  15032. },
  15033. {
  15034. name: "Style",
  15035. isAbstract: true,
  15036. properties: [
  15037. {
  15038. name: "id",
  15039. isAttr: true,
  15040. isId: true,
  15041. type: "String"
  15042. }
  15043. ]
  15044. },
  15045. {
  15046. name: "Extension",
  15047. properties: [
  15048. {
  15049. name: "values",
  15050. isMany: true,
  15051. type: "Element"
  15052. }
  15053. ]
  15054. }
  15055. ];
  15056. var associations$3 = [];
  15057. var xml$1 = {
  15058. tagAlias: "lowerCase"
  15059. };
  15060. var DiPackage = {
  15061. name: name$3,
  15062. uri: uri$3,
  15063. prefix: prefix$3,
  15064. types: types$3,
  15065. associations: associations$3,
  15066. xml: xml$1
  15067. };
  15068. var name$4 = "bpmn.io colors for BPMN";
  15069. var uri$4 = "http://bpmn.io/schema/bpmn/biocolor/1.0";
  15070. var prefix$4 = "bioc";
  15071. var types$4 = [
  15072. {
  15073. name: "ColoredShape",
  15074. "extends": [
  15075. "bpmndi:BPMNShape"
  15076. ],
  15077. properties: [
  15078. {
  15079. name: "stroke",
  15080. isAttr: true,
  15081. type: "String"
  15082. },
  15083. {
  15084. name: "fill",
  15085. isAttr: true,
  15086. type: "String"
  15087. }
  15088. ]
  15089. },
  15090. {
  15091. name: "ColoredEdge",
  15092. "extends": [
  15093. "bpmndi:BPMNEdge"
  15094. ],
  15095. properties: [
  15096. {
  15097. name: "stroke",
  15098. isAttr: true,
  15099. type: "String"
  15100. },
  15101. {
  15102. name: "fill",
  15103. isAttr: true,
  15104. type: "String"
  15105. }
  15106. ]
  15107. }
  15108. ];
  15109. var enumerations$2 = [];
  15110. var associations$4 = [];
  15111. var BiocPackage = {
  15112. name: name$4,
  15113. uri: uri$4,
  15114. prefix: prefix$4,
  15115. types: types$4,
  15116. enumerations: enumerations$2,
  15117. associations: associations$4
  15118. };
  15119. var packages = {
  15120. bpmn: BpmnPackage,
  15121. bpmndi: BpmnDiPackage,
  15122. dc: DcPackage,
  15123. di: DiPackage,
  15124. bioc: BiocPackage
  15125. };
  15126. function simple(additionalPackages, options) {
  15127. var pks = assign({}, packages, additionalPackages);
  15128. return new BpmnModdle(pks, options);
  15129. }
  15130. var diRefs = new objectRefs(
  15131. {name: 'bpmnElement', enumerable: true},
  15132. {name: 'di', configurable: true}
  15133. );
  15134. /**
  15135. * Returns true if an element has the given meta-model type
  15136. *
  15137. * @param {ModdleElement} element
  15138. * @param {string} type
  15139. *
  15140. * @return {boolean}
  15141. */
  15142. function is$1(element, type) {
  15143. return element.$instanceOf(type);
  15144. }
  15145. /**
  15146. * Find a suitable display candidate for definitions where the DI does not
  15147. * correctly specify one.
  15148. */
  15149. function findDisplayCandidate(definitions) {
  15150. return find(definitions.rootElements, function (e) {
  15151. return is$1(e, 'bpmn:Process') || is$1(e, 'bpmn:Collaboration');
  15152. });
  15153. }
  15154. function BpmnTreeWalker(handler, translate) {
  15155. // list of containers already walked
  15156. var handledElements = {};
  15157. // list of elements to handle deferred to ensure
  15158. // prerequisites are drawn
  15159. var deferred = [];
  15160. // Helpers //////////////////////
  15161. function contextual(fn, ctx) {
  15162. return function (e) {
  15163. fn(e, ctx);
  15164. };
  15165. }
  15166. function handled(element) {
  15167. handledElements[element.id] = element;
  15168. }
  15169. function isHandled(element) {
  15170. return handledElements[element.id];
  15171. }
  15172. function visit(element, ctx) {
  15173. var gfx = element.gfx;
  15174. // avoid multiple rendering of elements
  15175. if (gfx) {
  15176. throw new Error(
  15177. translate('already rendered {element}', {element: elementToString(element)})
  15178. );
  15179. }
  15180. // call handler
  15181. return handler.element(element, ctx);
  15182. }
  15183. function visitRoot(element, diagram) {
  15184. return handler.root(element, diagram);
  15185. }
  15186. function visitIfDi(element, ctx) {
  15187. try {
  15188. var gfx = element.di && visit(element, ctx);
  15189. handled(element);
  15190. return gfx;
  15191. } catch (e) {
  15192. logError(e.message, {element: element, error: e});
  15193. console.error(translate('failed to import {element}', {element: elementToString(element)}));
  15194. console.error(e);
  15195. }
  15196. }
  15197. function logError(message, context) {
  15198. handler.error(message, context);
  15199. }
  15200. // DI handling //////////////////////
  15201. function registerDi(di) {
  15202. var bpmnElement = di.bpmnElement;
  15203. if (bpmnElement) {
  15204. if (bpmnElement.di) {
  15205. logError(
  15206. translate('multiple DI elements defined for {element}', {
  15207. element: elementToString(bpmnElement)
  15208. }),
  15209. {element: bpmnElement}
  15210. );
  15211. } else {
  15212. diRefs.bind(bpmnElement, 'di');
  15213. bpmnElement.di = di;
  15214. }
  15215. } else {
  15216. logError(
  15217. translate('no bpmnElement referenced in {element}', {
  15218. element: elementToString(di)
  15219. }),
  15220. {element: di}
  15221. );
  15222. }
  15223. }
  15224. function handleDiagram(diagram) {
  15225. handlePlane(diagram.plane);
  15226. }
  15227. function handlePlane(plane) {
  15228. registerDi(plane);
  15229. forEach(plane.planeElement, handlePlaneElement);
  15230. }
  15231. function handlePlaneElement(planeElement) {
  15232. registerDi(planeElement);
  15233. }
  15234. // Semantic handling //////////////////////
  15235. /**
  15236. * Handle definitions and return the rendered diagram (if any)
  15237. *
  15238. * @param {ModdleElement} definitions to walk and import
  15239. * @param {ModdleElement} [diagram] specific diagram to import and display
  15240. *
  15241. * @throws {Error} if no diagram to display could be found
  15242. */
  15243. function handleDefinitions(definitions, diagram) {
  15244. // make sure we walk the correct bpmnElement
  15245. var diagrams = definitions.diagrams;
  15246. if (diagram && diagrams.indexOf(diagram) === -1) {
  15247. throw new Error(translate('diagram not part of bpmn:Definitions'));
  15248. }
  15249. if (!diagram && diagrams && diagrams.length) {
  15250. diagram = diagrams[0];
  15251. }
  15252. // no diagram -> nothing to import
  15253. if (!diagram) {
  15254. throw new Error(translate('no diagram to display'));
  15255. }
  15256. // load DI from selected diagram only
  15257. handleDiagram(diagram);
  15258. var plane = diagram.plane;
  15259. if (!plane) {
  15260. throw new Error(translate(
  15261. 'no plane for {element}',
  15262. {element: elementToString(diagram)}
  15263. ));
  15264. }
  15265. var rootElement = plane.bpmnElement;
  15266. // ensure we default to a suitable display candidate (process or collaboration),
  15267. // even if non is specified in DI
  15268. if (!rootElement) {
  15269. rootElement = findDisplayCandidate(definitions);
  15270. if (!rootElement) {
  15271. throw new Error(translate('no process or collaboration to display'));
  15272. } else {
  15273. logError(
  15274. translate('correcting missing bpmnElement on {plane} to {rootElement}', {
  15275. plane: elementToString(plane),
  15276. rootElement: elementToString(rootElement)
  15277. })
  15278. );
  15279. // correct DI on the fly
  15280. plane.bpmnElement = rootElement;
  15281. registerDi(plane);
  15282. }
  15283. }
  15284. var ctx = visitRoot(rootElement, plane);
  15285. if (is$1(rootElement, 'bpmn:Process')) {
  15286. handleProcess(rootElement, ctx);
  15287. } else if (is$1(rootElement, 'bpmn:Collaboration')) {
  15288. handleCollaboration(rootElement);
  15289. // force drawing of everything not yet drawn that is part of the target DI
  15290. handleUnhandledProcesses(definitions.rootElements, ctx);
  15291. } else {
  15292. throw new Error(
  15293. translate('unsupported bpmnElement for {plane}: {rootElement}', {
  15294. plane: elementToString(plane),
  15295. rootElement: elementToString(rootElement)
  15296. })
  15297. );
  15298. }
  15299. // handle all deferred elements
  15300. handleDeferred();
  15301. }
  15302. function handleDeferred() {
  15303. var fn;
  15304. // drain deferred until empty
  15305. while (deferred.length) {
  15306. fn = deferred.shift();
  15307. fn();
  15308. }
  15309. }
  15310. function handleProcess(process, context) {
  15311. handleFlowElementsContainer(process, context);
  15312. handleIoSpecification(process.ioSpecification, context);
  15313. handleArtifacts(process.artifacts, context);
  15314. // log process handled
  15315. handled(process);
  15316. }
  15317. function handleUnhandledProcesses(rootElements, ctx) {
  15318. // walk through all processes that have not yet been drawn and draw them
  15319. // if they contain lanes with DI information.
  15320. // we do this to pass the free-floating lane test cases in the MIWG test suite
  15321. var processes = filter(rootElements, function (e) {
  15322. return !isHandled(e) && is$1(e, 'bpmn:Process') && e.laneSets;
  15323. });
  15324. processes.forEach(contextual(handleProcess, ctx));
  15325. }
  15326. function handleMessageFlow(messageFlow, context) {
  15327. visitIfDi(messageFlow, context);
  15328. }
  15329. function handleMessageFlows(messageFlows, context) {
  15330. forEach(messageFlows, contextual(handleMessageFlow, context));
  15331. }
  15332. function handleDataAssociation(association, context) {
  15333. visitIfDi(association, context);
  15334. }
  15335. function handleDataInput(dataInput, context) {
  15336. visitIfDi(dataInput, context);
  15337. }
  15338. function handleDataOutput(dataOutput, context) {
  15339. visitIfDi(dataOutput, context);
  15340. }
  15341. function handleArtifact(artifact, context) {
  15342. // bpmn:TextAnnotation
  15343. // bpmn:Group
  15344. // bpmn:Association
  15345. visitIfDi(artifact, context);
  15346. }
  15347. function handleArtifacts(artifacts, context) {
  15348. forEach(artifacts, function (e) {
  15349. if (is$1(e, 'bpmn:Association')) {
  15350. deferred.push(function () {
  15351. handleArtifact(e, context);
  15352. });
  15353. } else {
  15354. handleArtifact(e, context);
  15355. }
  15356. });
  15357. }
  15358. function handleIoSpecification(ioSpecification, context) {
  15359. if (!ioSpecification) {
  15360. return;
  15361. }
  15362. forEach(ioSpecification.dataInputs, contextual(handleDataInput, context));
  15363. forEach(ioSpecification.dataOutputs, contextual(handleDataOutput, context));
  15364. }
  15365. function handleSubProcess(subProcess, context) {
  15366. handleFlowElementsContainer(subProcess, context);
  15367. handleArtifacts(subProcess.artifacts, context);
  15368. }
  15369. function handleFlowNode(flowNode, context) {
  15370. var childCtx = visitIfDi(flowNode, context);
  15371. if (is$1(flowNode, 'bpmn:SubProcess')) {
  15372. handleSubProcess(flowNode, childCtx || context);
  15373. }
  15374. if (is$1(flowNode, 'bpmn:Activity')) {
  15375. handleIoSpecification(flowNode.ioSpecification, context);
  15376. }
  15377. // defer handling of associations
  15378. // affected types:
  15379. //
  15380. // * bpmn:Activity
  15381. // * bpmn:ThrowEvent
  15382. // * bpmn:CatchEvent
  15383. //
  15384. deferred.push(function () {
  15385. forEach(flowNode.dataInputAssociations, contextual(handleDataAssociation, context));
  15386. forEach(flowNode.dataOutputAssociations, contextual(handleDataAssociation, context));
  15387. });
  15388. }
  15389. function handleSequenceFlow(sequenceFlow, context) {
  15390. visitIfDi(sequenceFlow, context);
  15391. }
  15392. function handleDataElement(dataObject, context) {
  15393. visitIfDi(dataObject, context);
  15394. }
  15395. function handleLane(lane, context) {
  15396. deferred.push(function () {
  15397. var newContext = visitIfDi(lane, context);
  15398. if (lane.childLaneSet) {
  15399. handleLaneSet(lane.childLaneSet, newContext || context);
  15400. }
  15401. wireFlowNodeRefs(lane);
  15402. });
  15403. }
  15404. function handleLaneSet(laneSet, context) {
  15405. forEach(laneSet.lanes, contextual(handleLane, context));
  15406. }
  15407. function handleLaneSets(laneSets, context) {
  15408. forEach(laneSets, contextual(handleLaneSet, context));
  15409. }
  15410. function handleFlowElementsContainer(container, context) {
  15411. handleFlowElements(container.flowElements, context);
  15412. if (container.laneSets) {
  15413. handleLaneSets(container.laneSets, context);
  15414. }
  15415. }
  15416. function handleFlowElements(flowElements, context) {
  15417. forEach(flowElements, function (e) {
  15418. if (is$1(e, 'bpmn:SequenceFlow')) {
  15419. deferred.push(function () {
  15420. handleSequenceFlow(e, context);
  15421. });
  15422. } else if (is$1(e, 'bpmn:BoundaryEvent')) {
  15423. deferred.unshift(function () {
  15424. handleFlowNode(e, context);
  15425. });
  15426. } else if (is$1(e, 'bpmn:FlowNode')) {
  15427. handleFlowNode(e, context);
  15428. } else if (is$1(e, 'bpmn:DataObject')) ; else if (is$1(e, 'bpmn:DataStoreReference')) {
  15429. handleDataElement(e, context);
  15430. } else if (is$1(e, 'bpmn:DataObjectReference')) {
  15431. handleDataElement(e, context);
  15432. } else {
  15433. logError(
  15434. translate('unrecognized flowElement {element} in context {context}', {
  15435. element: elementToString(e),
  15436. context: (context ? elementToString(context.businessObject) : 'null')
  15437. }),
  15438. {element: e, context: context}
  15439. );
  15440. }
  15441. });
  15442. }
  15443. function handleParticipant(participant, context) {
  15444. var newCtx = visitIfDi(participant, context);
  15445. var process = participant.processRef;
  15446. if (process) {
  15447. handleProcess(process, newCtx || context);
  15448. }
  15449. }
  15450. function handleCollaboration(collaboration) {
  15451. forEach(collaboration.participants, contextual(handleParticipant));
  15452. handleArtifacts(collaboration.artifacts);
  15453. // handle message flows latest in the process
  15454. deferred.push(function () {
  15455. handleMessageFlows(collaboration.messageFlows);
  15456. });
  15457. }
  15458. function wireFlowNodeRefs(lane) {
  15459. // wire the virtual flowNodeRefs <-> relationship
  15460. forEach(lane.flowNodeRef, function (flowNode) {
  15461. var lanes = flowNode.get('lanes');
  15462. if (lanes) {
  15463. lanes.push(lane);
  15464. }
  15465. });
  15466. }
  15467. // API //////////////////////
  15468. return {
  15469. handleDeferred: handleDeferred,
  15470. handleDefinitions: handleDefinitions,
  15471. handleSubProcess: handleSubProcess,
  15472. registerDi: registerDi
  15473. };
  15474. }
  15475. /**
  15476. * Import the definitions into a diagram.
  15477. *
  15478. * Errors and warnings are reported through the specified callback.
  15479. *
  15480. * @param {djs.Diagram} diagram
  15481. * @param {ModdleElement<Definitions>} definitions
  15482. * @param {ModdleElement<BPMNDiagram>} [bpmnDiagram] the diagram to be rendered
  15483. * (if not provided, the first one will be rendered)
  15484. * @param {Function} done the callback, invoked with (err, [ warning ]) once the import is done
  15485. */
  15486. function importBpmnDiagram(diagram, definitions, bpmnDiagram, done) {
  15487. if (isFunction(bpmnDiagram)) {
  15488. done = bpmnDiagram;
  15489. bpmnDiagram = null;
  15490. }
  15491. var importer,
  15492. eventBus,
  15493. translate;
  15494. var error,
  15495. warnings = [];
  15496. /**
  15497. * Walk the diagram semantically, importing (=drawing)
  15498. * all elements you encounter.
  15499. *
  15500. * @param {ModdleElement<Definitions>} definitions
  15501. * @param {ModdleElement<BPMNDiagram>} bpmnDiagram
  15502. */
  15503. function render(definitions, bpmnDiagram) {
  15504. var visitor = {
  15505. root: function (element) {
  15506. return importer.add(element);
  15507. },
  15508. element: function (element, parentShape) {
  15509. return importer.add(element, parentShape);
  15510. },
  15511. error: function (message, context) {
  15512. warnings.push({message: message, context: context});
  15513. }
  15514. };
  15515. var walker = new BpmnTreeWalker(visitor, translate);
  15516. // traverse BPMN 2.0 document model,
  15517. // starting at definitions
  15518. walker.handleDefinitions(definitions, bpmnDiagram);
  15519. }
  15520. try {
  15521. importer = diagram.get('bpmnImporter');
  15522. eventBus = diagram.get('eventBus');
  15523. translate = diagram.get('translate');
  15524. eventBus.fire('import.render.start', {definitions: definitions});
  15525. render(definitions, bpmnDiagram);
  15526. eventBus.fire('import.render.complete', {
  15527. error: error,
  15528. warnings: warnings
  15529. });
  15530. } catch (e) {
  15531. error = e;
  15532. }
  15533. done(error, warnings);
  15534. }
  15535. /**
  15536. * This file must not be changed or exchanged.
  15537. *
  15538. * @see http://bpmn.io/license for more information.
  15539. */
  15540. // inlined ../../resources/logo.svg
  15541. var BPMNIO_LOGO_SVG = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 960 960"><path fill="#fff" d="M960 60v839c0 33-27 61-60 61H60c-33 0-60-27-60-60V60C0 27 27 0 60 0h839c34 0 61 27 61 60z"/><path fill="#52b415" d="M217 548a205 205 0 0 0-144 58 202 202 0 0 0-4 286 202 202 0 0 0 285 3 200 200 0 0 0 48-219 203 203 0 0 0-185-128zM752 6a206 206 0 0 0-192 285 206 206 0 0 0 269 111 207 207 0 0 0 111-260A204 204 0 0 0 752 6zM62 0A62 62 0 0 0 0 62v398l60 46a259 259 0 0 1 89-36c5-28 10-57 14-85l99 2 12 85a246 246 0 0 1 88 38l70-52 69 71-52 68c17 30 29 58 35 90l86 14-2 100-86 12a240 240 0 0 1-38 89l43 58h413c37 0 60-27 60-61V407a220 220 0 0 1-44 40l21 85-93 39-45-76a258 258 0 0 1-98 1l-45 76-94-39 22-85a298 298 0 0 1-70-69l-86 22-38-94 76-45a258 258 0 0 1-1-98l-76-45 40-94 85 22a271 271 0 0 1 41-47z"/></svg>';
  15542. var BPMNIO_LOGO_URL = 'data:image/svg+xml,' + encodeURIComponent(BPMNIO_LOGO_SVG);
  15543. var BPMNIO_IMG = '<img width="52" height="52" src="' + BPMNIO_LOGO_URL + '" />';
  15544. function css(attrs) {
  15545. return attrs.join(';');
  15546. }
  15547. var LIGHTBOX_STYLES = css([
  15548. 'z-index: 1001',
  15549. 'position: fixed',
  15550. 'top: 0',
  15551. 'left: 0',
  15552. 'right: 0',
  15553. 'bottom: 0'
  15554. ]);
  15555. var BACKDROP_STYLES = css([
  15556. 'width: 100%',
  15557. 'height: 100%',
  15558. 'background: rgba(0,0,0,0.2)'
  15559. ]);
  15560. var NOTICE_STYLES = css([
  15561. 'position: absolute',
  15562. 'left: 50%',
  15563. 'top: 40%',
  15564. 'margin: 0 -130px',
  15565. 'width: 260px',
  15566. 'padding: 10px',
  15567. 'background: white',
  15568. 'border: solid 1px #AAA',
  15569. 'border-radius: 3px',
  15570. 'font-family: Helvetica, Arial, sans-serif',
  15571. 'font-size: 14px',
  15572. 'line-height: 1.2em'
  15573. ]);
  15574. var LIGHTBOX_MARKUP =
  15575. '<div class="bjs-powered-by-lightbox" style="' + LIGHTBOX_STYLES + '">' +
  15576. '<div class="backdrop" style="' + BACKDROP_STYLES + '"></div>' +
  15577. '<div class="notice" style="' + NOTICE_STYLES + '">' +
  15578. '<a href="http://bpmn.io" target="_blank" style="float: left; margin-right: 10px">' +
  15579. BPMNIO_IMG +
  15580. '</a>' +
  15581. 'Web-based tooling for BPMN, DMN and CMMN diagrams ' +
  15582. 'powered by <a href="http://bpmn.io" target="_blank">bpmn.io</a>.' +
  15583. '</div>' +
  15584. '</div>';
  15585. var lightbox;
  15586. function open() {
  15587. if (!lightbox) {
  15588. lightbox = domify(LIGHTBOX_MARKUP);
  15589. delegateEvents.bind(lightbox, '.backdrop', 'click', function (event) {
  15590. document.body.removeChild(lightbox);
  15591. });
  15592. }
  15593. document.body.appendChild(lightbox);
  15594. }
  15595. /**
  15596. * The code in the <project-logo></project-logo> area
  15597. * must not be changed.
  15598. *
  15599. * @see http://bpmn.io/license for more information.
  15600. */
  15601. /**
  15602. * A base viewer for BPMN 2.0 diagrams.
  15603. *
  15604. * Have a look at {@link Viewer}, {@link NavigatedViewer} or {@link Modeler} for
  15605. * bundles that include actual features.
  15606. *
  15607. * @param {Object} [options] configuration options to pass to the viewer
  15608. * @param {DOMElement} [options.container] the container to render the viewer in, defaults to body.
  15609. * @param {string|number} [options.width] the width of the viewer
  15610. * @param {string|number} [options.height] the height of the viewer
  15611. * @param {Object} [options.moddleExtensions] extension packages to provide
  15612. * @param {Array<didi.Module>} [options.modules] a list of modules to override the default modules
  15613. * @param {Array<didi.Module>} [options.additionalModules] a list of modules to use with the default modules
  15614. */
  15615. function BaseViewer(options) {
  15616. options = assign({}, DEFAULT_OPTIONS, options);
  15617. this._moddle = this._createModdle(options);
  15618. this._container = this._createContainer(options);
  15619. /* <project-logo> */
  15620. addProjectLogo(this._container);
  15621. /* </project-logo> */
  15622. this._init(this._container, this._moddle, options);
  15623. }
  15624. inherits_browser(BaseViewer, Diagram);
  15625. /**
  15626. * Parse and render a BPMN 2.0 diagram.
  15627. *
  15628. * Once finished the viewer reports back the result to the
  15629. * provided callback function with (err, warnings).
  15630. *
  15631. * ## Life-Cycle Events
  15632. *
  15633. * During import the viewer will fire life-cycle events:
  15634. *
  15635. * * import.parse.start (about to read model from xml)
  15636. * * import.parse.complete (model read; may have worked or not)
  15637. * * import.render.start (graphical import start)
  15638. * * import.render.complete (graphical import finished)
  15639. * * import.done (everything done)
  15640. *
  15641. * You can use these events to hook into the life-cycle.
  15642. *
  15643. * @param {string} xml the BPMN 2.0 xml
  15644. * @param {ModdleElement<BPMNDiagram>|string} [bpmnDiagram] BPMN diagram or id of diagram to render (if not provided, the first one will be rendered)
  15645. * @param {Function} [done] invoked with (err, warnings=[])
  15646. */
  15647. BaseViewer.prototype.importXML = function (xml, bpmnDiagram, done) {
  15648. if (isFunction(bpmnDiagram)) {
  15649. done = bpmnDiagram;
  15650. bpmnDiagram = null;
  15651. }
  15652. // done is optional
  15653. done = done || function () {
  15654. };
  15655. var self = this;
  15656. // hook in pre-parse listeners +
  15657. // allow xml manipulation
  15658. xml = this._emit('import.parse.start', {xml: xml}) || xml;
  15659. this._moddle.fromXML(xml, 'bpmn:Definitions', function (err, definitions, context) {
  15660. // hook in post parse listeners +
  15661. // allow definitions manipulation
  15662. definitions = self._emit('import.parse.complete', {
  15663. error: err,
  15664. definitions: definitions,
  15665. context: context
  15666. }) || definitions;
  15667. var parseWarnings = context.warnings;
  15668. if (err) {
  15669. err = checkValidationError(err);
  15670. self._emit('import.done', {error: err, warnings: parseWarnings});
  15671. return done(err, parseWarnings);
  15672. }
  15673. self.importDefinitions(definitions, bpmnDiagram, function (err, importWarnings) {
  15674. var allWarnings = [].concat(parseWarnings, importWarnings || []);
  15675. self._emit('import.done', {error: err, warnings: allWarnings});
  15676. done(err, allWarnings);
  15677. });
  15678. });
  15679. };
  15680. /**
  15681. * Import parsed definitions and render a BPMN 2.0 diagram.
  15682. *
  15683. * Once finished the viewer reports back the result to the
  15684. * provided callback function with (err, warnings).
  15685. *
  15686. * ## Life-Cycle Events
  15687. *
  15688. * During import the viewer will fire life-cycle events:
  15689. *
  15690. * * import.render.start (graphical import start)
  15691. * * import.render.complete (graphical import finished)
  15692. *
  15693. * You can use these events to hook into the life-cycle.
  15694. *
  15695. * @param {ModdleElement<Definitions>} definitions parsed BPMN 2.0 definitions
  15696. * @param {ModdleElement<BPMNDiagram>|string} [bpmnDiagram] BPMN diagram or id of diagram to render (if not provided, the first one will be rendered)
  15697. * @param {Function} [done] invoked with (err, warnings=[])
  15698. */
  15699. BaseViewer.prototype.importDefinitions = function (definitions, bpmnDiagram, done) {
  15700. if (isFunction(bpmnDiagram)) {
  15701. done = bpmnDiagram;
  15702. bpmnDiagram = null;
  15703. }
  15704. // done is optional
  15705. done = done || function () {
  15706. };
  15707. this._setDefinitions(definitions);
  15708. return this.open(bpmnDiagram, done);
  15709. };
  15710. /**
  15711. * Open diagram of previously imported XML.
  15712. *
  15713. * Once finished the viewer reports back the result to the
  15714. * provided callback function with (err, warnings).
  15715. *
  15716. * ## Life-Cycle Events
  15717. *
  15718. * During switch the viewer will fire life-cycle events:
  15719. *
  15720. * * import.render.start (graphical import start)
  15721. * * import.render.complete (graphical import finished)
  15722. *
  15723. * You can use these events to hook into the life-cycle.
  15724. *
  15725. * @param {string|ModdleElement<BPMNDiagram>} [bpmnDiagramOrId] id or the diagram to open
  15726. * @param {Function} [done] invoked with (err, warnings=[])
  15727. */
  15728. BaseViewer.prototype.open = function (bpmnDiagramOrId, done) {
  15729. if (isFunction(bpmnDiagramOrId)) {
  15730. done = bpmnDiagramOrId;
  15731. bpmnDiagramOrId = null;
  15732. }
  15733. var definitions = this._definitions;
  15734. var bpmnDiagram = bpmnDiagramOrId;
  15735. // done is optional
  15736. done = done || function () {
  15737. };
  15738. if (!definitions) {
  15739. return done(new Error('no XML imported'));
  15740. }
  15741. if (typeof bpmnDiagramOrId === 'string') {
  15742. bpmnDiagram = findBPMNDiagram(definitions, bpmnDiagramOrId);
  15743. if (!bpmnDiagram) {
  15744. return done(new Error('BPMNDiagram <' + bpmnDiagramOrId + '> not found'));
  15745. }
  15746. }
  15747. // clear existing rendered diagram
  15748. // catch synchronous exceptions during #clear()
  15749. try {
  15750. this.clear();
  15751. } catch (error) {
  15752. return done(error);
  15753. }
  15754. // perform graphical import
  15755. return importBpmnDiagram(this, definitions, bpmnDiagram, done);
  15756. };
  15757. /**
  15758. * Export the currently displayed BPMN 2.0 diagram as
  15759. * a BPMN 2.0 XML document.
  15760. *
  15761. * ## Life-Cycle Events
  15762. *
  15763. * During XML saving the viewer will fire life-cycle events:
  15764. *
  15765. * * saveXML.start (before serialization)
  15766. * * saveXML.serialized (after xml generation)
  15767. * * saveXML.done (everything done)
  15768. *
  15769. * You can use these events to hook into the life-cycle.
  15770. *
  15771. * @param {Object} [options] export options
  15772. * @param {boolean} [options.format=false] output formatted XML
  15773. * @param {boolean} [options.preamble=true] output preamble
  15774. *
  15775. * @param {Function} done invoked with (err, xml)
  15776. */
  15777. BaseViewer.prototype.saveXML = function (options, done) {
  15778. if (!done) {
  15779. done = options;
  15780. options = {};
  15781. }
  15782. var self = this;
  15783. var definitions = this._definitions;
  15784. if (!definitions) {
  15785. return done(new Error('no definitions loaded'));
  15786. }
  15787. // allow to fiddle around with definitions
  15788. definitions = this._emit('saveXML.start', {
  15789. definitions: definitions
  15790. }) || definitions;
  15791. this._moddle.toXML(definitions, options, function (err, xml) {
  15792. try {
  15793. xml = self._emit('saveXML.serialized', {
  15794. error: err,
  15795. xml: xml
  15796. }) || xml;
  15797. self._emit('saveXML.done', {
  15798. error: err,
  15799. xml: xml
  15800. });
  15801. } catch (e) {
  15802. console.error('error in saveXML life-cycle listener', e);
  15803. }
  15804. done(err, xml);
  15805. });
  15806. };
  15807. /**
  15808. * Export the currently displayed BPMN 2.0 diagram as
  15809. * an SVG image.
  15810. *
  15811. * ## Life-Cycle Events
  15812. *
  15813. * During SVG saving the viewer will fire life-cycle events:
  15814. *
  15815. * * saveSVG.start (before serialization)
  15816. * * saveSVG.done (everything done)
  15817. *
  15818. * You can use these events to hook into the life-cycle.
  15819. *
  15820. * @param {Object} [options]
  15821. * @param {Function} done invoked with (err, svgStr)
  15822. */
  15823. BaseViewer.prototype.saveSVG = function (options, done) {
  15824. if (!done) {
  15825. done = options;
  15826. options = {};
  15827. }
  15828. this._emit('saveSVG.start');
  15829. var svg, err;
  15830. try {
  15831. var canvas = this.get('canvas');
  15832. var contentNode = canvas.getDefaultLayer(),
  15833. defsNode = query('defs', canvas._svg);
  15834. var contents = innerSVG(contentNode),
  15835. defs = defsNode ? '<defs>' + innerSVG(defsNode) + '</defs>' : '';
  15836. var bbox = contentNode.getBBox();
  15837. svg =
  15838. '<?xml version="1.0" encoding="utf-8"?>\n' +
  15839. '<!-- created with bpmn-js / http://bpmn.io -->\n' +
  15840. '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\n' +
  15841. '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" ' +
  15842. 'width="' + bbox.width + '" height="' + bbox.height + '" ' +
  15843. 'viewBox="' + bbox.x + ' ' + bbox.y + ' ' + bbox.width + ' ' + bbox.height + '" version="1.1">' +
  15844. defs + contents +
  15845. '</svg>';
  15846. } catch (e) {
  15847. err = e;
  15848. }
  15849. this._emit('saveSVG.done', {
  15850. error: err,
  15851. svg: svg
  15852. });
  15853. done(err, svg);
  15854. };
  15855. /**
  15856. * Get a named diagram service.
  15857. *
  15858. * @example
  15859. *
  15860. * var elementRegistry = viewer.get('elementRegistry');
  15861. * var startEventShape = elementRegistry.get('StartEvent_1');
  15862. *
  15863. * @param {string} name
  15864. *
  15865. * @return {Object} diagram service instance
  15866. *
  15867. * @method BaseViewer#get
  15868. */
  15869. /**
  15870. * Invoke a function in the context of this viewer.
  15871. *
  15872. * @example
  15873. *
  15874. * viewer.invoke(function(elementRegistry) {
  15875. * var startEventShape = elementRegistry.get('StartEvent_1');
  15876. * });
  15877. *
  15878. * @param {Function} fn to be invoked
  15879. *
  15880. * @return {Object} the functions return value
  15881. *
  15882. * @method BaseViewer#invoke
  15883. */
  15884. BaseViewer.prototype._setDefinitions = function (definitions) {
  15885. this._definitions = definitions;
  15886. };
  15887. BaseViewer.prototype.getModules = function () {
  15888. return this._modules;
  15889. };
  15890. /**
  15891. * Remove all drawn elements from the viewer.
  15892. *
  15893. * After calling this method the viewer can still
  15894. * be reused for opening another diagram.
  15895. *
  15896. * @method BaseViewer#clear
  15897. */
  15898. BaseViewer.prototype.clear = function () {
  15899. if (!this.getDefinitions()) {
  15900. // no diagram to clear
  15901. return;
  15902. }
  15903. // remove businessObject#di binding
  15904. //
  15905. // this is necessary, as we establish the bindings
  15906. // in the BpmnTreeWalker (and assume none are given
  15907. // on reimport)
  15908. this.get('elementRegistry').forEach(function (element) {
  15909. var bo = element.businessObject;
  15910. if (bo && bo.di) {
  15911. delete bo.di;
  15912. }
  15913. });
  15914. // remove drawn elements
  15915. Diagram.prototype.clear.call(this);
  15916. };
  15917. /**
  15918. * Destroy the viewer instance and remove all its
  15919. * remainders from the document tree.
  15920. */
  15921. BaseViewer.prototype.destroy = function () {
  15922. // diagram destroy
  15923. Diagram.prototype.destroy.call(this);
  15924. // dom detach
  15925. remove$1(this._container);
  15926. };
  15927. /**
  15928. * Register an event listener
  15929. *
  15930. * Remove a previously added listener via {@link #off(event, callback)}.
  15931. *
  15932. * @param {string} event
  15933. * @param {number} [priority]
  15934. * @param {Function} callback
  15935. * @param {Object} [that]
  15936. */
  15937. BaseViewer.prototype.on = function (event, priority, callback, target) {
  15938. return this.get('eventBus').on(event, priority, callback, target);
  15939. };
  15940. /**
  15941. * De-register an event listener
  15942. *
  15943. * @param {string} event
  15944. * @param {Function} callback
  15945. */
  15946. BaseViewer.prototype.off = function (event, callback) {
  15947. this.get('eventBus').off(event, callback);
  15948. };
  15949. BaseViewer.prototype.attachTo = function (parentNode) {
  15950. if (!parentNode) {
  15951. throw new Error('parentNode required');
  15952. }
  15953. // ensure we detach from the
  15954. // previous, old parent
  15955. this.detach();
  15956. // unwrap jQuery if provided
  15957. if (parentNode.get && parentNode.constructor.prototype.jquery) {
  15958. parentNode = parentNode.get(0);
  15959. }
  15960. if (typeof parentNode === 'string') {
  15961. parentNode = query(parentNode);
  15962. }
  15963. parentNode.appendChild(this._container);
  15964. this._emit('attach', {});
  15965. this.get('canvas').resized();
  15966. };
  15967. BaseViewer.prototype.getDefinitions = function () {
  15968. return this._definitions;
  15969. };
  15970. BaseViewer.prototype.detach = function () {
  15971. var container = this._container,
  15972. parentNode = container.parentNode;
  15973. if (!parentNode) {
  15974. return;
  15975. }
  15976. this._emit('detach', {});
  15977. parentNode.removeChild(container);
  15978. };
  15979. BaseViewer.prototype._init = function (container, moddle, options) {
  15980. var baseModules = options.modules || this.getModules(),
  15981. additionalModules = options.additionalModules || [],
  15982. staticModules = [
  15983. {
  15984. bpmnjs: ['value', this],
  15985. moddle: ['value', moddle]
  15986. }
  15987. ];
  15988. var diagramModules = [].concat(staticModules, baseModules, additionalModules);
  15989. var diagramOptions = assign(omit(options, ['additionalModules']), {
  15990. canvas: assign({}, options.canvas, {container: container}),
  15991. modules: diagramModules
  15992. });
  15993. // invoke diagram constructor
  15994. Diagram.call(this, diagramOptions);
  15995. if (options && options.container) {
  15996. this.attachTo(options.container);
  15997. }
  15998. };
  15999. /**
  16000. * Emit an event on the underlying {@link EventBus}
  16001. *
  16002. * @param {string} type
  16003. * @param {Object} event
  16004. *
  16005. * @return {Object} event processing result (if any)
  16006. */
  16007. BaseViewer.prototype._emit = function (type, event) {
  16008. return this.get('eventBus').fire(type, event);
  16009. };
  16010. BaseViewer.prototype._createContainer = function (options) {
  16011. var container = domify('<div class="bjs-container"></div>');
  16012. assign(container.style, {
  16013. width: ensureUnit(options.width),
  16014. height: ensureUnit(options.height),
  16015. position: options.position
  16016. });
  16017. return container;
  16018. };
  16019. BaseViewer.prototype._createModdle = function (options) {
  16020. var moddleOptions = assign({}, this._moddleExtensions, options.moddleExtensions);
  16021. return new simple(moddleOptions);
  16022. };
  16023. BaseViewer.prototype._modules = [];
  16024. // helpers ///////////////
  16025. function checkValidationError(err) {
  16026. // check if we can help the user by indicating wrong BPMN 2.0 xml
  16027. // (in case he or the exporting tool did not get that right)
  16028. var pattern = /unparsable content <([^>]+)> detected([\s\S]*)$/;
  16029. var match = pattern.exec(err.message);
  16030. if (match) {
  16031. err.message =
  16032. 'unparsable content <' + match[1] + '> detected; ' +
  16033. 'this may indicate an invalid BPMN 2.0 diagram file' + match[2];
  16034. }
  16035. return err;
  16036. }
  16037. var DEFAULT_OPTIONS = {
  16038. width: '100%',
  16039. height: '100%',
  16040. position: 'relative'
  16041. };
  16042. /**
  16043. * Ensure the passed argument is a proper unit (defaulting to px)
  16044. */
  16045. function ensureUnit(val) {
  16046. return val + (isNumber(val) ? 'px' : '');
  16047. }
  16048. /**
  16049. * Find BPMNDiagram in definitions by ID
  16050. *
  16051. * @param {ModdleElement<Definitions>} definitions
  16052. * @param {string} diagramId
  16053. *
  16054. * @return {ModdleElement<BPMNDiagram>|null}
  16055. */
  16056. function findBPMNDiagram(definitions, diagramId) {
  16057. if (!diagramId) {
  16058. return null;
  16059. }
  16060. return find(definitions.diagrams, function (element) {
  16061. return element.id === diagramId;
  16062. }) || null;
  16063. }
  16064. /**
  16065. * Adds the project logo to the diagram container as
  16066. * required by the bpmn.io license.
  16067. *
  16068. * @see http://bpmn.io/license
  16069. *
  16070. * @param {Element} container
  16071. */
  16072. function addProjectLogo(container) {
  16073. var img = BPMNIO_IMG;
  16074. // var linkMarkup =
  16075. // '<a href="http://bpmn.io" ' +
  16076. // 'target="_blank" ' +
  16077. // 'class="bjs-powered-by" ' +
  16078. // 'title="Powered by bpmn.io" ' +
  16079. // 'style="position: absolute; bottom: 15px; right: 15px; z-index: 100">' +
  16080. // img +
  16081. // '</a>';
  16082. var linkMarkup =
  16083. '<a href="http://bpmn.io" ' +
  16084. 'target="_blank" ' +
  16085. 'class="bjs-powered-by" ' +
  16086. 'title="Powered by bpmn.io" ' +
  16087. 'style="position: absolute; bottom: 15px; right: 15px; z-index: 100;visibility:hidden;">' +
  16088. img +
  16089. '</a>';
  16090. var linkElement = domify(linkMarkup);
  16091. container.appendChild(linkElement);
  16092. componentEvent.bind(linkElement, 'click', function (event) {
  16093. open();
  16094. event.preventDefault();
  16095. });
  16096. }
  16097. /* </project-logo> */
  16098. /**
  16099. * A viewer for BPMN 2.0 diagrams.
  16100. *
  16101. * Have a look at {@link NavigatedViewer} or {@link Modeler} for bundles that include
  16102. * additional features.
  16103. *
  16104. *
  16105. * ## Extending the Viewer
  16106. *
  16107. * In order to extend the viewer pass extension modules to bootstrap via the
  16108. * `additionalModules` option. An extension module is an object that exposes
  16109. * named services.
  16110. *
  16111. * The following example depicts the integration of a simple
  16112. * logging component that integrates with interaction events:
  16113. *
  16114. *
  16115. * ```javascript
  16116. *
  16117. * // logging component
  16118. * function InteractionLogger(eventBus) {
  16119. * eventBus.on('element.hover', function(event) {
  16120. * console.log()
  16121. * })
  16122. * }
  16123. *
  16124. * InteractionLogger.$inject = [ 'eventBus' ]; // minification save
  16125. *
  16126. * // extension module
  16127. * var extensionModule = {
  16128. * __init__: [ 'interactionLogger' ],
  16129. * interactionLogger: [ 'type', InteractionLogger ]
  16130. * };
  16131. *
  16132. * // extend the viewer
  16133. * var bpmnViewer = new Viewer({ additionalModules: [ extensionModule ] });
  16134. * bpmnViewer.importXML(...);
  16135. * ```
  16136. *
  16137. * @param {Object} [options] configuration options to pass to the viewer
  16138. * @param {DOMElement} [options.container] the container to render the viewer in, defaults to body.
  16139. * @param {string|number} [options.width] the width of the viewer
  16140. * @param {string|number} [options.height] the height of the viewer
  16141. * @param {Object} [options.moddleExtensions] extension packages to provide
  16142. * @param {Array<didi.Module>} [options.modules] a list of modules to override the default modules
  16143. * @param {Array<didi.Module>} [options.additionalModules] a list of modules to use with the default modules
  16144. */
  16145. function Viewer(options) {
  16146. BaseViewer.call(this, options);
  16147. }
  16148. inherits_browser(Viewer, BaseViewer);
  16149. // modules the viewer is composed of
  16150. Viewer.prototype._modules = [
  16151. CoreModule,
  16152. TranslateModule,
  16153. SelectionModule,
  16154. OverlaysModule
  16155. ];
  16156. // default moddle extensions the viewer is composed of
  16157. Viewer.prototype._moddleExtensions = {};
  16158. /**
  16159. * Returns true if event was triggered with any modifier
  16160. * @param {KeyboardEvent} event
  16161. */
  16162. function hasModifier(event) {
  16163. return (event.ctrlKey || event.metaKey || event.shiftKey || event.altKey);
  16164. }
  16165. /**
  16166. * @param {KeyboardEvent} event
  16167. */
  16168. function isCmd(event) {
  16169. // ensure we don't react to AltGr
  16170. // (mapped to CTRL + ALT)
  16171. if (event.altKey) {
  16172. return false;
  16173. }
  16174. return event.ctrlKey || event.metaKey;
  16175. }
  16176. /**
  16177. * Checks if key pressed is one of provided keys.
  16178. *
  16179. * @param {string|Array<string>} keys
  16180. * @param {KeyboardEvent} event
  16181. */
  16182. function isKey(keys, event) {
  16183. keys = isArray(keys) ? keys : [keys];
  16184. return keys.indexOf(event.key) !== -1 || keys.indexOf(event.keyCode) !== -1;
  16185. }
  16186. /**
  16187. * @param {KeyboardEvent} event
  16188. */
  16189. function isShift(event) {
  16190. return event.shiftKey;
  16191. }
  16192. var KEYDOWN_EVENT = 'keyboard.keydown',
  16193. KEYUP_EVENT = 'keyboard.keyup';
  16194. var DEFAULT_PRIORITY$1 = 1000;
  16195. /**
  16196. * A keyboard abstraction that may be activated and
  16197. * deactivated by users at will, consuming key events
  16198. * and triggering diagram actions.
  16199. *
  16200. * For keys pressed down, keyboard fires `keyboard.keydown` event.
  16201. * The event context contains one field which is `KeyboardEvent` event.
  16202. *
  16203. * The implementation fires the following key events that allow
  16204. * other components to hook into key handling:
  16205. *
  16206. * - keyboard.bind
  16207. * - keyboard.unbind
  16208. * - keyboard.init
  16209. * - keyboard.destroy
  16210. *
  16211. * All events contain one field which is node.
  16212. *
  16213. * A default binding for the keyboard may be specified via the
  16214. * `keyboard.bindTo` configuration option.
  16215. *
  16216. * @param {Config} config
  16217. * @param {EventBus} eventBus
  16218. */
  16219. function Keyboard(config, eventBus) {
  16220. var self = this;
  16221. this._config = config || {};
  16222. this._eventBus = eventBus;
  16223. this._keydownHandler = this._keydownHandler.bind(this);
  16224. this._keyupHandler = this._keyupHandler.bind(this);
  16225. // properly clean dom registrations
  16226. eventBus.on('diagram.destroy', function () {
  16227. self._fire('destroy');
  16228. self.unbind();
  16229. });
  16230. eventBus.on('diagram.init', function () {
  16231. self._fire('init');
  16232. });
  16233. eventBus.on('attach', function () {
  16234. if (config && config.bindTo) {
  16235. self.bind(config.bindTo);
  16236. }
  16237. });
  16238. eventBus.on('detach', function () {
  16239. self.unbind();
  16240. });
  16241. }
  16242. Keyboard.$inject = [
  16243. 'config.keyboard',
  16244. 'eventBus'
  16245. ];
  16246. Keyboard.prototype._keydownHandler = function (event) {
  16247. this._keyHandler(event, KEYDOWN_EVENT);
  16248. };
  16249. Keyboard.prototype._keyupHandler = function (event) {
  16250. this._keyHandler(event, KEYUP_EVENT);
  16251. };
  16252. Keyboard.prototype._keyHandler = function (event, type) {
  16253. var target = event.target,
  16254. eventBusResult;
  16255. if (isInput(target)) {
  16256. return;
  16257. }
  16258. var context = {
  16259. keyEvent: event
  16260. };
  16261. eventBusResult = this._eventBus.fire(type || KEYDOWN_EVENT, context);
  16262. if (eventBusResult) {
  16263. event.preventDefault();
  16264. }
  16265. };
  16266. Keyboard.prototype.bind = function (node) {
  16267. // make sure that the keyboard is only bound once to the DOM
  16268. this.unbind();
  16269. this._node = node;
  16270. // bind key events
  16271. componentEvent.bind(node, 'keydown', this._keydownHandler, true);
  16272. componentEvent.bind(node, 'keyup', this._keyupHandler, true);
  16273. this._fire('bind');
  16274. };
  16275. Keyboard.prototype.getBinding = function () {
  16276. return this._node;
  16277. };
  16278. Keyboard.prototype.unbind = function () {
  16279. var node = this._node;
  16280. if (node) {
  16281. this._fire('unbind');
  16282. // unbind key events
  16283. componentEvent.unbind(node, 'keydown', this._keydownHandler, true);
  16284. componentEvent.unbind(node, 'keyup', this._keyupHandler, true);
  16285. }
  16286. this._node = null;
  16287. };
  16288. Keyboard.prototype._fire = function (event) {
  16289. this._eventBus.fire('keyboard.' + event, {node: this._node});
  16290. };
  16291. /**
  16292. * Add a listener function that is notified with `KeyboardEvent` whenever
  16293. * the keyboard is bound and the user presses a key. If no priority is
  16294. * provided, the default value of 1000 is used.
  16295. *
  16296. * @param {number} [priority]
  16297. * @param {Function} listener
  16298. * @param {string} type
  16299. */
  16300. Keyboard.prototype.addListener = function (priority, listener, type) {
  16301. if (isFunction(priority)) {
  16302. type = listener;
  16303. listener = priority;
  16304. priority = DEFAULT_PRIORITY$1;
  16305. }
  16306. this._eventBus.on(type || KEYDOWN_EVENT, priority, listener);
  16307. };
  16308. Keyboard.prototype.removeListener = function (listener, type) {
  16309. this._eventBus.off(type || KEYDOWN_EVENT, listener);
  16310. };
  16311. Keyboard.prototype.hasModifier = hasModifier;
  16312. Keyboard.prototype.isCmd = isCmd;
  16313. Keyboard.prototype.isShift = isShift;
  16314. Keyboard.prototype.isKey = isKey;
  16315. // helpers ///////
  16316. function isInput(target) {
  16317. return target && (matchesSelector(target, 'input, textarea') || target.contentEditable === 'true');
  16318. }
  16319. var LOW_PRIORITY$3 = 500;
  16320. var KEYCODE_C = 67;
  16321. var KEYCODE_V = 86;
  16322. var KEYCODE_Y = 89;
  16323. var KEYCODE_Z = 90;
  16324. var KEYS_COPY = ['c', 'C', KEYCODE_C];
  16325. var KEYS_PASTE = ['v', 'V', KEYCODE_V];
  16326. var KEYS_REDO = ['y', 'Y', KEYCODE_Y];
  16327. var KEYS_UNDO = ['z', 'Z', KEYCODE_Z];
  16328. /**
  16329. * Adds default keyboard bindings.
  16330. *
  16331. * This does not pull in any features will bind only actions that
  16332. * have previously been registered against the editorActions component.
  16333. *
  16334. * @param {EventBus} eventBus
  16335. * @param {Keyboard} keyboard
  16336. */
  16337. function KeyboardBindings(eventBus, keyboard) {
  16338. var self = this;
  16339. eventBus.on('editorActions.init', LOW_PRIORITY$3, function (event) {
  16340. var editorActions = event.editorActions;
  16341. self.registerBindings(keyboard, editorActions);
  16342. });
  16343. }
  16344. KeyboardBindings.$inject = [
  16345. 'eventBus',
  16346. 'keyboard'
  16347. ];
  16348. /**
  16349. * Register available keyboard bindings.
  16350. *
  16351. * @param {Keyboard} keyboard
  16352. * @param {EditorActions} editorActions
  16353. */
  16354. KeyboardBindings.prototype.registerBindings = function (keyboard, editorActions) {
  16355. /**
  16356. * Add keyboard binding if respective editor action
  16357. * is registered.
  16358. *
  16359. * @param {string} action name
  16360. * @param {Function} fn that implements the key binding
  16361. */
  16362. function addListener(action, fn) {
  16363. if (editorActions.isRegistered(action)) {
  16364. keyboard.addListener(fn);
  16365. }
  16366. }
  16367. // undo
  16368. // (CTRL|CMD) + Z
  16369. addListener('undo', function (context) {
  16370. var event = context.keyEvent;
  16371. if (isCmd(event) && !isShift(event) && isKey(KEYS_UNDO, event)) {
  16372. editorActions.trigger('undo');
  16373. return true;
  16374. }
  16375. });
  16376. // redo
  16377. // CTRL + Y
  16378. // CMD + SHIFT + Z
  16379. addListener('redo', function (context) {
  16380. var event = context.keyEvent;
  16381. if (isCmd(event) && (isKey(KEYS_REDO, event) || (isKey(KEYS_UNDO, event) && isShift(event)))) {
  16382. editorActions.trigger('redo');
  16383. return true;
  16384. }
  16385. });
  16386. // copy
  16387. // CTRL/CMD + C
  16388. addListener('copy', function (context) {
  16389. var event = context.keyEvent;
  16390. if (isCmd(event) && isKey(KEYS_COPY, event)) {
  16391. editorActions.trigger('copy');
  16392. return true;
  16393. }
  16394. });
  16395. // paste
  16396. // CTRL/CMD + V
  16397. addListener('paste', function (context) {
  16398. var event = context.keyEvent;
  16399. if (isCmd(event) && isKey(KEYS_PASTE, event)) {
  16400. editorActions.trigger('paste');
  16401. return true;
  16402. }
  16403. });
  16404. // zoom in one step
  16405. // CTRL/CMD + +
  16406. addListener('stepZoom', function (context) {
  16407. var event = context.keyEvent;
  16408. if (isKey(['+', 'Add'], event) && isCmd(event)) {
  16409. editorActions.trigger('stepZoom', {value: 1});
  16410. return true;
  16411. }
  16412. });
  16413. // zoom out one step
  16414. // CTRL + -
  16415. addListener('stepZoom', function (context) {
  16416. var event = context.keyEvent;
  16417. if (isKey(['-', 'Subtract'], event) && isCmd(event)) {
  16418. editorActions.trigger('stepZoom', {value: -1});
  16419. return true;
  16420. }
  16421. });
  16422. // zoom to the default level
  16423. // CTRL + 0
  16424. addListener('zoom', function (context) {
  16425. var event = context.keyEvent;
  16426. if (isKey('0', event) && isCmd(event)) {
  16427. editorActions.trigger('zoom', {value: 1});
  16428. return true;
  16429. }
  16430. });
  16431. // delete selected element
  16432. // DEL
  16433. addListener('removeSelection', function (context) {
  16434. var event = context.keyEvent;
  16435. if (isKey(['Delete', 'Del'], event)) {
  16436. editorActions.trigger('removeSelection');
  16437. return true;
  16438. }
  16439. });
  16440. };
  16441. var KeyboardModule = {
  16442. __init__: ['keyboard', 'keyboardBindings'],
  16443. keyboard: ['type', Keyboard],
  16444. keyboardBindings: ['type', KeyboardBindings]
  16445. };
  16446. var DEFAULT_CONFIG = {
  16447. moveSpeed: 50,
  16448. moveSpeedAccelerated: 200
  16449. };
  16450. /**
  16451. * A feature that allows users to move the canvas using the keyboard.
  16452. *
  16453. * @param {Object} config
  16454. * @param {number} [config.moveSpeed=50]
  16455. * @param {number} [config.moveSpeedAccelerated=200]
  16456. * @param {Keyboard} keyboard
  16457. * @param {Canvas} canvas
  16458. */
  16459. function KeyboardMove(
  16460. config,
  16461. keyboard,
  16462. canvas
  16463. ) {
  16464. var self = this;
  16465. this._config = assign({}, DEFAULT_CONFIG, config || {});
  16466. keyboard.addListener(arrowsListener);
  16467. function arrowsListener(context) {
  16468. var event = context.keyEvent,
  16469. config = self._config;
  16470. if (!keyboard.isCmd(event)) {
  16471. return;
  16472. }
  16473. if (keyboard.isKey([
  16474. 'ArrowLeft', 'Left',
  16475. 'ArrowUp', 'Up',
  16476. 'ArrowDown', 'Down',
  16477. 'ArrowRight', 'Right'
  16478. ], event)) {
  16479. var speed = (
  16480. keyboard.isShift(event) ?
  16481. config.moveSpeedAccelerated :
  16482. config.moveSpeed
  16483. );
  16484. var direction;
  16485. switch (event.key) {
  16486. case 'ArrowLeft':
  16487. case 'Left':
  16488. direction = 'left';
  16489. break;
  16490. case 'ArrowUp':
  16491. case 'Up':
  16492. direction = 'up';
  16493. break;
  16494. case 'ArrowRight':
  16495. case 'Right':
  16496. direction = 'right';
  16497. break;
  16498. case 'ArrowDown':
  16499. case 'Down':
  16500. direction = 'down';
  16501. break;
  16502. }
  16503. self.moveCanvas({
  16504. speed: speed,
  16505. direction: direction
  16506. });
  16507. return true;
  16508. }
  16509. }
  16510. this.moveCanvas = function (opts) {
  16511. var dx = 0,
  16512. dy = 0,
  16513. speed = opts.speed;
  16514. var actualSpeed = speed / Math.min(Math.sqrt(canvas.viewbox().scale), 1);
  16515. switch (opts.direction) {
  16516. case 'left': // Left
  16517. dx = actualSpeed;
  16518. break;
  16519. case 'up': // Up
  16520. dy = actualSpeed;
  16521. break;
  16522. case 'right': // Right
  16523. dx = -actualSpeed;
  16524. break;
  16525. case 'down': // Down
  16526. dy = -actualSpeed;
  16527. break;
  16528. }
  16529. canvas.scroll({
  16530. dx: dx,
  16531. dy: dy
  16532. });
  16533. };
  16534. }
  16535. KeyboardMove.$inject = [
  16536. 'config.keyboardMove',
  16537. 'keyboard',
  16538. 'canvas'
  16539. ];
  16540. var KeyboardMoveModule = {
  16541. __depends__: [
  16542. KeyboardModule
  16543. ],
  16544. __init__: ['keyboardMove'],
  16545. keyboardMove: ['type', KeyboardMove]
  16546. };
  16547. var CURSOR_CLS_PATTERN = /^djs-cursor-.*$/;
  16548. function set$1(mode) {
  16549. var classes = classes$1(document.body);
  16550. classes.removeMatching(CURSOR_CLS_PATTERN);
  16551. if (mode) {
  16552. classes.add('djs-cursor-' + mode);
  16553. }
  16554. }
  16555. function unset() {
  16556. set$1(null);
  16557. }
  16558. var TRAP_PRIORITY = 5000;
  16559. /**
  16560. * Installs a click trap that prevents a ghost click following a dragging operation.
  16561. *
  16562. * @return {Function} a function to immediately remove the installed trap.
  16563. */
  16564. function install(eventBus, eventName) {
  16565. eventName = eventName || 'element.click';
  16566. function trap() {
  16567. return false;
  16568. }
  16569. eventBus.once(eventName, TRAP_PRIORITY, trap);
  16570. return function () {
  16571. eventBus.off(eventName, trap);
  16572. };
  16573. }
  16574. function delta(a, b) {
  16575. return {
  16576. x: a.x - b.x,
  16577. y: a.y - b.y
  16578. };
  16579. }
  16580. var THRESHOLD = 15;
  16581. /**
  16582. * Move the canvas via mouse.
  16583. *
  16584. * @param {EventBus} eventBus
  16585. * @param {Canvas} canvas
  16586. */
  16587. function MoveCanvas(eventBus, canvas) {
  16588. var context;
  16589. // listen for move on element mouse down;
  16590. // allow others to hook into the event before us though
  16591. // (dragging / element moving will do this)
  16592. eventBus.on('element.mousedown', 500, function (e) {
  16593. return handleStart(e.originalEvent);
  16594. });
  16595. function handleMove(event) {
  16596. var start = context.start,
  16597. position = toPoint(event),
  16598. delta$1 = delta(position, start);
  16599. if (!context.dragging && length(delta$1) > THRESHOLD) {
  16600. context.dragging = true;
  16601. install(eventBus);
  16602. set$1('grab');
  16603. }
  16604. if (context.dragging) {
  16605. var lastPosition = context.last || context.start;
  16606. delta$1 = delta(position, lastPosition);
  16607. canvas.scroll({
  16608. dx: delta$1.x,
  16609. dy: delta$1.y
  16610. });
  16611. context.last = position;
  16612. }
  16613. // prevent select
  16614. event.preventDefault();
  16615. }
  16616. function handleEnd(event) {
  16617. componentEvent.unbind(document, 'mousemove', handleMove);
  16618. componentEvent.unbind(document, 'mouseup', handleEnd);
  16619. context = null;
  16620. unset();
  16621. }
  16622. function handleStart(event) {
  16623. // event is already handled by '.djs-draggable'
  16624. if (closest(event.target, '.djs-draggable')) {
  16625. return;
  16626. }
  16627. // reject non-left left mouse button or modifier key
  16628. if (event.button || event.ctrlKey || event.shiftKey || event.altKey) {
  16629. return;
  16630. }
  16631. context = {
  16632. start: toPoint(event)
  16633. };
  16634. componentEvent.bind(document, 'mousemove', handleMove);
  16635. componentEvent.bind(document, 'mouseup', handleEnd);
  16636. // we've handled the event
  16637. return true;
  16638. }
  16639. }
  16640. MoveCanvas.$inject = [
  16641. 'eventBus',
  16642. 'canvas'
  16643. ];
  16644. // helpers ///////
  16645. function length(point) {
  16646. return Math.sqrt(Math.pow(point.x, 2) + Math.pow(point.y, 2));
  16647. }
  16648. var MoveCanvasModule = {
  16649. __init__: ['moveCanvas'],
  16650. moveCanvas: ['type', MoveCanvas]
  16651. };
  16652. /**
  16653. * Get the logarithm of x with base 10
  16654. * @param {Integer} value
  16655. */
  16656. function log10(x) {
  16657. return Math.log(x) / Math.log(10);
  16658. }
  16659. /**
  16660. * Get step size for given range and number of steps.
  16661. *
  16662. * @param {Object} range
  16663. * @param {number} range.min
  16664. * @param {number} range.max
  16665. */
  16666. function getStepSize(range, steps) {
  16667. var minLinearRange = log10(range.min),
  16668. maxLinearRange = log10(range.max);
  16669. var absoluteLinearRange = Math.abs(minLinearRange) + Math.abs(maxLinearRange);
  16670. return absoluteLinearRange / steps;
  16671. }
  16672. function cap(range, scale) {
  16673. return Math.max(range.min, Math.min(range.max, scale));
  16674. }
  16675. var sign = Math.sign || function (n) {
  16676. return n >= 0 ? 1 : -1;
  16677. };
  16678. var RANGE = {min: 0.2, max: 4},
  16679. NUM_STEPS = 10;
  16680. var DELTA_THRESHOLD = 0.1;
  16681. var DEFAULT_SCALE = 0.75;
  16682. /**
  16683. * An implementation of zooming and scrolling within the
  16684. * {@link Canvas} via the mouse wheel.
  16685. *
  16686. * Mouse wheel zooming / scrolling may be disabled using
  16687. * the {@link toggle(enabled)} method.
  16688. *
  16689. * @param {Object} [config]
  16690. * @param {boolean} [config.enabled=true] default enabled state
  16691. * @param {number} [config.scale=.75] scroll sensivity
  16692. * @param {EventBus} eventBus
  16693. * @param {Canvas} canvas
  16694. */
  16695. function ZoomScroll(config, eventBus, canvas) {
  16696. config = config || {};
  16697. this._enabled = false;
  16698. this._canvas = canvas;
  16699. this._container = canvas._container;
  16700. this._handleWheel = bind(this._handleWheel, this);
  16701. this._totalDelta = 0;
  16702. this._scale = config.scale || DEFAULT_SCALE;
  16703. var self = this;
  16704. eventBus.on('canvas.init', function (e) {
  16705. self._init(config.enabled !== false);
  16706. });
  16707. }
  16708. ZoomScroll.$inject = [
  16709. 'config.zoomScroll',
  16710. 'eventBus',
  16711. 'canvas'
  16712. ];
  16713. ZoomScroll.prototype.scroll = function scroll(delta) {
  16714. this._canvas.scroll(delta);
  16715. };
  16716. ZoomScroll.prototype.reset = function reset() {
  16717. this._canvas.zoom('fit-viewport');
  16718. };
  16719. /**
  16720. * Zoom depending on delta.
  16721. *
  16722. * @param {number} delta
  16723. * @param {Object} position
  16724. */
  16725. ZoomScroll.prototype.zoom = function zoom(delta, position) {
  16726. // zoom with half the step size of stepZoom
  16727. var stepSize = getStepSize(RANGE, NUM_STEPS * 2);
  16728. // add until threshold reached
  16729. this._totalDelta += delta;
  16730. if (Math.abs(this._totalDelta) > DELTA_THRESHOLD) {
  16731. this._zoom(delta, position, stepSize);
  16732. // reset
  16733. this._totalDelta = 0;
  16734. }
  16735. };
  16736. ZoomScroll.prototype._handleWheel = function handleWheel(event) {
  16737. // event is already handled by '.djs-scrollable'
  16738. if (closest(event.target, '.djs-scrollable', true)) {
  16739. return;
  16740. }
  16741. var element = this._container;
  16742. event.preventDefault();
  16743. // pinch to zoom is mapped to wheel + ctrlKey = true
  16744. // in modern browsers (!)
  16745. var isZoom = event.ctrlKey;
  16746. var isHorizontalScroll = event.shiftKey;
  16747. var factor = -1 * this._scale,
  16748. delta;
  16749. if (isZoom) {
  16750. factor *= event.deltaMode === 0 ? 0.020 : 0.32;
  16751. } else {
  16752. factor *= event.deltaMode === 0 ? 1.0 : 16.0;
  16753. }
  16754. if (isZoom) {
  16755. var elementRect = element.getBoundingClientRect();
  16756. var offset = {
  16757. x: event.clientX - elementRect.left,
  16758. y: event.clientY - elementRect.top
  16759. };
  16760. delta = (
  16761. Math.sqrt(
  16762. Math.pow(event.deltaY, 2) +
  16763. Math.pow(event.deltaX, 2)
  16764. ) * sign(event.deltaY) * factor
  16765. );
  16766. // zoom in relative to diagram {x,y} coordinates
  16767. this.zoom(delta, offset);
  16768. } else {
  16769. if (isHorizontalScroll) {
  16770. delta = {
  16771. dx: factor * event.deltaY,
  16772. dy: 0
  16773. };
  16774. } else {
  16775. delta = {
  16776. dx: factor * event.deltaX,
  16777. dy: factor * event.deltaY
  16778. };
  16779. }
  16780. this.scroll(delta);
  16781. }
  16782. };
  16783. /**
  16784. * Zoom with fixed step size.
  16785. *
  16786. * @param {number} delta - Zoom delta (1 for zooming in, -1 for out).
  16787. * @param {Object} position
  16788. */
  16789. ZoomScroll.prototype.stepZoom = function stepZoom(delta, position) {
  16790. var stepSize = getStepSize(RANGE, NUM_STEPS);
  16791. this._zoom(delta, position, stepSize);
  16792. };
  16793. /**
  16794. * Zoom in/out given a step size.
  16795. *
  16796. * @param {number} delta
  16797. * @param {Object} position
  16798. * @param {number} stepSize
  16799. */
  16800. ZoomScroll.prototype._zoom = function (delta, position, stepSize) {
  16801. var canvas = this._canvas;
  16802. var direction = delta > 0 ? 1 : -1;
  16803. var currentLinearZoomLevel = log10(canvas.zoom());
  16804. // snap to a proximate zoom step
  16805. var newLinearZoomLevel = Math.round(currentLinearZoomLevel / stepSize) * stepSize;
  16806. // increase or decrease one zoom step in the given direction
  16807. newLinearZoomLevel += stepSize * direction;
  16808. // calculate the absolute logarithmic zoom level based on the linear zoom level
  16809. // (e.g. 2 for an absolute x2 zoom)
  16810. var newLogZoomLevel = Math.pow(10, newLinearZoomLevel);
  16811. canvas.zoom(cap(RANGE, newLogZoomLevel), position);
  16812. };
  16813. /**
  16814. * Toggle the zoom scroll ability via mouse wheel.
  16815. *
  16816. * @param {boolean} [newEnabled] new enabled state
  16817. */
  16818. ZoomScroll.prototype.toggle = function toggle(newEnabled) {
  16819. var element = this._container;
  16820. var handleWheel = this._handleWheel;
  16821. var oldEnabled = this._enabled;
  16822. if (typeof newEnabled === 'undefined') {
  16823. newEnabled = !oldEnabled;
  16824. }
  16825. // only react on actual changes
  16826. if (oldEnabled !== newEnabled) {
  16827. // add or remove wheel listener based on
  16828. // changed enabled state
  16829. componentEvent[newEnabled ? 'bind' : 'unbind'](element, 'wheel', handleWheel, false);
  16830. }
  16831. this._enabled = newEnabled;
  16832. return newEnabled;
  16833. };
  16834. ZoomScroll.prototype._init = function (newEnabled) {
  16835. this.toggle(newEnabled);
  16836. };
  16837. var ZoomScrollModule = {
  16838. __init__: ['zoomScroll'],
  16839. zoomScroll: ['type', ZoomScroll]
  16840. };
  16841. /**
  16842. * A viewer that includes mouse navigation facilities
  16843. *
  16844. * @param {Object} options
  16845. */
  16846. function NavigatedViewer(options) {
  16847. Viewer.call(this, options);
  16848. }
  16849. inherits_browser(NavigatedViewer, Viewer);
  16850. NavigatedViewer.prototype._navigationModules = [
  16851. KeyboardMoveModule,
  16852. MoveCanvasModule,
  16853. ZoomScrollModule
  16854. ];
  16855. NavigatedViewer.prototype._modules = [].concat(
  16856. Viewer.prototype._modules,
  16857. NavigatedViewer.prototype._navigationModules
  16858. );
  16859. return NavigatedViewer;
  16860. }));